libdwarf-20210528/0000775000175000017500000000000014054271043010554 500000000000000libdwarf-20210528/libdwarf/0000775000175000017500000000000014054271043012346 500000000000000libdwarf-20210528/libdwarf/pro_macinfo.h0000644000175000017500000000227113743575426014753 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); libdwarf-20210528/libdwarf/dwarf_tied_decls.h0000664000175000017500000000326714012266121015724 00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define HASHSEARCH #ifdef HASHSEARCH /* Only needed for hash based search in a tsearch style. */ #define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) #else #define INITTREE(x,y) #endif /* HASHSEARCH */ /* Contexts are in a list in a dbg and do not move once established. So saving one is ok. as long as the dbg exists. */ struct Dwarf_Tied_Entry_s { Dwarf_Sig8 dt_key; Dwarf_CU_Context dt_context; }; int _dwarf_tied_compare_function(const void *l, const void *r); void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val); DW_TSHASHTYPE _dwarf_tied_data_hashfunc(const void *keyp); libdwarf-20210528/libdwarf/pro_finish.c0000664000175000017500000000701513764007262014604 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include "pro_incl.h" #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" /* This routine deallocates all memory, and does some finishing up This is the original version using a badly designed return value approach. Please use dwarf_producer_finish_a() instead. */ /*ARGSUSED*/ Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error) { int res = dwarf_producer_finish_a(dbg,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } /* This routine deallocates all memory, and does some finishing up. New September 2016. */ int dwarf_producer_finish_a(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* this frees all blocks, then frees dbg. */ free(dbg->de_debug_sup.ds_filename); dbg->de_debug_sup.ds_filename = 0; dbg->de_debug_sup.ds_version = 0; free(dbg->de_debug_sup.ds_checksum); dbg->de_debug_sup.ds_checksum = 0; dbg->de_debug_sup.ds_checksum_len = 0; _dwarf_p_dealloc_all(dbg); return DW_DLV_OK ; } /* FIXME: Add stats for debug_line_str. */ int dwarf_pro_get_string_stats(Dwarf_P_Debug dbg, Dwarf_Unsigned * str_count, Dwarf_Unsigned * str_total_length, Dwarf_Unsigned * strp_count_debug_str, Dwarf_Unsigned * strp_len_debug_str, Dwarf_Unsigned * strp_reused_count, Dwarf_Unsigned * strp_reused_len, Dwarf_Error * error) { struct Dwarf_P_Str_stats_s* ps = 0; if (!dbg) { _dwarf_p_error(dbg, error, DW_DLE_IA); return DW_DLV_ERROR; } if (dbg->de_version_magic_number !=PRO_VERSION_MAGIC ) { _dwarf_p_error(dbg, error, DW_DLE_VMM); return DW_DLV_ERROR; } *str_count = dbg->de_stats.ps_str_count; *str_total_length = dbg->de_stats.ps_str_total_length; ps = &dbg->de_stats.ps_strp; *strp_count_debug_str = ps->ps_strp_count_debug_str; *strp_len_debug_str = ps->ps_strp_len_debug_str; *strp_reused_count = ps->ps_strp_reused_count; *strp_reused_len = ps->ps_strp_reused_len; return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_error.c0000664000175000017500000000676113764007262014464 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" extern char *_dwarf_errmsgs[]; /* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_P_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. The error number may be retrieved from the Dwarf_Error by calling dwarf_errno(). The error string implied by the error number may be retrieved from the Dwarf_Error by calling dwarf_errmsg(). */ void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, Dwarf_Unsigned errval) { Dwarf_Error errptr; if (errval > DW_DLE_LAST) { /* We do not expect to ever see such an error number, DW_DLE_LO_USER is not used. */ fprintf(stderr,"ERROR VALUE: %lu - %s\n", (unsigned long) errval, "this error value is unknown to libdwarf."); } /* 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) { errptr = (Dwarf_Error) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure\n"); abort(); } errptr->er_errval = (Dwarf_Signed) errval; *error = errptr; return; } if (dbg != NULL && dbg->de_errhand != NULL) { errptr = (Dwarf_Error) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure\n"); abort(); } errptr->er_errval = (Dwarf_Signed) errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } abort(); } libdwarf-20210528/libdwarf/pro_util.h0000664000175000017500000000271514012266121014274 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Definition of sizes of types. Independent of target or host, these are. */ #define sizeof_ubyte(dbg) 1 #define sizeof_uhalf(dbg) DWARF_HALF_SIZE /* Computes amount of padding necessary to align n to a k-boundary. */ /* Important: Assumes n, k both GREATER than zero. */ #define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) ) libdwarf-20210528/libdwarf/dwarf_elf_reloc_ppc64.h0000664000175000017500000001770513644370703016611 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_ppc64(unsigned long); #ifndef R_PPC64_ADDR30 #define R_PPC64_ADDR30 37 #endif /* R_PPC64_ADDR30 */ #ifndef R_PPC64_ADDR64 #define R_PPC64_ADDR64 38 #endif /* R_PPC64_ADDR64 */ #ifndef R_PPC64_ADDR16_HIGHER #define R_PPC64_ADDR16_HIGHER 39 #endif /* R_PPC64_ADDR16_HIGHER */ #ifndef R_PPC64_ADDR16_HIGHERA #define R_PPC64_ADDR16_HIGHERA 40 #endif /* R_PPC64_ADDR16_HIGHERA */ #ifndef R_PPC64_ADDR16_HIGHEST #define R_PPC64_ADDR16_HIGHEST 41 #endif /* R_PPC64_ADDR16_HIGHEST */ #ifndef R_PPC64_ADDR16_HIGHESTA #define R_PPC64_ADDR16_HIGHESTA 42 #endif /* R_PPC64_ADDR16_HIGHESTA */ #ifndef R_PPC64_UADDR64 #define R_PPC64_UADDR64 43 #endif /* R_PPC64_UADDR64 */ #ifndef R_PPC64_REL64 #define R_PPC64_REL64 44 #endif /* R_PPC64_REL64 */ #ifndef R_PPC64_PLT64 #define R_PPC64_PLT64 45 #endif /* R_PPC64_PLT64 */ #ifndef R_PPC64_PLTREL64 #define R_PPC64_PLTREL64 46 #endif /* R_PPC64_PLTREL64 */ #ifndef R_PPC64_TOC16 #define R_PPC64_TOC16 47 #endif /* R_PPC64_TOC16 */ #ifndef R_PPC64_TOC16_LO #define R_PPC64_TOC16_LO 48 #endif /* R_PPC64_TOC16_LO */ #ifndef R_PPC64_TOC16_HI #define R_PPC64_TOC16_HI 49 #endif /* R_PPC64_TOC16_HI */ #ifndef R_PPC64_TOC16_HA #define R_PPC64_TOC16_HA 50 #endif /* R_PPC64_TOC16_HA */ #ifndef R_PPC64_TOC #define R_PPC64_TOC 51 #endif /* R_PPC64_TOC */ #ifndef R_PPC64_PLTGOT16 #define R_PPC64_PLTGOT16 52 #endif /* R_PPC64_PLTGOT16 */ #ifndef R_PPC64_PLTGOT16_LO #define R_PPC64_PLTGOT16_LO 53 #endif /* R_PPC64_PLTGOT16_LO */ #ifndef R_PPC64_PLTGOT16_HI #define R_PPC64_PLTGOT16_HI 54 #endif /* R_PPC64_PLTGOT16_HI */ #ifndef R_PPC64_PLTGOT16_HA #define R_PPC64_PLTGOT16_HA 55 #endif /* R_PPC64_PLTGOT16_HA */ #ifndef R_PPC64_ADDR16_DS #define R_PPC64_ADDR16_DS 56 #endif /* R_PPC64_ADDR16_DS */ #ifndef R_PPC64_ADDR16_LO_DS #define R_PPC64_ADDR16_LO_DS 57 #endif /* R_PPC64_ADDR16_LO_DS */ #ifndef R_PPC64_GOT16_DS #define R_PPC64_GOT16_DS 58 #endif /* R_PPC64_GOT16_DS */ #ifndef R_PPC64_GOT16_LO_DS #define R_PPC64_GOT16_LO_DS 59 #endif /* R_PPC64_GOT16_LO_DS */ #ifndef R_PPC64_PLT16_LO_DS #define R_PPC64_PLT16_LO_DS 60 #endif /* R_PPC64_PLT16_LO_DS */ #ifndef R_PPC64_SECTOFF_DS #define R_PPC64_SECTOFF_DS 61 #endif /* R_PPC64_SECTOFF_DS */ #ifndef R_PPC64_SECTOFF_LO_DS #define R_PPC64_SECTOFF_LO_DS 62 #endif /* R_PPC64_SECTOFF_LO_DS */ #ifndef R_PPC64_TOC16_DS #define R_PPC64_TOC16_DS 63 #endif /* R_PPC64_TOC16_DS */ #ifndef R_PPC64_TOC16_LO_DS #define R_PPC64_TOC16_LO_DS 64 #endif /* R_PPC64_TOC16_LO_DS */ #ifndef R_PPC64_PLTGOT16_DS #define R_PPC64_PLTGOT16_DS 65 #endif /* R_PPC64_PLTGOT16_DS */ #ifndef R_PPC64_PLTGOT16_LO_DS #define R_PPC64_PLTGOT16_LO_DS 66 #endif /* R_PPC64_PLTGOT16_LO_DS */ #ifndef R_PPC64_TLS #define R_PPC64_TLS 67 #endif /* R_PPC64_TLS */ #ifndef R_PPC64_DTPMOD64 #define R_PPC64_DTPMOD64 68 #endif /* R_PPC64_DTPMOD64 */ #ifndef R_PPC64_TPREL16 #define R_PPC64_TPREL16 69 #endif /* R_PPC64_TPREL16 */ #ifndef R_PPC64_TPREL16_LO #define R_PPC64_TPREL16_LO 70 #endif /* R_PPC64_TPREL16_LO */ #ifndef R_PPC64_TPREL16_HI #define R_PPC64_TPREL16_HI 71 #endif /* R_PPC64_TPREL16_HI */ #ifndef R_PPC64_TPREL16_HA #define R_PPC64_TPREL16_HA 72 #endif /* R_PPC64_TPREL16_HA */ #ifndef R_PPC64_TPREL64 #define R_PPC64_TPREL64 73 #endif /* R_PPC64_TPREL64 */ #ifndef R_PPC64_DTPREL16 #define R_PPC64_DTPREL16 74 #endif /* R_PPC64_DTPREL16 */ #ifndef R_PPC64_DTPREL16_LO #define R_PPC64_DTPREL16_LO 75 #endif /* R_PPC64_DTPREL16_LO */ #ifndef R_PPC64_DTPREL16_HI #define R_PPC64_DTPREL16_HI 76 #endif /* R_PPC64_DTPREL16_HI */ #ifndef R_PPC64_DTPREL16_HA #define R_PPC64_DTPREL16_HA 77 #endif /* R_PPC64_DTPREL16_HA */ #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif /* R_PPC64_DTPREL64 */ #ifndef R_PPC64_GOT_TLSGD16 #define R_PPC64_GOT_TLSGD16 79 #endif /* R_PPC64_GOT_TLSGD16 */ #ifndef R_PPC64_GOT_TLSGD16_LO #define R_PPC64_GOT_TLSGD16_LO 80 #endif /* R_PPC64_GOT_TLSGD16_LO */ #ifndef R_PPC64_GOT_TLSGD16_HI #define R_PPC64_GOT_TLSGD16_HI 81 #endif /* R_PPC64_GOT_TLSGD16_HI */ #ifndef R_PPC64_GOT_TLSGD16_HA #define R_PPC64_GOT_TLSGD16_HA 82 #endif /* R_PPC64_GOT_TLSGD16_HA */ #ifndef R_PPC64_GOT_TLSLD16 #define R_PPC64_GOT_TLSLD16 83 #endif /* R_PPC64_GOT_TLSLD16 */ #ifndef R_PPC64_GOT_TLSLD16_LO #define R_PPC64_GOT_TLSLD16_LO 84 #endif /* R_PPC64_GOT_TLSLD16_LO */ #ifndef R_PPC64_GOT_TLSLD16_HI #define R_PPC64_GOT_TLSLD16_HI 85 #endif /* R_PPC64_GOT_TLSLD16_HI */ #ifndef R_PPC64_GOT_TLSLD16_HA #define R_PPC64_GOT_TLSLD16_HA 86 #endif /* R_PPC64_GOT_TLSLD16_HA */ #ifndef R_PPC64_GOT_TPREL16_DS #define R_PPC64_GOT_TPREL16_DS 87 #endif /* R_PPC64_GOT_TPREL16_DS */ #ifndef R_PPC64_GOT_TPREL16_LO_DS #define R_PPC64_GOT_TPREL16_LO_DS 88 #endif /* R_PPC64_GOT_TPREL16_LO_DS */ #ifndef R_PPC64_GOT_TPREL16_HI #define R_PPC64_GOT_TPREL16_HI 89 #endif /* R_PPC64_GOT_TPREL16_HI */ #ifndef R_PPC64_GOT_TPREL16_HA #define R_PPC64_GOT_TPREL16_HA 90 #endif /* R_PPC64_GOT_TPREL16_HA */ #ifndef R_PPC64_GOT_DTPREL16_DS #define R_PPC64_GOT_DTPREL16_DS 91 #endif /* R_PPC64_GOT_DTPREL16_DS */ #ifndef R_PPC64_GOT_DTPREL16_LO_DS #define R_PPC64_GOT_DTPREL16_LO_DS 92 #endif /* R_PPC64_GOT_DTPREL16_LO_DS */ #ifndef R_PPC64_GOT_DTPREL16_HI #define R_PPC64_GOT_DTPREL16_HI 93 #endif /* R_PPC64_GOT_DTPREL16_HI */ #ifndef R_PPC64_GOT_DTPREL16_HA #define R_PPC64_GOT_DTPREL16_HA 94 #endif /* R_PPC64_GOT_DTPREL16_HA */ #ifndef R_PPC64_TPREL16_DS #define R_PPC64_TPREL16_DS 95 #endif /* R_PPC64_TPREL16_DS */ #ifndef R_PPC64_TPREL16_LO_DS #define R_PPC64_TPREL16_LO_DS 96 #endif /* R_PPC64_TPREL16_LO_DS */ #ifndef R_PPC64_TPREL16_HIGHER #define R_PPC64_TPREL16_HIGHER 97 #endif /* R_PPC64_TPREL16_HIGHER */ #ifndef R_PPC64_TPREL16_HIGHERA #define R_PPC64_TPREL16_HIGHERA 98 #endif /* R_PPC64_TPREL16_HIGHERA */ #ifndef R_PPC64_TPREL16_HIGHEST #define R_PPC64_TPREL16_HIGHEST 99 #endif /* R_PPC64_TPREL16_HIGHEST */ #ifndef R_PPC64_TPREL16_HIGHESTA #define R_PPC64_TPREL16_HIGHESTA 100 #endif /* R_PPC64_TPREL16_HIGHESTA */ #ifndef R_PPC64_DTPREL16_DS #define R_PPC64_DTPREL16_DS 101 #endif /* R_PPC64_DTPREL16_DS */ #ifndef R_PPC64_DTPREL16_LO_DS #define R_PPC64_DTPREL16_LO_DS 102 #endif /* R_PPC64_DTPREL16_LO_DS */ #ifndef R_PPC64_DTPREL16_HIGHER #define R_PPC64_DTPREL16_HIGHER 103 #endif /* R_PPC64_DTPREL16_HIGHER */ #ifndef R_PPC64_DTPREL16_HIGHERA #define R_PPC64_DTPREL16_HIGHERA 104 #endif /* R_PPC64_DTPREL16_HIGHERA */ #ifndef R_PPC64_DTPREL16_HIGHEST #define R_PPC64_DTPREL16_HIGHEST 105 #endif /* R_PPC64_DTPREL16_HIGHEST */ #ifndef R_PPC64_DTPREL16_HIGHESTA #define R_PPC64_DTPREL16_HIGHESTA 106 #endif /* R_PPC64_DTPREL16_HIGHESTA */ #ifndef R_PPC64_TOC32 #define R_PPC64_TOC32 107 #endif /* R_PPC64_TOC32 */ #ifndef R_PPC64_DTPMOD32 #define R_PPC64_DTPMOD32 108 #endif /* R_PPC64_DTPMOD32 */ #ifndef R_PPC64_TPREL32 #define R_PPC64_TPREL32 109 #endif /* R_PPC64_TPREL32 */ #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif /* R_PPC64_DTPREL32 */ #ifndef R_PPC64_ADDR16_HIGHA #define R_PPC64_ADDR16_HIGHA 111 #endif /* R_PPC64_ADDR16_HIGHA */ #ifndef R_PPC64_TPREL16_HIGH #define R_PPC64_TPREL16_HIGH 112 #endif /* R_PPC64_TPREL16_HIGH */ #ifndef R_PPC64_TPREL16_HIGHA #define R_PPC64_TPREL16_HIGHA 113 #endif /* R_PPC64_TPREL16_HIGHA */ #ifndef R_PPC64_DTPREL16_HIGH #define R_PPC64_DTPREL16_HIGH 114 #endif /* R_PPC64_DTPREL16_HIGH */ #ifndef R_PPC64_DTPREL16_HIGHA #define R_PPC64_DTPREL16_HIGHA 115 #endif /* R_PPC64_DTPREL16_HIGHA */ #ifndef R_PPC64_JMP_IREL #define R_PPC64_JMP_IREL 247 #endif /* R_PPC64_JMP_IREL */ #ifndef R_PPC64_IRELATIVE #define R_PPC64_IRELATIVE 248 #endif /* R_PPC64_IRELATIVE */ #ifndef R_PPC64_REL16 #define R_PPC64_REL16 249 #endif /* R_PPC64_REL16 */ #ifndef R_PPC64_REL16_LO #define R_PPC64_REL16_LO 250 #endif /* R_PPC64_REL16_LO */ #ifndef R_PPC64_REL16_HI #define R_PPC64_REL16_HI 251 #endif /* R_PPC64_REL16_HI */ #ifndef R_PPC64_REL16_HA #define R_PPC64_REL16_HA 252 #endif /* R_PPC64_REL16_HA */ libdwarf-20210528/libdwarf/libdwarf2.1.mm0000664000175000017500000170105314047776052014657 00000000000000\." the following line may be removed if the \." ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." Increment body point size .S +2 \." ============================================== \." Put current date in the following at each rev .ds vE Rev 3.27 15 May 2021 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 4 \." set P one lower than desired start of printed page number of real \." content to get pdf and printed numbers to agree. .nr P 15 1 .SA 1 .TL A Consumer Library Interface to DWARF .AF "" .AU "David Anderson" .PF "'\*(vE'- \\\\nP -''" .AS 1 This document describes an interface to a library of functions to access DWARF debugging information entries, DWARF line number information, and other DWARF2/3/4/5 information). .P There are a few sections which are SGI-specific (those are clearly identified in the document). .P Starting December 2020 we rearrange the pdf that GNU groff -mm gives us (mm is not exceptionally flexible) using tools pdftotext, pdfseparate, and pdfunite from the poppler-utils package for debian/ubuntu. We hope the new arrangement with the table of contents following this page followed by the library documentation itself makes the document easier to navigate. .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" This document describes an interface to \fIlibdwarf\fP, a library of functions to provide access to DWARF debugging information records, DWARF line number information, DWARF address range and global names information, weak names information, DWARF frame description information, DWARF static function names, DWARF static variables, and DWARF type information. .P The document has long mentioned the "Unix International Programming Languages Special Interest Group" (PLSIG), under whose auspices the DWARF committee was formed around 1991. "Unix International" was disbanded in the 1990s and no longer exists. .P The DWARF committee published DWARF2 July 27, 1993. .P In the mid 1990s this document and the library it describes (which the committee never endorsed, having decided not to endorse or approve any particular library interface) was made available on the internet by Silicon Graphics, Inc. .P In 2005 the DWARF committee began an affiliation with FreeStandards.org. In 2007 FreeStandards.org merged with The Linux Foundation. The DWARF committee dropped its affiliation with FreeStandards.org in 2007 and established the dwarfstd.org website. See "http://www.dwarfstd.org" for current information on standardization activities and a copy of the standard. .H 2 "Copyright" Copyright 1993-2006 Silicon Graphics, Inc. Copyright 2007-2019 David Anderson. Permission is hereby granted to copy or republish or use any or all of this document without restriction except that when publishing more than a small amount of the document please acknowledge Silicon Graphics, Inc and David Anderson. This document is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .H 2 "Purpose and Scope" The purpose of this document is to document a library of functions to access DWARF debugging information. There is no effort made in this document to address the creation of these records as those issues are addressed separately (see "A Producer Library Interface to DWARF"). .P Additionally, the focus of this document is the functional interface, and as such, implementation as well as optimization issues are intentionally ignored. .H 2 "Document History" .P A document was written about 1991 which had similar layout and interfaces. Written by people from Hal Corporation, That document described a library for reading DWARF1. The authors distributed paper copies to the committee with the clearly expressed intent to propose the document as a supported interface definition. The committee decided not to pursue a library definition. .P SGI wrote the document you are now reading in 1993 with a similar layout and content and organization, but it was complete document rewrite with the intent to read DWARF2 (the DWARF version then in existence). The intent was (and is) to also cover future revisions of DWARF. All the function interfaces were changed in 1994 to uniformly return a simple integer success-code (see DW_DLV_OK etc), generally following the recommendations in the chapter titled "Candy Machine Interfaces" of "Writing Solid Code", a book by Steve Maguire (published by Microsoft Press). .H 2 "Definitions" DWARF debugging information entries (DIEs) are the segments of information placed in the \f(CW.debug_*\fP sections by compilers, assemblers, and linkage editors that, in conjunction with line number entries, are necessary for symbolic source-level debugging. Refer to the latest "\fIDWARF Debugging Information Format\fP" from www.dwarfstd.org for a more complete description of these entries. .P This document adopts all the terms and definitions in "\fIDWARF Debugging Information Format\fP" versions 2,3,4, and 5. It originally focused on the implementation at Silicon Graphics, Inc., but now attempts to be more generally useful. .H 2 "Overview" The remaining sections of this document describe the proposed interface to \f(CWlibdwarf\fP, first by describing the purpose of additional types defined by the interface, followed by descriptions of the available operations. This document assumes you are thoroughly familiar with the information contained in the \fIDWARF Debugging Information Format\fP document. .P We separate the functions into several categories to emphasize that not all consumers want to use all the functions. We call the categories Debugger, Internal-level, High-level, and Miscellaneous not because one is more important than another but as a way of making the rather large set of function calls easier to understand. .P Unless otherwise specified, all functions and structures should be taken as being designed for Debugger consumers. .P The Debugger Interface of this library is intended to be used by debuggers. The interface is low-level (close to dwarf) but suppresses irrelevant detail. A debugger will want to absorb all of some sections at startup and will want to see little or nothing of some sections except at need. And even then will probably want to absorb only the information in a single compilation unit at a time. A debugger does not care about implementation details of the library. .P The Internal-level Interface is for a DWARF prettyprinter and checker. A thorough prettyprinter will want to know all kinds of internal things (like actual FORM numbers and actual offsets) so it can check for appropriate structure in the DWARF data and print (on request) all that internal information for human users and libdwarf authors and compiler-writers. Calls in this interface provide data a debugger does not normally care about. .P The High-level Interface is for higher level access (it is not really a high level interface!). Programs such as disassemblers will want to be able to display relevant information about functions and line numbers without having to invest too much effort in looking at DWARF. .P The miscellaneous interface is just what is left over: the error handler functions. .P The following is a brief mention of the changes in this libdwarf from the libdwarf draft for DWARF Version 1 and recent changes. .H 2 "Items Changed" .P Added dwarf_get_FORM_CLASS_name() so library uses can print a form class value usefully. 2 February 2021. .P Added dwarf_decode_leb128() and dwarf_decode_signed_leb128() so library users can access these library-internal functions. .P Added dwarf_macro_context_total_length() because callers of dwarf_get_macro_context[_by_offset]() sometimes want to know the length of ops + header. .P The description of dwarf_srcfiles() now reflects the difference in line table handling between DWARF5 and other line table versions. If using dwarf_srcfiles() do read its documentation here (Section 6.14, page 117 in this version). .P Added functions dwarf_crc32() and dwarf_basic_crc32() so libdwarf can check debuglink/build-id CRC values. .P Clarified the DW_DLC* value meaning here and in libdwarf.h. In the consumer/reader case DW_DLC_READ is zero and zero is the only meaningful value to pass as the 'access' argument of dwarf_init(and the like) consumer/reader initialization functions. All this has been true for many years, it is only now being clearly (one hopes) stated. (September 28, 2020) .P Added dwarf_get_ranges_b() so clients reading DWARF4 split dwarf (a GNU extension) can get the final offset of the ranges. (September 10, 2020) .P All the dwarf_init*() and dwarf_elf_init*() calls have always been able to return DW_DLV_ERROR with a Dwarf_Error pointer returned too. We now update the advice on dealing with this situation, unifying with the rest of libdwarf errors. (September 9, 2020) .P The documentation of dwarf_init_path() was basically correct but omitted meaningful mention of the dbg argument and a little wrongly described the error argument (July 22, 2020); .P Added dwarf_get_debug_sup() to retrived the DWARF5 section .debug_sup content. (July 13, 2020); .P Added new functions for reading .debug_gnu_pubtypes and .debug_gnu_pubnames. dwarf_get_gnu_index_head() dwarf_gnu_index_dealloc dwarf_get_gnu_index_block() dwarf_get_gnu_index_block_entry() (July 9, 2020); .P Added new functions for full .debug_loclists access: dwarf_get_locdesc_entry_d(), dwarf_get_loclist_head_basics(), dwarf_get_loclist_head_kind(), and dwarf_loc_head_c_dealloc(). For accessing certain DWARF5 new location operators (for example DW_OP_const_type) as well as all other operators we add dwarf_get_location_op_value_d(). Added functions allowing simple reporting of .debug_loclists without involving other sections: dwarf_load_loclists(), dwarf_get_loclist_context_basics(), dwarf_get_loclist_lle(), dwarf_get_loclist_offset_index_value(), and dwarf_get_loclist_raw_entry_detail(). (June 10, 2020); .P Added new functions for full .debug_rnglists support and fixed issues with DWARF5 .debug_addr index FORMs. New functions for general use: dwarf_addr_form_is_indexed(), dwarf_get_rnglists_entry_fields_a(), dwarf_rnglists_get_rle_head(), dwarf_dealloc_rnglists_head(), New functions for a complete listing of the .debug_rnglists section. dwarf_load_rnglists(), dwarf_get_rnglist_offset_index_value(), dwarf_get_rnglist_context(), dwarf_get_rnglist_head_basics(), dwarf_get_rnglist_context_basics(), dwarf_get_rnglist_rle(). Also added new functions dwarf_dealloc_die(), dwarf_dealloc_error(), and dwarf_dealloc_attribute() to provide type-safe calls for deallocation of the specific data types. (May 20, 2020) .P What was historically called 'length_size' in libdwarf and dwarfdump is actually the size of an offset (4 or 8 in DWARF2,3,4 and 5). For readability all instances of 'length_size' are being converted, as time permits, to 'offset_size'. (May 1, 2020) .P Added a new function dwarf_set_de_alloc_flag() which allows turning-off of libdwarf-internal allocation tracking to improve libdwarf performance a few percent (which only really matters with giant DWARF sections). The downside of turning off the flag is consumer code must do all the dwarf_dealloc() calls itself to avoid memory leaks. (March 14, 2020) .P Corrected the documentation of dwarf_diename: It was never appropriate to use dwarf_dealloc on the string pointer returned but Up till now this document said such a call was required. (March 14, 2020) .P Now we document here that if one uses dwarf_init() or dwarf_init_b() or dwarf_init_path() that the function dwarf_get_elf() cannot succeed as there is no longer any Elf pointer (from libelf) to return. (November 26, 2019) .P New function dwarf_gnu_debuglink() allow callers to access fields that GNU compilers create and use to link an executable to its separate DWARF debugging content object file. (September 9, 2019, updated October 2019) .P dwarf_next_cu_header_d() (and the other earlier versions of this) now allow a null in place of a pointer for next_cu_offset. dwarf_hipc_b() now allows a null in place of the return_form and/or return_class arguments. Unless you know a sufficiently recent libdwarf is to be used it is not safe to pass those arguments as null pointers. This allowance of null is because we've become aware that the relevant NetBSD man pages on these functions incorrectly specified that null was allowed. (April 22,2019) .P The dwarf_elf_init() and dwarf_elf_init_b() are now deprecated as they require the use of elf.h and libelf.h and libelf. Use dwarf_init_path() or dwarf_init_b() instead. The new non-libelf reader code checks elf header values more thoroughly than libelf and detects corrupted Elf earlier and in more cases than libelf. Since the reports of elf corruption from libdwarf/dwarfdump are not detailed we suggest one use an object dumper to check the object file in question. Two useful object dumpers are GNU readelf (part of GNU binutils) and readelfobj (part of the readelfobj project on sourceforge.net). readelfobj uses essentially the same algorithms as libdwarf does and should report something meaningful. (April 20,2019) .P Added support for MacOS dSYM objects and PE object files as well as an initialization function allowing a path instead of a Posix/Unix fd or a libelf Elf*. (January 2019) .P Added a libdwarf interface dwarf_errmsg_by_number() so that places in the code that can have errors but do not want the Dwarf_Error complexities can report more details than just an error number. (December 19, 2018) .P Now Mach-o dSYM files containing dwarf are readable by libdwarf and their DWARF dumped by dwarfdump. There are no new options or choices, libdwarf and dwarfdump notice which kind of object they are processing. New functions added to libdwarf.h.in: dwarf_init_path(),dwarf_object_detector_path(), and dwarf_object_detector_fd(). (October 24, 2018) .P All references to Dwarf_Frame_Op3 have been removed as that struct was never created or available. The new function dwarf_get_fde_info_for_reg3_b() is documented. (May 12, 2018) .P With DWARF5 it became harder to use dwarf_srclines_data_b() as DWARF5 changed each line table header file table to zero-based indexing from one-based (and made the primary file index zero). So a new function dwarf_srclines_file_indexes() returns values that make it easy to step through and call dwarf_srclines_data_b() sensibly whether the line table is DWARF2,3,4, or 5. (March 23, 2018) .P Added COMDAT support. Recent compilers generate COMDAT sections (for some DWARF information) routinely so this became important recently. The new libdwarf COMDAT support extends the groupnumber idea as suggested just below. (May 17, 2017) .P Adding dwarf_init_b() and dwarf_elf_init_b() and dwarf_object_init_b() with a groupnumber option added. DWARF5 adds split-dwarf and we call original sections like .debug_info group one and new sections like .debug_info.dwo group two. It has not escaped our attention that this numbering can be extended to deal with Elf COMDAT section groups of DWARF information, though COMDAT groups are not currently supported. (April 02, 2017) .P Adding support for DWARF5 .debug_loc.dwo and split dwarf range tables. Added dwarf_get_offset_size(). (November 08, 2015) .P Adding support for reading DWARF5 line tables and GNU two-level line tables. The function dwarf_srclines() still works but those using DWARF4 or DWARF5 are advised to switch to dwarf_srclines_b(). dwarf_srclines() cannot handle skeleton line tables sensibly and a new interface was needed for two-level line tables so the new approach satisfies both. (October 5,2015) .P Adding support for Package Files (DWARF5) to enable access of address data using DW_FORM_addrx. See dwarf_set_tied_dbg(). (September 13, 2015) .P Adding some DWARF5 support and improved DWP Package File support, using dwarf_next_cu_header_d(). .P Added a note about dwarf_errmsg(): the string pointer returned should be considered ephemeral, not a string which remains valid permanently. User code should print it or copy it before calling other libdwarf functions on the specific Dwarf_Debug instance. (May 15, 2014) .P Added a printf-callback so libdwarf will not actually print to \f(CWstdout\fP. Added dwarf_highpc_b() so return of a DWARF4 DW_AT_high_pc of class constant can be returned properly. (August 15 2013) .P Defined how the new operator DW_OP_GNU_const_type is handled. (January 26 2013) .P Added dwarf_loclist_from_expr_b() function which adds arguments of the DWARF version (2 for DWARF2, etc) and the offset size to the dwarf_loclist_from_expr_a() function. Because the DW_OP_GNU_implicit_pointer opcode is defined differently for DWARF2 than for later versions. (November 2012) .P Added new functions (some for libdwarf client code) and internal logic support for the DWARF4 .debug_types section. The new functions are dwarf_next_cu_header_c(), dwarf_siblingof_b(), dwarf_offdie_b(), dwarf_get_cu_die_offset_given_cu_header_offset_b(), dwarf_get_die_infotypes_flag(), dwarf_get_section_max_offsets_b(). .P New functions and logic support additional detailed error reporting so that more compiler bugs can be reported sensibly by consumer code (as opposed to having libdwarf just assume things are ok and blindly continuing on with erroneous data). November 20, 2010 .P It seems impossible to default to both DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3 in a single build of libdwarf, so the default is now unambiguously DW_FRAME_CFA_COL3 unless the configure option --enable-oldframecol is specified at configure time. The function dwarf_set_frame_cfa_value() may be used to override the default : using that function gives consumer applications full control (its use is highly recommended). (January 17,2010) .P Added dwarf_set_reloc_application() and the default automatic application of Elf 'rela' relocations to DWARF sections (such rela sections appear in .o files, not in executables or shared objects, in general). The dwarf_set_reloc_application() routine lets a consumer turn off the automatic application of 'rela' relocations if desired (it is not clear why anyone would really want to do that, but possibly a consumer could write its own relocation application). An example application that traverses a set of DIEs was added to the new dwarfexample directory (not in this libdwarf directory, but in parallel to it). (July 10, 2009) .P Added dwarf_get_TAG_name() (and the FORM AT and so on) interface functions so applications can get the string of the TAG, Attribute, etc as needed. (June 2009) .P Added dwarf_get_ranges_a() and dwarf_loclist_from_expr_a() functions which add arguments allowing a correct address_size when the address_size varies by compilation unit (a varying address_size is quite rare as of May 2009). (May 2009) .P Added dwarf_set_frame_same_value(), and dwarf_set_frame_undefined_value() to complete the set of frame-information functions needed to allow an application get all frame information returned correctly (meaning that it can be correctly interpreted) for all ABIs. Documented dwarf_set_frame_cfa_value(). Corrected spelling to dwarf_set_frame_rule_initial_value(). (April 2009). .P Added support for various DWARF3 features, but primarily a new frame-information interface tailorable at run-time to more than a single ABI. See dwarf_set_frame_rule_initial_value(), dwarf_set_frame_rule_table_size(), dwarf_set_frame_cfa_value(). See also dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_cfa_reg3(). (April 2006) .P Added support for DWARF3 .debug_pubtypes section. Corrected various leaks (revising dealloc() calls, adding new functions) and corrected dwarf_formstring() documentation. .P Added dwarf_srclines_dealloc() as the previous deallocation method documented for data returned by dwarf_srclines() was incapable of freeing all the allocated storage (14 July 2005). .P dwarf_nextglob(), dwarf_globname(), and dwarf_globdie() were all changed to operate on the items in the .debug_pubnames section. .P All functions were modified to return solely an error code. Data is returned through pointer arguments. This makes writing safe and correct library-using-code far easier. For justification for this approach, see the chapter titled "Candy Machine Interfaces" in the book "Writing Solid Code" by Steve Maguire. .H 2 "Items Removed" .P Dwarf_Type was removed since types are no longer special. .P dwarf_typeof() was removed since types are no longer special. .P Dwarf_Ellist was removed since element lists no longer are a special format. .P Dwarf_Bounds was removed since bounds have been generalized. .P dwarf_nextdie() was replaced by dwarf_next_cu_header() to reflect the real way DWARF is organized. The dwarf_nextdie() was only useful for getting to compilation unit beginnings, so it does not seem harmful to remove it in favor of a more direct function. .P dwarf_childcnt() is removed on grounds that no good use was apparent. .P dwarf_prevline() and dwarf_nextline() were removed on grounds this is better left to a debugger to do. Similarly, dwarf_dieline() was removed. .P dwarf_is1stline() was removed as it was not meaningful for the revised DWARF line operations. .P Any libdwarf implementation might well decide to support all the removed functionality and to retain the DWARF Version 1 meanings of that functionality. This would be difficult because the original libdwarf draft specification used traditional C library interfaces which confuse the values returned by successful calls with exceptional conditions like failures and 'no more data' indications. .H 2 "Revision History" .VL 15 .LI "September 2020" A new approach (simpler, more uniform) to deal with a failure of a dwarf_init*() or dwarf_elf_init*() call is described in Chapter 4. Improved support for split dwarf. Added dwarf_get_ranges_b(). .LI "May 2020" Adding support for DWARF5 sections .debug_rnglists and .debug_loclists. .LI "March 2020" Added dwarf_set_de_alloc_flag() so consumers get a little better performance from libdwarf. At a price. See the description a bit later here. .LI "January 2019" Added support for reading DWARF in PE object files. .LI "October 2018" Added support for reading MacOS dSYM object files. .LI "2017" Added support for nearly all of DWARF5. .LI "July 2014" Added support for the .gdb_index section and started support for the .debug_cu_index and .debug_tu_index sections. .LI "October 2011" DWARF4 support for reading .debug_types added. .LI "March 93" Work on DWARF2 SGI draft begins .LI "June 94" The function returns are changed to return an error/success code only. .LI "April 2006" Support for DWARF3 consumer operations is close to completion. .LI "November 2010" Added various new functions and improved error checking. .LI "March 2017" Adding support for DWARF5 split dwarf. .LE .H 1 "Types Definitions" .H 2 "General Description" The \fIlibdwarf.h\fP header file contains typedefs and preprocessor definitions of types and symbolic names used to reference objects of \fIlibdwarf\fP. The types defined by typedefs contained in \fIlibdwarf.h\fP all use the convention of adding \f(CWDwarf_\fP as a prefix and can be placed in three categories: .BL .LI Scalar types : The scalar types defined in \fIlibdwarf.h\fP are defined primarily for notational convenience and identification. Depending on the individual definition, they are interpreted as a value, a pointer, or as a flag. .LI Aggregate types : Some values can not be represented by a single scalar type; they must be represented by a collection of, or as a union of, scalar and/or aggregate types. .LI Opaque types : The complete definition of these types is intentionally omitted; their use is as handles for query operations, which will yield either an instance of another opaque type to be used in another query, or an instance of a scalar or aggregate type, which is the actual result. .P .H 2 "Scalar Types" The following are the defined by \fIlibdwarf.h\fP: .DS \f(CW typedef int Dwarf_Bool; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Unsigned; typedef unsigned short Dwarf_Half; typedef unsigned char Dwarf_Small; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Addr; typedef void *Dwarf_Ptr; typedef void (*Dwarf_Handler)(Dwarf_Error error, Dwarf_Ptr errarg); .DE .nr aX \n(Fg+1 Dwarf_Ptr is an address for use by the host program calling the library, not for representing pc-values/addresses within the target object file. Dwarf_Addr is for pc-values within the target object file. The sample scalar type assignments above are for a \fIlibdwarf.h\fP that can read and write 32-bit or 64-bit binaries on a 32-bit or 64-bit host machine. The types must be defined appropriately for each implementation of libdwarf. A description of these scalar types in the SGI/MIPS environment is given in Figure \n(aX. .DS .TS center box, tab(:); lfB lfB lfB lfB l c c l. NAME:SIZE:ALIGNMENT:PURPOSE _ Dwarf_Bool:4:4:Boolean states Dwarf_Off:8:8:Unsigned file offset Dwarf_Unsigned:8:8:Unsigned large integer Dwarf_Half:2:2:Unsigned medium integer Dwarf_Small:1:1:Unsigned small integer Dwarf_Signed:8:8:Signed large integer Dwarf_Addr:8:8:Program address :::(target program) Dwarf_Ptr:4|8:4|8:Dwarf section pointer :::(host program) Dwarf_Handler:4|8:4|8:Pointer to :::error handler function .TE .FG "Scalar Types" .DE .H 2 "Aggregate Types" The following aggregate types are defined by \fIlibdwarf.h\fP: \f(CWDwarf_Loc\fP, \f(CWDwarf_Locdesc\fP, \f(CWDwarf_Block\fP, \f(CWDwarf_Frame_Op\fP. \f(CWDwarf_Regtable\fP. \f(CWDwarf_Regtable3\fP. While most of \f(CWlibdwarf\fP acts on or returns simple values or opaque pointer types, this small set of structures seems useful. Yet, at the same time, these public structures are inflexible as any change in format or content breaks binary (and possibly source in some cases) compatibility. .H 3 "Location Record" The \f(CWDwarf_Loc\fP type identifies a single atom of a location description or a location expression. This is obsolete and should not be used, though it works adequately for DWARF2. .DS \f(CWtypedef struct { Dwarf_Small lr_atom; Dwarf_Unsigned lr_number; Dwarf_Unsigned lr_number2; Dwarf_Unsigned lr_offset; } Dwarf_Loc;\fP .DE The \f(CWlr_atom\fP identifies the atom corresponding to the \f(CWDW_OP_*\fP definition in \fIdwarf.h\fP and it represents the operation to be performed in order to locate the item in question. .P The \f(CWlr_number\fP field is the operand to be used in the calculation specified by the \f(CWlr_atom\fP field; not all atoms use this field. Some atom operations imply signed numbers so it is necessary to cast this to a \f(CWDwarf_Signed\fP type for those operations. .P The \f(CWlr_number2\fP field is the second operand specified by the \f(CWlr_atom\fP field; only \f(CWDW_OP_BREGX\fP has this field. Some atom operations imply signed numbers so it may be necessary to cast this to a \f(CWDwarf_Signed\fP type for those operations. .P For a \f(CWDW_OP_implicit_value\fP operator the \f(CWlr_number2\fP field is a pointer to the bytes of the value. The field pointed to is \f(CWlr_number\fP bytes long. There is no explicit terminator. Do not attempt to \f(CWfree\fP the bytes which \f(CWlr_number2\fP points at and do not alter those bytes. The pointer value remains valid till the open Dwarf_Debug is closed. This is a rather ugly use of a host integer to hold a pointer. You will normally have to do a 'cast' operation to use the value. .P For a \f(CWDW_OP_GNU_const_type\fP operator the \f(CWlr_number2\fP field is a pointer to a block with an initial unsigned byte giving the number of bytes following, followed immediately that number of const value bytes. There is no explicit terminator. Do not attempt to \f(CWfree\fP the bytes which \f(CWlr_number2\fP points at and do not alter those bytes. The pointer value remains valid till the open Dwarf_Debug is closed. This is a rather ugly use of a host integer to hold a pointer. You will normally have to do a 'cast' operation to use the value. .P The \f(CWlr_offset\fP field is the byte offset (within the block the location record came from) of the atom specified by the \f(CWlr_atom\fP field. This is set on all atoms. This is useful for operations \f(CWDW_OP_SKIP\fP and \f(CWDW_OP_BRA\fP. .H 3 "Location Description" This is obsolete and should not be used, though it works ok for DWARF2.. The \f(CWDwarf_Locdesc\fP type represents an ordered list of \f(CWDwarf_Loc\fP records used in the calculation to locate an item. Note that in many cases, the location can only be calculated at runtime of the associated program. .DS \f(CWtypedef struct { Dwarf_Addr ld_lopc; Dwarf_Addr ld_hipc; Dwarf_Unsigned ld_cents; Dwarf_Loc* ld_s; } Dwarf_Locdesc;\fP .DE The \f(CWld_lopc\fP and \f(CWld_hipc\fP fields provide an address range for which this location descriptor is valid. Both of these fields are set to \fIzero\fP if the location descriptor is valid throughout the scope of the item it is associated with. These addresses are virtual memory addresses, not offsets-from-something. The virtual memory addresses do not account for dso movement (none of the pc values from libdwarf do that, it is up to the consumer to do that). .P The \f(CWld_cents\fP field contains a count of the number of \f(CWDwarf_Loc\fP entries pointed to by the \f(CWld_s\fP field. .P The \f(CWld_s\fP field points to an array of \f(CWDwarf_Loc\fP records. .H 3 "Data Block" .SP This is obsolete and should not be used, though it works ok for DWARF2. The \f(CWDwarf_Block\fP type is used to contain the value of an attribute whose form is either \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, \f(CWDW_FORM_block4\fP, \f(CWDW_FORM_block8\fP, or \f(CWDW_FORM_block\fP. Its intended use is to deliver the value for an attribute of any of these forms. .DS \f(CWtypedef struct { Dwarf_Unsigned bl_len; Dwarf_Ptr bl_data; Dwarf_Small bl_from_loclist; Dwarf_Unsigned bl_section_offset; } Dwarf_Block;\fP .DE .P The \f(CWbl_len\fP field contains the length in bytes of the data pointed to by the \f(CWbl_data\fP field. .P The \f(CWbl_data\fP field contains a pointer to the uninterpreted data. Since we use a \f(CWDwarf_Ptr\fP here one must copy the pointer to some other type (typically an \f(CWunsigned char *\fP) so one can add increments to index through the data. The data pointed to by \f(CWbl_data\fP is not necessarily at any useful alignment. .H 3 "Frame Operation Codes: DWARF 2" This interface is adequate for DWARF2 but not entirely suitable for DWARF3 or later. A new (functional) interface is needed. This DWARF2 interface is not sufficient but at present is the only available interface. .P See also the section "Low Level Frame Operations" below. .P The DWARF2 \f(CWDwarf_Frame_Op\fP type is used to contain the data of a single instruction of an instruction-sequence of low-level information from the section containing frame information. This is ordinarily used by Internal-level Consumers trying to print everything in detail. .DS \f(CWtypedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; Dwarf_Signed fp_offset; Dwarf_Offset fp_instr_offset; } Dwarf_Frame_Op; .DE \f(CWfp_base_op\fP is the 2-bit basic op code. \f(CWfp_extended_op\fP is the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an extended op code) and is zero otherwise. .P \f(CWfp_register\fP is any (or the first) register value as defined in the \f(CWCall frame instruction encodings\fP in the \f(CWdwarf\fP document (in DWARF3 see Figure 40,in DWARF5 see table 7.29). If not used with the operation it is 0. .P \f(CWfp_offset\fP is the address, delta, offset, or second register as defined in the \f(CWCall frame instruction encodings\fP documentation. If this is an \f(CWaddress\fP then the value should be cast to \f(CW(Dwarf_Addr)\fP before being used. In any implementation this field *must* be as large as the largest of Dwarf_Ptr, Dwarf_Signed, and Dwarf_Addr for this to work properly. If not used with the op it is 0. If the fp_extended_op is \f(CWDW_CFA_def_cfa\fP or \f(CWDW_CFA_val_expression\fP or \f(CWDW_CFA_expression\fP then \f(CWfp_offset\fP is a pointer to an expression block in the in-memory copy of the frame section. .P \f(CWfp_instr_offset\fP is the byte_offset (within the instruction stream of the frame instructions) of this operation. It starts at 0 for a given frame descriptor. .H 3 "Frame Regtable: DWARF 2" This interface is adequate for DWARF2 and MIPS but not for DWARF3 or later. A separate and preferred interface usable for DWARF3 and for DWARF2 is described below. See also the section "Low Level Frame Operations" below. .P The \f(CWDwarf_Regtable\fP type is used to contain the register-restore information for all registers at a given PC value. Normally used by debuggers. If you wish to default to this interface and to the use of DW_FRAME_CFA_COL, specify --enable_oldframecol at libdwarf configure time. Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) after your dwarf_init_b() call, this call replaces the default libdwarf-compile-time value with DW_FRAME_CFA_COL. .DS /* DW_REG_TABLE_SIZE must reflect the number of registers *(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h */ #define DW_REG_TABLE_SIZE \f(CWtypedef struct { struct { Dwarf_Small dw_offset_relevant; Dwarf_Half dw_regnum; Dwarf_Addr dw_offset; } rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable;\fP .DE .P The array is indexed by register number. The field values for each index are described next. For clarity we describe the field values for index rules[M] (M being any legal array element index). .P \f(CWdw_offset_relevant\fP is non-zero to indicate the \f(CWdw_offset\fP field is meaningful. If zero then the \f(CWdw_offset\fP is zero and should be ignored. .P \f(CWdw_regnum \fPis the register number applicable. If \f(CWdw_offset_relevant\fP is zero, then this is the register number of the register containing the value for register M. If \f(CWdw_offset_relevant\fP is non-zero, then this is the register number of the register to use as a base (M may be DW_FRAME_CFA_COL, for example) and the \f(CWdw_offset\fP value applies. The value of register M is therefore the value of register \f(CWdw_regnum\fP. .P \f(CWdw_offset\fP should be ignored if \f(CWdw_offset_relevant\fP is zero. If \f(CWdw_offset_relevant\fP is non-zero, then the consumer code should add the value to the value of the register \f(CWdw_regnum\fP to produce the value. .H 3 "Frame Operation Codes: DWARF 3 (for DWARF2 and later )" This interface was intended to be adequate for DWARF3 and for DWARF2 (and DWARF4) but was never implemented. .H 3 "Frame Regtable: DWARF 3 (for DWARF2 and later)" This interface is adequate for DWARF2 and later versions. It is new in libdwarf as of April 2006. The default configure of libdwarf inserts DW_FRAME_CFA_COL3 as the default CFA column. Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL3) after your dwarf_init_b() call, this call replaces the default libdwarf-compile-time value with DW_FRAME_CFA_COL3. .P The \f(CWDwarf_Regtable3\fP type is used to contain the register-restore information for all registers at a given PC value. Normally used by debuggers. .DS \f(CWtypedef struct Dwarf_Regtable_Entry3_s { Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3;\fP .DE .P The array is indexed by register number. The field values for each index are described next. For clarity we describe the field values for index rules[M] (M being any legal array element index). (DW_FRAME_CFA_COL3 DW_FRAME_SAME_VAL, DW_FRAME_UNDEFINED_VAL are not legal array indexes, nor is any index < 0 or >= rt3_reg_table_size); The caller of routines using this struct must create data space for rt3_reg_table_size entries of struct Dwarf_Regtable_Entry3_s and arrange that rt3_rules points to that space and that rt3_reg_table_size is set correctly. The caller need not (but may) initialize the contents of the rt3_cfa_rule or the rt3_rules array. The following applies to each rt3_rules rule M: .P .in +4 \f(CWdw_regnum\fP is the register number applicable. If \f(CWdw_regnum\fP is DW_FRAME_UNDEFINED_VAL, then the register I has undefined value. If \f(CWdw_regnum\fP is DW_FRAME_SAME_VAL, then the register I has the same value as in the previous frame. .P If \f(CWdw_regnum\fP is neither of these two, then the following apply: .P .P \f(CWdw_value_type\fP determines the meaning of the other fields. It is one of DW_EXPR_OFFSET (0), DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or DW_EXPR_VAL_EXPRESSION(3). .P If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (0) then this is as in DWARF2 and the offset(N) rule or the register(R) rule of the DWARF3 and DWARF2 document applies. The value is either: .in +4 If \f(CWdw_offset_relevant\fP is non-zero, then \f(CWdw_regnum\fP is effectively ignored but must be identical to DW_FRAME_CFA_COL3 (and the \f(CWdw_offset\fP value applies. The value of register M is therefore the value of CFA plus the value of \f(CWdw_offset\fP. The result of the calculation is the address in memory where the value of register M resides. This is the offset(N) rule of the DWARF2 and DWARF3 documents. .P \f(CWdw_offset_relevant\fP is zero it indicates the \f(CWdw_offset\fP field is not meaningful. The value of register M is the value currently in register \f(CWdw_regnum\fP (the value DW_FRAME_CFA_COL3 must not appear, only real registers). This is the register(R) rule of the DWARF3 spec. .in -4 .P If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (1) then this is the the val_offset(N) rule of the DWARF3 spec applies. The calculation is identical to that of DW_EXPR_OFFSET (0) but the value is interpreted as the value of register M (rather than the address where register M's value is stored). .P If \f(CWdw_value_type\fP is DW_EXPR_EXPRESSION (2) then this is the the expression(E) rule of the DWARF3 document. .P .in +4 \f(CWdw_offset_or_block_len\fP is the length in bytes of the in-memory block pointed at by \f(CWdw_block_ptr\fP. \f(CWdw_block_ptr\fP is a DWARF expression. Evaluate that expression and the result is the address where the previous value of register M is found. .in -4 .P If \f(CWdw_value_type\fP is DW_EXPR_VAL_EXPRESSION (3) then this is the the val_expression(E) rule of the DWARF3 spec. .P .in +4 \f(CWdw_offset_or_block_len\fP is the length in bytes of the in-memory block pointed at by \f(CWdw_block_ptr\fP. \f(CWdw_block_ptr\fP is a DWARF expression. Evaluate that expression and the result is the previous value of register M. .in -4 .P The rule \f(CWrt3_cfa_rule\fP is the current value of the CFA. It is interpreted exactly like any register M rule (as described just above) except that \f(CWdw_regnum\fP cannot be CW_FRAME_CFA_REG3 or DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL but must be a real register number. .in -4 .H 3 "Macro Details Record" The \f(CWDwarf_Macro_Details\fP type gives information about a single entry in the .debug.macinfo section (DWARF2, DWARF3, and DWARF4). It is not useful for DWARF 5 .debug_macro section data. .DS \f(CWstruct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; Dwarf_Small dmd_type; Dwarf_Signed dmd_lineno; Dwarf_Signed dmd_fileindex; char * dmd_macro; }; typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; .DE .P \f(CWdmd_offset\fP is the byte offset, within the .debug_macinfo section, of this macro information. .P \f(CWdmd_type\fP is the type code of this macro info entry (or 0, the type code indicating that this is the end of macro information entries for a compilation unit. See \f(CWDW_MACINFO_define\fP, etc in the DWARF document. .P \f(CWdmd_lineno\fP is the line number where this entry was found, or 0 if there is no applicable line number. .P \f(CWdmd_fileindex\fP is the file index of the file involved. This is only guaranteed meaningful on a \f(CWDW_MACINFO_start_file\fP \f(CWdmd_type\fP. Set to -1 if unknown (see the functional interface for more details). .P \f(CWdmd_macro\fP is the applicable string. For a \f(CWDW_MACINFO_define\fP this is the macro name and value. For a \f(CWDW_MACINFO_undef\fP, or this is the macro name. For a \f(CWDW_MACINFO_vendor_ext\fP this is the vendor-defined string value. For other \f(CWdmd_type\fPs this is 0. .H 2 "Opaque Types" The opaque types declared in \fIlibdwarf.h\fP are used as descriptors for queries against DWARF information stored in various debugging sections. Each time an instance of an opaque type is returned as a result of a \fIlibdwarf\fP operation (\f(CWDwarf_Debug\fP excepted), it should be freed, using \f(CWdwarf_dealloc()\fP when it is no longer of use (read the following documentation for details, as in at least one case there is a special routine provided for deallocation and \f(CWdwarf_dealloc()\fP is not directly called: see \f(CWdwarf_srclines()\fP). Some functions return a number of instances of an opaque type in a block, by means of a pointer to the block and a count of the number of opaque descriptors in the block: see the function description for deallocation rules for such functions. The list of opaque types defined in \fIlibdwarf.h\fP that are pertinent to the Consumer Library, and their intended use is described below. This is not a full list of the opaque types, see libdwarf.h for the full list. .DS \f(CWtypedef struct Dwarf_Debug_s* Dwarf_Debug;\fP .DE An instance of the \f(CWDwarf_Debug\fP type is created as a result of a successful call to \f(CWdwarf_init_b()\fP, or \f(CWdwarf_elf_init_b()\fP, and is used as a descriptor for subsequent access to most \f(CWlibdwarf\fP functions on that object. The storage pointed to by this descriptor should be not be freed, using the \f(CWdwarf_dealloc()\fP function. Instead free it with \f(CWdwarf_finish()\fP. .P .DS \f(CWtypedef struct Dwarf_Die_s* Dwarf_Die;\fP .DE An instance of a \f(CWDwarf_Die\fP type is returned from a successful call to the \f(CWdwarf_siblingof()\fP, \f(CWdwarf_child\fP, or \f(CWdwarf_offdie_b()\fP function, and is used as a descriptor for queries about information related to that DIE. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_DIE\fP when no longer needed, or, preferably, call \f(CWdwarf_dealloc_die()\fP instead. .DS \f(CWtypedef struct Dwarf_Line_s* Dwarf_Line;\fP .DE Instances of \f(CWDwarf_Line\fP type are returned from a successful call to the \f(CWdwarf_srclines()\fP function, and are used as descriptors for queries about source lines. The storage pointed to by these descriptors should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LINE\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Global_s* Dwarf_Global;\fP .DE Instances of \f(CWDwarf_Global\fP type are returned from a successful call to the \f(CWdwarf_get_globals()\fP function, and are used as descriptors for queries about global names (pubnames). .DS \f(CWtypedef struct Dwarf_Weak_s* Dwarf_Weak;\fP .DE Instances of \f(CWDwarf_Weak\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_weaks()\fP function, and are used as descriptors for queries about weak names. The storage pointed to by these descriptors should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_WEAK_CONTEXT\fP (or \f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) when no longer needed. .DS \f(CWtypedef struct Dwarf_Func_s* Dwarf_Func;\fP .DE Instances of \f(CWDwarf_Func\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_funcs()\fP function, and are used as descriptors for queries about static function names. .DS \f(CWtypedef struct Dwarf_Type_s* Dwarf_Type;\fP .DE Instances of \f(CWDwarf_Type\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_types()\fP function, and are used as descriptors for queries about user defined types. .DS \f(CWtypedef struct Dwarf_Var_s* Dwarf_Var;\fP .DE Instances of \f(CWDwarf_Var\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_vars()\fP function, and are used as descriptors for queries about static variables. .DS \f(CWtypedef struct Dwarf_Error_s* Dwarf_Error;\fP .DE This descriptor points to a structure that provides detailed information about errors detected by \f(CWlibdwarf\fP. Users typically provide a location for \f(CWlibdwarf\fP to store this descriptor for the user to obtain more information about the error. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ERROR\fP when no longer needed or, preferably, call \f(CWdwarf_dealloc_error()\fP instead. .DS \f(CWtypedef struct Dwarf_Attribute_s* Dwarf_Attribute;\fP .DE Instances of \f(CWDwarf_Attribute\fP type are returned from a successful call to the \f(CWdwarf_attrlist()\fP, or \f(CWdwarf_attr()\fP functions, and are used as descriptors for queries about attribute values. The storage pointed to by this descriptor should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP when no longer needed, or call \f(CWdwarf_dealloc_attribute()\fP instead. .DS \f(CWtypedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;\fP .DE An instance of a \f(CWDwarf_Abbrev\fP type is returned from a successful call to \f(CWdwarf_get_abbrev()\fP, and is used as a descriptor for queries about abbreviations in the .debug_abbrev section. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Fde_s* Dwarf_Fde;\fP .DE Instances of \f(CWDwarf_Fde\fP type are returned from a successful call to the \f(CWdwarf_get_fde_list()\fP, \f(CWdwarf_get_fde_for_die()\fP, or \f(CWdwarf_get_fde_at_pc()\fP functions, and are used as descriptors for queries about frames descriptors. .DS \f(CWtypedef struct Dwarf_Cie_s* Dwarf_Cie;\fP .DE Instances of \f(CWDwarf_Cie\fP type are returned from a successful call to the \f(CWdwarf_get_fde_list()\fP function, and are used as descriptors for queries about information that is common to several frames. .DS \f(CWtypedef struct Dwarf_Arange_s* Dwarf_Arange;\fP .DE Instances of \f(CWDwarf_Arange\fP type are returned from successful calls to the \f(CWdwarf_get_aranges()\fP, or \f(CWdwarf_get_arange()\fP functions, and are used as descriptors for queries about address ranges. The storage pointed to by this descriptor should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ARANGE\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex;\fP .DE Instances of \f(CWDwarf_Gdbindex\fP type are returned from successful calls to the \f(CWdwarf_gdbindex_header()\fP function and are used to extract information from a .gdb_index section. This section is a gcc/gdb extension and is designed to allow a debugger fast access to data in .debug_info. The storage pointed to by this descriptor should be freed using a call to \f(CWdwarf_gdbindex_free()\fP with a valid \f(CWDwarf_Gdbindex\fP pointer as the argument. .DS \f(CWtypedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_header;\fP .DE Instances of \f(CWDwarf_Xu_Index_Header_s\fP type are returned from successful calls to the \f(CWdwarf_get_xu_index_header()\fP function and are used to extract information from a .debug_cu_index or .debug_tu_index section. These sections are used to make possible access to .dwo sections gathered into a .dwp object as part of the DebugFission (ie Split Dwarf) project allowing separation of an executable from most of its DWARF debugging information. As of May 2015 these sections are accepted into DWARF5 but the standard has not been released. The storage pointed to by this descriptor should be freed using a call to \f(CWdwarf_xh_header_free()\fP with a valid \f(CWDwarf_XuIndexHeader\fP pointer as the argument. .DS \f(CWtypedef struct Dwarf_Line_Context_s * Dwarf_Line_Context;\fP .DE \f(CWdwarf_srclines_b()\fP returns a Dwarf_Line_Context through an argument and the new structure pointer lets us access line header information conveniently. .DS \f(CWtypedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;\fP \f(CWtypedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c;\fP .DE \f(CWDwarf_Loc*\fP are involved in the DWARF5 interfaces to location lists. The new interfaces are all functional and contents of the above types are not exposed. .DS \f(CWtypedef struct Dwarf_Macro_Context_s * Dwarf_Macro_Context;\fP .DE \f(CWdwarf_get_macro_context()\fP and \f(CWdwarf_get_macro_context_by_offset()\fP return a Dwarf_Line_Context through an argument and the new structure pointer lets us access macro data from the .debug_macro section. .DS \f(CWtypedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head;\fP .DE \f(CWdwarf_discr_list()\fP returns a Dwarf_Dsc_Head through an argument and the new structure pointer lets us access macro data from a \f(CWDW_AT_discr_list\fP attribute. .H 1 "UTF-8 strings" \fIlibdwarf\fP is defined, at various points, to return string pointers or to copy strings into string areas you define. DWARF allows the use of \f(CWDW_AT_use_UTF8\fP (DWARF3 and later) \f(CWDW_ATE_UTF\fP (DWARF4 and later) to specify that the strings returned are actually in UTF-8 format. What this means is that if UTF-8 is specified on a particular object it is up to callers that wish to print all the characters properly to use language-appropriate functions to print Unicode strings appropriately. All ASCII characters in the strings will print properly whether printed as wide characters or not. The methods to convert UTF-8 strings so they will print correctly for all such strings is beyond the scope of this document. .P If UTF-8 is not specified then one is probably safe in assuming the strings are iso_8859-15 and normal C printf() will work fine.. .P In either case one should be wary of corrupted (accidentally or intentionally) strings with ASCII control characters in the text. Such can cause bad effects if simply printed to a device (such as a terminal). .H 1 "Error Handling" The method for detection and disposition of error conditions that arise during access of debugging information via \fIlibdwarf\fP is consistent across all \fIlibdwarf\fP functions that are capable of producing an error. This section describes the method used by \fIlibdwarf\fP in notifying client programs of error conditions. .P Most functions within \fIlibdwarf\fP accept as an argument a pointer to a \f(CWDwarf_Error\fP descriptor where a \f(CWDwarf_Error\fP descriptor is stored if an error is detected by the function. Routines in the client program that provide this argument can query the \f(CWDwarf_Error\fP descriptor to determine the nature of the error and perform appropriate processing. The intent is that clients do the appropriate processing immediately on encountering an error and then the client calls \f(CWdwarf_dealloc_error\fP to free the Dwarf_Error descriptor (at which point the client should zero that descriptor as the non-zero value is stale). .P We think the following is appropriate as a general outline. See dwarfdump source for many examples of both of the following incomplete examples. The very few functions not following this general call/return plan are specifically documented. .in +2 .DS \f(CW int example_codea{Dwarf_Debug dbg,Dwarf_Die indie, int is_info, Dwarf_Die *sibdie, Dwarf_Error *err) { int res = 0; const char *secname = 0; res = dwarf_siblingof_b(dbg,indie,is_info,sibdie, err); if (res == DW_DLV_ERROR) { return res; /*Let higher level decide what to do and it will eventually need to do dwarf_dealloc_error() appropriately, the sibdie argument is not touched or used by the called function */ } else if (res == DW_DLV_NO_ENTRY) { return res; /* No sibdie created. Nothing done, the sibdie argument is not touched or used by the called function */ } /* sibdie created. The function stored a DIE pointer (pointing to a created DIE record) through the sibdie pointer. Caller should eventually do dwarf_dealloc_die() appropriately. */ ... return DW_DLV_OK; } \fP .DE .in -2 .P In a case where it is ok to suppress the error as being unimporant, this is an outline, not a useful function. .in +2 .DS \f(CW int example_codeb{Dwarf_Debug dbg, const char **sec_name, int is_info) { Dwarf_Error e = 0; int res = 0; res = dwarf_get_die_section_name(dbg,is_info, sec_name, &e); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(e); e = 0; return res; /*let higher level decide what to do, Nothing allocated in the call still exists. */ } if (res == DW_DLV_NO_ENTRY) { .... } ... } \fP .DE .in -2 .P In the rare case where the malloc arena is exhausted when trying to create a Dwarf_Error descriptor a pointer to a statically allocated descriptor will be returned. This static descriptor is new in December 2014. A call to \f(CWdwarf_dealloc()\fP to free the statically allocated descriptor is harmless (it sets the error value in the descriptor to DW_DLE_FAILSAFE_ERRVAL). The possible conflation of errors when the arena is exhausted (and a dwarf_error descriptor is saved past the next reader call in any thread) is considered better than having \fIlibdwarf\fP call \f(CWabort()\fP (as earlier \fIlibdwarf\fP did). .P We strongly suggest most applications calling \fIlibdwarf\fP follow the suggestion above (passing a valid Dwarf_Error address in the last argument when calling \fIlibdwarf\fP where there are such Dwarf_Error arguments) there are other approaches described just below that might be worth considering in small simple applications as they reduce the Dwarf_Error argument to just passing 0 (null pointer).. .P The cases that arise when passing a null for the Dwarf_Error and where there is an error detected are A) with an error handler function libdwarf will call that function and on return to \fIlibdwarf\fP, \fIlibdwarf\fP will return \f(CWDW_DLV_ERROR\fP to the original client call.. or B) with no error handler function (see below) libdwarf will print an error and call \f(CWabort()\fP. .P .AL A .LI For the error-handler case a client program can specify a function to be invoked upon detection of an error at the time the library is initialized (see \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP for example). When a \fIlibdwarf\fP routine detects an error, this function is called with two arguments: a code indicating the nature of the error and a pointer provided by the client at initialization (again see \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP). This pointer argument can be used to relay information between the error handler and other routines of the client program. A client program can specify or change both the error handling function and the pointer argument after initialization using \f(CWdwarf_seterrhand()\fP and \f(CWdwarf_seterrarg()\fP. When the client error function returns libdwarf returns \f(CWDW_DLV_ERROR\fP. .P If the client passed in a non-null \f(CWerror\fP argument in the libdwarf call finding an error, the \f(CWdwarf_seterrhand()\fP function-invocation mentioned here does not happen. .P .LI In the final case, where \fIlibdwarf\fP functions are not provided a pointer to a \f(CWDwarf_Error\fP descriptor, and no error handling function was provided at initialization, \fIlibdwarf\fP functions print a short message to \f(CWstdout\fP and terminate execution with \f(CWabort()\fP. .P Before March 2016 \fIlibdwarf\fP gave up when there was no error handling by emitting a short message on \f(CWstderr\fP and calling \f(CWabort(3C)\fP. .LE .P The following lists the processing steps taken upon detection of an error: .AL 1 .LI Check the \f(CWerror\fP argument; if not a \fINULL\fP pointer, allocate and initialize a \f(CWDwarf_Error\fP descriptor with information describing the error, place this descriptor in the area pointed to by \f(CWerror\fP, and return a value indicating an error condition. .LI If an \f(CWerrhand\fP argument was provided to \f(CWdwarf_init_b()\fP at initialization, call \f(CWerrhand()\fP passing it the error descriptor and the value of the \f(CWerrarg\fP argument provided to \f(CWdwarf_init_b()\fP. If the error handling function returns, return \f(CWDW_DLV_ERROR\fP indicating an error condition. .LI If neither the \f(CWerror\fP argument nor an \f(CWerrhand\fP argument was provided Terminate program execution by calling \f(CWabort(3C)\fP. .LE .SP In all cases, it is clear from the value returned from a function that an error occurred in executing the function, since DW_DLV_ERROR is returned. .P As can be seen from the above steps, the client program can provide an error handler at initialization, and still provide an \f(CWerror\fP argument to \fIlibdwarf\fP functions when it is not desired to have the error handler invoked. .P If a \f(CWlibdwarf\fP function is called with invalid arguments, the behavior is undefined. In particular, supplying a \f(CWNULL\fP pointer to a \f(CWlibdwarf\fP function (except where explicitly permitted), or pointers to invalid addresses or uninitialized data causes undefined behavior; the return value in such cases is undefined, and the function may fail to invoke the caller supplied error handler or to return a meaningful error number. Implementations also may abort execution for such cases. .P Some errors are so inconsequential that it does not warrant rejecting an object or returning an error. Examples would be a frame length not being a multiple of an address-size, an arange in .debug_aranges has some padding bytes, or a relocation could not be completed. To make it possible for a client to report such errors the function \f(CWdwarf_get_harmless_error_list\fP returns strings with error text in them. This function may be ignored if client code does not want to bother with such error reporting. .P .H 2 "Returned values in the functional interface" Values returned by \f(CWlibdwarf\fP functions to indicate success and errors .nr aX \n(Fg+1 are enumerated in Figure \n(aX. The \f(CWDW_DLV_NO_ENTRY\fP case is useful for functions need to indicate that while there was no data to return there was no error either. For example, \f(CWdwarf_siblingof()\fP may return \f(CWDW_DLV_NO_ENTRY\fP to indicate that that there was no sibling to return. .DS .TS center box, tab(:); lfB cfB lfB l c l. SYMBOLIC NAME:VALUE:MEANING _ DW_DLV_ERROR:1:Error DW_DLV_OK:0:Successful call DW_DLV_NO_ENTRY:-1:No applicable value .TE .FG "Error Indications" .DE .P Each function in the interface that returns a value returns one of the integers in the above figure. .P If \f(CWDW_DLV_ERROR\fP is returned and a pointer to a \f(CWDwarf_Error\fP pointer is passed to the function, then a Dwarf_Error handle is returned through the pointer. No other pointer value in the interface returns a value. After the \f(CWDwarf_Error\fP is no longer of interest, a \f(CWdwarf_dealloc(dbg,dw_err,DW_DLA_ERROR)\fP on the error pointer is appropriate to free any space used by the error information. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned no pointer value in the interface returns a value. .P If \f(CWDW_DLV_OK\fP is returned, the \f(CWDwarf_Error\fP pointer, if supplied, is not touched, but any other values to be returned through pointers are returned. In this case calls (depending on the exact function returning the error) to \f(CWdwarf_dealloc()\fP may be appropriate once the particular pointer returned is no longer of interest. .P Pointers passed to allow values to be returned through them are uniformly the last pointers in each argument list. .P All the interface functions are defined from the point of view of the writer-of-the-library (as is traditional for UN*X library documentation), not from the point of view of the user of the library. The caller might code: .P .DS \f(CWDwarf_Line line; Dwarf_Signed ret_loff; Dwarf_Error err; int retval = dwarf_lineoff(line,&ret_loff,&err);\fP .DE for the function defined as .P .DS \f(CWint dwarf_lineoff(Dwarf_Line line, Dwarf_Signed *return_lineoff, Dwarf_Error* err);\fP .DE and this document refers to the function as returning the value through *err or *return_lineoff or uses the phrase "returns in the location pointed to by err". Sometimes other similar phrases are used. .H 1 "Memory Management" Several of the functions that comprise \fIlibdwarf\fP return pointers (opaque descriptors) to structures that have been dynamically allocated by the library. To manage dynamic memory the function \f(CWdwarf_dealloc()\fP is provided to free storage allocated as a result of a call to a \fIlibdwarf\fP function. Some additional functions (described later) are provided to free storage in particular circumstances. This section describes the general strategy that should be taken by a client program in managing dynamic storage. .P By default \f(CWlibdwarf\fP tracks its allocations and \f(CWdwarf_finish()\fP cleans up allocations where \f(CWdwarf_dealloc()\fP was not called. See \f(CWdwarf_set_de_alloc_flag()\fP below. .H 2 "Read-only Properties" All pointers (opaque descriptors) returned by or as a result of a \fIlibdwarf Consumer Library\fP call should be assumed to point to read-only memory. The results are undefined for \fIlibdwarf\fP clients that attempt to write to a region pointed to by a value returned by a \fIlibdwarf Consumer Library\fP call. .H 2 "Storage Deallocation" See the section "Returned values in the functional interface", above, for the general rules where calls to \f(CWdwarf_dealloc()\fP are appropriate. .P As of May 2020 there are additional dealloc calls which enable type-checking the calls: \f(CWdwarf_dealloc_error()\fP, \f(CWdwarf_dealloc_die()\fP, and \f(CWdwarf_dealloc_attribute()\fP. .P .H 3 "dwarf_dealloc()" The first prototype is the generic one that can dealloc any of the libdwarf types, such as DW_DLA_DIE etc.. This has the disadvantages that the \f(CWspace_to_dealloc\fP argument cannot be type checked and the \f(CWappropriate_dla_name\fP is a simple integer, hence not meaningfully checkable either. .P Whenever possible, use a type-safe deallocation call (for several types that is the only documented deallocation call) and for \f(CWDwarf_Die\fP \f(CWDwarf_Attribute\fP or \f(CWDwarf_Error\fP use the following dealloc functions instead of this one. The use of this form remains fully supported, .P .DS \f(CWvoid dwarf_dealloc(Dwarf_Debug dbg, void *space_to_dealloc, int appropriate_dla_name);\fP .DE .in +2 .DS .FG "Example_dwarf_dealloc()" \f(CW void exampledealloc(Dwarf_Debug dbg,Dwarf_Die somedie) { dwarf_dealloc(dbg,somedie,DW_DLA_DIE); } \fP .DE .in -2 .H 3 "dwarf_dealloc_die()" The second prototype is only to dealloc a Dwarf_Die. Any call to this is typechecked. .P .DS \f(CWvoid dwarf_dealloc_die(Dwarf_Die mydie);\fP .DE .in +2 .DS .FG "Example_dwarf_dealloc_die()" \f(CW void exampledeallocdie(Dwarf_Die somedie) { dwarf_dealloc_die(somedie); } \fP .DE .in -2 .H 3 "dwarf_dealloc_attribute()" The second prototype is only to dealloc a Dwarf_Attribute. These arise from calls from \f(CWdwarf_attrlist()\fP Any call to this is typechecked. .P .DS \f(CWvoid dwarf_dealloc_error(Dwarf_Debug dbg, Dwarf_Die mydie);\fP .DE .in +2 .DS .FG "Example_dwarf_dealloc_attribute()" \f(CW void exampledeallocerror(Dwarf_Attribute attr) { dwarf_dealloc_attribute(attr);' } \fP .DE .in -2 .H 3 "dwarf_dealloc_error()" The second prototype is only to dealloc a Dwarf_Error. These arise when some libdwarf call returns DW_DLV_ERROR. Any call to this is typechecked. .P .DS \f(CWvoid dwarf_dealloc_error(Dwarf_Debug dbg, Dwarf_Die mydie);\fP .DE .in +2 .DS .FG "Example_dwarf_dealloc_error()" \f(CW void exampledeallocerror(Dwarf_Debug dbg,Dwarf_Error err) { dwarf_dealloc_error(dbg,err);' } \fP .DE .in -2 .P See also \f(CWErrors Returned from dwarf_init* calls\fP (below). In some cases the pointers returned by a \fIlibdwarf\fP call are pointers to data which is not freeable. The library knows from the allocation type provided to it whether the space is freeable or not and will not free inappropriately when \f(CWdwarf_dealloc()\fP is called. So it is vital that \f(CWdwarf_dealloc()\fP be called with the proper allocation type. .P For all storage allocated by \fIlibdwarf\fP, the client can free the storage for reuse by calling \f(CWdwarf_dealloc()\fP, providing it with the \f(CWDwarf_Debug\fP descriptor specifying the object for which the storage was allocated, a pointer to the area to be free-ed, and an identifier that specifies what the pointer points to (the allocation type). For example, to free a \f(CWDwarf_Die die\fP belonging the the object represented by \f(CWDwarf_Debug dbg\fP, allocated by a call to \f(CWdwarf_siblingof()\fP, the call to \f(CWdwarf_dealloc()\fP would be: .DS \f(CWdwarf_dealloc(dbg, die, DW_DLA_DIE);\fP or, preferably, \f(CWdwarf_dealloc_die(die);\fP .DE To free storage allocated in the form of a list of pointers (opaque descriptors), each member of the list should be deallocated, followed by deallocation of the actual list itself. The following code fragment uses an invocation of \f(CWdwarf_attrlist()\fP as an example to illustrate a technique that can be used to free storage from any \fIlibdwarf\fP routine that returns a list: .in +2 .DS .FG "Example1 dwarf_attrlist()" \f(CW void example1(Dwarf_Debug dbg,Dwarf_Die somedie) { Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; Dwarf_Error error = 0; Dwarf_Signed i = 0; int errv = 0; errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); if (errv == DW_DLV_OK) { for (i = 0; i < atcount; ++i) { /* use atlist[i] */ dwarf_dealloc_attribute(atlist[i]); /* This original form still works. dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); */ } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } } \fP .DE .in -2 \f(CWdwarf_finish()\fP will deallocate all dynamic storage associated with an instance of a \f(CWDwarf_Debug\fP type. In particular, it will deallocate all dynamically allocated space associated with the \f(CWDwarf_Debug\fP descriptor, and finally make the descriptor invalid. .H 3 "Errors Returned from dwarf_init* calls" These errors are almost always due to fuzzing objects, injecting random values into objects. Rarely seen in any valid object file. See "https://en.wikipedia.org/wiki/Fuzzing" .P A \f(CWDwarf_Error\fP returned from any \f(CWdwarf_init*()\fP or \f(CWdwarf_elf_init*()\fP should be dealt with like any other error. We start with an example of how to deal with this class of errors. See just below the example for a further discussion. .in +2 .DS void exampleinitfail(const char *path, char *true_pathbuf, unsigned tpathlen, unsigned access, unsigned groupnumber) { Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; Dwarf_Error error = 0; Dwarf_Debug dbg = 0; const char *reserved1 = 0; Dwarf_Unsigned reserved2 = 0; Dwarf_Unsigned reserved3 = 0; int res = 0; res = dwarf_init_path(path,true_pathbuf, tpathlen,access,groupnumber,errhand, errarg,&dbg,reserved1,reserved2, &reserved3, &error); /* Preferred version */ if (res == DW_DLV_ERROR) { /* Valid call even though dbg is null! */ dwarf_dealloc(dbg,error,DW_DLA_ERROR); /* Simpler newer form in this comment, but use the older form above for compatibility with older libdwarf. dwarf_dealloc_error(dbg,error); With libdwarf before September 2020 these dealloc calls will leave a few bytes allocated. */ /* The orginal recommendation to call free(error) in this case is still valid though it will not necessarily free every byte allocated with September 2020 and later libdwarf. */ } /* Horrible messy alternative, best effort if dwarf_package_version exists (function created in October 2019 package version 20191106). */ if (res == DW_DLV_ERROR) { const char *ver = dwarf_package_version(); int cmpres = 0; cmpres = strcmp(ver,"20200822"); if (cmpres > 0) { dwarf_dealloc_error(dbg,error); } else { free(error); } } } .DE .in -2 .P If your application needs to be absolutely sure not even a single byte leaks from a failed libdwarf init function call the only sure approach is to ensure you use a September 2020 (version 20200908) or later libdwarf. Versions between 20191104 and 20200908 have no available function that will guarantee freeing these last few bytes. .P If your application does not care if a failed libdwarf init function leaks a few bytes then the September 2020 advice of calling dwarf_dealloc(dbg,error,DW_DLA_ERROR) is best, as though leaks a few bytes with libdwarf before September 2020. .P If your application is using 20191104 or earlier libdwarf the choice of free(error) will avoid a leak from a failed dwarf init call, though changing to a more recent libdwarf will then make a few bytes leak quite possible until the application is changed to use the dwarf_dealloc call. .H 3 "Error DW_DLA error free types" The codes that identify the storage pointed to in calls to .nr aX \n(Fg+1 \f(CWdwarf_dealloc()\fP are described in figure \n(aX. .DS .TS center box, tab(:); lfB lfB l l. IDENTIFIER:USED TO FREE _ DW_DLA_STRING : char* DW_DLA_LOC : Dwarf_Loc DW_DLA_LOCDESC : Dwarf_Locdesc DW_DLA_ELLIST : Dwarf_Ellist (not used) DW_DLA_BOUNDS : Dwarf_Bounds (not used) DW_DLA_BLOCK : Dwarf_Block DW_DLA_DEBUG : Dwarf_Debug (do not use) DW_DLA_DIE : Dwarf_Die DW_DLA_LINE : Dwarf_Line DW_DLA_ATTR : Dwarf_Attribute DW_DLA_TYPE : Dwarf_Type (not used) DW_DLA_SUBSCR : Dwarf_Subscr (not used) DW_DLA_GLOBAL : Dwarf_Global DW_DLA_ERROR : Dwarf_Error DW_DLA_LIST : a list of opaque descriptors DW_DLA_LINEBUF : Dwarf_Line* (not used) DW_DLA_ARANGE : Dwarf_Arange DW_DLA_ABBREV : Dwarf_Abbrev DW_DLA_FRAME_OP : Dwarf_Frame_Op DW_DLA_CIE : Dwarf_Cie DW_DLA_FDE : Dwarf_Fde DW_DLA_LOC_BLOCK : Dwarf_Loc Block DW_DLA_FRAME_BLOCK : Dwarf_Frame Block (not used) DW_DLA_FUNC : Dwarf_Func DW_DLA_TYPENAME : Dwarf_Type DW_DLA_VAR : Dwarf_Var DW_DLA_WEAK : Dwarf_Weak DW_DLA_ADDR : Dwarf_Addr DW_DLA_RANGES : Dwarf_Ranges DW_DLA_GNU_INDEX_HEAD : .debug_gnu_type/pubnames DW_DLA_RNGLISTS_HEAD : .debug_rnglists DW_DLA_DGBINDEX : Dwarf_Gdbindex DW_DLA_XU_INDEX : Dwarf_Xu_Index_Header DW_DLA_LOC_BLOCK_C : Dwarf_Loc_c DW_DLA_LOCDESC_C : Dwarf_Locdesc_c DW_DLA_LOC_HEAD_C : Dwarf_Loc_Head_c DW_DLA_MACRO_CONTEXT : Dwarf_Macro_Context DW_DLA_DSC_HEAD : Dwarf_Dsc_Head DW_DLA_DNAMES_HEAD : Dwarf_Dnames_Head DW_DLA_STR_OFFSETS : Dwarf_Str_Offsets_Table .TE .FG "Allocation/Deallocation Identifiers" .DE .P .H 1 "Functional Interface" This section describes the functions available in the \fIlibdwarf\fP library. Each function description includes its definition, followed by one or more paragraph describing the function's operation. .P The following sections describe these functions. .H 2 "Initialization Operations" These functions are concerned with preparing an object file for subsequent access by the functions in \fIlibdwarf\fP and with releasing allocated resources when access is complete. \f(CWdwarf_init_path()\fP or \f(CWdwarf_init_path_dl()\fP are the initialization functions to use if one actually has a path (if you just have an open fd or open libelf handle you cannot use the _path_ versions that's fine). These both allow libdwarf to attempt to follow \f(CWGNU debuglink\fP hints in a specially produced executable/shared-object to find the object file with the DWARF sections to match tne executable(or shared-object). For non-debuglink executables these two functions behave identically. .P \f(CWGNU debuglink\fP is completely different than and separate from Split Dwarf and MacOS dSYM. it would seem unlikely that these could be combined in any single executable/shared-object. All are intended to have DWARF fully available but not taking space in the executable/shared object. See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html for information on debuglink and the related build-id. .P \f(CWdwarf_init_path()\fP provides no way to add extra global paths to debuglink searches. But \f(CWdwarf_init_path_dl()\fP has 2 extra arguments to make adding extra paths easy. .P libdwarf lets one access the executable's section .eh_frame with frame/backtrace information by turning off recognition of \f(CWGNU debuglink\fP in the Dwarf_Debug being opened by passing in \f(CWtrue_path_out_buffer\fP \f(CWtrue_path_bufferlen\fP as zero. .H 3 "dwarf_init_path()" .DS \f(CWint dwarf_init_path( const char * path, char * true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* dbg, const char * reserved1, Dwarf_Unsigned * reserved2, Dwarf_Unsigned * reserved3, Dwarf_Error* * error); .DE On success the function returns \f(CWDW_DLV_OK\fP, and returns a pointer to an initialized Dwarf_Debug through the dbg argument. All this work identically across all supported object file types. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no such file and nothing else is done or returned. .P If \f(CWDW_DLV_ERROR\fP is returned a Dwarf_Error is returned through the error pointer. and nothing else is done or returned. .P Now we turn to the arguments. .P Pass in the name of the object file via the \f(CWpath\fP argument. .P For MacOS pass in a pointer to \f(CWtrue_path_out_buffer\fP big pointing to a buffer large enough to hold the passed-in path if that were doubled plus adding 100 characters. Then pass that length in the \f(CWtrue_path_bufferlen\fP argument. If a file is found (the dSYM path or if not that the original path) the final path is copied into \f(CWtrue_path_out_buffer\fP. In any case, This is harmless with non-MacOS executables, but for non-MacOS non \f(CWGNU_debuglink\fP objects \f(CWtrue_path_out_buffer\fP will just match \f(CWpath\fP. .P For Elf executables/shared-objects using \f(CWGNU_debuglink\fP The same considerations apply: pass in a pointer to \f(CWtrue_path_out_buffer\fP big pointing to a buffer large enough to hold the passed-in path if that were doubled plus adding 100 characters (a heuristic) (the 100 is arbitrary: \f(CWGNU_debuglink\fP paths can be long but not likely longer than this suggested size. .P When you know you won't be reading MacOS executables and won't be accessing \f(CWGNU_debuglink\fP executables special treatment by passing 0 as arguments to \f(CWtrue_path_out_buffer\fP and \f(CWtrue_path_bufferlen\fP. If those are zero the \f(CWMacOS\fP/ \f(CWGNU_debuglink\fP special processing will not occur. .P Pass in zero with the \f(CWaccess\fP \f(CW \fP argument. The \f(CWDW_DLC_READ\fP flag, which only ever applied to libelf, is zero. .P The \f(CWgroupnumber\fP argument indicates which group is to be accessed Group one is normal dwarf sections such as \f(CW.debug_info\fP. Group two is DWARF5 dwo split-dwarf dwarf sections such as .debug_info.dwo. Groups three and higher are for COMDAT groups. If an object file has only sections from one of the groups then passing zero will access that group. Otherwise passing zero will access only group one. See \f(CWdwarf_sec_group_sizes()\fP and \f(CWdwarf_sec_group_map()\fP for more group information. Typically pass in DW_GROUPNUMBER_ANY to \f(CWgroupnumber\fP. Non-elf objects do not use this field. .P The \f(CWerrhand\fP argument is a pointer to a function that will be invoked whenever an error is detected as a result of a \fIlibdwarf\fP operation. The \f(CWerrarg\fP argument is passed as an argument to the \f(CWerrhand\fP function. .P \f(CWdbg\fP is used to return an initialized Dwarf_Debug pointer. .P \f(CWreserved1\fP, \f(CWreserved2\fP, and \f(CWreserved3\fP are currently unused, pass 0 in to all three. .P Pass in a pointer to a Dwarf_Error to the \f(CWerror\fP argument if you wish libdwarf to return an error code. .H 3 "dwarf_init_path_dl()" .DS \f(CWint dwarf_init_path_dl( const char * path, char * true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, char ** global_paths, unsigned int global_paths_count Dwarf_Debug* dbg, const char * reserved1, Dwarf_Unsigned * reserved2, Dwarf_Unsigned * reserved3, Dwarf_Error* * error); \fP .DE This function is identical to \f(CWdwarf_init_path()\fP in every respect except if you know that you must use special paths to find the \f(CWGNU debuglink\fP target file with DWARF information. .P \f(CWglobal_paths\fP allows you to specify such paths. Pass in \f(CWglobal_paths\fP as a pointer to an array of pointer-to-char, each pointing to a global path string. Pass in \f(CWglobal_paths_count\fP with the number of entries in the pointer array. Pass both as zero if there are no debuglink global paths other than the default standard \f(CW/usr/lib/debug\fP. .H 3 "dwarf_init_b()" .DS \f(CWint dwarf_init_b( int fd, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_init_b()\fP returns through \f(CWdbg\fP a \f(CWDwarf_Debug\fP descriptor that represents a handle for accessing debugging records associated with the open file descriptor \f(CWfd\fP. \f(CWDW_DLV_NO_ENTRY\fP is returned if the object does not contain DWARF debugging information. \f(CWDW_DLV_ERROR\fP is returned if an error occurred. .P The \f(CWaccess\fP argument indicates what access is allowed for the section. The \f(CWDW_DLC_READ\fP macro value is zero and valid for read access (only read access is defined or discussed in this document). No value other than zero should be passed in to these consumer/reader functions. The value passed in is ignored. .P The \f(CWgroupnumber\fP argument indicates which group is to be accessed Group one is normal dwarf sections such as \f(CW.debug_info\fP. Group two is DWARF5 dwo split-dwarf dwarf sections such as .debug_info.dwo. Groups three and higher are for COMDAT groups. If an object file has only sections from one of the groups then passing zero will access that group. Otherwise passing zero will access only group one. See \f(CWdwarf_sec_group_sizes()\fP and \f(CWdwarf_sec_group_map()\fP for more group information. .P The \f(CWerrhand\fP argument is a pointer to a function that will be invoked whenever an error is detected as a result of a \fIlibdwarf\fP operation. The \f(CWerrarg\fP argument is passed as an argument to the \f(CWerrhand\fP function. .P The file descriptor associated with the \f(CWfd\fP argument must refer to an ordinary file (i.e. not a pipe, socket, device, /proc entry, etc.), be opened with the at least as much permission as specified by the \f(CWaccess\fP argument, and cannot be closed or used as an argument to any system calls by the client until after \f(CWdwarf_finish()\fP is called. The seek position of the file associated with \f(CWfd\fP is undefined upon return of \f(CWdwarf_init()\fP. .P Historical Note: With SGI IRIX, by default it was allowed that the app \f(CWclose()\fP \f(CWfd\fP immediately after calling \f(CWdwarf_init()\fP, but that is not a portable approach (that it worked was an accidental side effect of the fact that SGI IRIX used \f(CWELF_C_READ_MMAP\fP in its hidden internal call to \f(CWelf_begin()\fP). The portable approach is to consider that \f(CWfd\fP must be left open till after the corresponding dwarf_finish() call has returned. .P Since \f(CWdwarf_init()\fP uses the same error handling processing as other \fIlibdwarf\fP functions (see \fIError Handling\fP above), client programs will generally supply an \f(CWerror\fP parameter to bypass the default actions during initialization unless the default actions are appropriate. .H 3 "dwarf_init()" .DS \f(CWint dwarf_init( int fd, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE \f(CWdwarf_init()\fP is identical to \f(CWdwarf_init_b()\fP except that \f(CWdwarf_init()\fP is missing the groupnumber argument so access to an object file containing both dwo and non-dwo DWARF5 object sections will access only group one (and will ignore the dwo sections). .P The \f(CWdwarf_get_elf()\fP function cannot succeed when using \f(CWdwarf_init()\fP or \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP to open an object file. .H 3 "dwarf_set_de_alloc_flag()" .DS \f(CWint dwarf_set_de_alloc_flag( int v)\fP .DE \f(CWdwarf_set_de_alloc_flag()\fP sets and returns a flag value applying to the current running instance of \f(CWlibdwarf\fP. It's action sets an internal value, and that value should be set/changed (if you wish to do that) before any other \f(CWlibdwarf\fP calls. .P By default \f(CWlibdwarf\fP keeps track of all its internal allocations. So if the documentation here says you should do \f(CWdwarf_dealloc()\fP calls (or other calls documented here for specific functions) and you omit some or all of them then calling \f(CWdwarf_finish()\fP will clean up all those allocations left undone. .P If you call \f(CWdwarf_set_de_alloc_flag(0)\fP then libdwarf will not keep track of allocations so your code must do all \f(CWdwarf_dealloc()\fP calls as defined below. .P If you call \f(CWdwarf_set_de_alloc_flag(1)\fP that sets/restores the setting to its default value so from that point all new internal allocations will be tracked and \f(CWdwarf_finish()\fP can clean the new ones up. .P The return value of \f(CWdwarf_set_de_alloc_flag()\fP is the previous value of the internal flag: One (1) is the default, meaning record allocations.. Zero (0) is the other possible value, meaning do not record \f(CWlibdwarf\fP allocations. .P It is best to ignore this call unless you have gigantic DWARF sections and you need whatever percent speed improvement from \f(CWlibdwarf\fP that you can get. If you do use it then by all means use tools such as cc --fsanitize... or valgrind to ensure there are no leaks in your application (at least given your test cases). .P The function name echos the spelling of a \f(CWlibdwarf\fP-internal field in \f(CWstruct Dwarf_Debug_s\fP named \f(CWde_alloc_tree\fP. .H 3 "Dwarf_Handler function" This is an example of a valid error handler function. A pointer to this (or another like it) may be passed to \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init_b()\fP. .DS \f(CWstatic void simple_error_handler(Dwarf_Error error, Dwarf_Ptr errarg) { printf("libdwarf error: %d %s\\n", dwarf_errno(error), dwarf_errmsg(error)); exit(1); }\fP .DE .P This will only be called if an error is detected inside libdwarf and the Dwarf_Error argument passed to libdwarf is NULL. A Dwarf_Error will be created with the error number assigned by the library and passed to the error handler. .P The second argument is a copy of the value passed in to \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init()\fP as the \f(CWerrarg()\fP argument. Typically the init function would be passed a pointer to an application-created struct containing the data the application needs to do what it wants to do in the error handler. .P In a language with exceptions or exception-like features an exception could be thrown here. Or the application could simply give up and call \f(CWexit()\fP as in the sample given above. .H 3 "dwarf_elf_init_b() [deprecated 2019]" .DS \f(CWint dwarf_elf_init_b( Elf * elf_file_pointer, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE We recommend you change to calling \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP instead. The \f(CW dwarf_elf_init() \fP and \f(CW dwarf_elf_init_b() \fP interfaces give no benefit over the other interfaces (other than allowing \f(CWdwarf_get_elf()\fP to succeed). .P The function \f(CWdwarf_elf_init_b()\fP is similar to \f(CWdwarf_init_b()\fP but an open \f(CWElf *\fP pointer is passed instead of a file descriptor so \f(CWdwarf_get_elf()\fP can succeed. .P The client is allowed to use the \f(CWElf *\fP pointer for its own purposes without restriction during the time the \f(CWDwarf_Debug\fP is open, except that the client should not \f(CWelf_end()\fP the pointer till after \f(CWdwarf_finish\fP is called. .H 3 "dwarf_elf_init() [deprecated 2019]" .DS \f(CWint dwarf_elf_init( Elf * elf_file_pointer, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_elf_init()\fP is identical to \f(CWdwarf_init[_b]()\fP except an open \f(CWElf *\fP pointer is passed instead of a file descriptor so \f(CWdwarf_get_elf()\fP can succeed. .P Code using \f(CWdwarf_elf_init[_b]()\fP should be switched to calling \f(CWdwarf_init_b()\fP. .H 3 "dwarf_get_elf()" .DS \f(CWint dwarf_get_elf( Dwarf_Debug dbg, Elf ** elf, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_get_elf()\fP is only meaningful if a \f(CWdwarf_elf_init[_b]()\fP function was used to initialize the pointer \f(CWdbg\fP. None of the other dwarf*init*() functions here ever use libelf, so there is no elf pointer to return through the pointer, so and the call will return \f(CWDW_DLV_NO_ENTRY\fP. In addition, this function is also not meaningful for an object file that is not in the Elf format. .P When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_get_elf()\fP returns through the pointer \f(CWelf\fP the \f(CWElf *\fP handle used to access the object represented by the \f(CWDwarf_Debug\fP descriptor \f(CWdbg\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_set_tied_dbg()" .DS \f(CWint dwarf_set_tied_dbg( Dwarf_Debug dbg, Dwarf_Debug tieddbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_set_tied_dbg()\fP enables cross-object access of DWARF data. If a DWARF5 Package object has \f(CWDW_FORM_addrx\fP or \f(CWDW_FORM_GNU_addr_index\fP or one of the other indexed forms in DWARF5 in an address attribute one needs both the Package file and the executable to extract the actual address with \f(CWdwarf_formaddr()\fP. The utility function \f(CWdwarf_addr_form_is_indexed(form)\fP is a handy way to know if an address form is indexed. One does a normal \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init()_b\fP on each object and then tie the two together with a call such as: .in +2 .DS .FG "Example2 dwarf_set_died_dbg()" \f(CW void example2(Dwarf_Debug dbg, Dwarf_Debug tieddbg) { Dwarf_Error error = 0; int res = 0; /* Do the dwarf_init_b() or dwarf_elf_init_b() calls to set dbg, tieddbg at this point. Then: */ res = dwarf_set_tied_dbg(dbg,tieddbg,&error); if (res != DW_DLV_OK) { /* Something went wrong*/ } } \fP .DE .in -2 When done with both dbg and tieddbg do the normal finishing operations on both in any order. It is possible to undo the tieing operation with .in +2 .FG "Example3 dwarf_set_tied_dbg() obsolete" .DS \f(CW void example3(Dwarf_Debug dbg) { Dwarf_Error error = 0; int res = 0; res = dwarf_set_tied_dbg(dbg,NULL,&error); if (res != DW_DLV_OK) { /* Something went wrong*/ } } \fP .DE .in -2 .P It is not necessary to undo the tieing operation before finishing on the dbg and tieddbg. .H 3 "dwarf_get_tied_dbg()" .DS \f(CWint dwarf_get_tied_dbg( Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/)\fP .DE \f(CWdwarf_get_tied_dbg\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWtieddbg_out\fP to the pointer to the 'tied' Dwarf_Debug. If there is no 'tied' object \f(CWtieddbg_out\fP is set to NULL. .P On error it returns \f(CWDW_DLV_ERROR\fP. .P It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_finish()" .DS \f(CWint dwarf_finish( Dwarf_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_finish()\fP releases all \fILibdwarf\fP internal resources associated with the descriptor \f(CWdbg\fP, and invalidates \f(CWdbg\fP. It returns \f(CWDW_DLV_ERROR\fP if there is an error during the finishing operation. It returns \f(CWDW_DLV_OK\fP for a successful operation. Because \f(CWint dwarf_init()\fP opens an Elf descriptor on its fd and \f(CWdwarf_finish()\fP does not close that descriptor, an app should use \f(CWdwarf_get_elf\fP and should call \f(CWelf_end\fP with the pointer returned through the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP. .H 3 "dwarf_set_stringcheck()" .DS \f(CWint dwarf_set_stringcheck( int stringcheck)\fP .DE The function \f(CWint dwarf_set_stringcheck()\fP sets a global flag and returns the previous value of the global flag. If the stringcheck global flag is zero (the default) libdwarf does string length validity checks (the checks do slow libdwarf down very slightly). If the stringcheck global flag is non-zero libdwarf does not do string length validity checks. The global flag is really just 8 bits long, upperbits are not noticed or recorded. .H 3 "dwarf_set_reloc_application()" .DS \f(CWint dwarf_set_reloc_application( int apply)\fP .DE The function \f(CWint dwarf_set_reloc_application()\fP sets a global flag and returns the previous value of the global flag. If the reloc_application global flag is non-zero (the default) then the applicable .rela section (if one exists) will be processed and applied to any DWARF section when it is read in. If the reloc_application global flag is zero no such relocation-application is attempted. Not all machine types (elf header e_machine) or all relocations are supported, but then very few relocation types apply to DWARF debug sections. The global flag is really just 8 bits long, upperbits are not noticed or recorded. It seems unlikely anyone will need to call this function. .H 3 "dwarf_record_cmdline_options()" .DS \f(CWint dwarf_record_cmdline_options( Dwarf_Cmdline_Options options)\fP .DE The function \f(CWint dwarf_record_cmdline_options()\fP copies a Dwarf_Cmdline_Options structure from consumer code to libdwarf. The structure is defined in \f(CWlibdwarf.h\fP. The initial version of this structure has a single field \f(CWcheck_verbose_mode\fP which, if non-zero, tells libdwarf to print some detailed messages to \f(CWstdout\fP in case certain errors are detected. The default for this value is FALSE (0) so the extra messages are off by default. .H 3 "dwarf_object_init_b()" .DS \f(CWint dwarf_object_init_b( Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, unsigned groupnumber, Dwarf_Debug* dbg, Dwarf_Error* error)\fP .DE The function \f(CWint dwarf_object_init_b()\fP enables access to non-Elf object files by allowing the caller to then provide function pointers to code (user-written, not part of libdwarf) that will look, to libdwarf, as if libdwarf was reading Elf. .P See \f(CWint dwarf_init_b()\fP for additional information on the arguments passed in (the \f(CWobj\fP argument here is a set of function pointers and describing how to access non-Elf files is beyond the scope of this document. .P As a hint, note that the source files with dwarf_elf_init_file_ownership() (dwarf_original_elf_init.c) and dwarf_elf_object_access_init() (dwarf_elf_access.c) are the only sources that would need replacement for a different object format. The replacement would need to emulate certain conventions of Elf objects, (mainly that section index 0 is an empty section) but the rest of libdwarf uses what these two source files set up without knowing how to operate on Elf. .P Writing the functions needed to support non-Elf will require study of Elf and of the object format involved. The topic is beyond the scope of this document. .H 3 "dwarf_object_init()" .DS \f(CWint dwarf_object_init( Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* dbg, Dwarf_Error* error)\fP .DE The function \f(CWint dwarf_object_init()\fP is the same as \f(CWint dwarf_object_init_b()\fP except \f(CWint dwarf_object_init()\fP is missing the groupnumber argument so DWARF5 split dwarf objects cannot be fully handled. .H 3 "dwarf_get_real_section_name()" .DS \f(CWint dwarf_get_real_section_name( Dwarf_Debug dbg, const char * std_section_name, const char ** actual_sec_name_out, Dwarf_Small * marked_compressed, Dwarf_Small * marked_zlib_compressed, Dwarf_Small * marked_shf_compressed, Dwarf_Unsigned * compressed_length, Dwarf_Unsigned * uncompressed_length, Dwarf_Error * error); .DE Elf sections are sometimes compressed to reduce the disk footprint of the sections. It's sometimes interesting to library users what the real name was in the object file and whether it was compressed. Libdwarf uncompresses such sections automatically. It's not usually necessary to know the true name or anything about compression. .P \f(CW \fP The caller passes in a \f(CWDwarf_Debug\fP pointer and a standard section name such as ".debug_info" . On success the function returns (through the other arguments) the true section name and a flag which, if non-zero means the section was compressed and a flag which, if non-zero means the section had the Elf section flag SHF_COMPRESSED set. The caller must ensure that the memory pointed to by \f(CWactual_sec_name_out\fP, \f(CWmarked_zcompressed\fP, and \f(CWmarked_zlib_compressed\fP, \f(CWmarked_shf_compressed\fP, \f(CWcompressed_length\fP, \f(CWuncompressed_length\fP, is zero at the point of call. .P The flag \f(CW*marked_compressed\fP, if non-zero, means the section name started with .zdebug (indicating compression was done). .P The flag \f(CWmarked_zlib_compressed\fP, if non-zero means the initial bytes of the section starte with the ASCII characters ZLIB and the section was compressed. .P The flag \f(CWmarked_shf_compressed\fP if non-zero means the Elf section sh_flag SHF_COMPRESSED is set and the section was compressed.. The flag value in an elf section header is (1<<11) (0x800). .P The value \f(CWcompressed_length\fP is passed back through the pointer if and only if the section is compressed and the pointer is non-null. .P The value \f(CWuncompressed_length\fP is passed back through the pointer if and only if the section is compressed and the pointer is non-null. .P If the section name passed in is not used by libdwarf for this object file the function returns \f(CWDW_DLV_NO_ENTRY\fP .P On error the function returns \f(CWDW_DLV_ERROR\fP. .P The string pointed to by \f(CW*actual_sec_name_out\fP must not be free()d. .H 3 "dwarf_package_version()" .DS \f(CWconst char * dwarf_package_version(void); \fP .DE The package version is set in config.h (from its value in configure.ac and in CMakeLists.txt in the source tree) at the build time of the library. A pointer to a static string is returned by this function. The format is standard ISO date format. For example "20180718". It's not entirely clear how this actually helps. But there is a request for this and we provide it as of 23 October 2019. .H 2 "Object Type Detectors" These are used by \f(CWlibdwarf\fP and may be of use generally. They have no connection to any Dwarf_Debug data as you see from the arguments passed in. .H 3 "dwarf_object_detector_path()" .DS \f(CWint dwarf_object_detector_path(const char *path, char *outpath, unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode);\fP .DE On success the function returns \f(CWDW_DLV_OK\fP, and returns various data through the arguments (described just below). This works identically across all supported object file types. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no such file and nothing else is done or returned. .P If \f(CWDW_DLV_ERROR\fP is returned a Dwarf_Error is returned through the error pointer. and nothing else is done or returned. .P Now we turn to the arguments. Pass in the name of the object file via the \f(CWpath\fP argument. .P To \f(CWoutpath\fP pass in a pointer big enough to hold the passed-in path if that were doubled plus adding 100 characters. Then pass that length in the \f(CWoutpath_len\fP argument. The path will be copied to outpath. In the case of certain MacOS dSYM object files the final outpath of the dSYM file (with MacOS conventional directories added) is copied into \f(CWoutpath\fP. Where the MacOS local directory tree is missing or incomplete \f(CWoutpath\fP will be left as a zero-lengh string. .P To entirely skip the MacOS special treatment pass 0 as arguments to \f(CWoutpath\fP and \f(CWoutpath_len\fP. .P The \f(CWftype\fP pointer argument returns \f(CWDW_FTYPE_ELF\fP, \f(CWDW_FTYPE_MACH_O\fP , \f(CWDW_FTYPE_PE\fP , \f(CWDW_FTYPE_ARCHIVE\fP or \f(CWDW_FTYPE_UNKNOWN\fP to the caller. The \f(CWDW_FTYPE_ARCHIVE\fP value says nothing whatever about the contents of the archive. .P The \f(CWendian\fP pointer argument returns \f(CWDW_ENDIAN_BIG\fP, \f(CWDW_ENDIAN_LITTLE\fP , \f(CWDW_ENDIAN_SAME\fP , \f(CWDW_ENDIAN_OPPOSITE\fP or \f(CWDW_ENDIAN_UNKNOWN\fP to the caller. .P The \f(CWoffsetsize\fP pointer argument returns a size value from the object file. If the object file uses 32-bit offsets it returns 32, and if 64-bit offsets it returns 64. Each object type uses such values but the ways the value is used varies. .P The \f(CWfilesize\fP pointer argument returns the size, in bytes, of the object file. This is essentially useless for \f(CWDW_FTYPE_ARCHIVE\fP files, one thinks. .P The \f(CWerrcode\fP pointer argument returns (if and only if DW_DLV_ERROR is returned by the function) an integer error code. At this time there is no handy function to turn that error code into a string. In the libdwarf source you will find that code in the DW_DLE_* error list. .H 3 "dwarf_object_detector_fd()" .DS \f(CWint dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode);\fP .DE \f(CWdwarf_object_detector_fd()\fP is the same as \f(CWdwarf_object_detector_path()\fP except that no path strings apply to \f(CWdwarf_object_detector_fd()\fP. .H 2 "Section Group Operations" The section group data is essential information when processing an object with COMDAT section group DWARF sections or with both split-dwarf (.dwo sections) and non-split dwarf sections. .P It relies on Elf section groups, whereas some compilers rely instead on relocation information to identify section groups. These relocation-specified groupings are not understood at this time. .P A standard DWARF2 or DWARF3 or DWARF4 object (Old Standard Object, or OSO) will not contain any of those new sections. The DWARF4 standard, Appendix E.1 "Using Compilation Units" offers an overview of COMDAT section groups. \f(CWlibdwarf\fP assigns the group number one(1) to OSO DWARF. Any sections that are split dwarf (section name ending in .dwo or one of the two special DWP index sections) are assigned group number two(2) by libdwarf. COMDAT section groups are assigned groups numbers 3 and higher as needed. .P The COMDAT section group uses are not well defined, but popular compilations systems are using such sections. There is no meaningful documentation that we can find (so far) on how the COMDAT section groups are used, so \f(CWlibdwarf\fP is based on observations of what compilers generate. .H 3 "dwarf_sec_group_sizes()" .DS \f(CW int dwarf_dwarf_sec_group_sizes( Dwarf_Debug dbg, Dwarf_Unsigned * section_count_out, Dwarf_Unsigned * group_count_out, Dwarf_Unsigned * selected_group_out, Dwarf_Unsigned * map_entry_count_out, Dwarf_Error * error) \fP .DE The function \f(CWdwarf_sec_group_sizes()\fP may be called on any open \f(CWDwarf_Debug\fP. It returns \f(CWDW_DLV_OK\fP on success and returns values via the pointer arguments. .P Once the \f(CWDwarf_Debug\fP is open the group information is set and it will not change for the life of this \f(CWDwarf_Debug\fP. .P The \f(CW*section_count_out\fP is set to the number of sections in the object. Many of the sections will be irrelevant to \f(CWlibdwarf\fP. .P The \f(CW*group_count_out\fP is set to the number of groups in the object (as \f(CWlibdwarf\fP counts them). An OSO will have exactly one group. A DWP object will have exactly one group. If is more than one group consumer code will likely want to open additional \f(CWDwarf_Debug\fP objects and request relevant information to process the DWARF contents. An executable or a DWP object will always have a \f(CW*group_count_out\fP of one(1). An executable or a shared library cannot have any COMDAT section groups as the linker will have dealt with them. .P The \f(CW*selected_group_out\fP is set to the group number that this \f(CWDwarf_Debug\fP will focus on. See \f(CWdwarf_sec_group_map()\fP for additional details on how \f(CW*selected_group_out\fP is interpreted. .P The \f(CW*map_entry_count_out\fP is set to the number of entries in the map. See \f(CWdwarf_sec_group_map()\fP. .P On failure it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP .P The initial implementation never returns \f(CWDW_DLV_ERROR\fP or \f(CWDW_DLV_NO_ENTRY\fP but callers should allow for that possibility. .H 3 " dwarf_sec_group_map()" .DS \f(CW int dwarf_sec_group_map( Dwarf_Debug dbg, Dwarf_Unsigned map_entry_count, Dwarf_Unsigned * group_numbers_array, Dwarf_Unsigned * section_numbers_array, const char ** sec_names_array, Dwarf_Error * error) \fP .DE The function \f(CWdwarf_sec_group_map()\fP may be called on any open \f(CWDwarf_Debug\fP. .P The caller must allocate \f(CWmap_entry_count\fP arrays used in the following three arguments the and pass the appropriate pointer into the function as well as passing in \f(CWmap_entry_count\fP itself. .P The map entries returned cover all the DWARF related sections in the object though the \f(CWselected_group\fP value will dictate which of the sections in the \f(CWDwarf_Debug\fP will actually be accessed via the usual \f(CWlibdwarf\fP functions. That is, only sections in the selected group may be directly accessed though libdwarf may indirectly access sections in section group one(1) so relevant details can be accessed, such as abbreviation tables etc. Describing the details of this access outside the current \f(CWselected_group\fP goes beyond what this document covers (as of this writing). .P It returns \f(CWDW_DLV_OK\fP on success and sets values into the user-allocated array elements (sorted by section number): .in +2 .DS \f(CW group_numbers_array[0]... group_numbers_array[map_entry_count-1] section_numbers_array[0]... section_numbers_array[map_entry_count-1] sec_names_array[0]... sec_names_array[map_entry_count-1] \fP .DE .in -2 .P \f(CWgroup_numbers_array[0]\fP for example is set to a group number. One(1), or two(2) or if there are COMDAT groups it will be three(3) or higher. .P \f(CWsection_numbers_array[0]\fP for example is set to a valid Elf section number relevant to \f(CWDWARF\fP (each section number shown will be greater than zero). .P \f(CWsec_names_array[0]\fP for example is set to a pointer to a string containing the Elf section name of the Elf section number in \f(CWsections_number_array[0]\fP. .P On error the function will return \f(CWDW_DLV_ERROR\fP or \f(CWDW_DLV_NO_ENTRY\fP which indicates a serious problem with this object. .P Here is an example of use of these functions. .in +2 .DS \f(CW void examplesecgroup(Dwarf_Debug dbg) { int res = 0; Dwarf_Unsigned section_count = 0; Dwarf_Unsigned group_count; Dwarf_Unsigned selected_group = 0; Dwarf_Unsigned group_map_entry_count = 0; Dwarf_Unsigned *sec_nums = 0; Dwarf_Unsigned *group_nums = 0; const char ** sec_names = 0; Dwarf_Error error = 0; Dwarf_Unsigned i = 0; res = dwarf_sec_group_sizes(dbg,§ion_count, &group_count,&selected_group, &group_map_entry_count, &error); if(res != DW_DLV_OK) { /* Something is badly wrong*/ return; } /* In an object without split-dwarf sections or COMDAT sections we now have selected_group == 1. */ sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!sec_nums) { /* FAIL. out of memory */ return; } group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!group_nums) { free(group_nums); /* FAIL. out of memory */ return; } sec_names = calloc(group_map_entry_count,sizeof(char*)); if(!sec_names) { free(group_nums); free(sec_nums); /* FAIL. out of memory */ return; } res = dwarf_sec_group_map(dbg,group_map_entry_count, group_nums,sec_nums,sec_names,&error); if(res != DW_DLV_OK) { /* FAIL. Something badly wrong. */ } for( i = 0; i < group_map_entry_count; ++i) { /* Now do something with group_nums[i],sec_nums[i],sec_names[i] */ } free(group_nums); free(sec_nums); /* The strings are in Elf data. Do not free() the strings themselves.*/ free(sec_names); } \fP .DE .in -2 .H 2 "Section size operations" .P These operations are informative but not normally needed. .H 3 "dwarf_get_section_max_offsets_b()" .DS \f(CWint dwarf_get_section_max_offsets_b(Dwarf_debug dbg, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); .DE .P The function \f(CWdwarf_get_section_max_offsets_b()\fP an open Dwarf_Dbg and reports on the section sizes by pushing section size values back through the pointers. Created in October 2011. .H 3 "dwarf_get_section_max_offsets()" .DS \f(CWint dwarf_get_section_max_offsets(Dwarf_debug dbg, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); .DE .P The function is the same as \f(CWdwarf_get_section_max_offsets_b()\fP except it is missing the \f(CWdebug_types_size()\fP argument. Though obsolete it is still supported. .H 2 "Printf Callbacks" .P This is new in August 2013. .P The \f(CWdwarf_print_lines()\fP function is intended as a helper to programs like \f(CWdwarfdump\fP and show some line internal details in a way only the internals of libdwarf can show them. But using printf directly in libdwarf means the caller has limited control of where the output appears. So now the 'printf' output is passed back to the caller through a callback function whose implementation is provided by the caller. .P Any code calling libdwarf can ignore the functions described in this section completely. If the functions are ignored the messages (if any) from libdwarf will simply not appear anywhere. .P The \f(CWlibdwarf.h\fP header file defines \f(CWstruct Dwarf_Printf_Callback_Info_s\fP and \f(CWdwarf_register_printf_callback\fP for those libdwarf callers wishing to implement the callback. In this section we describe how one uses that interface. The applications \f(CWdwarfdump\fP and \f(CWdwarfdump2\fP are examples of how these may be used. .H 3 "dwarf_register_printf_callback" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug dbg, struct Dwarf_Printf_Callback_Info_s * newvalues); .DE .P The \f(CWdwarf_register_printf_callback()\fP function can only be called after the Dwarf_Debug instance has been initialized, the call makes no sense at other times. The function returns the current value of the structure. If \f(CWnewvalues\fP is non-null then the passed-in values are used to initialize the libdwarf internal callback data (the values returned are the values before the \f(CWnewvalues\fP are recorded). If \f(CWnewvalues\fP is null no change is made to the libdwarf internal callback data. .H 3 "Dwarf_Printf_Callback_Info_s" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; .DE .P First we describe the fields as applicable in setting up for a call to \f(CWdwarf_register_printf_callback()\fP. .P The field \f(CWdp_user_pointer\fP is remembered by libdwarf and passed back in any call libdwarf makes to the user's callback function. It is otherwise ignored by libdwarf. .P The field \f(CWdp_fptr\fP is either NULL or a pointer to a user-implemented function. .P If the field \f(CWdp_buffer_user_provided\fP is non-zero then \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP must be set by the user and libdwarf will use that buffer without doing any malloc of space. If the field \f(CWdp_buffer_user_provided\fP is zero then the input fields \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP are ignored by libdwarf and space is malloc'd as needed. .P The field \f(CWdp_reserved\fP is ignored, it is reserved for future use. .P When the structure is returned by \f(CWdwarf_register_printf_callback()\fP the values of the fields before the \f(CWdwarf_register_printf_callback()\fP call are returned. .H 3 "dwarf_printf_callback_function_type" .DS \f(CWtypedef void (* dwarf_printf_callback_function_type)(void * user_pointer, const char * linecontent); .DE .P Any application using the callbacks needs to use the function \f(CWdwarf_register_printf_callback()\fP and supply a function matching the above function prototype from libdwarf.h. .H 3 "Example of printf callback use in a C++ application using libdwarf" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s printfcallbackdata; memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); printfcallbackdata.dp_fptr = printf_callback_for_libdwarf; dwarf_register_printf_callback(dbg,&printfcallbackdata); Assuming the user implements something like the following function in her application: void printf_callback_for_libdwarf(void *userdata,const char *data) { cout << data; } .DE .P It is crucial that the user's callback function copies or prints the data immediately. Once the user callback function returns the \f(CWdata\fP pointer may change or become stale without warning. .H 2 "Debugging Information Entry Delivery Operations" These functions are concerned with accessing debugging information entries, whether from a .debug_info, .debug_types, .debug_info.dwo, or .debug_types.dwo . .P Since all such sections use similar formats, one set of functions suffices. .H 3 "dwarf_get_die_section_name()" .DS int dwarf_get_die_section_name(Dwarf_Debug dbg, Dwarf_Bool is_info, const char ** sec_name, Dwarf_Error * error); .DE \f(CWdwarf_get_die_section_name()\fP lets consumers access the object section name when no specific DIE is at hand. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name_b()\fP. .P The function \f(CWdwarf_get_die_section_name()\fP operates on the either the .debug_info[.dwo] section (if \f(CWis_info\fP is non-zero) or .debug_types[.dwo] section (if \f(CWis_info\fP is zero). .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_die_section_name_b()" .DS int dwarf_get_die_section_name_b(Dwarf_Die die, const char ** sec_name, Dwarf_Error * error); .DE \f(CWdwarf_get_die_section_name_b()\fP lets consumers access the object section name when one has a DIE. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name()\fP. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_next_cu_header_d()" .DS \f(CWint dwarf_next_cu_header_d( Dwarf_debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned *cu_header_length, Dwarf_Half *version_stamp, Dwarf_Unsigned *abbrev_offset, Dwarf_Half *address_size, Dwarf_Half *offset_size, Dwarf_Half *extension_size, Dwarf_Sig8 *signature, Dwarf_Unsigned *typeoffset Dwarf_Unsigned *next_cu_header, Dwarf_Half *header_cu_type, Dwarf_Error *error); .DE The function \f(CWdwarf_next_cu_header_d()\fP operates on the either the .debug_info section (if \f(CWis_info\fP is non-zero) or .debug_types section (if \f(CWis_info\fP is zero). It returns \f(CWDW_DLV_ERROR\fP if it fails, and \f(CWDW_DLV_OK\fP if it succeeds. .P If it succeeds, \f(CW*next_cu_header\fP is set to the offset in the .debug_info section of the next compilation-unit header if it succeeds. On reading the last compilation-unit header in the .debug_info section it contains the size of the .debug_info or debug_types section. Beginning 22 April 2019 \f(CWnext_cu_header\fP will not be used to return the offset if \f(CWnext_cu_header\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. .P The next call to \f(CWdwarf_next_cu_header_b()\fP returns \f(CWDW_DLV_NO_ENTRY\fP without reading a compilation-unit or setting \f(CW*next_cu_header\fP. Subsequent calls to \f(CWdwarf_next_cu_header()\fP repeat the cycle by reading the first compilation-unit and so on. .P The other values returned through pointers are the values in the compilation-unit header. If any of \f(CWcu_header_length\fP, \f(CWversion_stamp\fP, \f(CWabbrev_offset\fP, \f(CWaddress_size\fP, \f(CWoffset_size\fP, \f(CWextension_size\fP, \f(CWsignature\fP, or \f(CWtypeoffset\fP, is \f(CWNULL\fP, the argument is ignored (meaning it is not an error to provide a \f(CWNULL\fP pointer for any or all of these arguments). .P \f(CWcu_header_length\fP returns the length in bytes of the compilation unit header. .P \f(CWversion_stamp\fP returns the section version, which would be (for .debug_info) 2 for DWARF2, 3 for DWARF3, 4 for DWARF4, or 5 for DWARF5.. .P \f(CWabbrev_offset\fP returns the .debug_abbrev section offset of the abbreviations for this compilation unit. .P \f(CWaddress_size\fP returns the size of an address in this compilation unit. Which is usually 4 or 8. .P \f(CWoffset_size\fP returns the size in bytes of an offset for the compilation unit. The offset size is 4 for 32bit dwarf and 8 for 64bit dwarf. This is the offset size in dwarf data, not the address size inside the executable code. The offset size can be 4 even if embedded in a 64bit elf file (which is normal for 64bit elf), and can be 8 even in a 32bit elf file (which probably will never be seen in practice). .P The \f(CWextension_size\fP pointer is only relevant if the \f(CWoffset_size\fP pointer returns 8. The value is not normally useful but is returned through the pointer for completeness. The pointer \f(CWextension_size\fP returns 0 if the CU is MIPS/IRIX non-standard 64bit dwarf (MIPS/IRIX 64bit dwarf was created years before DWARF3 defined 64bit dwarf) and returns 4 if the dwarf uses the standard 64bit extension (the 4 is the size in bytes of the 0xffffffff in the initial length field which indicates the following 8 bytes in the .debug_info section are the real length). See the DWARF3 or DWARF4 standard, section 7.4. .P The \f(CWsignature\fP pointer is only relevant if the CU has a type signature, and if relevant the 8 byte type signature of the .debug_types CU header is assigned through the pointer. .P The \f(CWtypeoffset\fP pointer is only relevant the CU has a type signature if relevant the local offset within the CU of the the type offset the .debug_types entry represents is assigned through the pointer. The \f(CWtypeoffset\fP matters because a DW_AT_type referencing the type unit may reference an inner type, such as a C++ class in a C++ namespace, but the type itself has the enclosing namespace in the .debug_type type_unit. .P The \f(CWheader_cu_type\fP pointer is applicable to all CU headers. The value returned through the pointer is either \f(CWDW_UT_compile\fP \f(CWDW_UT_partial\fP \f(CWDW_UT_type\fP and identifies the header type of this CU. In \f(CWDWARF4\fP a \f(CWDW_UT_type\fP will be in \f(CW.debug_types\fP, but in \f(CWDWARF5\fP these compilation units are in \f(CW.debug_info\fP and the Debug Fission (ie Split Dwarf) \f(CW.debug_info.dwo\fP sections . .H 3 "dwarf_next_cu_header_c()" .DS \f(CWint dwarf_next_cu_header_c( Dwarf_debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned *cu_header_length, Dwarf_Half *version_stamp, Dwarf_Unsigned *abbrev_offset, Dwarf_Half *address_size, Dwarf_Half *offset_size, Dwarf_Half *extension_size, Dwarf_Sig8 *signature, Dwarf_Unsigned *typeoffset Dwarf_Unsigned *next_cu_header, Dwarf_Error *error); .DE The function \f(CWdwarf_next_cu_header_c()\fP operates on the either the .debug_info section (if \f(CWis_info\fP is non-zero) or .debug_types section (if \f(CWis_info\fP is zero). .P It operates exactly like \f(CWdwarf_next_cu_header_d()\fP but is missing the \f(CWheader_type\fP field. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_d()\fP .H 3 "dwarf_next_cu_header_b()" .DS \f(CWint dwarf_next_cu_header_b( Dwarf_debug dbg, Dwarf_Unsigned *cu_header_length, Dwarf_Half *version_stamp, Dwarf_Unsigned *abbrev_offset, Dwarf_Half *address_size, Dwarf_Half *offset_size, Dwarf_Half *extension_size, Dwarf_Unsigned *next_cu_header, Dwarf_Error *error); .DE .P This is obsolete as of October 2011 though supported. .P The function \f(CWdwarf_next_cu_header_b()\fP operates on the .debug_info section. It operates exactly like \f(CWdwarf_next_cu_header_c()\fP but is missing the \f(CWsignature\fP, and \f(CWtypeoffset\fP fields. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_c()\fP .H 3 "dwarf_next_cu_header()" .P The following is the original form, missing the \f(CWoffset_size\fP, \f(CWextension_size\fP, \f(CWsignature\fP, and \f(CWtypeoffset\fP fields in \f(CWdwarf_next_cu_header_c()\fP. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_c()\fP .DS \f(CWint dwarf_next_cu_header( Dwarf_debug dbg, Dwarf_Unsigned *cu_header_length, Dwarf_Half *version_stamp, Dwarf_Unsigned *abbrev_offset, Dwarf_Half *address_size, Dwarf_Unsigned *next_cu_header, Dwarf_Error *error); .DE .H 3 "dwarf_siblingof_b()" .DS \f(CWint dwarf_siblingof_b( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Bool is_info, Dwarf_Die *return_sib, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_siblingof_b()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP pointer on error. If there is no sibling it returns \f(CWDW_DLV_NO_ENTRY\fP. When it succeeds, \f(CWdwarf_siblingof_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_sib\fP to the \f(CWDwarf_Die\fP descriptor of the sibling of \f(CWdie\fP. If \f(CWis_info\fP is non-zero then the \f(CWdie\fP is assumed to refer to a .debug_info DIE. If \f(CWis_info\fP is zero then the \f(CWdie\fP is assumed to refer to a .debug_types DIE. Note that the first call (the call that gets the compilation-unit DIE in a compilation unit) passes in a NULL \f(CWdie\fP so having the caller pass in \f(CWis_info\fP is essential. And if \f(CWdie\fP is non-NULL it is still essential for the call to pass in \f(CWis_info\fP set properly to reflect the section the DIE came from. The function \f(CWdwarf_get_die_infotypes_flag()\fP is of interest as it returns the proper is_info value from any non-NULL \f(CWdie\fP pointer. If \f(CWdie\fP is \fINULL\fP, the \f(CWDwarf_Die\fP descriptor of the first die in the compilation-unit is returned. This die has the \f(CWDW_TAG_compile_unit\fP, \f(CWDW_TAG_partial_unit\fP, or \f(CWDW_TAG_type_unit\fP tag. .in +2 .FG "Example4 dwarf_siblingof()" .DS \f(CW void example4(Dwarf_Debug dbg,Dwarf_Die in_die,Dwarf_Bool is_info) { Dwarf_Die return_sib = 0; Dwarf_Error error = 0; int res = 0; /* in_die might be NULL or a valid Dwarf_Die */ res = dwarf_siblingof_b(dbg,in_die,is_info,&return_sib, &error); if (res == DW_DLV_OK) { /* Use return_sib here. */ dwarf_dealloc_die(return_sib); /* This original form still works. dwarf_dealloc(dbg, return_sib, DW_DLA_DIE); */ /* return_sib is no longer usable for anything, we ensure we do not use it accidentally with: */ return_sib = 0; } } \fP .DE .in -2 .H 3 "dwarf_siblingof()" .DS \f(CWint dwarf_siblingof( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *return_sib, Dwarf_Error *error)\fP .DE .P \f(CWint dwarf_siblingof()\fP operates exactly the same as \f(CWint dwarf_siblingof_b()\fP, but \f(CWint dwarf_siblingof()\fP refers only to .debug_info DIEs. .H 3 "dwarf_child()" .DS \f(CWint dwarf_child( Dwarf_Die die, Dwarf_Die *return_kid, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_child()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. If there is no child it returns \f(CWDW_DLV_NO_ENTRY\fP. When it succeeds, \f(CWdwarf_child()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_kid\fP to the \f(CWDwarf_Die\fP descriptor of the first child of \f(CWdie\fP. The function \f(CWdwarf_siblingof()\fP can be used with the return value of \f(CWdwarf_child()\fP to access the other children of \f(CWdie\fP. .in +2 .FG "Example5 dwarf_child()" .DS \f(CW void example5(Dwarf_Die in_die) { Dwarf_Die return_kid = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_child(in_die,&return_kid, &error); if (res == DW_DLV_OK) { /* Use return_kid here. */ dwarf_dealloc_die(return_kid); /* The original form of dealloc still works dwarf_dealloc(dbg, return_kid, DW_DLA_DIE); */ /* return_die is no longer usable for anything, we ensure we do not use it accidentally with: */ return_kid = 0; } } \fP .DE .in -2 .H 3 "dwarf_offdie_b()" .DS \f(CWint dwarf_offdie_b( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Die *return_die, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_offdie_b()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. When it succeeds, \f(CWdwarf_offdie_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_die\fP to the the \f(CWDwarf_Die\fP descriptor of the debugging information entry at \f(CWoffset\fP in the section containing debugging information entries i.e the .debug_info section. A return of \f(CWDW_DLV_NO_ENTRY\fP means that the \f(CWoffset\fP in the section is of a byte containing all 0 bits, indicating that there is no abbreviation code. Meaning this 'die offset' is not the offset of a real die, but is instead an offset of a null die, a padding die, or of some random zero byte: this should not be returned in normal use. .P It is the user's responsibility to make sure that \f(CWoffset\fP is the start of a valid debugging information entry. The result of passing it an invalid offset could be chaos. .P If \f(CWis_info\fP is non-zero the \f(CWoffset\fP must refer to a .debug_info section offset. If \f(CWis_info\fP zero the \f(CWoffset\fP must refer to a .debug_types section offset. Error returns or misleading values may result if the \f(CWis_info\fP flag or the \f(CWoffset\fP value are incorrect. .in +2 .FG "Example6 dwarf_offdie_b()" .DS \f(CW void example6(Dwarf_Debug dbg,Dwarf_Off die_offset,Dwarf_Bool is_info) { Dwarf_Error error = 0; Dwarf_Die return_die = 0; int res = 0; res = dwarf_offdie_b(dbg,die_offset,is_info,&return_die, &error); if (res == DW_DLV_OK) { /* Use return_die here. */ dwarf_dealloc_die(return_die); /* The original form still works: dwarf_dealloc(dbg, return_die, DW_DLA_DIE); */ /* return_die is no longer usable for anything, we ensure we do not use it accidentally with: */ return_die = 0; } else { /* res could be NO ENTRY or ERROR, so no dealloc necessary. */ } } \fP .DE .in -2 .H 3 "dwarf_offdie()" .DS \f(CWint dwarf_offdie( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *return_die, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_offdie()\fP is obsolete, use \f(CWdwarf_offdie_b()\fP instead. The function is still supported in the library, but only references the .debug_info section. .H 3 "dwarf_validate_die_sibling()" .DS \f(CWint validate_die_sibling( Dwarf_Die sibling, Dwarf_Off *offset)\fP .DE When used correctly in a depth-first walk of a DIE tree this function validates that any DW_AT_sibling attribute gives the same offset as the direct tree walk. That is the only purpose of this function. The function \f(CWdwarf_validate_die_sibling()\fP returns \f(CWDW_DLV_OK\fP if the last die processed in a depth-first DIE tree walk was the same offset as generated by a call to \f(CWdwarf_siblingof()\fP. Meaning that the DW_AT_sibling attribute value, if any, was correct. If the conditions are not met then DW_DLV_ERROR is returned and \f(CW*offset\fP is set to the offset in the .debug_info section of the last DIE processed. If the application prints the offset a knowledgeable user may be able to figure out what the compiler did wrong. .H 2 "Debugging Information Entry Query Operations" These queries return specific information about debugging information entries or a descriptor that can be used on subsequent queries when given a \f(CWDwarf_Die\fP descriptor. Note that some operations are specific to debugging information entries that are represented by a \f(CWDwarf_Die\fP descriptor of a specific type. For example, not all debugging information entries contain an attribute having a name, so consequently, a call to \f(CWdwarf_diename()\fP using a \f(CWDwarf_Die\fP descriptor that does not have a name attribute will return \f(CWDW_DLV_NO_ENTRY\fP. This is not an error, i.e. calling a function that needs a specific attribute is not an error for a die that does not contain that specific attribute. .P There are several methods that can be used to obtain the value of an attribute in a given die: .AL 1 .LI Call \f(CWdwarf_hasattr()\fP to determine if the debugging information entry has the attribute of interest prior to issuing the query for information about the attribute. .LI Supply an \f(CWerror\fP argument, and check its value after the call to a query indicates an unsuccessful return, to determine the nature of the problem. The \f(CWerror\fP argument will indicate whether an error occurred, or the specific attribute needed was missing in that die. .LI Arrange to have an error handling function invoked upon detection of an error (see \f(CWdwarf_init()\fP). .LI Call \f(CWdwarf_attrlist()\fP and iterate through the returned list of attributes, dealing with each one as appropriate. .LE .P .H 3 "dwarf_get_die_infotypes_flag()" .DS \f(CWDwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die die)\fP .DE .P The function \f(CWdwarf_get_die_infotypes_flag()\fP returns the section flag indicating which section the DIE originates from. If the returned value is non-zero the DIE originates from the .debug_info section. If the returned value is zero the DIE originates from the .debug_types section. .H 3 "dwarf_cu_header_basics()" .DS \f(CWint dwarf_cu_header_basics(Dwarf_Die die Dwarf_Half *version, Dwarf_Bool *is_info, Dwarf_Bool *is_dwo, Dwarf_Half *offset_size, Dwarf_Half *address_size, Dwarf_Half *extension_size, Dwarf_Sig8 **signature, Dwarf_Off *offset_of_length, Dwarf_Unsigned *total_byte_length, Dwarf_Error *error)\fP .DE .P On success, the function \f(CWcu_header_basics()\fP various data items from the CU header and the CU die passed in. Any return-value pointer may be passed in as NULL, indicating that the value is not needed. .P Summing \f(CWoffset_size\fP and \f(CWextension_size\fP gives the length of the CU length field, which is immediately followed by the CU header. .P \f(CWis_dwo\fP field will surely always be 0 as dwo/dwp .debug_info cannot be skeleton CUs. .P The \f(CWsignature\fP value is returned if there a signature in the DWARF5 CU header or the CU die. .P The \f(CWoffset_of_length\fP returned is the offset of the first byte of the length field of the CU. .P The \f(CWtotal_byte_Length\fP returned is the length of data in the CU counting from the first byte at \f(CWoffset_of_length\fP. .H 3 "dwarf_tag()" .DS \f(CWint dwarf_tag( Dwarf_Die die, Dwarf_Half *tagval, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_tag()\fP returns the \f(CWtag\fP of \f(CWdie\fP through the pointer \f(CWtagval\fP if it succeeds. It returns \f(CWDW_DLV_OK\fP if it succeeds. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_dieoffset()" .DS \f(CWint dwarf_dieoffset( Dwarf_Die die, Dwarf_Off * return_offset, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_dieoffset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the position of \f(CWdie\fP in the section containing debugging information entries (the \f(CWreturn_offset\fP is a section-relative offset). In other words, it sets \f(CWreturn_offset\fP to the offset of the start of the debugging information entry described by \f(CWdie\fP in the section containing dies i.e .debug_info. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_addr_form_is_indexed()" \f(CWdwarf_addr_form_is_indexed(form)\fP is a utility function to make it simple to determine if a form is one of the indexed forms (there are several such in DWARF5). See DWARF5 section 7.5.5 \f(CWClasses and Forms\fP for more information. .DS int dwarf_addr_form_is_indexed(Dwarf_Half form); .DE It returns TRUE if the form is one of the indexed address forms (such as DW_FORM_addrx1) and FALSE otherwise. .H 3 "dwarf_debug_addr_index_to_addr()" .DS int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned index, Dwarf_Addr * return_addr, Dwarf_Error * error); .DE Attributes with form DW_FORM_addrx, the operation DW_OP_addrx, or certain of the split-dwarf location list entries give an index value to a machine address in the .debug_addr section (which is always in .debug_addr even when the form/operation are in a split dwarf .dwo section). .P On successful return this function turns such an index into a target address value through the pointer \f(CWreturn_addr\fP . .P If there is an error this may return DW_ \f(CWDW_DLV_ERROR\fP and it will have returned an error through \f(CW*error\fP. .P If there is no available .debug_addr section this may return \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_die_CU_offset()" .DS \f(CWint dwarf_die_CU_offset( Dwarf_Die die, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_CU_offset()\fP is similar to \f(CWdwarf_dieoffset()\fP, except that it puts the offset of the DIE represented by the \f(CWDwarf_Die\fP \f(CWdie\fP, from the start of the compilation-unit that it belongs to rather than the start of .debug_info (the \f(CWreturn_offset\fP is a CU-relative offset). .H 3 "dwarf_die_offsets()" .DS \f(CWint dwarf_die_offsets( Dwarf_Die die, Dwarf_Off *global_off, Dwarf_Off *cu_off, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_offsets()\fP is a combination of \f(CWdwarf_dieoffset()\fP and \f(CWdwarf_die_cu_offset()\fP in that it returns both the global .debug_info offset and the CU-relative offset of the \f(CWdie\fP in a single call. .H 3 "dwarf_ptr_CU_offset()" .DS \f(CWint dwarf_ptr_CU_offset( Dwarf_CU_Context cu_context, Dwarf_Byte_ptr di_ptr , Dwarf_Off *cu_off)\fP .DE Given a valid CU context pointer and a pointer into that CU context, the function \f(CWdwarf_ptr_CU_offset()\fP returns DW_DLV_OK and sets \f(CW*cu_off\fP to the CU-relative (local) offset in that CU. .H 3 "dwarf_CU_dieoffset_given_die()" .DS \f(CWint dwarf_CU_dieoffset_given_die( Dwarf_Die given_die, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_CU_dieoffset_given_die()\fP is similar to \f(CWdwarf_die_CU_offset()\fP, except that it puts the global offset of the CU DIE owning \f(CWgiven_die\fP of .debug_info (the \f(CWreturn_offset\fP is a global section offset). .P This is useful when processing a DIE tree and encountering an error or other surprise in a DIE, as the \f(CWreturn_offset\fP can be passed to \f(CWdwarf_offdie_b()\fP to return a pointer to the CU die of the CU owning the \f(CWgiven_die\fP passed to \f(CWdwarf_CU_dieoffset_given_die()\fP. The consumer can extract information from the CU die and the \f(CWgiven_die\fP (in the normal way) and print it. An example (a snippet) of code using this function follows. It assumes that \f(CWin_die\fP is a DIE in .debug_info that, for some reason, you have decided needs CU context printed (assuming \f(CWprint_die_data\fP does some reasonable printing). .in +2 .FG "Example7 dwarf_CU_dieoffset_given_die()" .DS \f(CW void example7(Dwarf_Debug dbg, Dwarf_Die in_die,Dwarf_Bool is_info) { int res = 0; Dwarf_Off cudieoff = 0; Dwarf_Die cudie = 0; Dwarf_Error error = 0; res = dwarf_CU_dieoffset_given_die(in_die,&cudieoff,&error); if(res != DW_DLV_OK) { /* FAIL */ return; } res = dwarf_offdie_b(dbg,cudieoff,is_info,&cudie,&error); if(res != DW_DLV_OK) { /* FAIL */ return; } /* do something with cu_die */ dwarf_dealloc_die(cudie); /* The original form still works. dwarf_dealloc(dbg,cudie, DW_DLA_DIE); */ } \fPy .DE .in -2 .H 3 "dwarf_die_CU_offset_range()" .DS \f(CWint dwarf_die_CU_offset_range( Dwarf_Die die, Dwarf_Off *cu_global_offset, Dwarf_Off *cu_length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_CU_offset_range()\fP returns the offset of the beginning of the CU and the length of the CU. The offset and length are of the entire CU that this DIE is a part of. It is used by dwarfdump (for example) to check the validity of offsets. Most applications will have no reason to call this function. .H 3 "dwarf_diename()" .DS \f(CWint dwarf_diename( Dwarf_Die die, char ** return_name, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_diename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string of characters that represents the name attribute (\f(CWDW_AT_name\fP) of \f(CWdie\fP. .P The storage pointed to by a successful return of \f(CWdwarf_diename()\fP should not be freed as the text is a string in static memory (for some error cases) or a string residing in a DWARF data section. .P Up to March 2020 this document said that dwarf_dealloc with DW_DLA_STRING should be applied to the string returned through the pointer. That was always incorrect. However, doing the dwarf_dealloc(dbg,xxx,DW_DLA_STRING) that was previously called for does not result in any error (dwarf_dealloc avoids freeing strings like this). .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have a name attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_die_text()" .DS \f(CWint dwarf_die_text( Dwarf_Die die, Dwarf_Half attrnum, char ** return_name, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_die_text()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string of characters that represents a string-value attribute of \f(CWdie\fP if an attribute \f(CWattrnum\fP is present. .P The storage pointed to by a successful return of \f(CWdwarf_die_text()\fP must never be freed, the string is in the DWARF data and is not dynamically allocated. .P As of March 2020 the description here has been corrected. \f(CWdwarf_dealloc()\fP should never have been applied to a string returned by \f(CWdwarf_die_text()\fP. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have the attribute \f(CWattrnum\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_die_abbrev_code()" .DS \f(CWint dwarf_die_abbrev_code( Dwarf_Die die)\fP .DE The function returns the abbreviation code of the DIE. That is, it returns the abbreviation "index" into the abbreviation table for the compilation unit of which the DIE is a part. It cannot fail. No errors are possible. The pointer \f(CWdie()\fP must not be NULL. .H 3 "dwarf_die_abbrev_children_flag()" .DS \f(CWint dwarf_die_abbrev_children_flag( Dwarf_Die die, Dwarf_Half *has_child)\fP .DE The function returns the has-children flag of the \f(CWdie\fP passed in through the \f(CW*has_child\fP passed in and returns \f(CWDW_DLV_OK\fP on success. A non-zero value of \f(CW*has_child\fP means the \f(CWdie\fP has children. On failure it returns \f(CWDW_DLV_ERROR\fP. The function was developed to let consumer code do better error reporting in some circumstances, it is not generally needed. .H 3 "dwarf_die_abbrev_global_offset()" .DS \f(CWint dwarf_die_abbrev_global_offset(Dwarf_Die die, Dwarf_Off * abbrev_offset, Dwarf_Unsigned * abbrev_count, Dwarf_Error* error);\fP .DE The function allows more detailed printing of abbreviation data. It is handy for analyzing abbreviations but is not normally needed by applications. The function first appears in March 2016. .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*abbrev_offset\fP to the global offset in the \f(CW.debug_abbrev\fP section of the abbreviation. It also sets \f(CW*abbrev_count\fP to the number of attribute/form pairs in the abbreviation entry. It is possible, though unusual, for the count to be zero (meaning there is abbreviation instance and a TAG instance which have no attributes). .P On failure it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP .P It should never return \f(CWDW_DLV_NO_ENTRY\fP, but callers should allow for that possibility.. .H 3 "dwarf_get_version_of_die()" .DS \f(CWint dwarf_get_version_of_die(Dwarf_Die die, Dwarf_Half *version, Dwarf_Half *offset_size)\fP .DE The function returns the CU context version through \f(CW*version\fP and the CU context offset-size through \f(CW*offset_size\fP and returns \f(CWDW_DLV_OK\fP on success. In case of error, the only errors possible involve an inappropriate NULL \f(CWdie\fP pointer so no Dwarf_Debug pointer is available. Therefore setting a Dwarf_Error would not be very meaningful (there is no Dwarf_Debug to attach it to). The function returns DW_DLV_ERROR on error. The values returned through the pointers are the values two arguments to dwarf_get_form_class() requires. .H 3 "dwarf_attrlist()" .DS \f(CWint dwarf_attrlist( Dwarf_Die die, Dwarf_Attribute** attrbuf, Dwarf_Signed *attrcount, Dwarf_Error *error)\fP .DE When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_attrlist()\fP sets \f(CWattrbuf\fP to point to an array of \f(CWDwarf_Attribute\fP descriptors corresponding to each of the attributes in die, and returns the number of elements in the array through \f(CWattrcount\fP. \f(CWDW_DLV_NO_ENTRY\fP is returned if the count is zero (no \f(CWattrbuf\fP is allocated in this case). \f(CWDW_DLV_ERROR\fP is returned on error. On a successful return from \f(CWdwarf_attrlist()\fP, each of the \f(CWDwarf_Attribute\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP, followed by free-ing the list pointed to by \f(CW*attrbuf\fP using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP, when no longer of interest (see \f(CWdwarf_dealloc()\fP). Freeing the attrlist: .in +2 .FG "Example8 dwarf_attrlist() free" .DS \f(CW void example8(Dwarf_Debug dbg, Dwarf_Die somedie) { Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; Dwarf_Error error = 0; int errv = 0; errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); if (errv == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < atcount; ++i) { /* use atlist[i] */ dwarf_dealloc_attribute(atlist[i]); /* The original form still works. dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); */ } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_hasattr()" .DS \f(CWint dwarf_hasattr( Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_hasattr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to \fInon-zero\fP if \f(CWdie\fP has the attribute \f(CWattr\fP and \fIzero\fP otherwise. If it fails, it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_attr()" .DS \f(CWint dwarf_attr( Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *return_attr, Dwarf_Error *error)\fP .DE .P When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_attr()\fP sets \f(CW*return_attr\fP to the \f(CWDwarf_Attribute\fP descriptor of \f(CWdie\fP having the attribute \f(CWattr\fP. When one no longer needs the attribute call \f(CWdwarf_dealloc_attribute(return_attr)\fP. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWattr\fP is not contained in \f(CWdie\fP. .P It returns \f(CWDW_DLV_ERROR\fP and sets the *error argument if an error occurred. .H 3 "dwarf_lowpc()" .DS \f(CWint dwarf_lowpc( Dwarf_Die die, Dwarf_Addr * return_lowpc, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_lowpc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lowpc\fP to the low program counter value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP represents a debugging information entry with the \f(CWDW_AT_low_pc\fP attribute. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_highpc_b()" .DS \f(CWint dwarf_highpc_b( Dwarf_Die die, Dwarf_Addr * return_highpc, Dwarf_Half * return_form*/, enum Dwarf_Form_Class * return_class*/, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_highpc_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP to the value of the \f(CWDW_AT_high_pc\fP attribute. It also sets \f(CW*return_form\fP to the FORM of the attribute. Beginning 22 April 2019 \f(CWreturn_form\fP will not be used to return the form class if \f(CWreturn_form\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. It sets \f(CW*return_class\fP to the form class of the attribute. Beginning 22 April 2019 \f(CWreturn_class\fP will not be used to return the form class if \f(CWreturn_class\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. If the form class returned is \f(CWDW_FORM_CLASS_ADDRESS\fP the \f(CWreturn_highpc\fP is an actual pc address (1 higher than the address of the last pc in the address range).. If the form class returned is \f(CWDW_FORM_CLASS_CONSTANT\fP the \f(CWreturn_highpc\fP is an offset from the value of the the DIE's low PC address (see DWARF4 section 2.17.2 Contiguous Address Range). It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have the \f(CWDW_AT_high_pc\fP attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_highpc()" .DS \f(CWint dwarf_highpc( Dwarf_Die die, Dwarf_Addr * return_highpc, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_highpc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP the high program counter value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP represents a debugging information entry with the \f(CWDW_AT_high_pc attribute\fP and the form is \f(CWDW_FORM_addr\fP (meaning the form is of class address). .P This function is useless for a \f(CWDW_AT_high_pc\fP which is encoded as a constant (which was first possible in DWARF4). .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this attribute. .P It returns \f(CWDW_DLV_ERROR\fP if an error occurred or if the form is not of class address. .H 3 "dwarf_dietype_offset()" .DS \f(CWint dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/);\fP .DE On success the function \f(CWdwarf_dietype_offset()\fP returns the offset referred to by \f(CWDW_AT_type\fP attribute of \f(CWdie\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is returned if the \f(CWdie\fP has no \f(CWDW_AT_type\fP attribute. .P \f(CWDW_DLV_ERROR\fP is returned if an error is detected. .P This feature was introduced in February 2016. .H 3 "dwarf_offset_list()" .DS \f(CWint dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Off ** offbuf, Dwarf_Unsigned * offcnt, Dwarf_Error * error); .DE On success The function \f(CWdwarf_offset_list()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*offbuf\fP to point to an array of the offsets of the direct children of the die at \f(CWoffset\fP. It sets \f(CW*offcnt\fP to point to the count of entries in the \f(CWoffset\fP array .P In case of error it returns \f(CWDW_DLV_OK\fP. .P It does not return \f(CWDW_DLV_NO_ENTRY\fP but callers should allow for that possibility anyway. .P This feature was introduced in March 2016. .P Freeing the offset_list is done as follows.: .in +2 .FG "Exampleoffset_list dwarf_offset_list() free" .DS \f(CW void exampleoffset_list(Dwarf_Debug dbg, Dwarf_Off dieoffset, Dwarf_Bool is_info) { Dwarf_Unsigned offcnt = 0; Dwarf_Off *offbuf = 0; Dwarf_Error error = 0; int errv = 0; errv = dwarf_offset_list(dbg,dieoffset, is_info, &offbuf,&offcnt, &error); if (errv == DW_DLV_OK) { Dwarf_Unsigned i = 0; for (i = 0; i < offcnt; ++i) { /* use offbuf[i] */ } dwarf_dealloc(dbg, offbuf, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_bytesize()" .DS \f(CWDwarf_Signed dwarf_bytesize( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bytesize()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bytes needed to contain an instance of the aggregate debugging information entry represented by \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the byte size attribute \f(CWDW_AT_byte_size\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_bitsize()" .DS \f(CWint dwarf_bitsize( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bitsize()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bits occupied by the bit field value that is an attribute of the given die. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the bit size attribute \f(CWDW_AT_bit_size\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_bitoffset()" .DS \f(CWint dwarf_bitoffset( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bitoffset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bits to the left of the most significant bit of the bit field value. This bit offset is not necessarily the net bit offset within the structure or class , since \f(CWDW_AT_data_member_location\fP may give a byte offset to this \f(CWDIE\fP and the bit offset returned through the pointer does not include the bits in the byte offset. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the bit offset attribute \f(CWDW_AT_bit_offset\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_srclang()" .DS \f(CWint dwarf_srclang( Dwarf_Die die, Dwarf_Unsigned *return_lang, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_srclang()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lang\fP to a code indicating the source language of the compilation unit represented by the descriptor \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not represent a source file debugging information entry (i.e. contain the attribute \f(CWDW_AT_language\fP). It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_arrayorder()" .DS \f(CWint dwarf_arrayorder( Dwarf_Die die, Dwarf_Unsigned *return_order, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_arrayorder()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_order\fP a code indicating the ordering of the array represented by the descriptor \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the array order attribute \f(CWDW_AT_ordering\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 2 "Attribute Queries" Based on the attributes form, these operations are concerned with returning uninterpreted attribute data. Since it is not always obvious from the return value of these functions if an error occurred, one should always supply an \f(CWerror\fP parameter or have arranged to have an error handling function invoked (see \f(CWdwarf_init()\fP ) to determine the validity of the returned value and the nature of any errors that may have occurred. A \f(CWDwarf_Attribute\fP descriptor describes an attribute of a specific die. Thus, each \f(CWDwarf_Attribute\fP descriptor is implicitly associated with a specific die. .H 3 "dwarf_hasform()" .DS \f(CWint dwarf_hasform( Dwarf_Attribute attr, Dwarf_Half form, Dwarf_Bool *return_hasform, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_hasform()\fP returns \f(CWDW_DLV_OK\fP and and puts a \fInon-zero\fP value in the \f(CW*return_hasform\fP boolean if the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP has the attribute form \f(CWform\fP. If the attribute does not have that form \fIzero\fP is put into \f(CW*return_hasform\fP. \f(CWDW_DLV_ERROR\fP is returned on error. .H 3 "dwarf_whatform()" .DS \f(CWint dwarf_whatform( Dwarf_Attribute attr, Dwarf_Half *return_form, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatform()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP to the attribute form code of the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. An attribute using DW_FORM_indirect effectively has two forms. This function returns the 'final' form for \f(CWDW_FORM_indirect\fP, not the \f(CWDW_FORM_indirect\fP itself. This function is what most applications will want to call. .H 3 "dwarf_whatform_direct()" .DS \f(CWint dwarf_whatform_direct( Dwarf_Attribute attr, Dwarf_Half *return_form, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatform_direct()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP to the attribute form code of the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. An attribute using \f(CWDW_FORM_indirect\fP effectively has two forms. This returns the form 'directly' in the initial form field. That is, it returns the 'initial' form of the attribute. .P So when the form field is \f(CWDW_FORM_indirect\fP this call returns the \f(CWDW_FORM_indirect\fP form, which is sometimes useful for dump utilities. .P It is confusing that the _direct() function returns DW_FORM_indirect if an indirect form is involved. Just think of this as returning the initial form the first form value seen for the attribute, which is also the final form unless the initial form is \f(CWDW_FORM_indirect\fP. .H 3 "dwarf_whatattr()" .DS \f(CWint dwarf_whatattr( Dwarf_Attribute attr, Dwarf_Half *return_attr, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatattr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_attr\fP to the attribute code represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formref()" .DS \f(CWint dwarf_formref( Dwarf_Attribute attr, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formref()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the CU-relative offset represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP class. \f(CWattr\fP must be a CU-local reference, not form \f(CWDW_FORM_ref_addr\fP and not \f(CWDW_FORM_sec_offset\fP . It is an error for the form to not belong to the \f(CWREFERENCE\fP class. It returns \f(CWDW_DLV_ERROR\fP on error. Beginning November 2010: All \f(CWDW_DLV_ERROR\fP returns set \f(CW*return_offset\fP. Most errors set \f(CW*return_offset\fP to zero, but for error \f(CWDW_DLE_ATTR_FORM_OFFSET_BAD\fP the function sets \f(CW*return_offset\fP to the invalid offset (which allows the caller to print a more detailed error message). See also \f(CWdwarf_global_formref\fP below. .H 3 "dwarf_global_formref()" .DS \f(CWint dwarf_global_formref( Dwarf_Attribute attr, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_global_formref()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the section-relative offset represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP or other section-references classes. .P \f(CWattr\fP can be any legal \f(CWREFERENCE\fP class form plus \f(CWDW_FORM_ref_addr\fP or \f(CWDW_FORM_sec_offset\fP. It is an error for the form to not belong to one of the reference classes. It returns \f(CWDW_DLV_ERROR\fP on error. See also \f(CWdwarf_formref\fP above. .P The caller must determine which section the offset returned applies to. The function \f(CWdwarf_get_form_class()\fP is useful to determine the applicable section. .P The function converts CU relative offsets from forms such as DW_FORM_ref4 into global section offsets. .H 3 "dwarf_convert_to_global_offset()" .DS \f(CWint dwarf_convert_to_global_offset( Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_convert_to_global_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the section-relative offset represented by the cu-relative offset \f(CWoffset\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP class. \f(CWattr\fP must be a CU-local reference (DWARF class REFERENCE) or form \f(CWDW_FORM_ref_addr\fP and the \f(CWattr\fP must be directly relevant for the calculated \f(CW*return_offset\fP to mean anything. The function returns \f(CWDW_DLV_ERROR\fP on error. The function is not strictly necessary but may be a convenience for attribute printing in case of error. .H 3 "dwarf_formaddr()" .DS \f(CWint dwarf_formaddr( Dwarf_Attribute attr, Dwarf_Addr * return_addr, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formaddr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_addr\fP to the address represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWADDRESS\fP class. It is an error for the form to not belong to this class. It returns \f(CWDW_DLV_ERROR\fP on error. One possible error that can arise (in a .dwo object file or a .dwp package file) is \f(CWDW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION\fP. Such an error means that the .dwo or .dwp file is missing the \f(CW.debug_addr\fP section. When opening a .dwo object file or a .dwp package file one should also open the corresponding executable and use \f(CWdwarf_set_tied_dbg()\fP to associate the objects before calling dwarf_formaddr(). H 3 "dwarf_get_debug_addr_index()" .DS \f(CWint dwarf_get_debug_addr_index( Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_debug_addr_index()\fP is only valid on attributes with form \f(CWDW_FORM_GNU_addr_index\fP or \f(CWDW_FORM_addrx\fP. The function makes it possible to print the index from a dwarf dumper program. When it succeeds, \f(CWdwarf_get_debug_addr_index()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_index\fP to the attribute's index (into the \f(CW.debug_addr\fP section). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_debug_str_index()" .DS \f(CWint dwarf_get_debug_str_index( Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error * error);\fP .DE .P For an attribute with form \f(CWDW_FORM_strx\fP or \f(CWDW_FORM_GNU_str_index\fP this function retrieves the index (which refers to a .debug_str_offsets section in this .dwo). .P If successful, the function \f(CWdwarf_get_debug_str_index()\fP returns \f(CWDW_DLV_OK\fP and returns the index through the \f(CWreturn_index()\fP pointer. .P If the passed in attribute does not have this form or there is no valid compilation unit context for the attribute the function returns \f(CWDW_DLV_ERROR\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .H 3 "dwarf_formflag()" .DS \f(CWint dwarf_formflag( Dwarf_Attribute attr, Dwarf_Bool * return_bool, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formflag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to the (one unsigned byte) flag value. Any non-zero value means true. A zero value means false. Before 29 November 2012 this would only return 1 or zero through the pointer, but that was always a strange thing to do. The DWARF specification has always been clear that any non-zero value means true. The function should report the value found truthfully, and now it does. It returns \f(CWDW_DLV_ERROR\fP on error or if the \f(CWattr\fP does not have form flag. .H 3 "dwarf_formudata()" .DS \f(CWint dwarf_formudata( Dwarf_Attribute attr, Dwarf_Unsigned * return_uvalue, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formudata()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_uvalue\fP to the \f(CWDwarf_Unsigned\fP value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWCONSTANT\fP class. It is an error for the form to not belong to this class. It returns \f(CWDW_DLV_ERROR\fP on error. Never returns \f(CWDW_DLV_NO_ENTRY\fP. For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP are possibly class \f(CWCONSTANT\fP, and for DWARF4 and later they are definitely class \f(CWCONSTANT\fP. .H 3 "dwarf_formsdata()" .DS \f(CWint dwarf_formsdata( Dwarf_Attribute attr, Dwarf_Signed * return_svalue, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_formsdata()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_svalue\fP to the \f(CWDwarf_Signed\fP value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWCONSTANT\fP class. It is an error for the form to not belong to this class. If the size of the data attribute referenced is smaller than the size of the \f(CWDwarf_Signed\fP type, its value is sign extended. It returns \f(CWDW_DLV_ERROR\fP on error. Never returns \f(CWDW_DLV_NO_ENTRY\fP. For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP are possibly class \f(CWCONSTANT\fP, and for DWARF4 and later they are definitely class \f(CWCONSTANT\fP. .H 3 "dwarf_formblock()" .DS \f(CWint dwarf_formblock( Dwarf_Attribute attr, Dwarf_Block ** return_block, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formblock()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_block\fP to a pointer to a \f(CWDwarf_Block\fP structure containing the value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWBLOCK\fP class. It is an error for the form to not belong to this class. The storage pointed to by a successful return of \f(CWdwarf_formblock()\fP should be freed using the allocation type \f(CWDW_DLA_BLOCK\fP, when no longer of interest (see \f(CWdwarf_dealloc()\fP). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formstring()" .DS \f(CWint dwarf_formstring( Dwarf_Attribute attr, char ** return_string, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_string\fP to a pointer to a null-terminated string containing the value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWSTRING\fP class. It is an error for the form to not belong to this class. .P The storage pointed to by a successful return of \f(CWdwarf_formstring()\fP should not be freed. The pointer points into existing DWARF memory and the pointer becomes stale/invalid after a call to \f(CWdwarf_finish\fP. \f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formsig8()" .DS \f(CWint dwarf_formsig8( Dwarf_Attribute attr, Dwarf_Sig8 * return_sig8, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formsig8()\fP returns \f(CWDW_DLV_OK\fP and copies the 8 byte signature to a \f(CWDwarf_Sig8\fP structure provided by the caller if the form of the attribute is of form \f(CWDW_FORM_ref_sig8\fP ( a member of the \f(CWREFERENCE\fP class). It is an error for the form to be anything but \f(CWDW_FORM_ref_sig8\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .P This form is used to refer to a type unit. .H 3 "dwarf_formexprloc()" .DS \f(CWint dwarf_formexprloc( Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formexprloc()\fP returns \f(CWDW_DLV_OK\fP and sets the two values thru the pointers to the length and bytes of the DW_FORM_exprloc entry if the form of the attribute is of form \f(CWDW_FORM_experloc\fP. It is an error for the form to be anything but \f(CWDW_FORM_exprloc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .P On success the value set through the \f(CWreturn_exprlen\fP pointer is the length of the location expression. On success the value set through the \f(CWblock_ptr\fP pointer is a pointer to the bytes of the location expression itself. .H 3 "dwarf_get_form_class()" .DS \f(CWenum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half dwversion, Dwarf_Half attrnum, Dwarf_Half offset_size, Dwarf_Half form)\fP .DE .P The function is just for the convenience of libdwarf clients that might wish to categorize the FORM of a particular attribute. The DWARF specification divides FORMs into classes in Chapter 7 and this function figures out the correct class for a form. .P The \f(CWdwversion\fP passed in shall be the dwarf version of the compilation unit involved (2 for DWARF2, 3 for DWARF3, 4 for DWARF 4). The \f(CWattrnum\fP passed in shall be the attribute number of the attribute involved (for example, \f(CWDW_AT_name\fP ). The \f(CWoffset_size\fP passed in shall be the length of an offset in the current compilation unit (4 for 32bit dwarf or 8 for 64bit dwarf). The \f(CWform\fP passed in shall be the attribute form number. If \f(CWform\fP \f(CWDW_FORM_indirect\fP is passed in \f(CWDW_FORM_CLASS_UNKNOWN\fP will be returned as this form has no defined 'class'. .P When it returns \f(CWDW_FORM_CLASS_UNKNOWN\fP the function is simply saying it could not determine the correct class given the arguments presented. Some user-defined attributes might have this problem. The function \f(CWdwarf_get_version_of_die()\fP may be helpful in filling out arguments for a call to \f(CWdwarf_get_form_class()\fP. .H 3 "dwarf_discr_list()" .DS \f(CWint dwarf_discr_list( Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, Dwarf_Dsc_Head * dsc_head_out, Dwarf_Unsigned * dsc_array_length_out, Dwarf_Error * error) Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_discr_list()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*dsc_head_out\fP to a pointer to the discriminant information for the discriminant list and sets \f(CW*dsc_array_length_out\fP to the count of discriminant entries. The only current applicability is the block value of a \f(CWDW_AT_discr_list\fP attribute. .P Those values are useful for calls to \f(CWdwarf_discr_entry_u()\fP or \f(CWdwarf_discr_entry_s()\fP to get the actual discriminant values. See the example below. It returns \f(CWDW_DLV_NO_ENTRY\fP if the block is empty. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .P When the call was successful and the \f(CWDwarf_Dsc_Head\fP is no longer needed, call \f(CWdwarf_dealloc()\fP to free all the space related to this. .DS void example_discr_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Half attrnum, Dwarf_Bool isunsigned, Dwarf_Half theform, Dwarf_Error *err) { /* The example here assumes that attribute attr is a DW_AT_discr_list. isunsigned should be set from the signedness of the parent of 'die' per DWARF rules for DW_AT_discr_list. */ enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; int wres = 0; wres = dwarf_get_version_of_die(die,&version,&offset_size); if (wres != DW_DLV_OK) { /* FAIL */ return; } fc = dwarf_get_form_class(version,attrnum,offset_size,theform); if (fc == DW_FORM_CLASS_BLOCK) { int fres = 0; Dwarf_Block *tempb = 0; fres = dwarf_formblock(attr, &tempb, err); if (fres == DW_DLV_OK) { Dwarf_Dsc_Head h = 0; Dwarf_Unsigned u = 0; Dwarf_Unsigned arraycount = 0; int sres = 0; sres = dwarf_discr_list(dbg, (Dwarf_Small *)tempb->bl_data, tempb->bl_len, &h,&arraycount,err); if (sres == DW_DLV_NO_ENTRY) { /* Nothing here. */ dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } if (sres == DW_DLV_ERROR) { /* FAIL . */ dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } for(u = 0; u < arraycount; u++) { int u2res = 0; Dwarf_Half dtype = 0; Dwarf_Signed dlow = 0; Dwarf_Signed dhigh = 0; Dwarf_Unsigned ulow = 0; Dwarf_Unsigned uhigh = 0; if (isunsigned) { u2res = dwarf_discr_entry_u(h,u, &dtype,&ulow,&uhigh,err); } else { u2res = dwarf_discr_entry_s(h,u, &dtype,&dlow,&dhigh,err); } if( u2res == DW_DLV_ERROR) { /* Something wrong */ dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } if( u2res == DW_DLV_NO_ENTRY) { /* Impossible. u < arraycount. */ dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } /* Do something with dtype, and whichever of ulow, uhigh,dlow,dhigh got set. Probably save the values somewhere. Simple casting of dlow to ulow (or vice versa) will not get the right value due to the nature of LEB values. Similarly for uhigh, dhigh. One must use the right call. */ } dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); } } } .DE .H 3 "dwarf_discr_entry_u()" .DS \f(CWint dwarf_discr_entry_u( Dwarf_Dsc_Head dsc_head, Dwarf_Unsigned dsc_array_index, Dwarf_Half *dsc_type, Dwarf_Unsigned *dsc_low, Dwarf_Unsigned *dsc_high, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_discr_entry_u()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*dsc_type\fP, \f(CW*dsc_low\fP, and \f(CW*dsc_high\fP to the discriminant values for that index. Valid \f(CWdsc_array_index\fP values are zero to \f(CW(dsc_array_length_out -1)\fP from a \f(CWdwarf_discr_list()\fP call. .P If \f(CW*dsc_type\fP is \f(CWDW_DSC_label\fP \f(CW*dsc_low\fP is set to the discriminant value and \f(CW*dsc_high\fP is set to zero. .P If \f(CW*dsc_type\fP is \f(CWDW_DSC_range\fP \f(CW*dsc_low\fP is set to the low end of the discriminant range and and \f(CW*dsc_high\fP is set to the high end of the discriminant range. .P Due to the nature of the LEB numbers in the discriminant representation in DWARF one must call the correct one of \f(CWdwarf_discr_entry_u()\fP or \f(CWdwarf_discr_entry_s()\fP based on whether the discriminant is signed or unsigned. Casting an unsigned to signed is not always going to get the right value. .P If \f(CWdsc_array_index\fP is outside the range of valid indexes the function returns \f(CWDW_DLV_NO_ENTRY\fP. On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to an error pointer. .H 3 "dwarf_discr_entry_s()" .DS \f(CWint dwarf_discr_entry_s( Dwarf_Dsc_Head dsc_head, Dwarf_Unsigned dsc_array_index, Dwarf_Half *dsc_type, Dwarf_Signed *dsc_low, Dwarf_Signed *dsc_high, Dwarf_Error *error)\fP .DE This is identical to \f(CWdwarf_discr_entry_u()\fP except that the discriminant values are signed values in this interface. Callers must check the discriminant type and call the correct function. .H 2 "Location List Operations, Raw .debug_loclists" This set of interfaces is to read the (entire) \f(CW.debug_loclists\fP section without reference to any DIE. As such these can only present the raw data from the file. There is no way in these interfaces to get actual addresses. These might be of interest if you want to know exactly what the compiler output in the \f(CW.debug_loclists\fP section. "dwarfdump ----print-raw-loclists" (try adding -v or -vvv) makes these calls. .P Here is an example using all the following calls. .in +2 .FG "Example Raw Loclist" .DS \f(CW int example_raw_loclist(Dwarf_Debug dbg,Dwarf_Error *error) { Dwarf_Unsigned count = 0; int res = 0; Dwarf_Unsigned i = 0; res = dwarf_load_loclists(dbg,&count,error); if (res != DW_DLV_OK) { return res; } for(i =0 ; i < count ; ++i) { Dwarf_Unsigned header_offset = 0; Dwarf_Small offset_size = 0; Dwarf_Small extension_size = 0; unsigned version = 0; /* 5 */ Dwarf_Small address_size = 0; Dwarf_Small segment_selector_size = 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned offset_of_offset_array = 0; Dwarf_Unsigned offset_of_first_locentry = 0; Dwarf_Unsigned offset_past_last_loceentry = 0; res = dwarf_get_loclist_context_basics(dbg,i, &header_offset,&offset_size,&extension_size, &version,&address_size,&segment_selector_size, &offset_entry_count,&offset_of_offset_array, &offset_of_first_locentry, &offset_past_last_locentry,error); if (res != DW_DLV_OK) { return res; } { Dwarf_Unsigned e = 0; unsigned colmax = 4; unsigned col = 0; Dwarf_Unsigned global_offset_of_value = 0; for ( ; e < offset_entry_count; ++e) { Dwarf_Unsigned value = 0; int resc = 0; resc = dwarf_get_loclist_offset_index_value(dbg, i,e,&value, &global_offset_of_value,error); if (resc != DW_DLV_OK) { return resc; } /* Do something */ col++; if (col == colmax) { col = 0; } } } { Dwarf_Unsigned curoffset = offset_of_first_loceentry; Dwarf_Unsigned endoffset = offset_past_last_loceentry; int rese = 0; Dwarf_Unsigned ct = 0; for ( ; curoffset < endoffset; ++ct ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned v1 = 0; Dwarf_Unsigned v2 = 0; rese = dwarf_get_loclist_lle(dbg,i, curoffset,endoffset, &entrylen, &code,&v1,&v2,error); if (rese != DW_DLV_OK) { return rese; } curoffset += entrylen; if (curoffset > endoffset) { return DW_DLV_ERROR; } } } } return DW_DLV_OK; } \fP .DE .in -2 .H 3 "dwarf_load_loclists()" .DS \f(CWint dwarf_load_loclists( Dwarf_Debug dbg, Dwarf_Unsigned *loclists_count, Dwarf_Error *error)\fP .DE On a successful call to \f(CWdwarf_load_loclists()\fP the function returns \f(CWDW_DLV_OK\fP, sets \f(CW*loclists_count\fP (if and only if \f(CWloclists_count\fP is non-null) to the number of distinct section contents that exist. A small amount of data for each Location List Table (DWARF5 section 7.29) is recorded in \f(CWdbg\fP as a side effect. Normally libdwarf will have already called this, but if an application never requests any \f(CW.debug_info\fP data the section might not be loaded. If the section is loaded this returns very quickly and will set \f(CW*loclists_count\fP just as described in this paragraph. .P If there is no \f(CW.debug_loclists\fP section in the object file this function returns \f(CWDW_DLV_NO_ENTRY\fP. .P If something is malformed it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to the applicable error pointer describing the problem. .P There is no dealloc call. Calling \f(CWdwarf_finish()\fP releases the modest amount of memory recorded for this section as a side effect. .P .H 3 "dwarf_get_loclist_context_basics()" .DS \f(CWint dwarf_get_loclist_context_basics(Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned * header_offset, Dwarf_Small * offset_size, Dwarf_Small * extension_size, unsigned * version, /* 5 */ Dwarf_Small * address_size, Dwarf_Small * segment_selector_size, Dwarf_Unsigned * offset_entry_count, Dwarf_Unsigned * offset_of_offset_array, Dwarf_Unsigned * offset_of_first_locentry, Dwarf_Unsigned * offset_past_last_locentry, Dwarf_Error * /*err*/);\fP .DE On success this returns \f(CWDW_DLV_OK\fP and returns values through the pointer arguments (other than \f(CWdbg\fP or \f(CWerror\fP) .P A call to \f(CWdwarf_load_loclists()\fP that succeeds gets you the count of contexts and \f(CWdwarf_get_loclist_context_basics()\fP for any "i >=0 and i < count" gets you the context values relevant to \f(CW.debug_loclists\fP. .P Any of the pointer-arguments for returning context values can be passed in as 0 (in which case they will be skipped). .P You will want \f(CW*offset_entry_count\fP so you can call \f(CWdwarf_get_loclist_offset_index_value()\fP usefully. .P If the \f(CWcontext_index\fP passed in is out of range the function returns \f(CWDW_DLV_NO_ENTRY\fP .P At the present time \f(CWDW_DLV_ERROR\fP is never returned. .H 3 "dwarf_get_loclist_offset_index_value()" .DS \f(CWint dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned offsetentry_index, Dwarf_Unsigned * offset_value_out, Dwarf_Unsigned * global_offset_value_out, Dwarf_Error *error)\fP .DE .P On success \f(CWdwarf_get_loclist_offset_index_value()\fP returns \f(CWDW_DLV_OK\fP, sets \f(CW* offset_value_out\fP to the value in the Range List Table offset array, and sets \f(CW* global_offset_value_out\fP to the section offset (in \f(CW.debug_addr\fP) of the offset value. .P Pass in \f(CWcontext_index\fP exactly as the same field passed to \f(CWdwarf_get_loclist_context_basics()\fP. .P Pass in \f(CWoffset_entry_index\fP based on the return field \f(CWoffset_entry_count\fP from \f(CWdwarf_get_loclist_context_basics()\fP, meaning for that \f(CWcontext_index\fP an \f(CWoffset_entry_index\fP >=0 and < \f(CWoffset_entry_count\fP. .P Pass in \f(CWoffset_entry_count\fP exactly as the same field passed to \f(CWdwarf_get_loclist_context_basics()\fP. .P If one of the indexes passed in is out of range \f(CWDW_DLV_NO_ENTRY\fP will be returned and no return arguments touched. .P If there is some corruption of DWARF5 data then \f(CWDW_DLV_ERROR\fP might be returned and \f(CW*error\fP set to the error details. .H 3 "dwarf_get_loclist_lle()" .DS \f(CWint dwarf_get_loclist_lle( Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned entry_offset, Dwarf_Unsigned endoffset, unsigned *entrylen, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Unsigned *expr_ops_blocksize, Dwarf_Unsigned *expr_ops_offset, Dwarf_Small **expr_opsdata, Dwarf_Error *error)\fP .DE On success it returns a single \f(CWDW_RLE*\fP record (see dwarf.h) fields. .P \f(CWcontextnumber\fP is the number of the current loclist context. .P \f(CWentry_offset\fP is the section offset (section-global offset) of the next record. .P \f(CWendoffset\fP is one past the last entry in this rle context. .P \f(CW*entrylen\fP returns the length in the .debug_loclists section of the particular record returned. It's used to increment to the next record within this loclist context. .P \f(CW*entrykind\fP returns is the \f(CWDW_RLE*\fP number. .P Some record kinds have 1 or 0 operands, most have two operands (the records describing ranges). .P \f(CW*expr_ops_blocksize\fP returns the size, in bytes, of the Dwarf Expression (some operations have no Dwarf Expression and those that do can have a zero length blocksize. .P \f(CW*expr_ops_offset\fP returns the offset (in the .debug_loclists section) of the first byte of the Dwarf Expression. .P \f(CW*expr_opsdata\fP returns a pointer to the bytes of the Dwarf Expression. .P If the contextnumber is out of range it will return \f(CWDW_DLV_NO_ENTRY\fP. .P If the \f(CW.debug_loclists\fP section is malformed or the \f(CWentry_offset\fP is incorrect it may return \f(CWDW_DLV_ERROR\fP. .H 2 "Location List operations .debug_loc & .debug_loclists" These operations apply to the .debug_loc section in DWARF2, DWARF3, DWARF4, and DWARF5 object files. Earlier versions still work as well as ever, but they only deal with, at most, DWARF2, DWARF3, and DWARF4. .H 3 "dwarf_get_loclist_c()" .DS \f(CW int dwarf_get_loclist_c (Dwarf_Attribute attr, Dwarf_Loc_Head_c * loclist_head, Dwarf_Unsigned * locCount, Dwarf_Error * error); \fP .DE This function returns a pointer that is, in turn, used to make possible calls to return the details of the location list. .P The incoming argument \f(CWattr\fP should have one of the FORMs of a location expression or location list. .P On success this returns \f(CWDW_DLV_OK\fP and sets \f(CW*loclist_head\fP to a pointer used in further calls (see the example and descriptions that follow it). \f(CWlocCount\fP is set to the number of entries in the location list (or if the FORM is of a location expression the \f(CWlocCount\fP will be set to one). At this point one cannot yet tell if it was a location list or a location expression (see . \f(CWdwarf_get_locdesc_entry_c{}\fP). .P In case of error \f(CWDW_DLV_ERROR\fP is returned and \f(CW*error\fP is set to an error designation. .P A return of \f(CWDW_DLV_NO_ENTRY\fP may be possible but is a bit odd. .DS \f(CW void example_loclistcv5(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Unsigned lcount = 0; Dwarf_Loc_Head_c loclist_head = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_get_loclist_c(someattr,&loclist_head,&lcount,&error); if (lres == DW_DLV_OK) { Dwarf_Unsigned i = 0; /* Before any return remember to call dwarf_loc_head_c_dealloc(loclist_head); */ for (i = 0; i < lcount; ++i) { Dwarf_Small loclist_lkind = 0; Dwarf_Small lle_value = 0; Dwarf_Unsigned rawval1 = 0; Dwarf_Unsigned rawval2 = 0; Dwarf_Bool debug_addr_unavailable = FALSE; Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Unsigned loclist_expr_op_count = 0; Dwarf_Locdesc_c locdesc_entry = 0; Dwarf_Unsigned expression_offset = 0; Dwarf_Unsigned locdesc_offset = 0; lres = dwarf_get_locdesc_entry_d(loclist_head, i, &lle_value, &rawval1,&rawval2, &debug_addr_unavailable, &lopc,&hipc, &loclist_expr_op_count, &locdesc_entry, &loclist_lkind, &expression_offset, &locdesc_offset, &error); if (lres == DW_DLV_OK) { Dwarf_Unsigned j = 0; int opres = 0; Dwarf_Small op = 0; for (j = 0; j < loclist_expr_op_count; ++j) { Dwarf_Unsigned raw1 = 0; Dwarf_Unsigned raw2 = 0; Dwarf_Unsigned raw3 = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned offsetforbranch = 0; opres = dwarf_get_location_op_value_d( locdesc_entry, j,&op, &raw1,&raw2,&raw3, &opd1, &opd2,&opd3,&offsetforbranch, &error); if (opres == DW_DLV_OK) { /* Do something with the operators. Usually you want to use opd1,2,3 as appropriate. Calculations involving base addresses etc have already been incorporated in opd1,2,3. */ } else { dwarf_dealloc_error(dbg,error); dwarf_loc_head_c_dealloc(loclist_head); /*Something is wrong. */ return; } } } else { /* Something is wrong. Do something. */ dwarf_loc_head_c_dealloc(loclist_head); dwarf_dealloc_error(dbg,error); return; } } } /* Always call dwarf_loc_head_c_dealloc() to free all the memory associated with loclist_head. */ if (error) { dwarf_dealloc_error(dbg,error); } dwarf_loc_head_c_dealloc(loclist_head); loclist_head = 0; return; } \fP .DE .H 3 "dwarf_get_locdesc_entry_d()" Earlier versions of this work with earlier versions of DWARF. This works with all DWARF from DWARF2 on. .DS \f(CW int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned index, Dwarf_Small *lle_value_out, Dwarf_Addr *rawval1_out, Dwarf_Addr *rawval2_out, Dwarf_Bool *debug_addr_unavailable, Dwarf_Addr *lopc_out, Dwarf_Addr *hipc_out, Dwarf_Unsigned *loc_expr_op_count_out, Dwarf_Locdesc_c *locentry_out, Dwarf_Small *loclist_kind, Dwarf_Unsigned *expression_offset_out, Dwarf_Unsigned *locdesc_offset_out, Dwarf_Error *error); \fP .DE This function returns overall information about a location list or location description. Details about location operators are retrieved by a call to \f(CWdwarf_get_location_op_value_d()\fP (described below). In case of success \f(CWDW_DLV_OK\fP is returned and arguments are set through the pointers to return values to the caller. Now we describe each argument. .P \f(CW*loclist_kind\fP returns \f(CWDW_LKIND_expression\fP, \f(CWDW_LKIND_loclist\fP, \f(CWDW_LKIND_GNU_exp_list\fP, or \f(CWDW_LKIND_loclists\fP. .P \f(CWDW_LKIND_expression\fP means the 'list' is really just a location expression. The only entry is with \f(CWindex\fP zero. In this case \f(CW*lle_value_out\fP will have the value \f(CWDW_LLE_start_end\fP. .P \f(CWDW_LKIND_loclist\fP, means the list is from DWARF2, DWARF3, or DWARF4. The \f(CW*lle_value_out\fP value has been synthesized as if it were a DWARF5 expression. .P \f(CWDW_LKIND_GNU_exp_list\fP, means the list is from a DWARF4 .debug_loc.dwo object section. It is an experimental version from before DWARF5 was published. The \f(CW*lle_value_out\fP is \f(CWDW_LLEX_start_end_entry\fP (or one of the other DW_LLEX values). .P \f(CWDW_LKIND_loclists\fP means this is a DWARF5 loclist, so \f(CWDW_LLE_start_end\fP is an example of one possible \f(CW*lle_value_out\fP values. In addition, if \f(CW*debug_addr_unavailable\fP is set it means the \f(CW*lopc_out\fP and \f(CW*hipc_out\fP could not be correctly set (so are meaningless) because the .debug_addr section is missing. Very likely the .debug_addr section is in the executable and that file needs to be opened and attached to the current Dwarf_Debug with \f(CWdwarf_set_tied_dbg()\fP. .P \f(CW*rawval1_out\fP returns the value of the first operand in the location list entry. Uninterpreted. Useful for reporting or for those wishing to do their own calculation of \f(CWlopc\fP. .P \f(CW*rawval2_out\fP returns the value of the second operand in the location list entry. Uninterpreted. Useful for reporting or for those wishing to do their own calculation of \f(CWhipc\fP. The argument \f(CWloc_expr_op_count_out\fP returns the number of operators in the location expression involved (which may be zero). .P The argument \f(CWlocentry_out\fP returns an identifier used in calls to \f(CWdwarf_get_location_op_value_d()\fP. .P The argument \f(CWexpression_offset_out\fP returns the offset (in the .debug_loc(.dso) or .debug_info(.dwo) of the location expression itself (possibly useful for debugging). .P The argument \f(CWlocdesc_offset_out\fP returns the offset (in the section involved (see \f(CWloclist_kind\fP) of the location list entry itself (possibly useful for debugging). .P In case of error \f(CWDW_DLV_ERROR\fP is returned and \f(CW*error\fP is set to an error designation. .P A return of \f(CWDW_DLV_NO_ENTRY\fP may be possible but is a bit odd. \f(CW \fP .H 3 "dwarf_get_locdesc_entry_c()" This is the same as \f(CWdwarf_get_locdesc_entry_d()\fP except that the \f(CWdebug_addr_unavailable\fP field is missing. Earlier versions (starting with \f(CWdwarf_get_locdesc_entry()\fP exist and work as well as they ever did, but we suggest you stop using those earlier versions. We suggest you switch to using \f(CWdwarf_get_locdesc_entry_d()\fP .DS \f(CW int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned index, Dwarf_Small *lle_value_out, Dwarf_Addr *rawval1_out, Dwarf_Addr *rawval2_out, Dwarf_Addr *lopc_out, Dwarf_Addr *hipc_out, Dwarf_Unsigned *loc_expr_op_count_out, Dwarf_Locdesc_c *locentry_out, Dwarf_Small *loclist_kind, Dwarf_Unsigned *expression_offset_out, Dwarf_Unsigned *locdesc_offset_out, Dwarf_Error *error); \fP .DE .H 3 "dwarf_get_loclist_head_kind()" .DS \f(CW int dwarf_get_loclist_head_kind( Dwarf_Loclists_Head head, unsigned int * kind, Dwarf_Error *error) \fP .DE Though one should test the return code, at present this always returns \f(CWDW_DLV_OK\fP, and sets \f(CW*kind\fP to the \f(CWDW_LKIND*\fP value for this \f(CWhead\fP. .P At the present time neither \f(CWDW_DLV_ERROR\fP nor \f(CWDW_DLV_NO_ENTRY\fP is returned. .H 3 "dwarf_get_location_op_value_d()" .DS \f(CW int dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc, Dwarf_Unsigned index, Dwarf_Small * atom_out, Dwarf_Unsigned * operand1, Dwarf_Unsigned * operand2, Dwarf_Unsigned * operand3, Dwarf_Unsigned * rawop1, Dwarf_Unsigned * rawop2, Dwarf_Unsigned * rawop3, Dwarf_Unsigned * offset_for_branch, Dwarf_Error* error); \fP .DE On success The function \f(CWdwarf_get_location_op_value_d()\fP returns the information for the single operator number \f(CWindex\fP from the location expression \f(CWlocdesc\fP. It sets the following values. .P \f(CWatom_out\fP is set to the applicable operator code, for example \f(CWDW_OP_reg5\fP. .P \f(CWoperand1\fP, \f(CWoperand2\fP, and \f(CWoperand3\fP are set to the operator operands as applicable (see DWARF documents on the operands for each operator). All additions of base fields, if any, have been done already. \f(CWoperand3\fP is new as of DWARF5. .P In some cases \f(CWoperand3\fP is actually a pointer into section data in memory and operand2 has the length of the data at operand3. Callers must extract the bytes and deal with endianness issues of the extracted value. .P \f(CWrawop1\fP, \f(CWrawop2\fP, and \f(CWrawop3\fP are set to the operator operands as applicable (see DWARF documents on the operands for each operator) before any base values were added in.. As for the previous, sometimes dealing with \f(CWrawop3\fP means interpreting it as a pointer and doing a dereference. .P More on the pointer values in Dwarf_Unsigned: When a DWARF operand is not of a size fixed by dwarf or whose type is unknown, or is possibly too large for a dwarf stack entry, libdwarf will insert a pointer (to memory in the dwarf data somewhere) as the operand value. \f(CWDW_OP_implicit_value operand 2\fP, \f(CWDW_OP_[GNU_]entry_value operand 2\fP, and \f(CWDW_OP_[GNU_]const_type operand 3\fP are instances of this. The problem with the values is that libdwarf is unclear what the type of the value is so we pass the problem to you, the callers! .P \f(CWoffset_for_branch\fP is set to the offset (in bytes) in this expression of this operator. The value makes it possible for callers to implement the operator branch operators. .P In case of an error, the function returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to an error value. .P \f(CWDW_DLV_NO_ENTRY\fP is probably not a possible return value, but please test for it anyway. .H 3 "dwarf_loclist_from_expr_c()" This is now obsolete, though it works as well as ever, so if it works for your object codes you may continue to use it. .DS \f(CW int dwarf_loclist_from_expr_c(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Loc_Head_c* loc_head, Dwarf_Unsigned * listlen, Dwarf_Error * error); \fP .DE This interface is not sufficient to work properly as it fails to pass in data from the Compilation Unit. The earlier versions \f(CWdwarf_loclist_from_expr()\fP, \f(CWdwarf_loclist_from_expr_a()\fP, and \f(CWdwarf_loclist_from_expr_b\fP are all similarly deficient. These suffice for early DWARF locations but cannot work for every kind of DWARF5 location list or location. .P Frame operators such as DW_CFA_def_cfa_expression have a location expression and the location_expression is accessed with this function. .P On success it returns \f(CWDW_DLV_OK\fP and sets the two return arguments (explained a few lines later here). .P The \f(CWexpression_in\fP argument must contain a valid pointer to location expression bytes. The \f(CWexpression_length\fP argument must contain the length of that location expression in bytes. .P The \f(CWaddress_size\fP argument must contain the size of an address on the target machine for this expression (normally 4 or 8). The \f(CWoffset_size\fP argument must contain the size of an offset in the expression (normally 4, sometimes 8). The \f(CWversion\fP argument must contain the dwarf_version of the expression (2,3,4, or 5). .P The returned value \f(CW*loc_head\fP is used to actually access the location expression details (see the example following). .P The returned value \f(CW*listlen\fP is the number of location expressions (ie 1) in the location list (for uniformity of access we make it look like a single-entry location list). .P On error the function returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to reflect the error. .P A return of \f(CWDW_DLV_NO_ENTRY\fP is probably impossible, but callers should assume it is possible. No return arguments are set in this case. .DS void example_locexprc(Dwarf_Debug dbg,Dwarf_Ptr expr_bytes, Dwarf_Unsigned expr_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version) { Dwarf_Loc_Head_c head = 0; Dwarf_Locdesc_c locentry = 0; int res2 = 0; Dwarf_Unsigned lopc = 0; Dwarf_Unsigned hipc = 0; Dwarf_Unsigned ulistlen = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Unsigned section_offset = 0; Dwarf_Unsigned locdesc_offset = 0; Dwarf_Small lle_value = 0; Dwarf_Small loclist_source = 0; Dwarf_Unsigned i = 0; Dwarf_Error error = 0; res2 = dwarf_loclist_from_expr_c(dbg, expr_bytes,expr_len, addr_size, offset_size, version, &head, &ulistlen, &error); if(res2 == DW_DLV_NO_ENTRY) { return; } if(res2 == DW_DLV_ERROR) { return; } /* These are a location expression, not loclist. So we just need the 0th entry. */ res2 = dwarf_get_locdesc_entry_c(head, 0, /* Data from 0th LocDesc */ &lle_value, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, &error); if (res2 == DW_DLV_ERROR) { dwarf_loc_head_c_dealloc(head); return; } else if (res2 == DW_DLV_NO_ENTRY) { dwarf_loc_head_c_dealloc(head); return; } /* ASSERT: ulistlen == 1 */ for (i = 0; i < ulocentry_count;++i) { Dwarf_Small op = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned offsetforbranch = 0; res2 = dwarf_get_location_op_value_c(locentry, i, &op,&opd1,&opd2,&opd3,&offsetforbranch, &error); /* Do something with the expression operator and operands */ if (res2 != DW_DLV_OK) { dwarf_loc_head_c_dealloc(head); return; } } dwarf_loc_head_c_dealloc(head); } .DE .H 3 "dwarf_loc_head_c_dealloc()" .DS void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head); .DE This function takes care of all the details so one does not have to _dwarf_dealloc() the pieces individually, though code that continues to do the pieces individually still works. .P This function frees all the memory associated with the \f(CWloclist_head\fP. There is no return value. It's good practice to set \f(CWloclist_head\fP. to zero immediately after the call, as the pointer is stale at that point. .H 3 "dwarf_loclist_n()" .DS \f(CWint dwarf_loclist_n( Dwarf_Attribute attr, Dwarf_Locdesc ***llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE This interface cannot handle DWARF5 or Split Dwarf. Use \f(CWdwarf_get_loclist_c()\fP and related functions instead (as of November 2015). The function \f(CWdwarf_loclist_n()\fP sets \f(CW*llbuf\fP to point to an array of \f(CWDwarf_Locdesc\fP pointers corresponding to each of the location expressions in a location list, and sets \f(CW*listlen\fP to the number of elements in the array and returns \f(CWDW_DLV_OK\fP if the attribute is appropriate. .P This is the preferred function for Dwarf_Locdesc as it is the interface allowing access to an entire loclist. (use of \f(CWdwarf_loclist_n()\fP is suggested as the better interface, though \f(CWdwarf_loclist()\fP is still supported.) .P If the attribute is a reference to a location list (DW_FORM_data4 or DW_FORM_data8) the location list entries are used to fill in all the fields of the \f(CWDwarf_Locdesc\fP(s) returned. .P If the attribute is a location description (DW_FORM_block2 or DW_FORM_block4) then some of the \f(CWDwarf_Locdesc\fP values of the single \f(CWDwarf_Locdesc\fP record are set to 'sensible' but arbitrary values. Specifically, ld_lopc is set to 0 and ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1. .P If the attribute is a reference to a location expression (DW_FORM_locexper) then some of the \f(CWDwarf_Locdesc\fP values of the single \f(CWDwarf_Locdesc\fP record are set to 'sensible' but arbitrary values. Specifically, ld_lopc is set to 0 and ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1. .P It returns \f(CWDW_DLV_ERROR\fP on error. .P \f(CWdwarf_loclist_n()\fP works on \f(CWDW_AT_location\fP, \f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, \f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and \f(CWDW_AT_return_addr\fP attributes. .P If the attribute is \f(CWDW_AT_data_member_location\fP the value may be of class CONSTANT. \f(CWdwarf_loclist_n()\fP is unable to read class CONSTANT, so you need to first determine the class using \f(CWdwarf_get_form_class()\fP and if it is class CONSTANT call \f(CWdwarf_formsdata()\fP or \f(CWdwarf_formudata()\fP to get the constant value (you may need to call both as DWARF4 does not define the signedness of the constant value). .P Storage allocated by a successful call of \f(CWdwarf_loclist_n()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. and the \f(CWllbuf[]\fP space pointed to should be deallocated with allocation type \f(CWDW_DLA_LOCDESC\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LIST\fP. .in +2 .DS \f(CW void example9(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Signed lcount = 0; Dwarf_Locdesc **llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist_n(someattr, &llbuf,&lcount,&error); if (lres == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < lcount; ++i) { /* Use llbuf[i]. Both Dwarf_Locdesc and the array of Dwarf_Loc it points to are defined in libdwarf.h: they are not opaque structs. */ dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist()" .DS \f(CWint dwarf_loclist( Dwarf_Attribute attr, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE Use \f(CWdwarf_get_loclist_c()\fP and related functions instead (as of November 2015). The function \f(CWdwarf_loclist()\fP sets \f(CW*llbuf\fP to point to a \f(CWDwarf_Locdesc\fP pointer for the single location expression it can return. It sets \f(CW*listlen\fP to 1. and returns \f(CWDW_DLV_OK\fP if the attribute is appropriate. .P It is less flexible than \f(CWdwarf_loclist_n()\fP in that \f(CWdwarf_loclist()\fP can handle a maximum of one location expression, not a full location list. If a location-list is present it returns only the first location-list entry location description. Use \f(CWdwarf_loclist_n()\fP instead. .P It returns \f(CWDW_DLV_ERROR\fP on error. \f(CWdwarf_loclist()\fP works on \f(CWDW_AT_location\fP, \f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, \f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and \f(CWDW_AT_return_addr\fP attributes. .P Storage allocated by a successful call of \f(CWdwarf_loclist()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LOCDESC\fP. .in +2 .FG "Examplea dwarf_loclist()" .DS \f(CW void examplea(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Signed lcount = 0; Dwarf_Locdesc *llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist(someattr, &llbuf,&lcount,&error); if (lres == DW_DLV_OK) { /* lcount is always 1, (and has always been 1) */ /* Use llbuf here. */ dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist_from_expr()" .DS \f(CWint dwarf_loclist_from_expr( Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE Use \f(CWdwarf_loclist_from_expr_b()\fP instead. This function is obsolete. .P The function \f(CWdwarf_loclist_from_expr()\fP sets \f(CW*llbuf\fP to point to a \f(CWDwarf_Locdesc\fP pointer for the single location expression which is pointed to by \f(CW*bytes_in\fP (whose length is \f(CW*bytes_len\fP). It sets \f(CW*listlen\fP to 1. and returns \f(CWDW_DLV_OK\fP if decoding is successful. Some sources of bytes of expressions are dwarf expressions in frame operations like \f(CWDW_CFA_def_cfa_expression\fP, \f(CWDW_CFA_expression\fP, and \f(CWDW_CFA_val_expression\fP. .P Any address_size data in the location expression is assumed to be the same size as the default address_size for the object being read (normally 4 or 8). .P It returns \f(CWDW_DLV_ERROR\fP on error. .P Storage allocated by a successful call of \f(CWdwarf_loclist_from_expr()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LOCDESC\fP. .in +2 .FG "Exampleb dwarf_loclist_from_expr()" .DS \f(CW void exampleb(Dwarf_Debug dbg,Dwarf_Ptr data, Dwarf_Unsigned len) { Dwarf_Signed lcount = 0; Dwarf_Locdesc *llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist_from_expr(dbg,data,len, &llbuf,&lcount, &error); if (lres == DW_DLV_OK) { /* lcount is always 1 */ /* Use llbuf here.*/ dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist_from_expr_b()" .DS \f(CWint dwarf_loclist_from_expr_a( Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version_stamp, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE This function is obsolete. The function \f(CWdwarf_loclist_from_expr_b()\fP is identical to \f(CWdwarf_loclist_from_expr_a()\fP in every way except that the caller passes an additional argument \f(CWversion_stamp\fP containing the version stamp (2 for DWARF2, etc) of the CU using this location expression and an additional argument of the offset size of the CU using this location expression. The DW_OP_GNU_implicit_pointer operation requires this version and offset information to be correctly processed. .P The \f(CWaddr_size\fP argument (from 27April2009) is needed to correctly interpret frame information as different compilation units can have different address sizes. DWARF4 adds address_size to the CIE header. .P .H 3 "dwarf_loclist_from_expr_a()" .DS \f(CWint dwarf_loclist_from_expr_a( Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE This function is obsolete. Use \f(CWdwarf_loclist_from_expr_b()\fP instead. This function is obsolete. .P The function \f(CWdwarf_loclist_from_expr_a()\fP is identical to \f(CWdwarf_loclist_from_expr()\fP in every way except that the caller passes the additional argument \f(CWaddr_size\fP containing the address size (normally 4 or 8) applying this location expression. .P The \f(CWaddr_size\fP argument (added 27April2009) is needed to correctly interpret frame information as different compilation units can have different address sizes. DWARF4 adds address_size to the CIE header. .P .H 2 "Line Number Operations" These functions are concerned with accessing line number entries, mapping debugging information entry objects to their corresponding source lines, and providing a mechanism for obtaining information about line number entries. Although, the interface talks of "lines" what is really meant is "statements". In case there is more than one statement on the same line, there will be at least one descriptor per statement, all with the same line number. If column number is also being represented they will have the column numbers of the start of the statements also represented. .P There can also be more than one Dwarf_Line per statement. For example, if a file is preprocessed by a language translator, this could result in translator output showing 2 or more sets of line numbers per translated line of output. .P \f(CW \fP As of October 2015 there are two sets of overall access and release functions. The older set of functions is \f(CWdwarf_srclines()\fP with \f(CWdwarf_srclines_dealloc()\fP. This set does not handle line table headers with no lines. .P A newer set is \f(CWdwarf_srclines_b()\fP with \f(CWdwarf_srclines_from_linecontext()\fP and \f(CWdwarf_srclines_dealloc_b()\fP. These functions provide for handling both DWARF2 through DWARF5 details and give access to line header information even if there are no lines in a particular compilation unit's line table. .P .H 3 "Get A Set of Lines (including skeleton line tables)" This set of functions works on any DWARF version. DWARF2,3,4,5 and the DWARF4 based experimental two-level line tables are all supported. What was once done by dwarf_srclines() alone is now done with two calls as described here. .P The interfaces support reading GNU two-level line tables. The format of such tables is a topic beyond the scope of this document. .P .H 3 "dwarf_srclines_b()" This is the .DS \f(CWint dwarf_srclines_b( Dwarf_Die die, Dwarf_Unsigned *version_out, Dwarf_Bool *is_single_table, Dwarf_Line_Context *context_out, Dwarf_Error *error)\fP .DE \f(CWdwarf_srclines_b()\fP takes a single argument as input, a pointer to a compilation-unit (CU) DIE. The other arguments are used to return values to the caller. On success \f(CWDW_DLV_OK\fP is returned and values are returned through the pointers. If there is no line table \f(CWDW_DLV_NO_ENTRY\fP is returned and no values are returned though the pointers. If \f(CWDW_DLV_ERROR\fP is returned the involved is returned through the \f(CWerror\fP pointer. .P The values returned on success are: .P \f(CW*version_out()\fP is set to the version number from the line table header for this CU. The experimental two-level line table value is 0xf006. Standard numbers are 2,3,4 and 5. .P \f(CW*is_single_table()\fP is set to non-zero if the line table is an ordinary single line table. If the line table is anything else (either a line table header with no lines or an experimental two-level line table) it is set to zero. .P \f(CW*context_out()\fP is set to an opaque pointer to a \f(CWDwarf_Line_Context\fP record which in turn is used to get other data from this line table. See below. .P See \f(CW*dwarf_srclines_dealloc_b()\fP for examples showing correct use. .H 3 "dwarf_get_line_section_name_from_die()" .DS \f(CWint dwarf_get_line_section_name_from_die( Dwarf_Die die, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_line_section_name_from_die()\fP retrieves the object file section name of the applicable line section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_srclines_from_linecontext()" .DS \f(CWint dwarf_srclines_from_linecontext( Dwarf_Line_Context line_context, Dwarf_Line ** linebuf, Dwarf_Signed *linecount, Dwarf_Error *error)\fP .DE \f(CW*dwarf_srclines_from_linecontext()\fP gives access to the line tables. On success it returns \f(CWDW_DLV_OK\fP and passes back line tables through the pointers. .P Though \f(CWDW_DLV_OK\fP will not be returned callers should assume it is possible. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error code set through the \f(CWerror\fP pointer. .P On success: .P \f(CW*linebuf\fP is set to an array of Dwarf_Line pointers. .P \f(CW*linecount\fP is set to the number of pointers in the array. .P .H 3 "dwarf_srclines_two_levelfrom_linecontext()" .DS \f(CWint dwarf_srclines_from_linecontext( Dwarf_Line_Context line_context, Dwarf_Line ** linebuf, Dwarf_Signed *linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed *linecount_actuals, Dwarf_Error *error)\fP .DE \f(CW*dwarf_srclines_two_levelfrom_linecontext()\fP gives access to the line tables. On success it returns \f(CWDW_DLV_OK\fP and passes back line tables through the pointers. .P Though \f(CWDW_DLV_OK\fP will not be returned callers should assume it is possible. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error code set through the \f(CWerror\fP pointer. .P On success: .P \f(CW*linebuf\fP is set to an array of Dwarf_Line pointers. .P \f(CW*linecount\fP is set to the number of pointers in the array. .P If one is not intending that the experimental two-level line tables are of interest then pass NULL for \f(CW*linebuf_actuals\fP and \f(CW*linecount_actuals\fP. The NULL pointers notify the library that the second table is not to be passed back. .P If a line table is actually a two-level tables \f(CW*linebuf\fP is set to point to an array of Logicals lines. \f(CW*linecount\fP is set to the number of Logicals. \f(CW*linebuf_actuals\fP is set to point to an array of Actuals lines. \f(CW*linecount_actuals\fP is set to the number of Actuals. .H 3 "dwarf_srclines_dealloc_b()" .DS \f(CWvoid dwarf_srclines_dealloc_b( Dwarf_Line_Context line_context, Dwarf_Error *error)\fP .DE This does a complete deallocation of the memory of the \f(CWDwarf_Line_Context\fP and the \f(CWDwarf_Line\fP array (or arrays) that came from the \f(CWDwarf_Line_Context\fP. On return you should set any local pointers to these buffers to NULL as a reminder that any use of the local pointers would be to stale memory. .in +2 .FG "Examplec dwarf_srclines_b()" .DS \f(CW void examplec(Dwarf_Die cu_die) { /* EXAMPLE: DWARF5 style access. */ Dwarf_Line *linebuf = 0; Dwarf_Signed linecount = 0; Dwarf_Line *linebuf_actuals = 0; Dwarf_Signed linecount_actuals = 0; Dwarf_Line_Context line_context = 0; Dwarf_Signed linecount_total = 0; Dwarf_Small table_count = 0; Dwarf_Unsigned lineversion = 0; Dwarf_Error err = 0; int sres = 0; /* ... */ /* we use 'return' here to signify we can do nothing more at this point in the code. */ sres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context,&err); if (sres != DW_DLV_OK) { /* Handle the DW_DLV_NO_ENTRY or DW_DLV_ERROR No memory was allocated so there nothing to dealloc. */ return; } if (table_count == 0) { /* A line table with no actual lines. This occurs in a DWARF5 or DWARF5 DW_TAG_type_unit as such has no lines of code but needs data for DW_AT_decl_file attributes. */ /*...do something, see dwarf_srclines_files_count() etc below. */ dwarf_srclines_dealloc_b(line_context); /* All the memory is released, the line_context and linebuf zeroed now as a reminder they are stale. */ linebuf = 0; line_context = 0; } else if (table_count == 1) { Dwarf_Signed i = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Standard dwarf 2,3,4, or 5 line table */ /* Do something. */ /* First let us index through all the files listed in the line table header. */ sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,&err); if (sres != DW_DLV_OK) { /* Something badly wrong! */ return; } /* Works for DWARF2,3,4 (one-based index) and DWARF5 (zero-based index) */ for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,&err); if (vres != DW_DLV_OK) { /* something very wrong. */ return; } /* Do something. */ } /* For this case where we have a line table we will likely wish to get the line details: */ sres = dwarf_srclines_from_linecontext(line_context, &linebuf,&linecount, &err); if (sres != DW_DLV_OK) { /* Error. Clean up the context information. */ dwarf_srclines_dealloc_b(line_context); return; } /* The lines are normal line table lines. */ for (i = 0; i < linecount; ++i) { /* use linebuf[i] */ } dwarf_srclines_dealloc_b(line_context); /* All the memory is released, the line_context and linebuf zeroed now as a reminder they are stale */ linebuf = 0; line_context = 0; linecount = 0; } else { Dwarf_Signed i = 0; /* ASSERT: table_count == 2, Experimental two-level line table. Version 0xf006 We do not define the meaning of this non-standard set of tables here. */ /* For 'something C' (two-level line tables) one codes something like this Note that we do not define the meaning or use of two-level line tables as these are experimental, not standard DWARF. */ sres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf,&linecount, &linebuf_actuals,&linecount_actuals, &err); if (sres == DW_DLV_OK) { for (i = 0; i < linecount; ++i) { /* use linebuf[i], these are the 'logicals' entries. */ } for (i = 0; i < linecount_actuals; ++i) { /* use linebuf_actuals[i], these are the actuals entries */ } dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else if (sres == DW_DLV_NO_ENTRY) { /* This should be impossible, but do something. */ /* Then Free the line_context */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else { /* ERROR, show the error or something. Free the line_context. */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } } } \fP .DE .in -2 .H 2 "Line Context Details (DWARF5 style)" New in October 2015. When a \f(CW Dwarf_Line_Context \fP has been returned by \f(CWdwarf_srclines_b()\fP that line context data's details can be retrieved with the following set of calls. .H 3 "dwarf_srclines_table_offset()" .DS \f(CW int dwarf_srclines_table_offset(Dwarf_Line_Context line_context, Dwarf_Unsigned * offset, Dwarf_Error * error); \fP .DE On success, this function returns the offset (in the object file line section) of the actual line data (i.e. after the line header for this compilation unit) through the \f(CWoffset\fP pointer. The offset is probably only of interest when printing detailed information about a line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_version()" .DS \f(CW int dwarf_srclines_version(Dwarf_Line_Context line_context, Dwarf_Unsigned * version, Dwarf_Error * error); \fP .DE On success \f(CWDW_DLV_OK\fP is returned and the line table version number is returned through the \f(CWversion\fP pointer. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_comp_dir()" .DS \f(CW int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context, const char ** compilation_directory, Dwarf_Error * error); \fP .DE On success this returns a pointer to the compilation directory string for this line table in \f(CW*compilation_directory\fP. That compilation string may be NULL or the empty string. The string pointer is valid until the \f(CWline_context\fP has been deallocated. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_indexes()" .DS \f(CW int dwarf_srclines_files_indexes(Dwarf_Line_Context line_context, Dwarf_Signed * baseindex, Dwarf_Signed * count, Dwarf_Signed * endindex, Dwarf_Error * error); \fP .DE With DWARF5 the base file number index in the line table changed from zero (DWARF2,3,4) to one (DWARF5). Which meant iterating through the valid source file indexes became messy if one used the older \f(CWdwarf_srclines_files_count()\fP function (zero-based and one-based indexing being incompatible). See Figure "Examplec dwarf_srclines_b()" above for use of this function in accessing file names. .P The base index of files in the files list of a line table header will be returned through \f(CWbaseindex\fP. .P The number of files in the files list of a line table header will be returned through \f(CWcount\fP. .P The end index of files in the files list of a line table header will be returned through \f(CWendindex\fP. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_count()" .DS \f(CW int dwarf_srclines_files_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP .DE On success, the number of files in the files list of a line table header will be returned through \f(CWcount\fP. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_data_b()" This supplants \f(CWdwarf_srclines_files_data()\fP as of March 2018 to allow access to the md5 value in DWARF5. The function \f(CWdwarf_srclines_files_data()\fP continues to be supported. .DS \f(CW int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5_value, Dwarf_Error * error); \fP .DE On success, data about a single file in the files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. \f(CWcount\fP. Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF2,3,4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P If \f(CWmd5_value\fP is non-null it is used to pass a back a pointer to a \f(CWDwarf_Form_Data16\fP md5 value if the md5 value is present. Otherwise a zero value is passed back to indicate there was no such field. The 16-byte value pointed to is inside the line_context, so if you want to keep the value you should probably copy it to storage you control. .P This returns the raw files data from the line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_data()" This interface was created in October 2015. It cannot return the DWARF5 MD5 value. See the newer dwarf_srclines_files_data_b(). .DS \f(CW int dwarf_srclines_files_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Error * error); \fP .DE On success, data about a single file in the files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. \f(CWcount\fP. Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF2,3,4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P This returns the raw files data from the line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_include_dir_count()" .DS \f(CW int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP .DE On success, the number of files in the includes list of a line table header will be returned through \f(CWcount\fP. .P Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF 2,3 and 4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_include_dir_data()" .DS \f(CW int dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Error * error); \fP .DE On success, data about a single file in the include files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. .P Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_subprog_count()" \f(CW int dwarf_srclines_subprog_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP This is only useful with experimental two-level line tables. .H 3 "dwarf_srclines_subprog_data()" \f(CW int dwarf_srclines_subprog_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * decl_file, Dwarf_Unsigned * decl_line, Dwarf_Error * error); \fP This is only useful with experimental two-level line tables. .H 2 "Get A Set of Lines (DWARF2,3,4 style)" The function returns information about every source line for a particular compilation-unit. The compilation-unit is specified by the corresponding die. It does not support line tables with no lines very well nor does it support experimental two-level linetables. .H 3 "dwarf_srclines()" .DS \f(CWint dwarf_srclines( Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, Dwarf_Error *error)\fP .DE This function is not useful for DWARF5 skeleton line tables nor for two-level line tables. It works for DWARF2,3,4,5 ordinary single line tables. The function \f(CWdwarf_srclines()\fP places all line number descriptors for a single compilation unit into a single block, sets \f(CW*linebuf\fP to point to that block, sets \f(CW*linecount\fP to the number of descriptors in this block and returns \f(CWDW_DLV_OK\fP. .in +2 .P To get a more detailed view of the contents of a dwarf line table header see \f(CWdwarf_srclines_b()\fP and the routines that use the Dwarf_Line_Context information, such as \f(CWdwarf_srcfiles_comp_dir()\fP, \f(CWdwarf_srclines_files_count()\fP, \f(CWdwarf_srclines_include_dir_count()\fP and similar functions. .in -2 .P The compilation-unit is indicated by the given \f(CWdie\fP which must be a compilation-unit die. It returns \f(CWDW_DLV_ERROR\fP on error. On successful return, line number information should be freed using \f(CWdwarf_srclines_dealloc()\fP when no longer of interest. .P .in +2 .FG "Exampled dwarf_srclines()" .DS \f(CW void exampled(Dwarf_Debug dbg,Dwarf_Die somedie) { Dwarf_Signed count = 0; Dwarf_Line *linebuf = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int sres = 0; sres = dwarf_srclines(somedie, &linebuf,&count, &error); if (sres == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use linebuf[i] */ } dwarf_srclines_dealloc(dbg, linebuf, count); } } \fP .DE .in -2 .P An alternative using \f(CWdwarf_dealloc()\fP directly is no longer (as of 2015) described here. It works as well as ever, but it has been obsolete since 2005. still works, but does not completely free all data allocated. The \f(CWdwarf_srclines_dealloc()\fP routine was created to fix the problem of incomplete deallocation. .H 2 "Get the set of Source File Names" The function returns the names of the source files that have contributed to the compilation-unit represented by the given DIE. Only the source files named in the statement program prologue (which in current DWARF standards is referred to as the Line Table Header) are returned. .H 3 "dwarf_srcfiles()" This works for for all line tables. However indexing is different in DWARF5 than in other versions of dwarf. To understand the DWARF5 version look at the following which explains a contradiction in the DWARF5 document and how libdwarf (and at least some compilers) resolve it. Join the next two strings together with no spaces to recreate the web reference. .P If the applicable file name in the line table Statement Program Prolog does not start with a '/' character the string in \f(CWDW_AT_comp_dir\fP (if applicable and present) and the applicable directory name from the line Statement Program Prolog is prepended to the file name in the line table Statement Program Prolog to make a full path. .P For all versions of dwarf this function and dwarf_linesrc() prepend the value of DW_AT_co prepend the value of DW_AT_comp_dir to the name created from the line table header file names and directory names if the line table header name(s) are not full paths.mp_dir to the name created from the line table header file names and directory names if the line table header name(s) are not full paths. .P http://wiki.dwarfstd.org/index.php?title =DWARF5_Line_Table_File_Numbers .P It may help understand the file tables and dwarf_srcfiles() to use \f(CWdwarfdump\fP. The \f(CWdwarfdump\fP utility program now will print the dwarf_srcfiles() values in addition to the compilation unit DIE and the line table header details (and much more) if one does "dwarfdump -vvv -i -l " or "dwarfdump -vvv -a " for example. Since the output can be large, with your editor focus on lines beginning with "COMPILE_UNIT" (do not type the quotes) to quickly get to the CU die and the line table for that CU as those tend to be far apart in the output. .P DWARF5: \f(CWDW_MACRO_start_file\fP, \f(CWDW_LNS_set_file\fP, \f(CWDW_AT_decl_file\fP, \f(CWDW_AT_call_file\fP, and the line table state machine file numbers begin at zero. To index srcfiles use the values directly with no subtraction. .P DWARF2-4 and experimental line table: \f(CWDW_MACINFO_start_file\fP, \f(CWDW_LNS_set_file\fP, \f(CWDW_AT_decl_file\fP, and line table state machine file numbers begin at one. In all these the value of 0 means there is no source file or source file name. To index the srcfiles array subtract one from the \f(CWDW_AT_decl_file\fP (etc) file number. .P .DS \f(CWint dwarf_srcfiles( Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, Dwarf_Error *error)\fP .DE When it succeeds \f(CWdwarf_srcfiles()\fP returns \f(CWDW_DLV_OK\fP and puts the number of source files named in the statement program prologue indicated by the given \f(CWdie\fP into \f(CW*srccount\fP. Source files defined in the statement program are ignored. The given \f(CWdie\fP should have the tag \f(CWDW_TAG_compile_unit\fP, \f(CWDW_TAG_partial_unit\fP, or \f(CWDW_TAG_type_unit\fP . The location pointed to by \f(CWsrcfiles\fP is set to point to a list of pointers to null-terminated strings that name the source files. .P On a successful return from \f(CWdwarf_srcfiles()\fP each of the strings returned should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. This should be followed by free-ing the list using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no corresponding statement program (i.e., if there is no line information). .P .in +2 .FG "Exampled dwarf_srcfiles()" .DS \f(CW void examplee(Dwarf_Debug dbg,Dwarf_Die somedie) { Dwarf_Signed count = 0; char **srcfiles = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_srcfiles(somedie, &srcfiles,&count,&error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use srcfiles[i] */ dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); } } \fP .DE .in -2 .H 2 "Get Information About a Single Line Table Line" The following functions can be used on the \f(CWDwarf_Line\fP descriptors returned by \f(CWdwarf_srclines()\fP or \f(CWdwarf_srclines_from_linecontext()\fP to obtain information about the source lines. .H 3 "dwarf_linebeginstatement()" .DS \f(CWint dwarf_linebeginstatement( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_linebeginstatement()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to \fInon-zero\fP (if \f(CWline\fP represents a line number entry that is marked as beginning a statement). or \fIzero\fP ((if \f(CWline\fP represents a line number entry that is not marked as beginning a statement). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineendsequence()" .DS \f(CWint dwarf_lineendsequence( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineendsequence()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP \fInon-zero\fP (in which case \f(CWline\fP represents a line number entry that is marked as ending a text sequence) or \fIzero\fP (in which case \f(CWline\fP represents a line number entry that is not marked as ending a text sequence). A line number entry that is marked as ending a text sequence is an entry with an address one beyond the highest address used by the current sequence of line table entries (that is, the table entry is a DW_LNE_end_sequence entry (see the DWARF specification)). .P The function \f(CWdwarf_lineendsequence()\fP returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineno()" .DS \f(CWint dwarf_lineno( Dwarf_Line line, Dwarf_Unsigned * returned_lineno, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_lineno()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineno\fP to the source statement line number corresponding to the descriptor \f(CWline\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_line_srcfileno()" .DS \f(CWint dwarf_line_srcfileno( Dwarf_Line line, Dwarf_Unsigned * returned_fileno, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_fileno\fP to the source statement line number corresponding to the descriptor \f(CWfile number\fP. .P DWARF2-4 and experimental: When the number returned through \f(CW*returned_fileno\fP is zero it means the file name is unknown (see the DWARF2/3 line table specification). When the number returned through \f(CW*returned_fileno\fP is non-zero it is a file number: subtract 1 from this file number to get an index into the array of strings returned by \f(CWdwarf_srcfiles()\fP (verify the resulting index is in range for the array of strings before indexing into the array of strings). The file number may exceed the size of the array of strings returned by \f(CWdwarf_srcfiles()\fP because \f(CWdwarf_srcfiles()\fP does not return files names defined with the \f(CWDW_DLE_define_file\fP operator. .P DWARF5: To index into the array of strings returned by \f(CWdwarf_srcfiles()\fP use the number returned through \f(CW*returned_fileno\fP. .P The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineaddr()" .DS \f(CWint dwarf_lineaddr( Dwarf_Line line, Dwarf_Addr *return_lineaddr, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineaddr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineaddr\fP to the address associated with the descriptor \f(CWline\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineoff()" .DS \f(CWint dwarf_lineoff( Dwarf_Line line, Dwarf_Signed * return_lineoff, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineoff()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineoff\fP to the column number at which the statement represented by \f(CWline\fP begins. .P It sets \f(CWreturn_lineoff\fP to zero if the column number of the statement is not represented (meaning the producer library call was given zero as the column number). Zero is the correct value meaning "left edge" as defined in the DWARF2/3/4 specification (section 6.2.2). .P Before December 2011 zero was not returned through the \f(CWreturn_lineoff\fP pointer, -1 was returned through the pointer. The reason for this oddity is unclear, lost in history. But there is no good reason for -1. .P The type of \f(CWreturn_lineoff\fP is a pointer-to-signed, but there is no good reason for the value to be signed, the DWARF specification does not deal with negative column numbers. However, changing the declaration would cause compilation errors for little benefit, so the pointer-to-signed is left unchanged. .P On error it returns \f(CWDW_DLV_ERROR\fP. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_lineoff_b()" .DS \f(CWint dwarf_lineoff_b( Dwarf_Line line, Dwarf_Unsigned * return_lineoff, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineoff_b()\fP returns exactly the same as \f(CWdwarf_lineoff()\fP except the line offset returned through \f(CWreturn_lineoff()\fP is an unsigned value. The signed return offset never made much sense but was harmless since line lengths are limited by most language standards. .H 3 "dwarf_linesrc()" .DS \f(CWint dwarf_linesrc( Dwarf_Line line, char ** return_linesrc, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_linesrc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to a pointer to a null-terminated string of characters that represents the name of the source-file where \f(CWline\fP occurs. It returns \f(CWDW_DLV_ERROR\fP on error. .P If the applicable file name in the line table Statement Program Prolog does not start with a '/' character the string in \f(CWDW_AT_comp_dir\fP (if applicable and present) or the applicable directory name from the line Statement Program Prolog is prepended to the file name in the line table Statement Program Prolog to make a full path. .P The storage pointed to by a successful return of \f(CWdwarf_linesrc()\fP should be freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_lineblock()" .DS \f(CWint dwarf_lineblock( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineblock()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to non-zero (i.e. true)(if the line is marked as beginning a basic block) or zero (i.e. false) (if the line is marked as not beginning a basic block). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_is_addr_set()" .DS \f(CWint dwarf_line_is_addr_set( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_line_is_addr_set()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to non-zero (i.e. true)(if the line is marked as being a DW_LNE_set_address operation) or zero (i.e. false) (if the line is marked as not being a DW_LNE_set_address operation). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. This is intended to allow consumers to do a more useful job printing and analyzing DWARF data, it is not strictly necessary. .H 3 "dwarf_prologue_end_etc()" .DS \f(CWint dwarf_prologue_end_etc(Dwarf_Line line, Dwarf_Bool * prologue_end, Dwarf_Bool * epilogue_begin, Dwarf_Unsigned * isa, Dwarf_Unsigned * discriminator, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_prologue_end_etc()\fP returns \f(CWDW_DLV_OK\fP and sets the returned fields to values currently set. While it is pretty safe to assume that the \f(CWisa\fP and \f(CWdiscriminator\fP values returned are very small integers, there is no restriction in the standard. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. This function is new in December 2011. .H 2 "Accelerated Access By Name operations" These operations operate on the .debug_pubnames section as well as all the other sections with this specific format and purpose: .debug_pubtypes, .debug_typenames, .debug_varnames, .debug_funcnames, and .debug_weaknames. The first in the list is generic DWARF 2,3,4. The second in the list is generic DWARF 3,4. The rest are SGI specific and rarely used. .P The interface types are Dwarf_Global Dwarf_Type,Dwarf_Weak,Dwarf_Func, and Dwarf_Var. Only Dwarf_Global is a real type. The others are opaque pointers with no actual definition or instantiation and can be converted to Dwarf_Global with a simple cast. .P In hindsight it would have been simpler to write a single set of interfaces for Accelerated Access By Name. .H 3 "Fine Tuning Accelerated Access" By default the various dwarf_get*() functions here return an array of pointers to opaque records with a .debug_info DIE offset and a string (the fields are accessible by function calls). While the actual .debug_pubnames (etc) section contains CU-local DIE offsets for the named things the accelerated access functions below return a .debug_info (or .debug_types) global section offset. .P .H 4 "dwarf_return_empty_pubnames" New March 2019. Mostly special for dwarfdump. If called with a flag value of one (1) it tells libdwarf, for any pubnames(etc) section list returned to add to the list an entry with a global-DIE-offset of zero (0) for any section Compilation Unit entry with no pubnames(etc) name( ie, an empty list for the Compilation Unit). .P If called with a value of zero(0) (zero is the default set by any \f(CWdwarf_init*()\fP call) it causes such empty lists to be omitted from the array of pointers returned, which is the standard behavior of libdwarf since libdwarf was first written. .P Since zero is never a valid DIE offset in .debug_info (or .debug_types) consumers requesting such can detect the special Dwarf_Global entries. .P For example, calling \f(CW dwarf_global_name_offsets()\fP on one of the special global records sets \f(CW*die_offset\fP to 0, \f(CW*return_name\fP to a pointer to an empty string, and \f(CW*cu_offset\fP to the offset of the compilation unit die in the .debug_info (or .debug_types if applicable) section. .DS \f(CWint dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag , Dwarf_Error* error)\fP .DE Callers should pass in one (1) or zero(0), no other value. On success it returns DW_DLV_OK. On failure it returns DW_DLV_ERROR; .P The assumption is that programs calling this with value one (1) will be calling dwarf_get_globals_header() to retrieve the relevant pubnames(etc) section Compilation Unit header. .H 4 "dwarf_get_globals_header" New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. .P This allows dwarfdump, or any DWARF dumper, to print pubnames(etc) specific CU header data. .DS \f(CWint dwarf_get_globals_header(Dwarf_Global global, Dwarf_Off * offset_pub_header, Dwarf_Unsigned * offset_size, Dwarf_Unsigned * length_pub, Dwarf_Unsigned * version, Dwarf_Unsigned * header_info_offset, Dwarf_Unsigned * info_length, Dwarf_Error* error)\fP .DE On success it returns DW_DLV_OK and it returns the header data (and calculated values) though the pointers. Casting Dwarf_Type (etc) to Dwarf_Global for a call to this function allows this to be used for any of these accelerated-access types. .H 3 "Accelerated Access Pubnames" .H 4 "dwarf_get_globals()" This is .debug_pubnames and is standard DWARF2, DWARF3, and DWARF4. .DS \f(CWint dwarf_get_globals( Dwarf_Debug dbg, Dwarf_Global **globals, Dwarf_Signed * return_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_globals()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_count\fP to the count of pubnames represented in the section containing pubnames i.e. .debug_pubnames. It also stores at \f(CW*globals\fP, a pointer to a list of \f(CWDwarf_Global\fP descriptors, one for each of the pubnames in the .debug_pubnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubnames section does not exist. .P On a successful return from \f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP descriptors should be freed using \f(CWdwarf_globals_dealloc()\fP. \f(CWdwarf_globals_dealloc()\fP is new as of July 15, 2005 and is the preferred approach to freeing this memory.. .P Global names refer exclusively to names and offsets in the .debug_info section. See section 6.1.1 "Lookup by Name" in the dwarf standard. .in +2 .FG "Exampled dwarf_get_globals()" .DS \f(CW void examplef(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Global *globs = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_get_globals(dbg, &globs,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use globs[i] */ } dwarf_globals_dealloc(dbg, globs, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_GLOBAL_CONTEXT\fP, (or \f(CWDW_DLA_GLOBAL\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .DS \f(CW Dwarf_Signed cnt; Dwarf_Global *globs; int res; res = dwarf_get_globals(dbg, &globs,&cnt, &error); if (res == DW_DLV_OK) { /* OBSOLETE: DO NOT USE to deallocate*/ for (i = 0; i < cnt; ++i) { /* use globs[i] */ dwarf_dealloc(dbg, globs[i], DW_DLA_GLOBAL_CONTEXT); } dwarf_dealloc(dbg, globs, DW_DLA_LIST); } \fP .DE .in -2 .H 4 "dwarf_globname()" .DS \f(CWint dwarf_globname( Dwarf_Global global, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_globname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the pubname represented by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_global_die_offset()" .DS \f(CWint dwarf_global_die_offset( Dwarf_Global global, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the pubname that is described by the \f(CWDwarf_Global\fP descriptor, \f(CWglob\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_global_cu_offset()" .DS \f(CWint dwarf_global_cu_offset( Dwarf_Global global, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the pubname described by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()" .DS \f(CWint dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, Dwarf_Off * out_cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_cu_die_offset\fP to the offset of the compilation-unit DIE given the offset \f(CWin_cu_header_offset\fP of a compilation-unit header. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P If \f(CWis_info\fP is non-zero the \f(CWin_cu_header_offset\fP must refer to a .debug_info section offset. If \f(CWis_info\fP zero the \f(CWin_cu_header_offset\fP must refer to a .debug_types section offset. Chaos may result if the \f(CWis_info\fP flag is incorrect. This effectively turns a compilation-unit-header offset into a compilation-unit DIE offset (by adding the size of the applicable CU header). This function is also sometimes useful with the \f(CWdwarf_weak_cu_offset()\fP, \f(CWdwarf_func_cu_offset()\fP, \f(CWdwarf_type_cu_offset()\fP, and \f(CWint dwarf_var_cu_offset()\fP functions, though for those functions the data is only in .debug_info by definition. .H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()" .DS \f(CWint dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Off * out_cu_die_offset, Dwarf_Error *error)\fP .DE This function is superseded by \f(CWdwarf_get_cu_die_offset_given_cu_header_offset_b()\fP, a function which is still supported thought it refers only to the .debug_info section. .P \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP added Rev 1.45, June, 2001. .P This function was declared as 'optional' in libdwarf.h on IRIX systems so the _MIPS_SYMBOL_PRESENT predicate could be used at run time to determine if the version of libdwarf linked into an application has this function. .H 4 "dwarf_global_name_offsets()" .DS \f(CWint dwarf_global_name_offsets( Dwarf_Global global, char **return_name, Dwarf_Off *die_offset, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that gives the name of the pubname described by the \f(CWDwarf_Global\fP descriptor \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the global offset of the DIE representing the pubname, and the offset of the DIE representing the compilation-unit containing the pubname, respectively. On a successful return from \f(CWdwarf_global_name_offsets()\fP the storage pointed to by \f(CWreturn_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .P If a portion of .debug_pubnames ( or .debug_types etc) represents a compilation unit with no names there is a .debug_pubnames header there with no content. In that case a single Dwarf_Global record is created with the value of *die_offset zero and the name-pointer returned points to the empty string. A zero is never a valid DIE offset, so zero always means this is an uninteresting (Dwarf_Global). .H 3 "Accelerated Access Pubtypes" Section ".debug_pubtypes" is in DWARF3 and DWARF4. .P These functions operate on the .debug_pubtypes section of the debugging information. The .debug_pubtypes section contains the names of file-scope user-defined types, the offsets of the \f(CWDIE\fPs that represent the definitions of those types, and the offsets of the compilation-units that contain the definitions of those types. .H 4 "dwarf_get_pubtypes()" This is standard DWARF3 and DWARF4. .DS \f(CWint dwarf_get_pubtypes( Dwarf_Debug dbg, Dwarf_Type **types, Dwarf_Signed *typecount, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_pubtypes()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to the count of user-defined type names represented in the section containing user-defined type names, i.e. .debug_pubtypes. It also stores at \f(CW*types\fP, a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the user-defined type names in the .debug_pubtypes section. The returned results are for the entire section. It returns \f(CWDW_DLV_NOCOUNT\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubtypes section does not exist. .P On a successful return from \f(CWdwarf_get_pubtypes()\fP, the \f(CWDwarf_Type\fP descriptors should be freed using \f(CWdwarf_types_dealloc()\fP. \f(CWdwarf_types_dealloc()\fP is used for both \f(CWdwarf_get_pubtypes()\fP and \f(CWdwarf_get_types()\fP as the data types are the same. .P Global type names refer exclusively to names and offsets in the .debug_info section. See section 6.1.1 "Lookup by Name" in the dwarf standard. .in +2 .FG "Exampled dwarf_get_pubtypes()" .DS \f(CW Avoid exampleg(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_pubtypes(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ } dwarf_types_dealloc(dbg, types, count); } } \fP .DE .in -2 .H 4 "dwarf_pubtypename()" .DS \f(CWint dwarf_pubtypename( Dwarf_Type type, char **return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtypename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the user-defined type represented by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_pubtype_type_die_offset()" .DS \f(CWint dwarf_pubtype_type_die_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_type_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the user-defined type that is described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_pubtype_cu_offset()" .DS \f(CWint dwarf_pubtype_cu_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the user-defined type described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_pubtype_name_offsets()" .DS \f(CWint dwarf_pubtype_name_offsets( Dwarf_Type type, char ** returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the user-defined type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the user-defined type, and the DIE representing the compilation-unit containing the user-defined type, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_pubtype_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Weaknames" This section is SGI specific and is not part of standard DWARF. .P These functions operate on the .debug_varnames section of the debugging information. The .debug_varnames section contains the names of file-scope static variables, the offsets of the \f(CWDIE\fPs that represent the definitions of those variables, and the offsets of the compilation-units that contain the definitions of those variables. .P These operations operate on the .debug_weaknames section of the debugging information. .H 4 "dwarf_get_weaks()" .DS \f(CWint dwarf_get_weaks( Dwarf_Debug dbg, Dwarf_Weak **weaks, Dwarf_Signed *weak_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_weaks()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*weak_count\fP to the count of weak names represented in the section containing weak names i.e. .debug_weaknames. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the section does not exist. It also stores in \f(CW*weaks\fP, a pointer to a list of \f(CWDwarf_Weak\fP descriptors, one for each of the weak names in the .debug_weaknames section. The returned results are for the entire section. .P On a successful return from this function, the \f(CWDwarf_Weak\fP descriptors should be freed using \f(CWdwarf_weaks_dealloc()\fP when the data is no longer of interest. \f(CWdwarf_weaks_dealloc()\fPis new as of July 15, 2005. .in +2 .FG "Exampleh dwarf_get_weaks()" .DS \f(CW void exampleh(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Weak *weaks = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_weaks(dbg, &weaks, &count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use weaks[i] */ } dwarf_weaks_dealloc(dbg, weaks, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_weaks()\fP the \f(CWDwarf_Weak\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_WEAK_CONTEXT\fP, (or \f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplei dwarf_get_weaks() obsolete" .DS \f(CW void examplei(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Weak *weaks = 0; Dwarf_Signed i = 0; int res = 0; /* Obsolete, see exampleh instead */ res = dwarf_get_weaks(dbg, &weaks, &count, &error); if (res == DW_DLV_OK) { /* OBSOLETE: do not use dealloc for this. See above */ for (i = 0; i < count; ++i) { /* use weaks[i] */ dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK); } dwarf_dealloc(dbg, weaks, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_weakname()" .DS \f(CWint dwarf_weakname( Dwarf_Weak weak, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weakname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the weak name represented by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .DS \f(CWint dwarf_weak_die_offset( Dwarf_Weak weak, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the weak name that is described by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_weak_cu_offset()" .DS \f(CWint dwarf_weak_cu_offset( Dwarf_Weak weak, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the weak name described by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_weak_name_offsets()" .DS \f(CWint dwarf_weak_name_offsets( Dwarf_Weak weak, char ** weak_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*weak_name\fP to a pointer to a null-terminated string that gives the name of the weak name described by the \f(CWDwarf_Weak\fP descriptor \f(CWweak\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the weakname, and the DIE representing the compilation-unit containing the weakname, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_weak_name_offsets()\fP the storage pointed to by \f(CWweak_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Funcnames" This section is SGI specific and is not part of standard DWARF. .P These function operate on the .debug_funcnames section of the debugging information. The .debug_funcnames section contains the names of static functions defined in the object, the offsets of the \f(CWDIE\fPs that represent the definitions of the corresponding functions, and the offsets of the start of the compilation-units that contain the definitions of those functions. .H 4 "dwarf_get_funcs()" .DS \f(CWint dwarf_get_funcs( Dwarf_Debug dbg, Dwarf_Func **funcs, Dwarf_Signed *func_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_funcs()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*func_count\fP to the count of static function names represented in the section containing static function names, i.e. .debug_funcnames. It also stores, at \f(CW*funcs\fP, a pointer to a list of \f(CWDwarf_Func\fP descriptors, one for each of the static functions in the .debug_funcnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_funcnames section does not exist. .P On a successful return from \f(CWdwarf_get_funcs()\fP, the \f(CWDwarf_Func\fP descriptors should be freed using \f(CWdwarf_funcs_dealloc()\fP. \f(CWdwarf_funcs_dealloc()\fP is new as of July 15, 2005. .in +2 .FG "Examplej dwarf_get_funcs()" .DS \f(CW void examplej(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Func *funcs = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_funcs(dbg, &funcs, &count, &error); if (fres == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use funcs[i] */ } dwarf_funcs_dealloc(dbg, funcs, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_funcs()\fP, the \f(CWDwarf_Func\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FUNC_CONTEXT\fP, (or \f(CWDW_DLA_FUNC\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplek dwarf_get_funcs() obsolete" .DS \f(CW void examplek(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Func *funcs = 0; Dwarf_Signed count = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_funcs(dbg, &funcs,&count, &error); if (fres == DW_DLV_OK) { /* OBSOLETE: see dwarf_funcs_dealloc() above */ for (i = 0; i < count; ++i) { /* use funcs[i] */ dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC); } dwarf_dealloc(dbg, funcs, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_funcname()" .DS \f(CWint dwarf_funcname( Dwarf_Func func, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_funcname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the static function represented by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_func_die_offset()" .DS \f(CWint dwarf_func_die_offset( Dwarf_Func func, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_die_offset()\fP, returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the static function that is described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_func_cu_offset()" .DS \f(CWint dwarf_func_cu_offset( Dwarf_Func func, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the static function described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_func_name_offsets()" .DS \f(CWint dwarf_func_name_offsets( Dwarf_Func func, char **func_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*func_name\fP to a pointer to a null-terminated string that gives the name of the static function described by the \f(CWDwarf_Func\fP descriptor \f(CWfunc\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the static function, and the DIE representing the compilation-unit containing the static function, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_func_name_offsets()\fP the storage pointed to by \f(CWfunc_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Typenames" Section "debug_typenames" is SGI specific and is not part of standard DWARF. (However, an identical section is part of DWARF version 3 named ".debug_pubtypes", see \f(CWdwarf_get_pubtypes()\fP above.) .P These functions operate on the .debug_typenames section of the debugging information. The .debug_typenames section contains the names of file-scope user-defined types, the offsets of the \f(CWDIE\fPs that represent the definitions of those types, and the offsets of the compilation-units that contain the definitions of those types. .H 4 "dwarf_get_types()" .DS \f(CWint dwarf_get_types( Dwarf_Debug dbg, Dwarf_Type **types, Dwarf_Signed *typecount, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_types()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to the count of user-defined type names represented in the section containing user-defined type names, i.e. .debug_typenames. It also stores at \f(CW*types\fP, a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the user-defined type names in the .debug_typenames section. The returned results are for the entire section. It returns \f(CWDW_DLV_NOCOUNT\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_typenames section does not exist. .P On a successful return from \f(CWdwarf_get_types()\fP, the \f(CWDwarf_Type\fP descriptors should be freed using \f(CWdwarf_types_dealloc()\fP. \f(CWdwarf_types_dealloc()\fP is new as of July 15, 2005 and frees all memory allocated by \f(CWdwarf_get_types()\fP. .in +2 .FG "Examplel dwarf_get_types()" .DS \f(CW void examplel(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_types(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ } dwarf_types_dealloc(dbg, types, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_types()\fP, the \f(CWDwarf_Type\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_TYPENAME_CONTEXT\fP, (or \f(CWDW_DLA_TYPENAME\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplel dwarf_get_types() obsolete" .DS \f(CW void examplem(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; /* OBSOLETE: see dwarf_types_dealloc() above */ res = dwarf_get_types(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME); } dwarf_dealloc(dbg, types, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_typename()" .DS \f(CWint dwarf_typename( Dwarf_Type type, char **return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_typename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the user-defined type represented by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_type_die_offset()" .DS \f(CWint dwarf_type_die_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the user-defined type that is described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_type_cu_offset()" .DS \f(CWint dwarf_type_cu_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the user-defined type described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_type_name_offsets()" .DS \f(CWint dwarf_type_name_offsets( Dwarf_Type type, char ** returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the user-defined type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the user-defined type, and the DIE representing the compilation-unit containing the user-defined type, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_type_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access varnames" This section is SGI specific and is not part of standard DWARF. .P These functions operate on the .debug_varnames section of the debugging information. The .debug_varnames section contains the names of file-scope static variables, the offsets of the \f(CWDIE\fPs that represent the definitions of those variables, and the offsets of the compilation-units that contain the definitions of those variables. .H 4 "dwarf_get_vars()" .DS \f(CWint dwarf_get_vars( Dwarf_Debug dbg, Dwarf_Var **vars, Dwarf_Signed *var_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_vars()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*var_count\fP to the count of file-scope static variable names represented in the section containing file-scope static variable names, i.e. .debug_varnames. It also stores, at \f(CW*vars\fP, a pointer to a list of \f(CWDwarf_Var\fP descriptors, one for each of the file-scope static variable names in the .debug_varnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_varnames section does not exist. .P The following is new as of July 15, 2005. On a successful return from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be freed using \f(CWdwarf_vars_dealloc()\fP. .in +2 .FG "Examplen dwarf_get_vars()" .DS \f(CW void examplen(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Var *vars = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_vars(dbg, &vars,&count,&error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use vars[i] */ } dwarf_vars_dealloc(dbg, vars, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_VAR_CONTEXT\fP, (or \f(CWDW_DLA_VAR\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Exampleo dwarf_get_vars() obsolete" .DS \f(CW void exampleo(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Var *vars = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_vars(dbg, &vars,&count,&error); if (res == DW_DLV_OK) { /* DO NOT USE: see dwarf_vars_dealloc() above */ for (i = 0; i < count; ++i) { /* use vars[i] */ dwarf_dealloc(dbg, vars[i], DW_DLA_VAR); } dwarf_dealloc(dbg, vars, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_varname()" .DS \f(CWint dwarf_varname( Dwarf_Var var, char ** returned_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_varname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that names the file-scope static variable represented by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_var_die_offset()" .DS \f(CWint dwarf_var_die_offset( Dwarf_Var var, Dwarf_Off *returned_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the file-scope static variable that is described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_var_cu_offset()" .DS \f(CWint dwarf_var_cu_offset( Dwarf_Var var, Dwarf_Off *returned_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the file-scope static variable described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_var_name_offsets()" .DS \f(CWint dwarf_var_name_offsets( Dwarf_Var var, char **returned_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the file-scope static variable described by the \f(CWDwarf_Var\fP descriptor \f(CWvar\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the representing the compilation-unit containing the file-scope static variable, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_var_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 2 "Names Fast Access (DWARF5) .debug_names" The section \f(CW.debug_names\fP section is new in DWARF5 so a new set of functions is defined to access this section. This section replaces \f(CW.debug_pubnames\fP and \f(CW.debug_pubtypes\fP as those older sections were not found to be useful in practice. See also \f(CWNames Fast Access .debug_gnu_pubnames\fP .H 3 "dwarf_debugnames_header()" .DS \f(CWint dwarf_debugnames_header( Dwarf_Debug dbg, Dwarf_Dnames_Head * dn_out, Dwarf_Unsigned * dn_index_count_out, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_debugnames_header()\fP allocates an opaque data structure used in all the other debugnames calls. .P Many of the function calls here let one extract the entire content of the section, which is useful if one wishes to dump the section or to use its data to create one's own internal data structures. .P To free space allocated when one has finished with these data structures, call .DS Debug_Dnames_Head dn /* Assume set somehow */; ... dwarf_dealloc(dbg,dn,DW_DLA_DNAMES_HEAD); .DE which will free up all data allocated for \f(CWdwarf_debugnames_header()\fP. .P On success the function returns \f(CWDW_DLV_OK\fP and returns a pointer to the Head structure through \f(CWdn_out\fP. .P It also returns the count of debugnames entry in the debugnames index through the \f(CWdn_index_count_out\fP value. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no \f(CW.debug_names\fP section. .P It returns \f(CWDW_DLV_ERROR\fP if there is an internal error such as data corruption in the section. .H 3 " dwarf_debugnames_sizes()" .DS \f(CW int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned * section_offsets, Dwarf_Unsigned * version, Dwarf_Unsigned * offset_size, /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * comp_unit_count, Dwarf_Unsigned * local_type_unit_count, Dwarf_Unsigned * foreign_type_unit_count, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * name_count, /* The following are counted in bytes */ Dwarf_Unsigned * indextable_overall_length, Dwarf_Unsigned * abbrev_table_size, Dwarf_Unsigned * entry_pool_size, Dwarf_Unsigned * augmentation_string_size, Dwarf_Error * error*/)\fP .DE .P Given a properly created head \f(CWdn\fP this Allows access to fields a \f(CW.debug_names\fP \f(CWDWARF5\fP header record \f(CWindex_number\fP. .P We will not describe the fields in detail here. See the \f(CWDWARF5\fP standard and \f(CWdwarfdump\fP for the motivation of this function. .H 3 " dwarf_debugnames_cu_entry()" .DS \f(CW int dwarf_debugnames_cu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error)\fP .DE Given a properly created head \f(CWdn\fP this Allows access to fields in cu entry \f(CWindex_number\fP from a \f(CW.debug_names\fP \f(CWDWARF5\fP Compilation Unit entry. .P We will not describe the fields in detail here. See the \f(CWDWARF5\fP standard and \f(CWdwarfdump\fP for the motivation of this function. .H 3 " dwarf_debugnames_local_tu_entry()" .DS \f(CW int dwarf_debugnames_local_tu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) \fP .DE .P The same as \f(CWdwarf_debugnames_cu_entry()\fP but referencing type unit fields. .H 3 " dwarf_debugnames_foreign_tu_entry()" .DS \f(CW int dwarf_debugnames_foreign_tu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned sig_number, Dwarf_Unsigned * sig_minimum, Dwarf_Unsigned * sig_count, Dwarf_Sig8 * signature, Dwarf_Error * error) \fP .DE Allows retrieving the data for foreign type-unit entries. .H 3 " dwarf_debugnames_bucket()" .DS \f(CW int dwarf_debugnames_bucket( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned bucket_number, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * index_of_name_entry, Dwarf_Error * error) \fP .DE Allows retrieving the data for hash buckets. .H 3 " dwarf_debugnames_name()" .DS \f(CW int dwarf_debugnames_bucket( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned name_entry, Dwarf_Unsigned * names_count, Dwarf_Sig8 * signature, Dwarf_Unsigned * offset_to_debug_str, Dwarf_Unsigned * offset_in_entrypool, Dwarf_Error * error) \fP .DE Allows retrieving the data about names and signatures. .H 3 " dwarf_debugnames_abbrev_by_index()" .DS \f(CW int dwarf_debugnames_abbrev_by_index( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * number_of_abbrev, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) \fP .DE Allows retrieving the abbreviations from a portion of the section by index. .H 3 " dwarf_debugnames_abbrev_by_code()" .DS \f(CW int dwarf_debugnames_abbrev_by_code( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * index_of_attr_form_entries, Dwarf_Error * error) \fP .DE Allows retrieving the abbreviations from a portion of the section by abbrev-code. .H 3 " dwarf_debugnames_form_by_index()" .DS \f(CW int dwarf_debugnames_form_by_index( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry_index, Dwarf_Unsigned abbrev_form_index, Dwarf_Unsigned * name_attr_index, Dwarf_Unsigned * form, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) \fP .DE Allows retrieving the abbreviations forms from a portion of the section by index. .H 3 " dwarf_debugnames_entrypool()" .DS \f(CW int dwarf_debugnames_entrypool( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_in_entrypool, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * value_count, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * offset_of_initial_value, Dwarf_Error * error) \fP .DE Allows retrieving the data from a portion of the entrypool by index and offset. .H 3 " dwarf_debugnames_entrypool_values()" .DS \f(CW int dwarf_debugnames_entrypool_values( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned index_of_abbrev, Dwarf_Unsigned offset_in_entrypool_of_values, Dwarf_Unsigned * array_dw_idx_number, Dwarf_Unsigned * array_form, Dwarf_Unsigned * array_of_offsets, Dwarf_Sig8 * array_of_signatures, Dwarf_Error * error) \fP .DE Allows retrieving detailed data from a portion of the entrypool by index and offset. .H 2 "Names Fast Access .debug_gnu_pubnames" The sections \f(CW.debug_gnu_pubnames\fP and \f(CW.debug_gnu_pubtypes\fP are non-standard sections emitted by gcc and clang with DWARF5. Typically they will be in the skeleton executable and the split dwarf section \f(CW.debug_info.dwo\fP will have the actual DWARF the offsets refer to, These sections would normally be read once by a program wanting them and filed in an internal format and then the program would do the cleanup \f(CWdwarf_gnu_index_dealloc()\fP. .P Each section is divided into what we term blocks here and within each block there is an array of entries. The functions below enable access. .H 3 "dwarf_get_gnu_index_head()" .DS \f(CWint dwarf_get_gnu_index_head( Dwarf_Debug dbg, /* The following arg false to select gnu_pubtypes */ Dwarf_Bool for_gdb_pubnames , Dwarf_Gnu_Index_Head * head, Dwarf_Unsigned * index_block_count, Dwarf_Error * error); \fP .DE This creates an open header to use in subsequent data access. Free the memory associated with this by calling \f(CWdwarf_gnu_index_dealloc(head)\fP. \f(CW \fP .P The field \f(CWindex_block_count\fP is set through the pointer to the number of blocks in the section. Call \f(CWdwarf_get_gnu_index_block()\fP and pass in valid block number (zero through index_block_count-1) to get block information. .P If the section does not exist or is empty it returns \f(CWDW_DLV_NO_ENTRY\fP and does nothing else. .P If there is data corruption or some serious error it returns \f(CWDW_DLV_ERROR\fP and sets the error pointer with information about the error. \f(CW \fP .H 3 "dwarf_gnu_index_dealloc()" .DS \f(CWvoid dwarf_gnu_index_dealloc( Dwarf_Gnu_Index_Head index_head); .DE This frees all data associated with the section. .H 3 "dwarf_get_gnu_index_block()" .DS \f(CWint dwarf_get_gnu_index_block( Dwarf_Gnu_Index_Head head, Dwarf_Unsigned blocknumber, Dwarf_Unsigned * block_length, Dwarf_Half * version , Dwarf_Unsigned * offset_into_debug_info, Dwarf_Unsigned * size_of_debug_info_area, Dwarf_Unsigned * count_of_index_entries, Dwarf_Error * error); \fP .DE On success this returns \f(CWDW_DLV_OK\fP and fills in the various fields through the pointers. If the pointer to a field is null the function ignores that field. .P The field \f(CWblock_length\fP has the byte length of the block (with its entries). .P The field \f(CWversion\fP has the version number. Currently it must be 2. .P The field \f(CWoffsetinto_debug_info\fP is the offset (in some .debug_info or .debug_info.owo section) of a Compilation Unit Header. .P The field \f(CWsize_of_debug_info_area\fP is the size of the referenced compilation unit. .P The field \f(CWcount_of_index_entries\fP is the number of entries attached to the block. See \f(CWdwarf_get_gnu_index_block_entry()\fP. .P If the block number is outside the valid range (zero through \f(CWindex_block_count\fP -1) it returns \f(CWDW_DLV_NO_ENTRY\fP and does nothing. .P If there is data corruption or some serious error it returns \f(CWDW_DLV_ERROR\fP and sets the error pointer with information about the error. .H 3 "dwarf_get_gnu_index_block_entry()" .DS \f(CWint dwarf_get_gnu_index_block_entry( Dwarf_Gnu_Index_Head head, Dwarf_Unsigned blocknumber, Dwarf_Unsigned entrynumber, Dwarf_Unsigned * offset_in_debug_info const char ** name, unsigned char * flagbyte, unsigned char * staticorglobal, unsigned char * typeofentry, Dwarf_Error * error); \fP .DE If either \f(CWblocknumber\fP or \f(CWentrynumber\fP is outside the range of valid values it returns \f(CWDW_DLV_NO_ENTRY\fP and does nothing. .P On success it returns \f(CWDW_DLV_OK\fP and sets information about each entry through the pointers. Any pointers pased in as NULL are ignored. .P The field \f(CWoffset_in_debug_info\fP has the offset of DIE in a .debug_info section. .P The field \f(CWname\fP has a pointer to the name of the variable or function that the DIE refers to. .P The field \f(CWflagbyte\fP has the entire 8 bits of a byte that has two useful fields. The next two fields are those useful fields. .P The field \f(CWstaticorglobal\fP has an integer 0 if the DIE involved describes a global (externally-visible) name. It has an integer 1 if the name refers to a static (file-local) DIE. .P The field \f(CWtypeofentry\fP has a small integer describing the type. Zero means the type is "none". One means the type is "type". Two means the type is "variable". Three means the type is "function". Four means the type is "other". Any other value has, apparently, no assigned meaning. .P If there is data corruption or some serious error it returns \f(CWDW_DLV_ERROR\fP and sets the error pointer with information about the error. .H 2 "Macro Information Operations (DWARF4, DWARF5)" This section refers to DWARF4 and later macro information from the .debug_macro section (for DWARF 4 some producers generated .debug_macro before its formal standardization in DWARF 5). While standard operations are supported there is as yet no support for implementation-defined extensions. Once someone has defined such things it will make sense to design an interface for extensions. .H 3 "Getting access" The opaque struct pointer Dwarf_Macro_Context is allocated by either \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP and once the context is no longer needed one frees up all its storage by \f(CWdwarf_dealloc_macro_context()\fP. .H 4 "dwarf_get_macro_context()" .DS \f(CWint dwarf_get_macro_context(Dwarf_Die die, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length_out, Dwarf_Error * error);\fP .DE Given a Compilation Unit (CU) die, on success \f(CWdwarf_get_macro_context()\fP opens a \f(CWDwarf_Macro_Context\fP and returns a pointer to it and some data from the macro unit for that CU. The \f(CWDwarf_Macro_Context\fP is used to get at the details of the macros. .P The value \f(CWversion_out\fP is set to the DWARF version number of the macro data. Version 5 means DWARF5 version information. Version 4 means the DWARF5 format macro data is present as an extension of DWARF4. .P The value \f(CWmacro_unit_offset_out\fP is set to the offset in the .debug_macro section of the first byte of macro data for this CU. .P Macro unit is defined in the DWARF5 standard, Section 6.3 Macro Information on page 165. .P The value \f(CWmacro_ops_count_out\fP is set to the number of macro entries in the macro data data for this CU. The count includes the final zero entry (which is not really a macro, it is a terminator, a zero byte ending the macro unit). .P The value \f(CWmacro_ops_data_length_out\fP is set to the number of bytes of data in the set of ops (not including macro_unit header bytes). See \f(CWdwarf_macro_context_total_length()\fP to get the macro unit total length. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned the CU has no macro data attribute or there is no .debug_macro section present. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_context_by_offset()" .DS \f(CWint dwarf_get_macro_context_by_offset(Dwarf_Die die, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_total_byte_len, Dwarf_Error * error);\fP .DE Given a Compilation Unit (CU) die and the offset of an imported macro unit \f(CWdwarf_get_macro_context_by_offset()\fP opens a \f(CWDwarf_Macro_Context\fP and returns a pointer to it and some data from the macro unit for that CU on success. .P On success the function produces the same output values as \f(CWdwarf_get_macro_context()\fP. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no .debug_macro section present. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_macro_context_total_length()" .DS \f(CWint dwarf_macro_context_total_length( Dwarf_Macro_Context macro_context, Dwarf_Unsigned *total_length, Dwarf_Error * error);\fP .DE New in December, 2020, \f(CWdwarf_macro_context_total_length()\fP because callers of \f(CWdwarf_get_macro_context[_by_offset]()\fP sometimes want to know the length of macro ops plus the length of the DWARF5-style header. .P On success function returns \f(CWDW_DLV_OK\fP and sets \f(CW*total_length\fP to the total length of the DWARF5-style macro unit. .P It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P If the \f(CW \fP macro_context argument is NULL or invalid it returns \f(CWDW_DLV_ERROR\fP. and sets \f(CW*error\fP to an appropriate error value. .H 4 "dwarf_dealloc_macro_context()" .DS \f(CWvoid dwarf_dealloc_macro_context(Dwarf_Macro_Context macro_context);\fP .DE The function \f(CWdwarf_dealloc_macro_context()\fP cleans up memory allocated by a successful call to \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP. .in +2 .FG "Examplep5 dwarf_dealloc_macro_context()" .DS \f(CW /* This builds an list or some other data structure (not defined) to give an import somewhere to list the import offset and then later to enquire if the list has unexamined offsets. A candidate set of hypothetical functions that callers would write: has_unchecked_import_in_list() get_next_import_from_list() mark_this_offset_as_examined(macro_unit_offset); add_offset_to_list(offset); */ void examplep5(Dwarf_Debug dbg, Dwarf_Die cu_die) { int lres = 0; Dwarf_Unsigned version = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Unsigned macro_unit_offset = 0; Dwarf_Unsigned number_of_ops = 0; Dwarf_Unsigned ops_total_byte_len = 0; Dwarf_Bool is_primary = TRUE; unsigned k = 0; Dwarf_Error err = 0; for(;;) { if (is_primary) { lres = dwarf_get_macro_context(cu_die, &version,¯o_context, ¯o_unit_offset, &number_of_ops, &ops_total_byte_len, &err); is_primary = FALSE; } else { if (has_unchecked_import_in_list()) { macro_unit_offset = get_next_import_from_list(); } else { /* We are done */ break; } lres = dwarf_get_macro_context_by_offset(cu_die, macro_unit_offset, &version, ¯o_context, &number_of_ops, &ops_total_byte_len, &err); mark_this_offset_as_examined(macro_unit_offset); } if (lres == DW_DLV_ERROR) { /* Something is wrong. */ return; } if (lres == DW_DLV_NO_ENTRY) { /* We are done. */ break; } /* lres == DW_DLV_OK) */ for (k = 0; k < number_of_ops; ++k) { Dwarf_Unsigned section_offset = 0; Dwarf_Half macro_operator = 0; Dwarf_Half forms_count = 0; const Dwarf_Small *formcode_array = 0; Dwarf_Unsigned line_number = 0; Dwarf_Unsigned index = 0; Dwarf_Unsigned offset =0; const char * macro_string =0; int lres = 0; lres = dwarf_get_macro_op(macro_context, k, §ion_offset,¯o_operator, &forms_count, &formcode_array,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_op()", lres,err); dwarf_dealloc_macro_context(macro_context); return; } switch(macro_operator) { case 0: /* Nothing to do. This sigifies it is the end-marker, standing in for the 0 byte at the end of his macro group. */ break; case DW_MACRO_end_file: /* Do something */ break; case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: case DW_MACRO_undef_strp: case DW_MACRO_define_strx: case DW_MACRO_undef_strx: case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { lres = dwarf_get_macro_defundef(macro_context, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from sup dwarf_get_macro_defundef()", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; case DW_MACRO_start_file: { lres = dwarf_get_macro_startend_file(macro_context, k,&line_number, &index, ¯o_string,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_startend_file()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; case DW_MACRO_import: { lres = dwarf_get_macro_import(macro_context, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } add_offset_to_list(offset); } break; case DW_MACRO_import_sup: { lres = dwarf_get_macro_import(macro_context, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; } } dwarf_dealloc_macro_context(macro_context); macro_context = 0; } } \fP .DE .in -2 .H 3 "Getting Macro Unit Header Data" .H 4 "dwarf_macro_context_head()" .DS \f(CWint dwarf_macro_context_head(Dwarf_Macro_Context macro_context, Dwarf_Half * version, Dwarf_Unsigned * mac_offset, Dwarf_Unsigned * mac_len, Dwarf_Unsigned * mac_header_len, unsigned * flags, Dwarf_Bool * has_line_offset, Dwarf_Unsigned * line_offset, Dwarf_Bool * has_offset_size_64, Dwarf_Bool * has_operands_table, Dwarf_Half * opcode_count, Dwarf_Error * error); \fP .DE Given a \f(CWDwarf_Macro_Context\fP pointer this function returns the basic fields of a macro unit header (Macro Information Header) on success. .P The value \f(CWversion\fP is set to the DWARF version number of the macro unit header. Version 5 means DWARF5 version information. Version 4 means the DWARF5 format macro data is present as an extension of DWARF4. .P The value \f(CWmac_offset\fP is set to the offset in the .debug_macro section of the first byte of macro data for this CU. .P The value \f(CWmac_len\fP is set to the number of bytes of data in the macro unit, including the macro unit header. .P The value \f(CWmac_header_len\fP is set to the number of bytes in the macro unit header (not a field that is generally useful). .P The value \f(CWflags\fP is set to the value of the \f(CWflags\fP field of the macro unit header. .P The value \f(CWhas_line_offset\fP is set to non-zero if the \f(CWdebug_line_offset_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header. If \f(CWhas_line_offset\fP is set then \f(CWline_offset\fP is set to the value of the \f(CWdebug_line_offset\fP field in the macro unit header. If \f(CWhas_line_offset\fP is not set there is no \f(CWdebug_line_offset\fP field present in the macro unit header. .P The value \f(CWhas_offset_size_64\fP is set non-zero if the \f(CWoffset_size_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header and in this case offset fields in this macro unit are 64 bits. If \f(CWhas_offset_size_64\fP is not set then offset fields in this macro unit are 32 bits. .P The value \f(CWhas_operands_table\fP is set to non-zero if the \f(CWopcod_operands_table_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header. .P If \f(CWhas_operands_table\fP is set non-zero then The value \f(CWopcode_count\fP is set to the number of opcodes in the macro unit header \f(CWopcode_operands_table\fP. See \f(CWdwarf_get_macro_op()\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_macro_operands_table()" .DS \f(CWint dwarf_macro_operands_table(Dwarf_Macro_Context macro_context, Dwarf_Half index, /* 0 to opcode_count -1 */ Dwarf_Half * opcode_number, Dwarf_Half * operand_count, const Dwarf_Small ** operand_array, Dwarf_Error * error); \fP .DE \f(CWdwarf_macro_operands_table()\fP is used to index through the operands table in a macro unit header if the operands table exists in the macro unit header. The operands table provides the mechanism for implementations to add extensions to the macro operations while allowing clients to skip macro operations the client code does not recognize. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWindex\fP field passed in identifies which macro operand to look at. Valid index values are zero through the \f(CWopcode_count\fP-1 (returned by \f(CWdwarf_macro_context_head()\fP). .P The \f(CWopcode_number\fP value returned through the pointer is the the macro operation code. The operation code could be one of the standard codes or if there are user extensions there would be an extension code in the \f(CWDW_MACRO_lo_user\fP to \f(CWDW_MACRO_hi_user\fP range. .P The \f(CWoperand_count\fP returned is the number of form codes in the form codes array of unsigned bytes \f(CWoperand_array\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 3 "Getting Individual Macro Operations Data" .H 4 "dwarf_get_macro_op()" .DS \f(CWint dwarf_get_macro_op(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * op_start_section_offset, Dwarf_Half * macro_operator, Dwarf_Half * forms_count, const Dwarf_Small ** formcode_array, Dwarf_Error * error);\fP .DE Use \f(CWdwarf_get_macro_op()\fP to access the macro operations of this macro unit. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P On success the function returns values through the pointers. .P If \f(CWmacro_operator\fP returned is zero that means this is a placeholder for the null byte at the end of this array of macros. The other pointer values returned are also zero in this case. .P The \f(CWop_start_section_offset\fP returned is useful for debugging but otherwise is not normally useful. It is the byte offset of the beginning of this macro operator's data. .P The \f(CWmacro_operator\fP returned is one of the defined macro operations such as \f(CWDW_MACRO_define\fP. This is the field you will use to choose what call to use to get the data for a macro operator. For example, for \f(CWDW_MACRO_undef\fP one would call \f(CWdwarf_get_macro_defundef()\fP (see below) to get the details about the undefine. .P The \f(CWforms_count\fP returned is useful for debugging but otherwise is not normally useful. It is the number of bytes of form numbers in the \f(CWformcode_array\fP of this macro operator's applicable forms. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_defundef()" .DS \f(CWint dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * index, Dwarf_Unsigned * offset, Dwarf_Half * forms_count, const char ** macro_string, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_defundef\fP for any of the macro define/undefine operators. Which fields are set through the pointers depends on the particular operator. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP). .P The \f(CWline_number\fP field is set with the source line number of the macro. .P The \f(CWindex\fP field only set meaningfully if the macro operator is \f(CWDW_MACRO_define_strx\fP or \f(CWDW_MACRO_undef_strx\fP. If set it is an index into an array of offsets in the .debug_str_offsets section. .P The \f(CWoffset\fP field only set meaningfully if the macro operator is \f(CWDW_MACRO_define_strx\fP, \f(CWDW_MACRO_undef_strx\fP \f(CWDW_MACRO_define_strp\fP, or \f(CWDW_MACRO_undef_strp\fP If set it is an offset of a string in the .debug_str section. .P The \f(CWforms_count\fP is set to the number of forms that apply to the macro operator. .P The \f(CWmacro_string\fP pointer is used to return a pointer to the macro string. If the actual string cannot be found (as when section with the string is in a different object, see \f(CWset_tied_dbg()\fP) the string returned may be "<:No string available>" or "<.debug_str_offsets not available>" (without the quotes). .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the define/undef operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_startend_file()" .DS \f(CWint dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * name_index_to_line_tab, const char ** src_file_name, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_startend_file\fP for operators \f(CWDW_MACRO_start_file\fP or \f(CWDW_MACRO_end_file\fP. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. .P The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P For \f(CWDW_MACRO_end_file\fP none of the following fields are set on successful return, they are only set for. \f(CWDW_MACRO_start_file\fP .P The \f(CWline_number\fP field is set with the source line number of the macro. .P .P The \f(CWname_index_to_line_tab\fP field is set with the index into the file name table of the line table section. For DWARF2, DWARF3, DWARF4 line tables the index value assumes DWARF2 line table header rules (identical to DWARF3, DWARF4 line table header rules). For DWARF5 the index value assumes DWARF5 line table header rules. The \f(CWsrc_file_name\fP is set with the source file name. If the index seems wrong or the line table is unavailable the name returned is ""); .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the start/end operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_import()" .DS \f(CWint dwarf_get_macro_import(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * target_offset, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_import\fP for operators \f(CWDW_MACRO_import\fP or \f(CWDW_MACRO_import_sup\fP. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P On success the \f(CWtarget_offset\fP field is set to the offset in the referenced section. For DW_MACRO_import the referenced section is the same section as the macro operation referenced here. For DW_MACRO_import_sup the referenced section is in a supplementary object. .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the import operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 2 "Macro Information Operations (DWARF2, DWARF3, DWARF4)" This section refers to DWARF2,DWARF3,and DWARF4 macro information from the .debug_macinfo section. These do not apply to DWARF5 macro data. .H 3 "General Macro Operations" .H 4 "dwarf_find_macro_value_start()" .DS \f(CWchar *dwarf_find_macro_value_start(char * macro_string);\fP .DE Given a macro string in the standard form defined in the DWARF document ("name value" or "name(args)value") this returns a pointer to the first byte of the macro value. It does not alter the string pointed to by macro_string or copy the string: it returns a pointer into the string whose address was passed in. .H 3 "Debugger Interface Macro Operations" Macro information is accessed from the .debug_info section via the DW_AT_macro_info attribute (whose value is an offset into .debug_macinfo). .P No Functions yet defined. .H 3 "Low Level Macro Information Operations" .H 4 "dwarf_get_macro_details()" .DS \f(CWint dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off macro_offset, Dwarf_Unsigned maximum_count, Dwarf_Signed * entry_count, Dwarf_Macro_Details ** details, Dwarf_Error * err);\fP .DE \f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWentry_count\fP to the number of \f(CWdetails\fP records returned through the \f(CWdetails\fP pointer. The data returned through \f(CWdetails\fP should be freed by a call to \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP. If \f(CWDW_DLV_OK\fP is returned, the \f(CWentry_count\fP will be at least 1, since a compilation unit with macro information but no macros will have at least one macro data byte of 0. .P \f(CWdwarf_get_macro_details()\fP begins at the \f(CWmacro_offset\fP offset you supply and ends at the end of a compilation unit or at \f(CWmaximum_count\fP detail records (whichever comes first). If \f(CWmaximum_count\fP is 0, it is treated as if it were the maximum possible unsigned integer. .P \f(CWdwarf_get_macro_details()\fP attempts to set \f(CWdmd_fileindex\fP to the correct file in every \f(CWdetails\fP record. If it is unable to do so (or whenever the current file index is unknown, it sets \f(CWdmd_fileindex\fP to -1. .P \f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no more macro information at that \f(CWmacro_offset\fP. If \f(CWmacro_offset\fP is passed in as 0, a \f(CWDW_DLV_NO_ENTRY\fP return means there is no macro information. .P .in +2 .FG "Examplep2 dwarf_get_macro_details()" .DS \f(CW void examplep2(Dwarf_Debug dbg, Dwarf_Off cur_off) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Macro_Details *maclist = 0; Dwarf_Signed i = 0; Dwarf_Unsigned max = 500000; /* sanity limit */ int errv = 0; /* Given an offset from a compilation unit, start at that offset (from DW_AT_macroinfo) and get its macro details. */ errv = dwarf_get_macro_details(dbg, cur_off,max, &count,&maclist,&error); if (errv == DW_DLV_OK) { for (i = 0; i < count; ++i) { Dwarf_Macro_Details * mentry = maclist +i; /* example of use */ Dwarf_Signed lineno = mentry->dmd_lineno; functionusingsigned(lineno); } dwarf_dealloc(dbg, maclist, DW_DLA_STRING); } /* Loop through all the compilation units macro info from zero. This is not guaranteed to work because DWARF does not guarantee every byte in the section is meaningful: there can be garbage between the macro info for CUs. But this loop will sometimes work. */ cur_off = 0; while((errv = dwarf_get_macro_details(dbg, cur_off,max, &count,&maclist,&error))== DW_DLV_OK) { for (i = 0; i < count; ++i) { Dwarf_Macro_Details * mentry = maclist +i; /* example of use */ Dwarf_Signed lineno = mentry->dmd_lineno; functionusingsigned(lineno); } cur_off = maclist[count-1].dmd_offset + 1; dwarf_dealloc(dbg, maclist, DW_DLA_STRING); } } \fP .DE .in -2 .H 2 "Low Level Frame Operations" These functions provide information about stack frames to be used to perform stack traces. The information is an abstraction of a table with a row per instruction and a column per register and a column for the canonical frame address (CFA, which corresponds to the notion of a frame pointer), as well as a column for the return address. .P From 1993-2006 the interface we'll here refer to as DWARF2 made the CFA be a column in the matrix, but left DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL out of the matrix (giving them high numbers). As of the DWARF3 interfaces introduced in this document in April 2006, there are *two* interfaces (the original set and a new set). Several frame functions work transparently for either set, we will focus on the ones that are not equally suitable now. .P The original DWARF2 interface set still exists (dwarf_get_fde_info_for_reg(), dwarf_get_fde_info_for_cfa_reg(), and dwarf_get_fde_info_for_all_regs()) and works adequately for MIPS/IRIX DWARF2 and ABI/ISA sets that are sufficiently similar to MIPS. These functions not a good choice for non-MIPS architectures nor were they a good design for MIPS either. It's better to switch entirely to the new functions mentioned in the next paragraph. This DWARF2 interface set assumes and uses DW_FRAME_CFA_COL and that is assumed when libdwarf is configured with --enable-oldframecol . .P A new DWARF3 interface set of dwarf_get_fde_info_for_reg3(), dwarf_get_fde_info_for_cfa_reg3(), dwarf_get_fde_info_for_all_regs3(), dwarf_set_frame_rule_table_size() dwarf_set_frame_cfa_value(), dwarf_set_frame_same_value(), dwarf_set_frame_undefined_value(), and dwarf_set_frame_rule_initial_value() is more flexible and will work for many more architectures. It is also entirely suitable for use with DWARF2 and DWARF4. The setting of the 'frame cfa column number' defaults to DW_FRAME_CFA_COL3 and it can be set at runtime with dwarf_set_frame_cfa_value(). .P Mixing use of the DWARF2 interface set with use of the new DWARF3 interface set on a single open Dwarf_Debug instance is a mistake. Do not do it. .P We will pretend, from here on unless otherwise specified, that DW_FRAME_CFA_COL3, DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL are the synthetic column numbers. These columns may be user-chosen by calls of dwarf_set_frame_cfa_value() dwarf_set_frame_undefined_value(), and dwarf_set_frame_same_value() respectively. .P Each cell in the table contains one of the following: .AL .LI A register + offset(a)(b) .LI A register(c)(d) .LI A marker (DW_FRAME_UNDEFINED_VAL) meaning \fIregister value undefined\fP .LI A marker (DW_FRAME_SAME_VAL) meaning \fIregister value same as in caller\fP .LE .P (a old DWARF2 interface) When the column is DW_FRAME_CFA_COL: the register number is a real hardware register, not a reference to DW_FRAME_CFA_COL, not DW_FRAME_UNDEFINED_VAL, and not DW_FRAME_SAME_VAL. The CFA rule value should be the stack pointer plus offset 0 when no other value makes sense. A value of DW_FRAME_SAME_VAL would be semi-logical, but since the CFA is not a real register, not really correct. A value of DW_FRAME_UNDEFINED_VAL would imply the CFA is undefined -- this seems to be a useless notion, as the CFA is a means to finding real registers, so those real registers should be marked DW_FRAME_UNDEFINED_VAL, and the CFA column content (whatever register it specifies) becomes unreferenced by anything. .P (a new April 2006 DWARF2/3 interface): The CFA is separately accessible and not part of the table. The 'rule number' for the CFA is a number outside the table. So the CFA is a marker, not a register number. See DW_FRAME_CFA_COL3 in libdwarf.h and dwarf_get_fde_info_for_cfa_reg3() and dwarf_set_frame_rule_cfa_value(). .P (b) When the column is not DW_FRAME_CFA_COL3, the 'register' will and must be DW_FRAME_CFA_COL3(COL), implying that to get the final location for the column one must add the offset here plus the DW_FRAME_CFA_COL3 rule value. .P (c) When the column is DW_FRAME_CFA_COL3, then the 'register' number is (must be) a real hardware register . (This paragraph does not apply to the April 2006 new interface). If it were DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL it would be a marker, not a register number. .P (d) When the column is not DW_FRAME_CFA_COL3, the register may be a hardware register. It will not be DW_FRAME_CFA_COL3. .P There is no 'column' for DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Nor for DW_FRAME_CFA_COL3. Figure \n(aX is machine dependent and represents MIPS CPU register assignments. The DW_FRAME_CFA_COL define in dwarf.h is historical and really belongs in libdwarf.h, not dwarf.h. .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_CFA_COL:0:column used for CFA DW_FRAME_REG1:1:integer register 1 DW_FRAME_REG2:2:integer register 2 ---::obvious names and values here DW_FRAME_REG30:30:integer register 30 DW_FRAME_REG31:31:integer register 31 DW_FRAME_FREG0:32:floating point register 0 DW_FRAME_FREG1:33:floating point register 1 ---::obvious names and values here DW_FRAME_FREG30:62:floating point register 30 DW_FRAME_FREG31:63:floating point register 31 DW_FRAME_RA_COL:64:column recording ra DW_FRAME_UNDEFINED_VAL:1034:register val undefined DW_FRAME_SAME_VAL:1035:register same as in caller .TE .FG "Frame Information Rule Assignments MIPS" .DE .P The following table shows SGI/MIPS specific special cell values: these values mean that the cell has the value \fIundefined\fP or \fIsame value\fP respectively, rather than containing a \fIregister\fP or \fIregister+offset\fP. It assumes DW_FRAME_CFA_COL is a table rule, which is not readily accomplished or even sensible for some architectures. .P .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_UNDEFINED_VAL:1034:means undefined value. ::Not a column or register value DW_FRAME_SAME_VAL:1035:means 'same value' as ::caller had. Not a column or ::register value DW_FRAME_CFA_COL:0:means register zero is ::usurped by the CFA column. :: .TE .FG "Frame Information Special Values any architecture" .DE .P The following table shows more general special cell values. These values mean that the cell register-number refers to the \fIcfa-register\fP or \fIundefined-value\fP or \fIsame-value\fP respectively, rather than referring to a \fIregister in the table\fP. The generality arises from making DW_FRAME_CFA_COL3 be outside the set of registers and making the cfa rule accessible from outside the rule-table. .P .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_UNDEFINED_VAL:1034:means undefined ::value. Not a column or register value DW_FRAME_SAME_VAL:1035:means 'same value' as ::caller had. Not a column or ::register value DW_FRAME_CFA_COL3:1436:means 'cfa register' ::is referred to, not a real register, not ::a column, but the cfa (the cfa does have ::a value, but in the DWARF3 libdwarf interface ::it does not have a 'real register number'). .TE .DE .P .H 3 "dwarf_get_frame_section_name()" .DS \f(CWint dwarf_get_frame_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_string_section_name()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_frame_section_name_eh_gnu()\fP. .P The function \f(CWdwarf_get_frame_section_name()\fP operates on the the .debug_frame section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_frame_section_name_eh_gnu()" .DS \f(CWint dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_frame_section_name_eh_gnu()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_frame_section_name()\fP. .P The function \f(CWdwarf_get_frame_section_name_eh_ghu()\fP operates on the the .eh_frame section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_fde_list()" .DS \f(CWint dwarf_get_fde_list( Dwarf_Debug dbg, Dwarf_Cie **cie_data, Dwarf_Signed *cie_element_count, Dwarf_Fde **fde_data, Dwarf_Signed *fde_element_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_list()\fP stores a pointer to a list of \f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the count of the number of descriptors in \f(CW*cie_element_count\fP. There is a descriptor for each CIE in the .debug_frame section. Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP descriptors in \f(CW*fde_data\fP, and the count of the number of descriptors in \f(CW*fde_element_count\fP. There is one descriptor per FDE in the .debug_frame section. \f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find frame entries. It returns \f(CWDW_DLV_OK\fP on a successful return. .P On successful return, structures pointed to by a descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP. This dealloc approach is new as of July 15, 2005. .in +2 .FG "Exampleq dwarf_get_fde_list()" .DS \f(CW void exampleq(Dwarf_Debug dbg) { Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; int fres = 0; fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, fde_data,fde_count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. .in +2 .FG "Exampleqb dwarf_get_fde_list() obsolete" .DS \f(CW /* OBSOLETE EXAMPLE */ void exampleqb(Dwarf_Debug dbg) { Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { for (i = 0; i < cie_count; ++i) { /* use cie[i] */ dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); } for (i = 0; i < fde_count; ++i) { /* use fde[i] */ dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); } dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_get_fde_list_eh()" .DS \f(CWint dwarf_get_fde_list_eh( Dwarf_Debug dbg, Dwarf_Cie **cie_data, Dwarf_Signed *cie_element_count, Dwarf_Fde **fde_data, Dwarf_Signed *fde_element_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_list_eh()\fP is identical to \f(CWdwarf_get_fde_list()\fP except that \f(CWdwarf_get_fde_list_eh()\fP reads the GNU gcc section named .eh_frame (C++ exception handling information). \f(CWdwarf_get_fde_list_eh()\fP stores a pointer to a list of \f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the count of the number of descriptors in \f(CW*cie_element_count\fP. There is a descriptor for each CIE in the .debug_frame section. Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP descriptors in \f(CW*fde_data\fP, and the count of the number of descriptors in \f(CW*fde_element_count\fP. There is one descriptor per FDE in the .debug_frame section. \f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find exception handling entries. It returns \f(CWDW_DLV_OK\fP on a successful return. .P On successful return, structures pointed to by a descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP. This dealloc approach is new as of July 15, 2005. .in +2 .FG "Exampler dwarf_get_fde_list_eh()" .DS \f(CW void exampler(Dwarf_Debug dbg,Dwarf_Addr mypcval) { /* Given a pc value for a function find the FDE and CIE data for the function. Example shows basic access to FDE/CIE plus one way to access details given a PC value. dwarf_get_fde_n() allows accessing all FDE/CIE data so one could build up an application-specific table of information if that is more useful. */ Dwarf_Signed count = 0; Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; int fres = 0; fres = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { Dwarf_Fde myfde = 0; Dwarf_Addr low_pc = 0; Dwarf_Addr high_pc = 0; fres = dwarf_get_fde_at_pc(fde_data,mypcval, &myfde,&low_pc,&high_pc, &error); if (fres == DW_DLV_OK) { Dwarf_Cie mycie = 0; fres = dwarf_get_cie_of_fde(myfde,&mycie,&error); if (fres == DW_DLV_OK) { /* Now we can access a range of information about the fde and cie applicable. */ } } dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, fde_data,fde_count); } /* ERROR or NO ENTRY. Do something */ } \fP .DE .in -2 .P .H 3 "dwarf_get_cie_of_fde()" .DS \f(CWint dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *cie_returned, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_cie_of_fde()\fP stores a \f(CWDwarf_Cie\fP into the \f(CWDwarf_Cie\fP that \f(CWcie_returned\fP points at. If one has called \f(CWdwarf_get_fde_list()\fP must avoid dwarf_dealloc-ing the FDEs and the CIEs for those FDEs individually (see its documentation here). Failing to observe this restriction will cause the FDE(s) not dealloc'd to become invalid: an FDE contains (hidden in it) a CIE pointer which will be be invalid (stale, pointing to freed memory) if the CIE is dealloc'd. The invalid CIE pointer internal to the FDE cannot be detected as invalid by libdwarf. If one later passes an FDE with a stale internal CIE pointer to one of the routines taking an FDE as input the result will be failure of the call (returning DW_DLV_ERROR) at best and it is possible a coredump or worse will happen (eventually). \f(CWdwarf_get_cie_of_fde()\fP returns \f(CWDW_DLV_OK\fP if it is successful (it will be unless fde is the NULL pointer). It returns \f(CWDW_DLV_ERROR\fP if the fde is invalid (NULL). .P Each \f(CWDwarf_Fde\fP descriptor describes information about the frame for a particular subroutine or function. \f(CWint dwarf_get_fde_for_die\fP is SGI/MIPS specific. .H 3 "dwarf_get_fde_for_die()" .DS \f(CWint dwarf_get_fde_for_die( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Fde * return_fde, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_get_fde_for_die()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_fde\fP to a \f(CWDwarf_Fde\fP descriptor representing frame information for the given \f(CWdie\fP. It looks for the \f(CWDW_AT_MIPS_fde\fP attribute in the given \f(CWdie\fP. If it finds it, is uses the value of the attribute as the offset in the .debug_frame section where the FDE begins. If there is no \f(CWDW_AT_MIPS_fde\fP it returns \f(CWDW_DLV_NO_ENTRY\fP. If there is an error it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_get_fde_range()" .DS \f(CWint dwarf_get_fde_range( Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_length, Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_length, Dwarf_Off *cie_offset, Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_OK\fP. The location pointed to by \f(CWlow_pc\fP is set to the low pc value for this function. The location pointed to by \f(CWfunc_length\fP is set to the length of the function in bytes. This is essentially the length of the text section for the function. The location pointed to by \f(CWfde_bytes\fP is set to the address where the FDE begins in the .debug_frame section. The location pointed to by \f(CWfde_byte_length\fP is set to the length in bytes of the portion of .debug_frame for this FDE. This is the same as the value returned by \f(CWdwarf_get_fde_range\fP. The location pointed to by \f(CWcie_offset\fP is set to the offset in the .debug_frame section of the CIE used by this FDE. The location pointed to by \f(CWcie_index\fP is set to the index of the CIE used by this FDE. The index is the index of the CIE in the list pointed to by \f(CWcie_data\fP as set by the function \f(CWdwarf_get_fde_list()\fP. However, if the function \f(CWdwarf_get_fde_for_die()\fP was used to obtain the given \f(CWfde\fP, this index may not be correct. The location pointed to by \f(CWfde_offset\fP is set to the offset of the start of this FDE in the .debug_frame section. \f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_cie_info()" .DS \f(CWint dwarf_get_cie_info( Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *code_alignment_factor, Dwarf_Signed *data_alignment_factor, Dwarf_Half *return_address_register_rule, Dwarf_Ptr *initial_instructions, Dwarf_Unsigned *initial_instructions_length, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_cie_info()\fP is primarily for Internal-level Interface consumers. If successful, it returns \f(CWDW_DLV_OK\fP and sets \f(CW*bytes_in_cie\fP to the number of bytes in the portion of the frames section for the CIE represented by the given \f(CWDwarf_Cie\fP descriptor, \f(CWcie\fP. The other fields are directly taken from the cie and returned, via the pointers to the caller. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_cie_index()" .DS \f(CWint dwarf_get_cie_index( Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_get_cie_index()\fP returns \f(CWDW_DLV_OK\fP. On error this function returns \f(CWDW_DLV_ERROR\fP. The location pointed to by \f(CWcie_index\fP is set to the index of the CIE of this FDE. The index is the index of the CIE in the list pointed to by \f(CWcie_data\fP as set by the function \f(CWdwarf_get_fde_list()\fP. So one must have used \f(CWdwarf_get_fde_list()\fP or \f(CWdwarf_get_fde_list_eh()\fP to get a cie list before this is meaningful. This function is occasionally useful, but is little used. .H 3 "dwarf_get_fde_instr_bytes()" .DS \f(CWint dwarf_get_fde_instr_bytes( Dwarf_Fde fde, Dwarf_Ptr *outinstrs, Dwarf_Unsigned *outlen, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_instr_bytes()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*outinstrs\fP to a pointer to a set of bytes which are the actual frame instructions for this fde. It also sets \f(CW*outlen\fP to the length, in bytes, of the frame instructions. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. The intent is to allow low-level consumers like a dwarf-dumper to print the bytes in some fashion. The memory pointed to by \f(CWoutinstrs\fP must not be changed and there is nothing to free. .H 3 "dwarf_get_fde_info_for_reg()" This interface is suitable for DWARF2 but is not sufficient for DWARF3. See \f(CWint dwarf_get_fde_info_for_reg3\fP. .DS \f(CWint dwarf_get_fde_info_for_reg( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_info_for_reg()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*offset_relevant\fP to non-zero if the offset is relevant for the row specified by \f(CWpc_requested\fP and column specified by \f(CWtable_column\fP, for the FDE specified by \f(CWfde\fP. The intent is to return the rule for the given pc value and register. The location pointed to by \f(CWregister_num\fP is set to the register value for the rule. The location pointed to by \f(CWoffset\fP is set to the offset value for the rule. If offset is not relevant for this rule, \f(CW*offset_relevant\fP is set to zero. Since more than one pc value will have rows with identical entries, the user may want to know the earliest pc value after which the rules for all the columns remained unchanged. Recall that in the virtual table that the frame information represents there may be one or more table rows with identical data (each such table row at a different pc value). Given a \f(CWpc_requested\fP which refers to a pc in such a group of identical rows, the location pointed to by \f(CWrow_pc\fP is set to the lowest pc value within the group of identical rows. The value put in \f(CW*register_num\fP any of the \f(CWDW_FRAME_*\fP table columns values specified in \f(CWlibdwarf.h\fP or \f(CWdwarf.h\fP. \f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. It is usable with either \f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. \f(CWdwarf_get_fde_info_for_reg()\fP is tailored to MIPS, please use \f(CWdwarf_get_fde_info_for_reg3()\fP instead for all architectures. .H 3 "dwarf_get_fde_info_for_all_regs()" .DS \f(CWint dwarf_get_fde_info_for_all_regs( Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_info_for_all_regs()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by \f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. .P The intent is to return the rules for decoding all the registers, given a pc value. \f(CWreg_table\fP is an array of rules, one for each register specified in \f(CWdwarf.h\fP. The rule for each register contains three items - \f(CWdw_regnum\fP which denotes the register value for that rule, \f(CWdw_offset\fP which denotes the offset value for that rule and \f(CWdw_offset_relevant\fP which is set to zero if offset is not relevant for that rule. See \f(CWdwarf_get_fde_info_for_reg()\fP for a description of \f(CWrow_pc\fP. .P \f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. .P \f(CWint dwarf_get_fde_info_for_all_regs\fP is tailored to SGI/MIPS, please use dwarf_get_fde_info_for_all_regs3() instead for all architectures. .H 3 "dwarf_fde_section_offset()" .DS \f(CWint dwarf_fde_section_offset( Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error *error);\fP .DE On success \f(CWdwarf_fde_section_offset()\fP returns the .dwarf_line section offset of the fde passed in and also the offset of its CIE. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It is intended to be used by applications like dwarfdump when such want to print the offsets of CIEs and FDEs. .H 3 "dwarf_cie_section_offset()" .DS \f(CWint dwarf_cie_section_offset( Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); Dwarf_Error *error);\fP .DE On success \f(CWdwarf_cie_section_offset()\fP returns the .dwarf_line section offset of the cie passed in. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It is intended to be used by applications like dwarfdump when such want to print the offsets of CIEs. .H 3 "dwarf_set_frame_rule_table_size()" .P This allows consumers to set the size of the (internal to libdwarf) rule table when using the 'reg3' interfaces (these interfaces are strongly preferred over the older 'reg' interfaces). It should be at least as large as the number of real registers in the ABI which is to be read in for the dwarf_get_fde_info_for_reg3() or dwarf_get_fde_info_for_all_regs3() functions to work properly. The frame rule table size must be less than the marker values DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL, DW_FRAME_CFA_COL3 (dwarf_set_frame_rule_undefined_value() dwarf_set_frame_same_value() dwarf_set_frame_cfa_value() effectively set these markers so the frame rule table size can actually be any value regardless of the macro values in libdwarf.h as long as the table size does not overlap these markers). .P .DS \f(CWDwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_table_size()\fP sets the value \f(CWvalue\fP as the size of libdwarf-internal rules tables of \f(CWdbg\fP. .P The function returns the previous value of the rules table size setting (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_rule_initial_value()" This allows consumers to set the initial value for rows in the frame tables. By default it is taken from libdwarf.h and is DW_FRAME_REG_INITIAL_VALUE (which itself is either DW_FRAME_SAME_VAL or DW_FRAME_UNDEFINED_VAL). The MIPS/IRIX default is DW_FRAME_SAME_VAL. Consumer code should set this appropriately and for many architectures (but probably not MIPS) DW_FRAME_UNDEFINED_VAL is an appropriate setting. Note: an earlier spelling of dwarf_set_frame_rule_inital_value() is still supported as an interface, but please change to use the new correctly spelled name. .DS \f(CWDwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_initial_value()\fP sets the value \f(CWvalue\fP as the initial value for this \f(CWdbg\fP when initializing rules tables. .P The function returns the previous value of initial value (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_cfa_value()" This allows consumers to set the number of the CFA register for rows in the frame tables. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_CFA_COL\fP. Consumer code should set this appropriately and for nearly all architectures \f(CWDW_FRAME_CFA_COL3\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_cfa_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_cfa_value()\fP sets the value \f(CWvalue\fP as the number of the cfa 'register rule' for this \f(CWdbg\fP when initializing rules tables. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_same_value()" This allows consumers to set the number of the pseudo-register when DW_CFA_same_value is the operation. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_SAME_VAL\fP. Consumer code should set this appropriately, though for many architectures \f(CWDW_FRAME_SAME_VAL\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_same_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_same_value()\fP sets the value \f(CWvalue\fP as the number of the register that is the pseudo-register set by the DW_CFA_same_value frame operation. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_undefined_value()" This allows consumers to set the number of the pseudo-register when DW_CFA_undefined_value is the operation. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_UNDEFINED_VAL\fP. Consumer code should set this appropriately, though for many architectures \f(CWDW_FRAME_UNDEFINED_VAL\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_undefined_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_undefined_value()\fP sets the value \f(CWvalue\fP as the number of the register that is the pseudo-register set by the DW_CFA_undefined_value frame operation. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_default_address_size()" This allows consumers to set a default address size. When one has an object where the default address_size does not match the frame address size where there is no debug_info available to get a frame-specific address-size, this function is useful. For example, if an Elf64 object has a .debug_frame whose real address_size is 4 (32 bits). This a very rare situation. .DS \f(CWDwarf_Small dwarf_set_default_address_size(Dwarf_Debug dbg, Dwarf_Small value);\fP .DE \f(CWdwarf_set_default_address_size()\fP sets the value \f(CWvalue\fP as the default address size for this activation of the reader, but only if \f(CWvalue\fP is greater than zero (otherwise the default address size is not changed). .P The function returns the previous value of the default address size (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_get_fde_info_for_reg3()" This interface is suitable for DWARF2 and later. It returns the values for a particular real register (Not for the CFA virtual register, see dwarf_get_fde_info_for_cfa_reg3() below). If the application is going to retrieve the value for more than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP (by calling this function multiple times) it is much more efficient to call dwarf_get_fde_info_for_all_regs3() (in spite of the additional setup that requires of the caller). .DS \f(CWint dwarf_get_fde_info_for_reg3( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE See also the nearly identical function \f(CWdwarf_get_fde_info_for_reg3_b()\fP. .P \f(CWdwarf_get_fde_info_for_reg3()\fP returns \f(CWDW_DLV_OK\fP on success. It sets \f(CW*value_type\fP to one of DW_EXPR_OFFSET (0), DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or DW_EXPR_VAL_EXPRESSION(3). On call, \f(CWtable_column\fP must be set to the register number of a real register. Not the cfa 'register' or DW_FRAME_SAME_VALUE or DW_FRAME_UNDEFINED_VALUE. if \f(CW*value_type\fP has the value DW_EXPR_OFFSET (0) then: .in +4 .P It sets \f(CW*offset_relevant\fP to non-zero if the offset is relevant for the row specified by \f(CWpc_requested\fP and column specified by \f(CWtable_column\fP or, for the FDE specified by \f(CWfde\fP. In this case the \f(CW*register_num\fP will be set to DW_FRAME_CFA_COL3 (. This is an offset(N) rule as specified in the DWARF3/2 documents. .P Adding the value of \f(CW*offset_or_block_len\fP to the value of the CFA register gives the address of a location holding the previous value of register \f(CWtable_column\fP. .P If offset is not relevant for this rule, \f(CW*offset_relevant\fP is set to zero. \f(CW*register_num\fP will be set to the number of the real register holding the value of the \f(CWtable_column\fP register. This is the register(R) rule as specified in DWARF3/2 documents. .P The intent is to return the rule for the given pc value and register. The location pointed to by \f(CWregister_num\fP is set to the register value for the rule. The location pointed to by \f(CWoffset\fP is set to the offset value for the rule. Since more than one pc value will have rows with identical entries, the user may want to know the earliest pc value after which the rules for all the columns remained unchanged. Recall that in the virtual table that the frame information represents there may be one or more table rows with identical data (each such table row at a different pc value). Given a \f(CWpc_requested\fP which refers to a pc in such a group of identical rows, the location pointed to by \f(CWrow_pc\fP is set to the lowest pc value within the group of identical rows. .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_VAL_OFFSET (1) then: .in +4 This will be a val_offset(N) rule as specified in the DWARF3/2 documents so \f(CW*offset_relevant\fP will be non zero. The calculation is identical to the DW_EXPR_OFFSET (0) calculation with \f(CW*offset_relevant\fP non-zero, but the value resulting is the actual \f(CWtable_column\fP value (rather than the address where the value may be found). .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_EXPRESSION (1) then: .in +4 \f(CW*offset_or_block_len\fP is set to the length in bytes of a block of memory with a DWARF expression in the block. \f(CW*block_ptr\fP is set to point at the block of memory. The consumer code should evaluate the block as a DWARF-expression. The result is the address where the previous value of the register may be found. This is a DWARF3/2 expression(E) rule. .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_VAL_EXPRESSION (1) then: .in +4 The calculation is exactly as for DW_EXPR_EXPRESSION (1) but the result of the DWARF-expression evaluation is the value of the \f(CWtable_column\fP (not the address of the value). This is a DWARF3/2 val_expression(E) rule. .in -4 \f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error and if there is an error only the \f(CWerror\fP pointer is set, none of the other output arguments are touched. It is usable with either \f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. .H 3 "dwarf_get_fde_info_for_reg3_b()" This interface is suitable for DWARF2 and later. It returns the values for a particular real register (Not for the CFA virtual register, see dwarf_get_fde_info_for_cfa_reg3_b() below). If the application is going to retrieve the value for more than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP (by calling this function multiple times) it is much more efficient to call dwarf_get_fde_info_for_all_regs3() (in spite of the additional setup that requires of the caller). .DS \f(CWint dwarf_get_fde_info_for_reg3_b( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Bool *has_more_rows, Dwarf_Addr *subsequent_pc, Dwarf_Error *error);\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_reg3()\fP except for the new arguments \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP which allow the caller to know if there are more rows in the frame table and what the next pc value in the frame table for this fde is. The two new arguments may be passed in as NULL if their values are not needed by the caller. .H 3 "dwarf_get_fde_info_for_cfa_reg3()" .DS \f(CWint dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed* offset_relevant, Dwarf_Signed* register_num, Dwarf_Signed* offset_or_block_len, Dwarf_Ptr * block_ptr , Dwarf_Addr * row_pc_out, Dwarf_Error * error)\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_reg3()\fP except the returned values are for the CFA rule. So register number \f(CW*register_num\fP will be set to a real register, not one of the pseudo registers (which are usually DW_FRAME_CFA_COL3, DW_FRAME_SAME_VALUE, or DW_FRAME_UNDEFINED_VALUE). .P Applications like dwarfdump which access the register rules for every pc value in a function may find the following function a slight performance improvement if the new arguments are used appropriately. See \f(CWdwarfdump\fP for an example of use. .H 3 "dwarf_get_fde_info_for_cfa_reg3_b()" .DS \f(CWint dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed* offset_relevant, Dwarf_Signed* register_num, Dwarf_Signed* offset_or_block_len, Dwarf_Ptr * block_ptr , Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error)\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP except for the new arguments \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP which allow the caller to know if there are more rows in the frame table and what the next pc value is. The two new arguments may be passed in as NULL if their values are not needed by the caller. .P For a tool just wanting the frame information for a single pc_value this interface is no more useful or efficient than \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP. .P The essential difference is that when using \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP for all pc values for a function the caller has no idea what is the next pc value that might have new frame data and iterating through pc values (calling \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP on each) is a waste of cpu cycles. With \f(CWdwarf_get_fde_info_for_cfa_reg3_b()\fP the \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP arguments let the caller know whether there are further rows and if so at what pc value. .P If \f(CWhas_more_rows\fP is non-null then 1 is returned through the pointer if, for the \f(CWpc_requested\fP there is frame data for addresses after \f(CWpc_requested\fP in the frame. And if there are no more rows in the frame data then 0 is set through the \f(CWhas_more_rows\fP pointer. .P If \f(CWsubsequent_pc\fP is non-null then the pc-value which has the next frame operator is returned through the pointer. If no more rows are present zero is returned through the pointer, but please use \f(CWhas_more_rows\fP to determine if there are more rows. .H 3 "dwarf_get_fde_info_for_all_regs3()" .DS \f(CWint dwarf_get_fde_info_for_all_regs3( Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_fde_info_for_all_regs3()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by \f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. The intent is to return the rules for decoding all the registers, given a pc value. \f(CWreg_table\fP is an array of rules, the array size specified by the caller. plus a rule for the CFA. The rule for the cfa returned in \f(CW*reg_table\fP defines the CFA value at \f(CWpc_requested\fP The rule for each register contains several values that enable the consumer to determine the previous value of the register (see the earlier documentation of Dwarf_Regtable3). \f(CWdwarf_get_fde_info_for_reg3()\fP and the Dwarf_Regtable3 documentation above for a description of the values for each row. \f(CWdwarf_get_fde_info_for_all_regs3\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. It is up to the caller to allocate space for \f(CW*reg_table\fP and initialize it properly. .H 3 "dwarf_get_fde_n()" .DS \f(CWint dwarf_get_fde_n( Dwarf_Fde *fde_data, Dwarf_Unsigned fde_index, Dwarf_Fde *returned_fde Dwarf_Error *error)\fP .DE \f(CWdwarf_get_fde_n()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to the \f(CWDwarf_Fde\fP descriptor whose index is \f(CWfde_index\fP in the table of \f(CWDwarf_Fde\fP descriptors pointed to by \fPfde_data\fP. The index starts with 0. The table pointed to by fde_data is required to contain at least one entry. If the table has no entries at all the error checks may refer to uninitialized memory. Returns \f(CWDW_DLV_NO_ENTRY\fP if the index does not exist in the table of \f(CWDwarf_Fde\fP descriptors. Returns \f(CWDW_DLV_ERROR\fP if there is an error. This function cannot be used unless the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to \f(CWdwarf_get_fde_list()\fP. .H 3 "dwarf_get_fde_at_pc()" .DS \f(CWint dwarf_get_fde_at_pc( Dwarf_Fde *fde_data, Dwarf_Addr pc_of_interest, Dwarf_Fde *returned_fde, Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_fde_at_pc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to a \f(CWDwarf_Fde\fP descriptor for a function which contains the pc value specified by \f(CWpc_of_interest\fP. In addition, it sets the locations pointed to by \f(CWlopc\fP and \f(CWhipc\fP to the low address and the high address covered by this FDE, respectively. The table pointed to by fde_data is required to contain at least one entry. If the table has no entries at all the error checks may refer to uninitialized memory. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWpc_of_interest\fP is not in any of the FDEs represented by the block of \f(CWDwarf_Fde\fP descriptors pointed to by \f(CWfde_data\fP. This function cannot be used unless the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to \f(CWdwarf_get_fde_list()\fP. .H 3 "dwarf_expand_frame_instructions()" .DS \f(CWint dwarf_expand_frame_instructions( Dwarf_Cie cie, Dwarf_Ptr instruction, Dwarf_Unsigned i_length, Dwarf_Frame_Op **returned_op_list, Dwarf_Signed * returned_op_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_expand_frame_instructions()\fP is a High-level interface function which expands a frame instruction byte stream into an array of \f(CWDwarf_Frame_Op\fP structures. To indicate success, it returns \f(CWDW_DLV_OK\fP. The address where the byte stream begins is specified by \f(CWinstruction\fP, and the length of the byte stream is specified by \f(CWi_length\fP. The location pointed to by \f(CWreturned_op_list\fP is set to point to a table of \f(CWreturned_op_count\fP pointers to \f(CWDwarf_Frame_Op\fP which contain the frame instructions in the byte stream. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. After a successful return, the array of structures should be freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FRAME_BLOCK\fP (when they are no longer of interest). .P Not all CIEs have the same address-size, so it is crucial that a CIE pointer to the frame's CIE be passed in. .in +2 .FG "Examples dwarf_expand_frame_instructions()" .DS \f(CW void examples(Dwarf_Debug dbg,Dwarf_Cie cie, Dwarf_Ptr instruction,Dwarf_Unsigned len) { Dwarf_Signed count = 0; Dwarf_Frame_Op *frameops = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_expand_frame_instructions(cie,instruction,len, &frameops,&count, &error); if (res == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < count; ++i) { /* use frameops[i] */ } dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK); } } \fP .DE .in -2 .H 3 "dwarf_get_fde_exception_info()" .DS \f(CWint dwarf_get_fde_exception_info( Dwarf_Fde fde, Dwarf_Signed * offset_into_exception_tables, Dwarf_Error * error); .DE \f(CWdwarf_get_fde_exception_info()\fP is an IRIX specific function which returns an exception table signed offset through \f(CWoffset_into_exception_tables\fP. The function never returns \f(CWDW_DLV_NO_ENTRY\fP. If \f(CWDW_DLV_NO_ENTRY\fP is NULL the function returns \f(CWDW_DLV_ERROR\fP. For non-IRIX objects the offset returned will always be zero. For non-C++ objects the offset returned will always be zero. The meaning of the offset and the content of the tables is not defined in this document. The applicable CIE augmentation string (see above) determines whether the value returned has meaning. .H 2 "Location Expression Evaluation" An "interpreter" which evaluates a location expression is required in any debugger. There is no interface defined here at this time. .P One problem with defining an interface is that operations are machine dependent: they depend on the interpretation of register numbers and the methods of getting values from the environment the expression is applied to. .P It would be desirable to specify an interface. .H 3 "Location List Internal-level Interface" .H 4 "dwarf_get_loclist_entry()" .DS \f(CWint dwarf_get_loclist_entry( Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr *hipc_offset, Dwarf_Addr *lopc_offset, Dwarf_Ptr *data, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error)\fP .DE This function is ill suited to use with 21st century DWARF as there is just not enough data provided in the interface. Do not use this interface. Use \f(CWdwarf_get_locdesc_entry_c()\fP instead. .P The function reads a location list entry starting at \f(CWoffset\fP and returns through pointers (when successful) the high pc \f(CWhipc_offset\fP, low pc \f(CWlopc_offset\fP, a pointer to the location description data \f(CWdata\fP, the length of the location description data \f(CWentry_len\fP, and the offset of the next location description entry \f(CWnext_entry\fP. .P This function will often work correctly (meaning with most objects compiled for DWARF3 or DWARF3) but will not work correctly (and can crash an application calling it) if either some location list applies to a compilation unit with an address_size different from the overall address_size of the object file being read or if the .debug_loc section being read has random padding bytes between loclists. Neither of these characteristics necessarily represents a bug in the compiler/linker toolset that produced the object file being read. The DWARF standard allows both characteristics. .P \f(CWdwarf_dwarf_get_loclist_entry()\fP returns \f(CWDW_DLV_OK\fP if successful. \f(CWDW_DLV_NO_ENTRY\fP is returned when the offset passed in is beyond the end of the .debug_loc section (expected if you start at offset zero and proceed through all the entries). \f(CWDW_DLV_ERROR\fP is returned on error. .P The \f(CWhipc_offset\fP, low pc \f(CWlopc_offset\fP are offsets from the beginning of the current procedure, not genuine pc values. .P The example of use has been deleted. Do not use this function. .H 2 "Abbreviations access" These are Internal-level Interface functions. Debuggers can ignore this. .H 3 "dwarf_get_abbrev()" .DS \f(CWint dwarf_get_abbrev( Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Abbrev *returned_abbrev, Dwarf_Unsigned *length, Dwarf_Unsigned *attr_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_abbrev\fP to \f(CWDwarf_Abbrev\fP, a descriptor for the abbreviation that begins at offset \f(CW*offset\fP in the abbreviations section (i.e .debug_abbrev) on success. The user is responsible for making sure that a valid abbreviation begins at \f(CWoffset\fP in the abbreviations section. The location pointed to by \f(CWlength\fP is set to the length in bytes of the abbreviation set in the abbreviations section. The location pointed to by \f(CWattr_count\fP is set to the number of attributes in the abbreviation. An abbreviation entry with a length of 1 is the 0 byte of the last abbreviation entry of a compilation unit. .P \f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_abbrev section is missing or if the offset passed in is past the end of the section. .P \f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_ERROR\fP on error. If the call succeeds, the storage pointed to by \f(CW*returned_abbrev\fP should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. .H 3 "dwarf_get_abbrev_tag()" .DS \f(CWint dwarf_get_abbrev_tag( Dwarf_Abbrev abbrev, Dwarf_Half *return_tag, Dwarf_Error *error);\fP .DE If successful, \f(CWdwarf_get_abbrev_tag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_tag\fP to the \fItag\fP of the given abbreviation. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_get_abbrev_code()" .DS \f(CWint dwarf_get_abbrev_code( Dwarf_Abbrev abbrev, Dwarf_Unsigned *return_code, Dwarf_Error *error);\fP .DE If successful, \f(CWdwarf_get_abbrev_code()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_code\fP to the abbreviation code of the given abbreviation. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_get_abbrev_children_flag()" .DS \f(CWint dwarf_get_abbrev_children_flag( Dwarf_Abbrev abbrev, Dwarf_Signed *returned_flag, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_abbrev_children_flag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_flag\fP to \f(CWDW_children_no\fP (if the given abbreviation indicates that a die with that abbreviation has no children) or \f(CWDW_children_yes\fP (if the given abbreviation indicates that a die with that abbreviation has a child). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_abbrev_entry_b()" .DS \f(CWint dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned index, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implicit_const, Dwarf_Off * offset, Dwarf_Error * error)\fP .DE \f(CWdwarf_get_abbrev_entry_b()\fP is new in August 2019. It should be used in place of \f(CWdwarf_get_abbrev_entry()\fP as \f(CWdwarf_get_abbrev_entry()\fP cannot return the DWARF5 implicit const value and and \f(CWdwarf_get_abbrev_entry()\fP can hide some instances of corrupt uleb abbreviation values. .P While the \f(CWreturned_attr_num\fP and and \f(CWreturned_form\fP are only correct if they each fit in a \f(CWDwarf_Half\fP value, we return larger values in certain cases (see next paragraph). .P If \f(CWfilter_outliers\fP is passed in zero then erroneous \f(CWreturned_attr_num\fP or and \f(CWreturned_form\fP are returned whether their values are sensible or not and \f(CWDW_DLV_OK\fP is the returned value. This is useful for dwarfdump as dwarfdump checks abbreviation values quite thoroughly and reports errors in detail (dwarfdump -kb). .P If \f(CWfilter_outliers\fP is passed in non-zero then \f(CWDW_DLV_OK\fP is returned only if \f(CWreturned_attr_num\fP and and \f(CWreturned_form\fP are both legitimate values. .P If successful, \f(CWdwarf_get_abbrev_entry_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of the attribute whose index is specified by \f(CWindex\fP in the given abbreviation. .P The index starts at 0. .P The location pointed to by \f(CWreturned_attr_num\fP is set to the attribute number (example: \f(CWDW_AT_name\fP). The location pointed to by \f(CWreturned_form\fP is set to the form of the attribute (example: \f(CWDW_FORM_string\fP). The location pointed to by \f(CWreturned_implicit_const\fP is set to the implicit const value if and only if the FORM returned is \f(CWDW_FORM_implicit_const\fP The location pointed to by \f(CWoffset\fP is set to the byte offset of the attribute in the abbreviations section. .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside the range of attributes in this abbreviation. .P The function returns \f(CWDW_DLV_ERROR\fP on error and sets \f(CW*error\fP to an error value instance. .H 3 "dwarf_get_abbrev_entry()" .DS \f(CWint dwarf_get_abbrev_entry( Dwarf_Abbrev abbrev, Dwarf_Signed index, Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, Dwarf_Error *error)\fP .DE .P This function cannot return DW_FORM_implicit_const const values. When convenient all callers should switch to using the \f(CWdwarf_get_abbrev_entry_b()\fP function. .P If successful, \f(CWdwarf_get_abbrev_entry()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of the attribute whose index is specified by \f(CWindex\fP in the given abbreviation. The index starts at 0. The location pointed to by \f(CWform\fP is set to the form of the attribute. The location pointed to by \f(CWoffset\fP is set to the byte offset of the attribute in the abbreviations section. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside the range of attributes in this abbreviation. .P It returns \f(CWDW_DLV_ERROR\fP on error. .H 2 "String Section Operations" The .debug_str section contains only strings. Debuggers need never use this interface: it is only for debugging problems with the string section itself. .H 3 "dwarf_get_string_section_name()" .DS \f(CWint dwarf_get_string_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_string_section_name()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name_b()\fP. .P The function \f(CWdwarf_get_string_section_name()\fP operates on the the .debug_string[.dwo] section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_str()" .DS \f(CWint dwarf_get_str( Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed *returned_str_len, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_str()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_str_len\fP to the length of the string, not counting the null terminator, that begins at the offset specified by \f(CWoffset\fP in the .debug_str section. The location pointed to by \f(CWstring\fP is set to a pointer to this string. The next string in the .debug_str section begins at the previous \f(CWoffset\fP + 1 + \f(CW*returned_str_len\fP. A zero-length string is NOT the end of the section. If there is no .debug_str section, \f(CWDW_DLV_NO_ENTRY\fP is returned. If there is an error, \f(CWDW_DLV_ERROR\fP is returned. If we are at the end of the section (that is, \f(CWoffset\fP is one past the end of the section) \f(CWDW_DLV_NO_ENTRY\fP is returned. If the \f(CWoffset\fP is some other too-large value then \f(CWDW_DLV_ERROR\fP is returned. .H 2 "String Offsets Section Operations" The .debug_str_offsets section contains only table arrays (with headers) and Debuggers should never need to use this interface. The normal string access functions use the section tables transparently. The functions here are only intended to allow dwarfdump (or the like) print the section completely and to help compiler developers look for bugs in the section. .in +2 .FG "examplestringoffsets dwarf_open_str_offsets_table_access() etc" .DS \f(CW void examplestringoffsets(Dwarf_Debug dbg) { int res = 0; Dwarf_Str_Offsets_Table sot = 0; Dwarf_Unsigned wasted_byte_count = 0; Dwarf_Unsigned table_count = 0; Dwarf_Error error = 0; res = dwarf_open_str_offsets_table_access(dbg, &sot,&error); if(res == DW_DLV_NO_ENTRY) { /* No such table */ return; } if(res == DW_DLV_ERROR) { /* Something is very wrong. Print the error? */ return; } for(;;) { Dwarf_Unsigned unit_length =0; Dwarf_Unsigned unit_length_offset =0; Dwarf_Unsigned table_start_offset =0; Dwarf_Half entry_size = 0; Dwarf_Half version =0; Dwarf_Half padding =0; Dwarf_Unsigned table_value_count =0; Dwarf_Unsigned i = 0; Dwarf_Unsigned table_entry_value = 0; res = dwarf_next_str_offsets_table(sot, &unit_length, &unit_length_offset, &table_start_offset, &entry_size,&version,&padding, &table_value_count,&error); if (res == DW_DLV_NO_ENTRY) { /* We have dealt with all tables */ break; } if (res == DW_DLV_ERROR) { /* Something badly wrong. Do something. */ return; } /* One could call dwarf_str_offsets_statistics to get the wasted bytes so far, but we do not do that in this example. */ /* Possibly print the various table-related values returned just above. */ for (i=0; i < table_value_count; ++i) { res = dwarf_str_offsets_value_by_index(sot,i, &table_entry_value,&error); if (res != DW_DLV_OK) { /* Something is badly wrong. Do something. */ return; } /* Do something with the table_entry_value at this index. Maybe just print it. It is an offset in .debug_str. */ } } res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,&error); if (res == DW_DLV_OK) { /* The wasted byte count is set. Print it or something. One hopes zero bytes are wasted. Print the table count if one is interested. */ } res = dwarf_close_str_offsets_table_access(sot,&error); /* There is little point in checking the return value as little can be done about any error. */ sot = 0; } \fP .DE .in -2 .H 3 "dwarf_open_str_offsets_table_access()" .DS \f(CWint dwarf_open_str_offsets_table_access( Dwarf_Debug dbg, Dwarf_Str_Offsets_Table * table_data, Dwarf_Error * error);\fP .DE \f(CWdwarf_open_str_offsets_table_access()\fP creates an opaque struct and returns a pointer to it on success. That struct pointer is used in all subsequent operations on the table. Through the function \f(CWdwarf_next_str_offsets_table()\fP the caller can iterate through each of the per-CU offset tables. .P If there is no such section, or if the section is empty the function returns DW_DLV_NO_ENTRY. .P If there is an error (such as out-of-memory) the function returns DW_DLV_ERROR and sets an error value through the \f(CWerror\fP pointer. .H 3 "dwarf_close_str_offsets_table_access()" .DS \f(CWint dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table table_data, Dwarf_Error * error);\fP .DE On success, \f(CWdwarf_close_str_offsets_table_access()\fP frees any allocated data associated with the struct pointed to by \f(CWtable_data\fP and returns DW_DLV_OK. It is up to the caller to set the \f(CWtable_data\fP pointer to NULL if desired. The pointer is unusable at that point and any other calls to libdwarf using that pointer will fail. .P It returns DW_DLV_OK on error. Any error suggests there is memory corruption or an error in the call. Something serious happened. .P It never returns DW_DLV_NO_ENTRY, but if it did there would be nothing the caller could do anyway.. .P If one forgets to call this function the memory allocated will be freed automatically by to call to \f(CWdwarf_finish()\fP, as is true of all other data allocated by libdwarf. .H 3 "dwarf_next_str_offsets_table()" .DS \f(CWint dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table table, Dwarf_Unsigned *unit_length_out, Dwarf_Unsigned *unit_length_offset_out, Dwarf_Unsigned *table_start_offset_out, Dwarf_Half *entry_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned *table_value_count_out, Dwarf_Error * error);\fP .DE Each call to \f(CWdwarf_next_str_offsets_table()\fP returns the next String Offsets table in the .debug_str_offsets section. Typically there would be one such table for each CU in .debug_info[.dwo] contributing to .debug_str_offsets. The \f(CWtable\fP contains (internally, hidden) the section offset of the next table. .P On success it returns DW_DLV_OK and sets various fields representing data about the current table (fields described below). .P If there are no more tables it returns DW_DLV_NO_ENTRY. .P On error it returns DW_DLV_ERROR and passes back error details through the \f(CWerror\fP pointer. .P The returned values are intended to let the caller understand the table header and the table in detail. These pointers are only used if the call returned DW_DLV_OK. .P \f(CWunit_length_out\fP is set to the unit_length of a String Offsets Table Header. Which means it gives the length, in bytes, of the data following the length value that belongs to this table. .P \f(CWunit_length_offset_out\fP is set to the section offset of the table header. .P \f(CWtable_start_offset_out\fP is set to the section offset of the array of offsets in this table. .P \f(CWentry_size_out\fP is set to the size of a table entry. Which is 4 for 32-bit offsets in this table and 8 for 64-bit offsets in this table. .P \f(CWversion_out\fP is set to the version number in the table header. The only current valid value is 5. .P \f(CWpadding_out\fP is set to the 16-bit padding value in the table header. In a correct table header the value is zero. .P \f(CWtable_value_count_out\fP is set to the number of entries in the array of offsets in this table. Each entry is \f(CWentry_size_out\fP bytes long. Use this value in calling \f(CWdwarf_str_offsets_value_by_index()\fP. .H 3 "dwarf_str_offsets_value_by_index()" .DS \f(CWint dwarf_str_offsets_value_by_index( Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned index, Dwarf_Unsigned *stroffset, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_str_offsets_value_by_index()\fP returns DW_DLV_OK and sets the offset from the array of string offsets in the current table at the input \f(CWindex\fP. .P Valid index values are zero through \f(CWtable_value_count_out - 1\fP .P A function is used instead of simply letting callers use pointers as libdwarf correctly handles endianness differences (between the system running libdwarf and the object file being inspected) so offsets can be reported properly. .P DW_DLV_ERROR is returned on error. .P DW_DLV_NO_ENTRY is never returned. .H 3 "dwarf_str_offsets_statistics()" .DS \f(CWint dwarf_str_offsets_statistics( Dwarf_Str_Offsets_Table table_data, Dwarf_Unsigned * wasted_byte_count, Dwarf_Unsigned * table_count, Dwarf_Error * error);\fP .DE Normally called after all tables have been inspected to return (through a pointer) the count of apparently-wasted bytes in the section. It can be called at any point that the \f(CWDwarf_Str_Offsets_Table\fP pointer is valid. .P On error it returns DW_DLV_ERROR and sets an error value through the pointer. .P DW_DLV_NO_ENTRY is never returned. .P On success it returns DW_DLV_OK and sets values through the two pointers. Calling just after each table is accessed by \f(CWdwarf_next_str_offsets_table()\fP will reveal the sum of all wasted bytes at that point in iterating through the section. .P \f(CWtable_count\fP is the count of table headers encountered so far. .P By wasted bytes we mean bytes in between tables. libdwarf has no idea whether any apparently-valid table data is in fact useless. .H 2 "Address Range Operations" These functions provide information about address ranges. The content is in the \f(CW.debug_aranges\fP section. Address ranges map ranges of pc values to the corresponding compilation-unit die that covers the address range. In the DWARF2,3,4 Standards this is described under "Accelerated Access" "Lookup by Address". .H 3 "dwarf_get_aranges_section_name()" .DS \f(CWint dwarf_get_aranges_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_aranges_section_name()\fP retrieves the object file section name of the applicable aranges section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_aranges()" .DS \f(CWint dwarf_get_aranges( Dwarf_Debug dbg, Dwarf_Arange **aranges, Dwarf_Signed * returned_arange_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_aranges()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange_count\fP to the count of the number of address ranges in the .debug_aranges section (for all compilation units). It sets \f(CW*aranges\fP to point to a block of \f(CWDwarf_Arange\fP descriptors, one for each address range. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges section. .P This not only reads all the ranges, it also reads the per-compilation-unit headers in .debug_aranges and verifies they make sense. .in +2 .FG "Exampleu dwarf_get_aranges()" .DS \f(CW void exampleu(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Arange *arang = 0; int res = 0; Dwarf_Error error = 0; res = dwarf_get_aranges(dbg, &arang,&count, &error); if (res == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < count; ++i) { /* use arang[i] */ dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE); } dwarf_dealloc(dbg, arang, DW_DLA_LIST); } } \fP .DE .in -2 .H 3 "dwarf_get_arange()" .DS \f(CWint dwarf_get_arange( Dwarf_Arange *aranges, Dwarf_Unsigned arange_count, Dwarf_Addr address, Dwarf_Arange *returned_arange, Dwarf_Error *error);\fP .DE The function \f(CWdwarf_get_arange()\fP takes as input a pointer to a block of \f(CWDwarf_Arange\fP pointers, and a count of the number of descriptors in the block. It then searches for the descriptor that covers the given \f(CWaddress\fP. If it finds one, it returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange\fP to the descriptor. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges entry covering that address. .P .H 3 "dwarf_get_cu_die_offset()" .DS \f(CWint dwarf_get_cu_die_offset( Dwarf_Arange arange, Dwarf_Off *returned_cu_die_offset, Dwarf_Error *error);\fP .DE The function \f(CWdwarf_get_cu_die_offset()\fP takes a \f(CWDwarf_Arange\fP descriptor as input, and if successful returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_die_offset\fP to the offset in the .debug_info section of the compilation-unit DIE for the compilation-unit represented by the given address range. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_arange_cu_header_offset()" .DS \f(CWint dwarf_get_arange_cu_header_offset( Dwarf_Arange arange, Dwarf_Off *returned_cu_header_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_arange_cu_header_offset()\fP takes a \f(CWDwarf_Arange\fP descriptor as input, and if successful returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_header_offset\fP to the offset in the .debug_info section of the compilation-unit header for the compilation-unit represented by the given address range. It returns \f(CWDW_DLV_ERROR\fP on error. This function added Rev 1.45, June, 2001. This function is declared as 'optional' in libdwarf.h on IRIX systems so the _MIPS_SYMBOL_PRESENT predicate may be used at run time to determine if the version of libdwarf linked into an application has this function. .H 3 "dwarf_get_arange_info_b()" .DS \f(CWint dwarf_get_arange_info_b( Dwarf_Arange arange, Dwarf_Unsigned *segment, Dwarf_Unsigned *segment_entry_size; Dwarf_Addr *start, Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_arange_info_b()\fP returns \f(CWDW_DLV_OK\fP and returns detailed information on the address range through the pointers. .P \f(CWsegment\fP is the segment number for segmented addresss spaces and it is only meaningful if \f(CWsegment_entry_size\fP is non-zero. .P It puts the starting value of the address range in the location pointed to by \f(CWstart\fP, and the length of the address range in the location pointed to by \f(CWlength\fP. .P It sets the \f(CWcu_die_offset\fP. in the \f(CW.debug_info\fP, section of the compilation-unit DIE for the compilation-unit represented by the address range. .P It returns \f(CWDW_DLV_ERROR\fP on error. and sets \f(CWerror\fP, .H 3 "dwarf_get_arange_info()" .DS \f(CWint dwarf_get_arange_info( Dwarf_Arange arange, Dwarf_Addr *start, Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE This is the same as \f(CWdwarf_get_arange_info_b()\fP except that this earlier function does not have a way to return the segment information. .H 2 "General Low Level Operations" This function is low-level and intended for use only by programs such as dwarf-dumpers. .H 3 "dwarf_get_offset_size()" .DS \f(CWint dwarf_get_offset_size(Dwarf_Debug dbg, Dwarf_Half *offset_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_offset_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*offset_size\fP to the size in bytes of an offset. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*offset_size\fP. The offset size returned is the overall address size, which can be misleading if different compilation units have different address sizes. Many ABIs have only a single address size per executable, but differing address sizes are becoming more common. .H 3 "dwarf_get_address_size()" .DS \f(CWint dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_address_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*addr_size\fP to the size in bytes of an address. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*addr_size\fP. The address size returned is the overall address size, which can be misleading if different compilation units have different address sizes. Many ABIs have only a single address size per executable, but differing address sizes are becoming more common. Use \f(CWdwarf_get_die_address_size()\fP instead whenever possible. .H 3 "dwarf_get_die_address_size()" .DS \f(CWint dwarf_get_die_address_size(Dwarf_Die die, Dwarf_Half *addr_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_die_address_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*addr_size\fP to the size in bytes of an address. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*addr_size\fP. The address size returned is the address size of the compilation unit owning the \f(CWdie\fP This is the preferred way to get address size when the \f(CWDwarf_Die\fP is known. .H 3 "dwarf_decode_leb128()" See the DWARF5 standard Section 7.6 for a general description of LEB encoded values. .DS \f(CWint dwarf_decode_leb128(char* leb, Dwarf_Unsigned* leblen, Dwarf_Unsigned* outval, char* endptr)\fP .DE In December 2020 this makes library decoding visible to library users for the first time. .P The user should pass in \f(CWleb\fP with a pointer to the initial byte of the leb number. and pass in \f(CWendptr\fP with a pointer at least one-past the content of the leb value. Typically \f(CWendptr\fP points at an end of section (if reading object sections) or some other value representing the end of memory the function should be allowed to read. .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CWleblen\fP (if \f(CWleblen\fP passed in non-null) to the number of bytes read in decoding. It sets \f(CWoutval\fP to the unsigned value decoded. .P If the function detects it has read to the \f(CWendptr\fP it returns \f(CWDW_DLV_ERROR\fP. .P If the function reads too many bytes without reaching a terminator or \f(CWendptr\fP it returns \f(CWDW_DLV_ERROR\fP on the assumption that nobody would intentionally produce wastefully long LEB data, so something is wrong. .P Only the argument \f(CWleblen\fP may be passed in as NULL, the others must be valid non-null values. .P There is no way for the library to determine whether the value is signed or unsigned. The caller must know and call the the correct function. .H 3 "dwarf_decode_signed_leb128()" See the DWARF5 standard Section 7.6 for a general description of LEB encoded values. .DS \f(CWint dwarf_decode_signed_leb128(char* leb, Dwarf_Unsigned* leblen, Dwarf_Signed* outval, char* endptr)\fP .DE In December 2020 this makes library decoding visible to library users for the first time. .P The user should pass in \f(CWleb\fP with a pointer to the initial byte of the leb number. and pass in \f(CWendptr\fP with a pointer at least one-past the content of the leb value. Typically \f(CWendptr\fP points at an end of section (if reading object sections) or some other value representing the end of memory the function should be allowed to read. .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CWleblen\fP (if \f(CWleblen\fP passed in non-null) to the number of bytes read in decoding. It sets \f(CWoutval\fP to the signed value decoded. .P If the function detects it has read to the \f(CWendptr\fP it returns \f(CWDW_DLV_ERROR\fP. .P If the function reads too many bytes without reaching a terminator or \f(CWendptr\fP it returns \f(CWDW_DLV_ERROR\fP on the assumption that nobody would intentionally produce wastefully long LEB data, so something is wrong. .P .P Only the argument \f(CWleblen\fP may be passed in as NULL, the others must be valid non-null values. .P There is no way for the library to determine whether the value is signed or unsigned. The caller must know and call the the correct function. .H 2 "Ranges Operations DWARF5 (.debug_rnglists)" These functions provide information about the address ranges indicated by a \f(CWDW_AT_ranges\fP attribute of a DIE. The ranges are recorded in the \f(CW.debug_rnglists\fP section. .P The section requires that each group of ranges has a header and the compilation unit may have a \f(CWDW_AT_ranges_base\fP attribute that must be added to the \f(CWDW_AT_ranges\fP attribute value to get the true ranges offset. .P (A compiler generating \f(CWDW_AT_ranges_base\fP will add a relocation for that attribute value but will not have to make the \f(CWDW_AT_ranges\fP attributes relocatable and will thus save space in the object (ie, .o) file and save link time.) .P See DWARF5 Section 2.17.3 Non-Contiguous Address Ranges and Section 7.28 Range List Table. .P Section 7.28 describes the header fields for a Range List Table. There will usually be many such tables, in some sequence, in the .debug_rnglists section. Here we call each header \f(CWDwarf_Rnglists_Head\fP (a pointer to an opaque struct). .H 3 "Getting rnglists data for a DIE" This set of interfaces provides access to the DWARF5 .debug_rnglists entries for a particular DIE. . Here is an example using the functions described below: .in +2 .DS .FG "Example .debug_rnglist for attribute" \f(CW int example_rnglist_for_attribute(Dwarf_Attribute attr, Dwarf_Unsigned attrvalue,Dwarf_Error *error) { /* attrvalue must be the DW_AT_ranges DW_FORM_rnglistx or DW_FORM_sec_offset value extracted from attr. */ int res = 0; Dwarf_Half theform = 0; Dwarf_Unsigned entries_count; Dwarf_Unsigned global_offset_of_rle_set; Dwarf_Rnglists_Head rnglhead = 0; Dwarf_Unsigned i = 0; res = dwarf_rnglists_get_rle_head(attr, theform, attrvalue, &rnglhead, &entries_count, &global_offset_of_rle_set, error); if (res != DW_DLV_OK) { return res; } for (i = 0; i < entries_count; ++i) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned rawlowpc = 0; Dwarf_Unsigned rawhighpc = 0; Dwarf_Unsigned lowpc = 0; Dwarf_Unsigned highpc = 0; Dwarf_Bool debug_addr_unavailable = FALSE; /* Actual addresses are most likely what one wants to know, not the lengths/offsets recorded in .debug_rnglists. */ res = dwarf_get_rnglists_entry_fields_a(rnglhead, i,&entrylen,&code, &rawlowpc,&rawhighpc, &debug_addr_unavailable, &lowpc,&highpc,error); if (res != DW_DLV_OK) { dwarf_dealloc_rnglists_head(rnglhead); return res; } if (code == DW_RLE_end_of_list) { /* we are done */ break; } if (code == DW_RLE_base_addressx || code == DW_RLE_base_address) { /* We do not need to use these, they have been accounted for already. */ continue; } if (debug_addr_unavailable) { /* lowpc and highpc are not real addresses */ continue; } /* Here do something with lowpc and highpc, these are real addresses */ } dwarf_dealloc_rnglists_head(rnglhead); return DW_DLV_OK; } \fP .DE .in -2 .H 4 "dwarf_rnglists_get_rle_head()" This function is used to enable access to the specific set of rnglist entries applying to a specific \f(CWDW_AT_rangees\fP attribute. .DS \f(CWint dwarf_rnglists_get_rle_head( Dwarf_Attribute attr, Dwarf_Half theform, Dwarf_Unsigned attr_val, Dwarf_Rnglists_Head *head_out, Dwarf_Unsigned *entries_count_out, Dwarf_Unsigned *global_offset_of_rle_set, Dwarf_Error *error); \fP .DE .P Given a \f(CWDW_AT_ranges\fP \f(CWDwarf_Attribute\fP, the FORM from that attribute, and the value of the the attribute (which might be an index from \f(CWDW_FORM_rnglistx\fP or a section offset from \f(CWDW_FORM_sec_offset\fP the function determines which \f(CWDwarf_Rnglists_Head\fP applies and returns the pointer on success (meaning it returned . \f(CWDW_DLV_OK\fP). And on success it also returns the global offset of a set of rnglist entries within that particular Dwarf_Rnglists_Head (not needed except to show it to users) as well as the count of entries in that set (which is crucial to iterate through the rnglist entries applicable). .P If not successful none of the pointers \f(CWhead_out\fP, \f(CWentries_count_out\fP, \f(CWglobal_offset\fP will not be touched by the function. .P If there is some problem with the section it will return \f(CWDW_DLV_ERROR\fP and return the error informatio through. \f(CW*error\fP. .P There is, currently, no situation in which it will return \f(CWDW_DLV_NO_ENTRY\fP. .P See \f(CWdwarf_dealloc_rnglists_head()\fP below to release the storage allocated by a successful call here. .H 4 "dwarf_get_rnglist_head_basics()" .DS int dwarf_get_rnglist_head_basics( Dwarf_Rnglists_Head head, Dwarf_Unsigned * rle_count, Dwarf_Unsigned * rle_version, Dwarf_Unsigned * rnglists_index_returned, Dwarf_Unsigned * bytes_total_in_rle, unsigned * offset_size, unsigned * address_size, unsigned * segment_selector_size, Dwarf_Unsigned * overall_offset_of_this_context, Dwarf_Unsigned * total_length_of_this_context, Dwarf_Bool * rnglists_base_present, Dwarf_Unsigned * rnglists_base, Dwarf_Bool * rnglists_base_address_present, Dwarf_Unsigned * rnglists_base_address, Dwarf_Bool * rnglists_debug_addr_base_present, Dwarf_Unsigned * rnglists_debug_addr_base, Dwarf_Error *error) .DE The function \f(CWdwarf_get_rnglist_head_basics()\fP allows caller to print or display the fields of the Dwarf_Rnglists_Head that might be of interest for understanding the section data for that \f(CWDwarf_Rnglists_Head\fP. .P It is not needed to access the rangelist data. It currently returns only \f(CWDW_DLV_OK\fP. \f(CW \fP .H 4 "dwarf_get_rnglists_entry_fields_a()" .DS \f(CWint dwarf_get_rnglists_entry_fields_a( Dwarf_Rnglists_Head head, Dwarf_Unsigned entrynum, unsigned *entrylen, unsigned *code, Dwarf_Unsigned *raw1, Dwarf_Unsigned *raw2, Dwarf_Bool *debug_addr_unavailable, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, Dwarf_Error *err)\fP .DE This is the function to access the rnglist entries for this \f(CWDwarf_Rnglists_Head\fP \f(CWCall this with\fP \f(CWentrynum\fP in the normal iteration "i = 0; i < entries_count; ++i" where \f(CWentries_count\fP was returned by \f(CWdwarf_rnglists_get_rle_head()\fP through a pointer. .P On success \f(CWDW_DLV_OK\fP is returned and the following fields are set through the pointers. .P The \f(CWentrylen\fP value returned is the length, in bytes, of the single entry's length. .P The \f(CWcode\fP value returned is the type of entry, \f(CWDW_RLE_startx_endx\fP (see \f(CWdwarf.h\fP). .P The \f(CWraw1\fP and \f(CWraw2\fP values returned are the actual values in the rangelist entry (address, length, or index depending). For basename entries both values are set to the single value in the entry (an address or index). For end of list entries neither value is set. .P If \f(CWdebug_addr_unavailable\fP is returns non-zero then the \f(CWcooked1\fP and \f(CWcooked2\fP values are not set usefully and should be ignored. The issue arises because with dwp/dwo object files the \f(CW.debug_addr\fP section will be in the executable and if the \f(CWdwarf_set_tied_dbg()\fP function was not called to enable access to .debug_addr the 'cooked' fields cannot be calculated. .P The \f(CWcooked1\fP \f(CWcooked2\fP values returned are the actual addresses in the rangelist entry, after any necessary translation of indexes and offsets and lengths. For non-basename entries these two values are the start and end addresses of the rnglist entry. If and only if \f(CWdebug_addr_unavailable\fP returns zero. For basename entries these two values are both the basename address. For end-of-list entries neither value means anything. .P If the \f(CWentrynum\fP is out of range, \f(CWDW_DLV_NO_ENTRY\fP is returned. .P At present \f(CWDW_DLV_ERROR\fP is never returned, but callers should not assume that will always be true. .H 4 "dwarf_get_rnglists_entry_fields()" .DS \f(CWint dwarf_get_rnglists_entry_fields( Dwarf_Rnglists_Head head, Dwarf_Unsigned entrynum, unsigned *entrylen, unsigned *code, Dwarf_Unsigned *raw1, Dwarf_Unsigned *raw2, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, Dwarf_Error *err)\fP .DE This the same as \f(CWdwarf_get_rnglists_entry_fields_a()\fP except this is missing the \f(CWdebug_addr_unavailable\fP argument so it's impossible for callers to know that the cooked values are not calculated. Do not use this function. .H 4 "dwarf_dealloc_rnglists_head()" .DS \f(CWint dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head /*head*/); .DE This frees the storage allocated by the \f(CWdwarf_rnglists_get_rle_head()\fP call that created the \f(CWDwarf_Rnglists_Head\fP pointer. .P It only returns DW_DLV_OK. .H 3 "Getting raw .debug_rnglists entries" This set of interfaces is to read the (entire) \f(CW.debug_rnglists\fP section without reference to any DIE. As such these can only present the raw data from the file. There is no way in these interfaces to get actual addresses. These might be of interest if you want to know exactly what the compiler output in the \f(CW.debug_rnglists\fP section. "dwarfdump ----print-raw-rnglists" (try adding -v or -vvv) makes these calls. .P Here is an example using all the following calls. example_rngl .in +2 .FG "Examplev dwarf_get_ranges_a()" .DS \f(CW int example_raw_rnglist(Dwarf_Debug dbg,Dwarf_Error *error) { Dwarf_Unsigned count = 0; int res = 0; Dwarf_Unsigned i = 0; res = dwarf_load_rnglists(dbg,&count,error); if (res != DW_DLV_OK) { return res; } for(i =0 ; i < count ; ++i) { Dwarf_Unsigned header_offset = 0; Dwarf_Small offset_size = 0; Dwarf_Small extension_size = 0; unsigned version = 0; /* 5 */ Dwarf_Small address_size = 0; Dwarf_Small segment_selector_size = 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned offset_of_offset_array = 0; Dwarf_Unsigned offset_of_first_rangeentry = 0; Dwarf_Unsigned offset_past_last_rangeentry = 0; res = dwarf_get_rnglist_context_basics(dbg,i, &header_offset,&offset_size,&extension_size, &version,&address_size,&segment_selector_size, &offset_entry_count,&offset_of_offset_array, &offset_of_first_rangeentry, &offset_past_last_rangeentry,error); if (res != DW_DLV_OK) { return res; } { Dwarf_Unsigned e = 0; unsigned colmax = 4; unsigned col = 0; Dwarf_Unsigned global_offset_of_value = 0; for ( ; e < offset_entry_count; ++e) { Dwarf_Unsigned value = 0; int resc = 0; resc = dwarf_get_rnglist_offset_index_value(dbg, i,e,&value, &global_offset_of_value,error); if (resc != DW_DLV_OK) { return resc; } /* Do something */ col++; if (col == colmax) { col = 0; } } } { Dwarf_Unsigned curoffset = offset_of_first_rangeentry; Dwarf_Unsigned endoffset = offset_past_last_rangeentry; int rese = 0; Dwarf_Unsigned ct = 0; for ( ; curoffset < endoffset; ++ct ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned v1 = 0; Dwarf_Unsigned v2 = 0; rese = dwarf_get_rnglist_rle(dbg,i, curoffset,endoffset, &entrylen, &code,&v1,&v2,error); if (rese != DW_DLV_OK) { return rese; } curoffset += entrylen; if (curoffset > endoffset) { return DW_DLV_ERROR; } } } } return DW_DLV_OK; } \fP .DE .in -2 .H 4 "dwarf_load_rnglists()" .DS \f(CWint dwarf_load_rnglists( Dwarf_Debug dbg, Dwarf_Unsigned *rnglists_count, Dwarf_Error *error)\fP .DE On a successful call to \f(CWdwarf_load_rnglists()\fP the function returns \f(CWDW_DLV_OK\fP, sets \f(CW*rnglists_count\fP (if and only if \f(CWrnglists_count\fP is non-null) to the number of distinct section contents that exist. A small amount of data for each Range Line Table is recorded in \f(CWdbg\fP as a side effect. Normally libdwarf will have already called this, but if an application never requests any \f(CW.debug_info\fP data the section might not be loaded. If the section is loaded this returns very quickly and will set \f(CW*rnglists_count\fP just as described in this paragraph. .P If there is no \f(CW.debug_rnglists\fP section in the object file this function returns \f(CWDW_DLV_NO_ENTRY\fP. .P If something is malformed it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to the applicable error pointer describing the problem. .P There is no dealloc call. Calling \f(CWdwarf_finish()\fP releases the modest amount of memory recorded for this section as a side effect. .P .H 4 "dwarf_get_rnglist_context_basics()" .DS \f(CWint dwarf_get_rnglist_context_basics(Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned * header_offset, Dwarf_Small * offset_size, Dwarf_Small * extension_size, unsigned * version, /* 5 */ Dwarf_Small * address_size, Dwarf_Small * segment_selector_size, Dwarf_Unsigned * offset_entry_count, Dwarf_Unsigned * offset_of_offset_array, Dwarf_Unsigned * offset_of_first_rangeentry, Dwarf_Unsigned * offset_past_last_rangeentry, Dwarf_Error * /*err*/);\fP .DE On success this returns \f(CWDW_DLV_OK\fP and returns values through the pointer arguments (other than \f(CWdbg\fP or \f(CWerror\fP) .P A call to \f(CWdwarf_load_rnglists()\fP that suceeds gets you the count of contexts and \f(CWdwarf_get_rnglist_context_basics()\fP for any "i >=0 and i < count" gets you the context values relevant to \f(CW.debug_rnglists\fP. .P Any of the pointer-arguments for returning context values can be passed in as 0 (in which case they will be skipped). .P You will want \f(CW*offset_entry_count\fP so you can call \f(CWdwarf_get_rnglist_offset_index_value()\fP usefully. .P If the \f(CWcontext_index\fP passed in is out of range the function returns \f(CWDW_DLV_NO_ENTRY\fP .P At the present time \f(CWDW_DLV_ERROR\fP is never returned. .H 4 "dwarf_get_rnglist_offset_index_value()" .DS \f(CWint dwarf_get_rnglist_offset_index_value(Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned offsetentry_index, Dwarf_Unsigned * offset_value_out, Dwarf_Unsigned * global_offset_value_out, Dwarf_Error *error)\fP .DE .P On success \f(CWdwarf_get_rnglist_offset_index_value()\fP returns \f(CWDW_DLV_OK\fP, sets \f(CW* offset_value_out\fP to the value in the Range List Table offset array, and sets \f(CW* global_offset_value_out\fP to the section offset (in \f(CW.debug_addr\fP) of the offset value. .P Pass in \f(CWcontext_index\fP exactly as the same field passed to \f(CWdwarf_get_rnglist_context_basics()\fP. .P Pass in \f(CWoffset_entry_index\fP based on the return field \f(CWoffset_entry_count\fP from \f(CWdwarf_get_rnglist_context_basics()\fP, meaning for that \f(CWcontext_index\fP an \f(CWoffset_entry_index\fP >=0 and < \f(CWoffset_entry_count\fP. .P Pass in \f(CWoffset_entry_count\fP exactly as the same field passed to \f(CWdwarf_get_rnglist_context_basics()\fP. .P If one of the indexes passed in is out of range \f(CWDW_DLV_NO_ENTRY\fP will be returned and no return arguments touched. .P If there is some corruption of DWARF5 data then \f(CWDW_DLV_ERROR\fP might be returned and \f(CW*error\fP set to the error details. .H 4 "dwarf_get_rnglist_rle()" .DS \f(CWint dwarf_get_rnglist_rle( Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned entry_offset, Dwarf_Unsigned endoffset, unsigned *entrylen, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Error *error)\fP .DE On success it returns a single \f(CWDW_RLE*\fP record (see dwarf.h) fields. .P \f(CWcontextnumber\fP is the number of the current rnglist context. .P \f(CWentry_offset\fP is the section offset (section-global offset) of the next record. .P \f(CWendoffset\fP is one past the last entry in this rle context. .P \f(CW*entrylen\fP returns the length in the .debug_rnglists section of the particular record returned. It's used to increment to the next record within this rnglist context. .P \f(CW*entrykind\fP returns is the \f(CWDW_RLE*\fP number. .P Some record kinds have 1 or 0 operands, most have two operands (the records describing ranges). .P If the contextnumber is out of range it will return \f(CWDW_DLV_NO_ENTRY\fP. .P If the \f(CW.debug_rnglists\fP section is malformed or the \f(CWentry_offset\fP is incorrect it may return \f(CWDW_DLV_ERROR\fP. .H 2 "Ranges Operations DWARF3,4 (.debug_ranges)" These functions provide information about the address ranges indicated by a \f(CWDW_AT_ranges\fP attribute (the ranges are recorded in the \f(CW.debug_ranges\fP section) of a DIE. These functions apply to DWARF3 and DWARF4. Each call of \f(CWdwarf_get_ranges_a()\fP or \f(CWdwarf_get_ranges()\fP returns a an array of Dwarf_Ranges structs, each of which represents a single ranges entry. The struct is defined in \f(CWlibdwarf.h\fP. .P New in DWARF3, for DWARF3, and DWARF4 the section contains just ranges. The ranges are referenced by \f(CWDW_AT_ranges\fP attributes in various DIEs. .P For DWARF5 the section requires that each group of ranges has a header and the compilation unit may have a \f(CWDW_AT_ranges_base\fP attribute that must be added to the \f(CWDW_AT_ranges\fP attribute value to get the true ranges offset. .P (A compiler generating \f(CWDW_AT_ranges_base\fP will add a relocation for that attribute value but will not have to make the \f(CWDW_AT_ranges\fP attributes relocatable and will thus save space in the object (ie, .o) file and link time.) .H 3 "dwarf_get_ranges_section_name()" .DS \f(CWint dwarf_get_ranges_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_ranges_section_name()\fP retrieves the object file section name of the applicable ranges section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_ranges()" This is the original call and it will work fine when all compilation units have the same address_size. There is no \f(CWdie\fP argument to this original version of the function. Other arguments (and deallocation) match the use of \f(CWdwarf_get_ranges_b()\fP and \f(CWdwarf_get_ranges_a()\fP. .H 3 "dwarf_get_ranges_a()" This is the same as \f(CWdwarf_get_ranges_b()\fP except it is missing the \f(CWfinaloffset\fP pointer argument, so when reading DWARF4 split-dwarf GNU extension DIEs it's not possible to know the final offset of the ranges, but few applications will care.. .DS \f(CWint dwarf_get_ranges_a( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die, Dwarf_Ranges **ranges, Dwarf_Signed * returned_ranges_count, Dwarf_Unsigned * returned_byte_count, Dwarf_Error *error)\fP .DE .P Though missing \f(CWfinaloffset\fP this function works properly and is usable on and DWARF2,3,4 objects. .H 3 "dwarf_get_ranges_b()" .DS \f(CWint dwarf_get_ranges_b( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die, Dwarf_Off *finaloffset, Dwarf_Ranges **ranges, Dwarf_Signed * returned_ranges_count, Dwarf_Unsigned * returned_byte_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_ranges_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_ranges_count\fP to the count of the number of address ranges in the group of ranges in the .debug_ranges section where the \f(CWDW_AT_ranges\fP attribute gives offset \f(CWoffset\fP. This function is new as of 10 September 2020. .P DWARF4 GNU split-dwarf extension ONLY: With a .dwp object and the tied (executable,a.out) involved the actual .debug_ranges offset is determined from the DW_AT_GNU_ranges_base from the tied file and the offset from \f(CWDW_AT_ranges\fP in the .dwp object and returned through the \f(CWfinaloffset\fP pointer. If \f(CWfinaloffset\fP pointer is null the function ignores it. .P If there is no use of the GNU split-dwarf extension to DWARF4 the \f(CWfinaloffset\fP value returned is identical to the \f(CWoffset\fP passed in. If the pointer is null it is ignored by the function. .P This function is normally used when one has a DIE with the \f(CWDW_AT_ranges\fP attribute (whose value is the offset needed). The ranges thus apply to the DIE involved. .P See also \f(CWdwarf_get_aranges()\fP, .P The \f(CWoffset\fP argument should be the value of a \f(CWDW_AT_ranges\fP attribute of a Debugging Information Entry. The \f(CWdie\fP argument should be the value of a \f(CWDwarf_Die\fP pointer of a \f(CWDwarf_Die\fP with the attribute containing this range set offset. Because each compilation unit has its own address_size field this argument is necessary to to correctly read ranges. (Most executables have the same address_size in every compilation unit, but some ABIs allow multiple address sized in an executable). If a NULL pointer is passed in libdwarf assumes a single address_size is appropriate for all ranges records. On success, The call sets \f(CW*ranges\fP to point to a block of \f(CWDwarf_Ranges\fP structs, one for each address range. If the \f(CW*returned_byte_count\fP pointer is passed as non-NULL the number of bytes that the returned ranges were taken from is returned through the pointer (for example if the returned_ranges_count is 2 and the pointer-size is 4, then returned_byte_count will be 8). If the \f(CW*returned_byte_count\fP pointer is passed as NULL the parameter is ignored. The \f(CW*returned_byte_count\fP is only of use to certain dumper applications, most applications will not use it. The \f(CWfinaloffset\fP pointer is only of use to certain dumper applications, and if null is passed the function ignores the argument. .P On error the function returns \f(CWDW_DLV_ERROR\fP. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no \f(CW.debug_ranges\fP section or if \f(CWoffset\fP is past the end of the \f(CW.debug_ranges\fP section. .in +2 .FG "Examplev dwarf_get_ranges_b()" .DS \f(CW void examplev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die) { Dwarf_Signed count = 0; Dwarf_Ranges *ranges = 0; Dwarf_Unsigned bytes = 0; Dwarf_Error error = 0; Dwarf_Off finaloffset = 0; int res = 0; res = dwarf_get_ranges_b(dbg,offset,die, &finaloffset, &ranges,&count,&bytes,&error); if (res == DW_DLV_OK) { Dwarf_Signed i; for( i = 0; i < count; ++i ) { Dwarf_Ranges *cur = ranges+i; /* Use cur. */ functionusingrange(cur); } dwarf_ranges_dealloc(dbg,ranges,count); } } \fP .DE .in -2 .H 3 "dwarf_ranges_dealloc()" .DS \f(CWint dwarf_ranges_dealloc( Dwarf_Debug dbg, Dwarf_Ranges *ranges, Dwarf_Signed range_count, );\fP .DE The function \f(CWdwarf_ranges_dealloc()\fP takes as input a pointer to a block of \f(CWDwarf_Ranges\fP array and the number of structures in the block. It frees all the data in the array of structures. .H 2 "Gdb Index operations" These functions get access to the fast lookup tables defined by gdb and gcc and stored in the \f(CW.gdb_index\fP section. The section is of sufficient complexity that a number of function interfaces are needed. For additional information see "https://sourceware.org/gdb/onlinedocs/gdb/" "Index-Section-Format.html#Index-Section-Format". (We split the url to two pieces so it can fit on the printed page join the pieces to make a usable url). .H 3 "dwarf_gdbindex_header()" .DS int dwarf_gdbindex_header(Dwarf_Debug dbg, Dwarf_Gdbindex * gdbindexptr, Dwarf_Unsigned * version, Dwarf_Unsigned * cu_list_offset, Dwarf_Unsigned * types_cu_list_offset, Dwarf_Unsigned * address_area_offset, Dwarf_Unsigned * symbol_table_offset, Dwarf_Unsigned * constant_pool_offset, Dwarf_Unsigned * section_size, Dwarf_Unsigned * unused_reserved, const char ** section_name, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_header()\fP takes as input a pointer to a Dwarf_Debug structure and returns fields through various pointers. .P If the function returns DW_DLV_NO_ENTRY there is no .gdb_index section and none of the return-pointer argument values are set. .P If the function returns DW_DLV_ERROR \f(CWerror\fP is set to indicate the specific error, but no other return-pointer arguments are touched. .P If successful, the function returns DW_DLV_OK and other values are set. The other values are set as follows: .P The field \f(CW*gdbindexptr\fP is set to an opaque pointer to a libdwarf_internal structure used as an argument to other .gdbindex functions below. .P The remaining fields are set to values that are mostly of interest to a pretty-printer application. See the detailed layout specification for specifics. The values returned are recorded in the Dwarf_Gdbindex opaque structure for the other gdbindex functions documented below. .P The field \f(CW*version\fP is set to the version of the gdb index header (2).. .P The field \f(CW*cu_list_offset\fP is set to the offset (in the .gdb_index section) of the cu-list. .P The field \f(CW*types_cu_list_offset\fP is set to the offset (in the .gdb_index section) of the types-list. .P The field \f(CW*address_area_offset\fP is set to the offset (in the .gdb_index section) of the address area. .P The field \f(CW*symbol_table_offset\fP is set to the offset (in the .gdb_index section) of the symbol table. .P The field \f(CW*constant_pool_offset\fP is set to the offset (in the .gdb_index section) of the constant pool. .P The field \f(CW*section_size\fP is set to the length of the .gdb_index section. .P The field \f(CW*unused_reserved\fP is set to zero. .P The field \f(CW*section_name\fP is set to the Elf object file section name (.gdb_index). If a non-Elf object file has such a section the value set might be NULL or might point to an empty string (NUL terminated), so code to account for NULL or empty. .P The field \f(CW*error\fP is not set. .P Here we show a use of the set of cu_list functions (using all the functions in one example makes it rather too long). .in +2 .FG "Examplew dwarf_get_gdbindex_header()" .DS \f(CW void examplew(Dwarf_Debug dbg { Dwarf_Gdbindex gindexptr = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned cu_list_offset = 0; Dwarf_Unsigned types_cu_list_offset = 0; Dwarf_Unsigned address_area_offset = 0; Dwarf_Unsigned symbol_table_offset = 0; Dwarf_Unsigned constant_pool_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Unsigned reserved = 0; Dwarf_Error error = 0; const char * section_name = 0; int res = 0; res = dwarf_gdbindex_header(dbg,&gindexptr, &version,&cu_list_offset, &types_cu_list_offset, &address_area_offset,&symbol_table_offset, &constant_pool_offset, §ion_size, &reserved,§ion_name,&error); if (res == DW_DLV_NO_ENTRY) { return; } else if (res == DW_DLV_ERROR) { return; } { /* do something with the data */ Dwarf_Unsigned length = 0; Dwarf_Unsigned typeslength = 0; Dwarf_Unsigned i = 0; res = dwarf_gdbindex_culist_array(gindexptr, &length,&error); /* Example actions. */ if (res == DW_DLV_OK) { for(i = 0; i < length; ++i) { Dwarf_Unsigned cuoffset = 0; res = dwarf_gdbindex_culist_entry(gindexptr, i,&cuoffset,&culength,&error); if (res == DW_DLV_OK) { /* Do something with cuoffset, culength */ } } } res = dwarf_gdbindex_types_culist_array(gindexptr, &typeslength,&error); if (res == DW_DLV_OK) { for(i = 0; i < typeslength; ++i) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned tuoffset = 0; Dwarf_Unsigned culength = 0; Dwarf_Unsigned type_signature = 0; res = dwarf_gdbindex_types_culist_entry(gindexptr, i,&cuoffset,&tuoffset,&type_signature,&error); if (res == DW_DLV_OK) { /* Do something with cuoffset etc. */ } } } dwarf_gdbindex_free(gindexptr); } } \fP .DE .in -2 .H 3 "dwarf_gdbindex_culist_array()" .DS int dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_culist_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P While currently only DW_DLV_OK is returned one should test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something sensible if either is returned. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the culist through the\f(CWlist_length\fP pointer. .H 3 "dwarf_gdbindex_culist_entry()" .DS int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * cu_length, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_culist_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the culist array. Valid indexes are 0 through \f(CWlist_length -1\fP . .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind and the error is indicated by the vale returned through the \f(CWerror\fP pointer. .P On success it returns DW_DLV_OK and returns the \f(CWcu_offset\fP (the section global offset of the CU in .debug_info)) and \f(CWcu_length\fP (the length of the CU in .debug_info) values through the pointers. .H 3 "dwarf_gdbindex_types_culist_array()" .DS int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); .DE The function \f(CWdwarf_gdbindex_types_culist_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P While currently only DW_DLV_OK is returned one should test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something sensible if either is returned. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the types culist through the\f(CWlist_length\fP .P .H 3 "dwarf_gdbindex_types_culist_entry()" .DS int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * tu_offset, Dwarf_Unsigned * type_signature, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_types_culist_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the types culist array. Valid indexes are 0 through \f(CWtypes_list_length -1\fP . .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P On success it returns DW_DLV_OK and returns the \f(CWtu_offset\fP (the section global offset of the CU in .debug_types)) and \f(CWtu_length\fP (the length of the CU in .debug_types) values through the pointers. It also returns the type signature (a 64bit value) through the \f(CWtype_signature\fP pointer. .H 3 "dwarf_gdbindex_addressarea()" .DS int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); .DE The function \f(CWdwarf_addressarea()\fP takes as input valid Dwarf_Gdbindex pointer and returns the length of the address area through \f(CWaddressarea_list_length\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the address area through the \f(CWaddressarea_list_length\fP pointer. .H 3 "dwarf_gdbindex_addressarea_entry()" .DS int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * low_address, Dwarf_Unsigned * high_address, Dwarf_Unsigned * cu_index, Dwarf_Error * error); .DE The function \f(CWdwarf_addressarea_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the address area (valid indexes are zero through \f(CWaddressarea_list_length - 1\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWlow_address\fP \f(CWhigh_address\fP and \f(CWcu_index\fP through the pointers. .P Given an open Dwarf_Gdbindex one uses the function as follows: .P .DS .FG "Examplewgdbindex dwarf_gdbindex_addressarea()" \f(CW void examplewgdbindex(Dwarf_Gdbindex gdbindex) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i = 0; int res = 0; Dwarf_Error err = 0; res = dwarf_gdbindex_addressarea(gdbindex, &list_len,&err); if (res != DW_DLV_OK) { /* Something wrong, ignore the addressarea */ } /* Iterate through the address area. */ for( i = 0; i < list_len; i++) { Dwarf_Unsigned lowpc = 0; Dwarf_Unsigned highpc = 0; Dwarf_Unsigned cu_index = 0; res = dwarf_gdbindex_addressarea_entry(gdbindex,i, &lowpc,&highpc, &cu_index, &err); if (res != DW_DLV_OK) { /* Something wrong, ignore the addressarea */ return; } /* We have a valid address area entry, do something with it. */ } } \fP .DE .H 3 "dwarf_gdbindex_symboltable_array()" .DS int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * symtab_list_length, Dwarf_Error * error); .DE One can look at the symboltable as a two-level table (with The outer level indexes through symbol names and the inner level indexes through all the compilation units that define that symbol (each symbol having a different number of compilation units, this is not a simple rectangular table). .P The function \f(CWdwarf_gdbindex_symboltable_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWsymtab_list_length\fP through the pointer. .P Given a valid Dwarf_Gdbindex pointer, one can access the entire symbol table as follows (using 'return' here to indicate we are giving up due to a problem while keeping the example code fairly short): .DS .FG "Examplex dwarf_gdbindex_symboltable_array()" \f(CW void examplex(Dwarf_Gdbindex gdbindex) { Dwarf_Unsigned symtab_list_length = 0; Dwarf_Unsigned i = 0; Dwarf_Error err = 0; int res = 0; res = dwarf_gdbindex_symboltable_array(gdbindex, &symtab_list_length,&err); if (res != DW_DLV_OK) { return; } for( i = 0; i < symtab_list_length; i++) { Dwarf_Unsigned symnameoffset = 0; Dwarf_Unsigned cuvecoffset = 0; Dwarf_Unsigned cuvec_len = 0; Dwarf_Unsigned ii = 0; const char *name = 0; res = dwarf_gdbindex_symboltable_entry(gdbindex,i, &symnameoffset,&cuvecoffset, &err); if (res != DW_DLV_OK) { return; } res = dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset,&name,&err); if(res != DW_DLV_OK) { return; } res = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset,&cuvec_len,&err); if( res != DW_DLV_OK) { return; } for(ii = 0; ii < cuvec_len; ++ii ) { Dwarf_Unsigned attributes = 0; Dwarf_Unsigned cu_index = 0; Dwarf_Unsigned reserved1 = 0; Dwarf_Unsigned symbol_kind = 0; Dwarf_Unsigned is_static = 0; res = dwarf_gdbindex_cuvector_inner_attributes( gdbindex,cuvecoffset,ii, &attributes,&err); if( res != DW_DLV_OK) { return; } /* 'attributes' is a value with various internal fields so we expand the fields. */ res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex, attributes, &cu_index,&reserved1,&symbol_kind, &is_static, &err); if( res != DW_DLV_OK) { return; } /* Do something with the attributes. */ } } } \fP .DE .H 3 "dwarf_gdbindex_symboltable_entry()" .DS int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * string_offset, Dwarf_Unsigned * cu_vector_offset, Dwarf_Error * error); .DE .P The function \f(CWdwarf_gdbindex_symboltable_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an entry index(valid index values being zero through \f(CWsymtab_list_length -1\fP). .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWstring_offset\fP and \f(CWcu_vector_offset\fP through the pointers. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_length()" .DS int dwarf_gdbindex_cuvector_length( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned * innercount, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_length()\fP takes as input valid Dwarf_Gdbindex pointer and an a cu vector offset. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the \f(CWinner_count\fP through the pointer. The \f(CWinner_count\fP is the number of compilation unit vectors for this array of vectors. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_inner_attributes()" .DS int dwarf_gdbindex_cuvector_inner_attributes( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned innerindex, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * attr_value, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_inner_attributes()\fP takes as input valid Dwarf_Gdbindex pointer and an a cu vector offset and a \f(CWinner_index\fP (valid \f(CWinner_index\fP values are zero through \f(CWinner_count - 1\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWattr_value\fP through the pointer. The \f(CWattr_value\fP is actually composed of several fields, see the next function which expands the value. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_instance_expand_value()" .DS int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned attr_value, Dwarf_Unsigned * cu_index, Dwarf_Unsigned * reserved1, Dwarf_Unsigned * symbol_kind, Dwarf_Unsigned * is_static, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_instance_expand_value()\fP takes as input valid Dwarf_Gdbindex pointer and an \f(CWattr_value\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the following values through the pointers: The \f(CWcu_index\fP field is the index in the applicable CU list of a compilation unit. For the purpose of indexing the CU list and the types CU list form a single array so the \f(CWcu_index\fP can be indicating either list. The \f(CWsymbol_kind\fP field is a small integer with the symbol kind( zero is reserved, one is a type, 2 is a variable or enum value, etc). The \f(CWreserved1\fP field should have the value zero and is the value of a bit field defined as reserved for future use. The \f(CWis_static\fP field is zero if the CU indexed is global and one if the CU indexed is static. See the example above which uses this function. .H 3 "dwarf_gdbindex_string_by_offset()" .DS \f(CWint dwarf_gdbindex_string_by_offset( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned stringoffset, const char ** string_ptr, Dwarf_Error * error);\fP .DE The function \f(CWdwarf_gdbindex_string_by_offset()\fP takes as input valid Dwarf_Gdbindex pointer and a \f(CWstringoffset\fP If it returns \f(CWDW_DLV_NO_ENTRY\fP there is a coding error. If it returns \f(CWDW_DLV_ERROR\fP there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If it succeeds, the call returns a pointer to a string from the 'constant pool' through the \f(CWstring_ptr\fP. The string pointed to must never be free()d. .P See the example above which uses this function. .H 2 "GNU linking (.gnu_debuglink, .note.gnu.build-id) operations" This section deals with the way GNU tools allow creation of DWARF separated from the executable file involved. See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html for more information. The function here is new in September 2019, revised in October 2020. An example of use follows the description of arguments. .P These functions are concerned with finding DWARF data in a companion file. There is no Split-Dwarf involved, this is a different way of splitting DWARF out of an executable or shared object.. It never applies to simple .o object files, only to executable objects (or shared libraries). .H 3 "dwarf_gnu_debuglink()" .DS \f(CWint dwarf_gnu_debuglink(Dwarf_Debug dbg, char **debuglink_path_returned, unsigned char **crc_returned, char **debuglink_fullpath_returned, unsigned *buildid_type returned, char **builid_returned, unsigned *builid_length_returned, char ***paths_returned, unsigned *paths_count_returned, Dwarf_Error* error);\fP .DE This returns \f(CWDW_DLV_NO_ENTRY\fP if there is neither a \f(CW.gnu_debuglink\fP object-file section nor a \f(CW.note.gnu.build-id\fP section in the object file. .P If there is an error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to point to the error value. .P On success it returns \f(CWDW_DLV_OK\fP and sets the fields through the pointers as described below. Two fields must be free()d to avoid a memory leak. None of the other fields should be freed. .P If there is a \f(CW.gnu_debuglink\fP section the first four fields will be set. .P \f(CW*debuglink_path_returned\fP points to the null-terminated string in the section. Do not free this. The bytes are in the object itself and the pointer is invalid once dwarf_finish() is run on the dbg. .P \f(CW*crc_returned\fP points to a 4-byte CRC value. The bytes pointed to are not a string. .P \f(CW*debuglink_fullpath_returned\fP points to a full pathname derived from the \f(CW*debuglink_fullpath_returned\fP string. And then \f(CW*debuglink_fullpath_strlen\fP is set to the length of \f(CW*debuglink_fullpath_returned\fP just as \f(CWstrlen()\fP would count the length. Callers must free() \f(CW*debuglink_fullpath_returned\fP. .P If there is a \f(CW.note.gnu.build-id\fP section the buildid fields will be set through the pointers. .P \f(CW*buildid_type_returned\fP will be set to the value 3. .P \f(CW*buildid_owner_name_returned\fP will be set to point to the null-terminated string which will be "GNU". Do not free() this. The bytes are in the object itself and the pointer is invalid once dwarf_finish() is run on the dbg. .P \f(CW*buildid_returned\fP will be set to point to the group of bytes of length \f(CW*buildid_length_returned\fP. This is not a string and is not null-terminated. It is normally a 20-byte field to be used in its ascii-hex form. Do not free() this. The bytes are in the object itself and the pointer is invalid once dwarf_finish() is run on the dbg. .P If \f(CW*paths_returned\fP is passed as NULL then no paths calculation will be made and \f(CW*paths_count_returned\fP is not referenced by libdwarf. .P If \f(CW*paths_returned\fP is passed in non-NULL then \f(CW*paths_returned\fP and \f(CW*paths_count_returned\fP provide an array of pointers-to-strings (with the actual strings following the array) and the count of the pointers in the array. When the strings are no longer needed free() \f(CW*paths_returned\fP. The number of paths returned will depend on which (of the two) sections exist and on how many global paths have been set by \f(CWdwarf_add_debuglink_global_path()\fP. and defined by the rules described in the web page mentioned above. The default global path is "/usr/lib/debug" and that is set by libdwarf as \f(CWpaths_returned[0]\fP. .P An example of calling this function follows .DS .FG "Example debuglink ()" \f(CWvoid exampledebuglink(Dwarf_Debug dbg) { int res = 0; char *debuglink_path = 0; unsigned char *crc = 0; char *debuglink_fullpath = 0; unsigned debuglink_fullpath_strlen = 0; unsigned buildid_type = 0; char * buildidowner_name = 0; unsigned char *buildid_itself = 0; unsigned buildid_length = 0; char ** paths = 0; unsigned paths_count = 0; Dwarf_Error error = 0; unsigned i = 0; /* This is just an example if one knows of another place full-DWARF objects may be. "/usr/lib/debug" is automatically set. */ res = dwarf_add_debuglink_global_path(dbg, "/some/path/debug",&error); if (res != DW_DLV_OK) { /* Something is wrong, but we'll ignore that. */ } res = dwarf_gnu_debuglink(dbg, &debuglink_path, &crc, &debuglink_fullpath, &debuglink_fullpath_strlen, &buildid_type, &buildidowner_name, &buildid_itself, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { /* Do something with the error */ return; } if (res == DW_DLV_NO_ENTRY) { /* No such sections as .note.gnu.build-id or .gnu_debuglink */ return; } if (debuglink_fullpath_strlen) { printf("debuglink path: %s\\n",debuglink_path); printf("crc length : %u crc: ",4); for (i = 0; i < 4;++i ) { printf("%02x",crc[i]); } printf("\\n"); printf("debuglink fullpath: %s\\n",debuglink_fullpath); } if(buildid_length) { printf("buildid type : %u\\n",buildid_type); printf("Buildid owner : %s\\n",buildidowner_name); printf("buildid byte count: %u\\n",buildid_length); printf(" "); /* buildid_length should be 20. */ for (i = 0; i < buildid_length;++i) { printf("%02x",buildid_itself[i]); } printf("\\n"); } printf("Possible paths count %u\\n",paths_count); for ( ; i < paths_count; ++i ){ printf("%2u: %s\\n",i,paths[i]); } free(debuglink_fullpath); free(paths); return; } \fP .DE .H 3 "dwarf_add_debuglink_global_path()" .DS \f(CWint dwarf_add_debuglink_global_path(Dwarf_Debug dbg, const char * path, Dwarf_Error* error);\fP .DE This is unlikely to return \f(CWDW_DLV_ERROR\fP unless one passes in a NULL instead of an open \f(CWDwarf_Debug\fP. It cannot return \f(CWDW_DLV_NO_ENTRY\fP. .P On success it returns \f(CWDW_DLV_OK\fP after adding the path to the global list recorded in the \f(CWDwarf_Debug\fP. .H 3 "dwarf_crc32()" .DS \f(CWint dwarf_crc32(Dwarf_Debug dbg, unsigned char * crc_buf, Dwarf_Error* error); \fP .DE The caller must pass the address of a 4 byte array of unsigned char in \f(CWcrc_buf\fP. And the Dwarf_Debug must have been opened with \f(CWdwarf_init_path()\fP to be useful. If the executable is named \f(CWexecutable\fP the file containing most of the f(CWDWARF\fP data would often be \f(CWexecutable.debug\fP. This is normally called from libdwarf code on opening \f(CWexecutable\fP and \f(CWlibdwarf\fP may call this function on \f(CWexecutable.debug\fP. Library users could would likely never call it. .P On success it returns \f(CWDW_DLV_OK\fP and sets the 4 bytes pointed to by \f(CWcrc_buf\fP to the calculated CRC value. .P If it returns \f(CWDW_DLV_NO_ENTRY\fP or \f(CWDW_DLV_ERROR\fP somethine went wrong and \f(CWcrc_buf\fP is not touched. .P The function was added October 2020. .H 3 "dwarf_basic_crc32()" .DS \f(CWunsigned int dwarf_crc32(const unsigned char *buf, int len, unsigned int init); \fP .DE This computes the crc on \f(CWbuf\fP of length \f(CWlen\fP with initial value \f(CWinit\fP. See libdwarf source for the details of calling this. It is not likely useful for library uses to call this directly. .P The function was added October 2020. .H 2 "DWARF5 .debug_sup section access" The .debug_sup section is new in DWARF5 and this function returns all the data in that section. The section enables splitting off some DWARF5 information to a separate file, enabling a debugger to find the file, and ensuring the file found actually matches. See the DWARF5 standard. .H 3 "dwarf_get_debug_sup()" .DS \f(CWint dwarf_get_debug_sup(Dwarf_Debug dbg, Dwarf_Half * version, Dwarf_Small * is_supplementary, char ** filename, Dwarf_Unsigned * checksum_len, Dwarf_Small ** checksum, Dwarf_Error* error);\fP .DE On success it returns \f(CWDW_DLV_OK\fP and sets values through the pointer fields (other than \f(CWerror\fP). If any of the pointer fields are NULL those pointers are ignored. There is nothing resulting from this call to free or dealloc. .P The pointer values are as follows: .P \f(CWversion\fP is defined to be 2, and any other value is an error (libdwarf does not indicate an error). .P \f(CWis_supplementary\fP is a flag and only 0 or 1 should be present. and any other value is an error, though libdwarf does not indicate an error. .P \f(CWfilename\fP is a null-terminated string. .P \f(CWchecksum_len\fP is the length, in bytes, of the data \f(CWchecksum\fP points to. .P If there is no .debug_sup section or if that is empty \f(CWDW_DLV_NO_ENTRY\fP is returned. .P On error (for example, if a field runs off the end of the section due to data corruption) \f(CWDW_DLV_ERROR\fP is returned and \f(CW*error\fP returns the error information as is standard in libdwarf. .H 2 "Debug Fission (.debug_tu_index, .debug_cu_index) operations" We name things "xu" as these sections have the same format so we let "x" stand for either section. The DWARF5 standard refers to Split Dwarf while libdwarf tends to refer to this as "Fission". .P These functions get access to the index functions needed to access and print the contents of an object file which is an aggregate of .dwo objects. These sections are implemented in gcc/gdb and are DWARF5. The idea is that much debug information can be separated off into individual .dwo Elf objects and then aggregated simply into a single .dwp object so the executable need not have the complete debug information in it at runtime yet allow good debugging. .P For additional information, see "https://gcc.gnu.org/wiki/DebugFissionDWP", "https://gcc.gnu.org/wiki/DebugFission", and "http://www.bayarea.net/~cary/dwarf/Accelerated%20Access%20Diagram.png" and as of 17 February 2017, the DWARF5 standard. .P There are FORM access functions related to Debug Fission (Split Dwarf). See \f(CWdwarf_formaddr()\fP and \f(CWdwarf_get_debug_addr_index()\fP and \f(CWdwarf_get_debug_str_index()\fP. .P The FORM with the hash value (for a reference to a type unit ) is \f(CWDW_FORM_ref_sig8\fP. .P In a compilation unit of Debug Fission object (or a .dwp Package FIle) \f(CWDW_AT_dwo_id\fP the hash is expected to be \f(CWDW_FORM_data8\fP. .P The \f(CWDWARF5\fP standard defines the hash as an 8 byte value which we could use \f(CWDwarf_Unsigned\fP. Instead (and mostly for type safety) we define the value as a structure whose type name is \f(CWDwarf_Sig8\fP. .P To look up a name in the hash (to find which CU(s) it exists in). use \f(CWdwarf_get_debugfission_for_key()\fP, defined below. .P The second group of interfaces here beginning with \f(CWdwarf_get_xu_index_header()\fP are useful if one wants to print a .debug_tu_index or .debug_cu_index section. .P To access DIE, macro, etc information the support is built into DIE, Macro, etc operations so applications usually won't need to use these operations at all. .H 3 "Dwarf_Debug_Fission_Per_CU" .DS #define DW_FISSION_SECT_COUNT 12 struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; .DE .P The structure is used to return data to callers with the data from either .debug_tu_index or .debug_cu_index that is applicable to a single compilation unit or type unit. .P Callers to the applicable functions (see below) should allocate the structure and zero all the bytes in it. The structure has a few fields that are presently unused. These are reserved for future use since it is impossible to alter the structure without breaking binary compatibility. .H 3 "dwarf_die_from_hash_signature()" .DS int dwarf_die_from_hash_signature(Dwarf_Debug dbg, Dwarf_Sig8 * hash_sig, const char * sig_type, Dwarf_Die* returned_die, Dwarf_Error* error); .DE The function \f(CWdwarf_die_from_hash_signature()\fP is the most direct way to go from the hash data from a \f(CWDW_FORM_ref_sig8\fP or a \f(CWDW_AT_dwo_id\fP (form \f(CWDW_FORM_data8\fP) to a DIE from a .dwp package file or a .dwo object file ( .dwo access not supported yet). .P The caller passes in \f(CWdbg\fP which should be \f(CWDwarf_Debug\fP open/initialized on a .dwp package file (or a .dwo object file). .P The caller also passes in \f(CWhash_sig\fP, a pointer to the hash signature for which the caller wishes to find a DIE. .P The caller also passes in \f(CWsig_type\fP which must contain either "tu" (identifying the hash referring to a type unit) or "cu" (identifying the hash as referring to a compilation unit). .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_die\fP to be a pointer to a valid DIE for the compilation unit or type unit. If the type is "tu" the DIE returned is the specific type DIE that the hash refers to. If the type is "cu" the DIE returned is the compilation unit DIE of the compilation unit referred to. .P When appropriate the caller should free the space of the returned DIE by a call something like .DS dwarf_dealloc(dbg,die,DW_DLA_DIE); .DE .P If there is no DWP Package File section or the hash cannot be found the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CWreturned_die\fP untouched. Only .dwo objects and .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CWreturned_die\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .P .H 3 "dwarf_get_debugfission_for_die()" .DS int dwarf_get_debugfission_for_die(Dwarf_Die die, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error); .DE The function \f(CWdwarf_get_debugfission_for_die()\fP returns the debug fission for the compilation unit the DIE is a part of. Any DIE in the compilation (or type) unit will get the same result. .P On a call to this function ensure the pointed-to space is fully initialized. .P On success the function returns \f(CWDW_DLV_OK\fP and fills in the fields of \f(CW*percu_out\fP for which it has data. .P If there is no DWP Package File section the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP untouched. Only .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .H 3 "dwarf_get_debugfission_for_key()" .DS int dwarf_get_debugfission_for_key(Dwarf_Debug dbg, Dwarf_Sig8 * key, const char * key_type , Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error); .DE The function \f(CWdwarf_get_debugfission_for_key()\fP returns the debug fission data for the compilation unit in a .dwp package file. .P If there is no DWP Package File section the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP untouched. Only .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .H 3 "dwarf_get_xu_index_header()" .DS int dwarf_get_xu_index_header(Dwarf_Debug dbg, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * xuhdr, Dwarf_Unsigned * version_number, Dwarf_Unsigned * offsets_count /* L*/, Dwarf_Unsigned * units_count /* N*/, Dwarf_Unsigned * hash_slots_count /* M*/, const char ** sect_name, Dwarf_Error * err); .DE The function \f(CWdwarf_get_xu_index_header()\fP takes as input a valid Dwarf_Debug pointer and an \f(CWsection_type\fP value, which must one of the strings \f(CWtu\fP or \f(CWcu\fP. .P It returns DW_DLV_NO_ENTRY if the section requested is not in the object file. .P It returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the following values through the pointers: .P The \f(CWxuhdr\fP field is a pointer usable in other operations (see below). .P The \f(CWversion_number\fP field is a the index version number. For gcc before DWARF5 the version number is 2. For DWARF5 the version number is 5. .P The \f(CWoffsets_count\fP field is a the number of columns in the table of section offsets. Sometimes known as \f(CWL\fP. .P The \f(CWunits_count\fP field is a the number of compilation units or type units in the index. Sometimes known as \f(CWN\fP. .P The \f(CWhash_slots_count\fP field is a the number of slots in the hash table. Sometimes known as \f(CWM\fP. .P The \f(CWsect_name\fP field is the name of the section in the object file. Because non-Elf objects may not use section names callers must recognize that the sect_name may be set to NULL (zero) or to point to the empty string and this is not considered an error. .P An example of initializing and disposing of a \f(CWDwarf_Xu_Index_Header\fP follows. .DS .FG "Exampley dwarf_get_xu_index_header()" \f(CW void exampley(Dwarf_Debug dbg, const char *type) { /* type is "tu" or "cu" */ int res = 0; Dwarf_Xu_Index_Header xuhdr = 0; Dwarf_Unsigned version_number = 0; Dwarf_Unsigned offsets_count = 0; /*L */ Dwarf_Unsigned units_count = 0; /* M */ Dwarf_Unsigned hash_slots_count = 0; /* N */ Dwarf_Error err = 0; const char * section_name = 0; res = dwarf_get_xu_index_header(dbg, type, &xuhdr, &version_number, &offsets_count, &units_count, &hash_slots_count, §ion_name, &err); if (res == DW_DLV_NO_ENTRY) { /* No such section. */ return; } if (res == DW_DLV_ERROR) { /* Something wrong. */ return; } /* Do something with the xuhdr here . */ dwarf_xu_header_free(xuhdr); } \fP .DE .H 3 "dwarf_get_xu_index_section_type()" .DS int dwarf_get_xu_index_section_type( Dwarf_Xu_Index_Header xuhdr, const char ** typename, const char ** sectionname, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_section_type()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP. It is only useful when one already as an open \f(CWxuhdr\fP but one does not know if this is a type unit or compilation unit index section. .P If it returns DW_DLV_NO_ENTRY something is wrong (should never happen). If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWtypename\fP is set to the string \f(CWtu\fP or \f(CWcu\fP to indicate the index is of a type unit or a compilation unit, respectively. .P \f(CWsectionname\fP is set to name of the object file section. Because non-Elf objects may not use section names callers must recognize that the sect_name may be set to NULL (zero) or to point to the empty string and this is not considered an error. .P Neither string should be free()d. .H 3 "dwarf_get_xu_header_free()" .DS void dwarf_xu_header_free(Dwarf_Xu_Index_Header xuhdr); .DE The function \f(CWdwarf_get_xu_header_free()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and frees all the special data allocated for this access type. Once called, any pointers returned by use of the \f(CWxuhdr\fP should be considered stale and unusable. .H 3 "dwarf_get_xu_hash_entry()" .DS int dwarf_get_xu_hash_entry( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned index, Dwarf_Sig8 * hash_value, Dwarf_Unsigned * index_to_sections, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_hash_entry()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and an \f(CWindex\fP of a hash slot entry (valid hash slot index values are zero (0) through \f(CWhash_slots_count -1\fP (M-1)). .P If it returns DW_DLV_NO_ENTRY something is wrong .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWhash_value\fP is set to the 64bit hash of of the symbol name. .P \f(CWindex_to_sections\fP is set to the index into offset-size tables of this hash entry. .P If both \f(CWhash_value\fP and \f(CWindex_to_sections\fP are zero (0) then the hash slot is unused. \f(CWindex_to_sections\fP is used in calls to the function \f(CWdwarf_get_xu_section_offset()\fP as the \f(CWrow_index\fP. .P An example of use follows. .DS .FG "Examplez dwarf_get_xu_hash_entry()" \f(CW void examplez( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned hash_slots_count) { /* hash_slots_count returned by dwarf_get_xu_index_header(), see above. */ static Dwarf_Sig8 zerohashval; Dwarf_Error err = 0; Dwarf_Unsigned h = 0; for( h = 0; h < hash_slots_count; h++) { Dwarf_Sig8 hashval; Dwarf_Unsigned index = 0; int res = 0; res = dwarf_get_xu_hash_entry(xuhdr,h, &hashval,&index,&err); if (res == DW_DLV_ERROR) { /* Oops. hash_slots_count wrong. */ return; } else if (res == DW_DLV_NO_ENTRY) { /* Impossible */ return; } else if (!memcmp(&hashval,&zerohashval, sizeof(Dwarf_Sig8)) && index == 0 ) { /* An unused hash slot */ continue; } /* Here, hashval and index (a row index into offsets and lengths) are valid. But the row to be passed into various functions here is index-1. */ } } \fP .DE .H 3 "dwarf_get_xu_section_names()" .DS int dwarf_get_xu_section_names( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned column_index, Dwarf_Unsigned* number, const char ** name, Dwarf_Error * err); .DE The function \f(CWdwarf_get_xu_section_names()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and a \f(CWcolumn_index\fP of a hash slot entry (valid column_index values are zero (0) through \f(CWoffsets_count -1\fP (L-1)). .P If it returns DW_DLV_NO_ENTRY something is wrong .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWnumber\fP is set to a number identifying which section this column applies to. For example, if the value is \f(CWDW_SECT_INFO\fP (1) the column came from a .debug_info.dwo section. See the table of \f(CWDW_SECT_\fP identifiers and assigned numbers in DWARF5. .P \f(CWname\fP is set to the applicable spelling of the section identifier, for example \f(CWDW_SECT_INFO\fP. .H 3 "dwarf_get_xu_section_offset()" .DS int dwarf_get_xu_section_offset( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned row_index, Dwarf_Unsigned column_index, Dwarf_Unsigned* sec_offset, Dwarf_Unsigned* sec_size, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_section_offset()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and a \f(CWrow_index\fP (see \f(CWdwarf_get_xu_hash_entry()\fP above) and a \f(CWcolumn_index\fP. .P Valid row_index values are zero (0) through \f(CWunits_count-1\fP (N) but one uses \f(CWdwarf_get_xu_hash_entry()\fP (above) to get row index and it returns a 1-origin index as that is what the DWARF5 standard specifies. Since a zero index from \f(CWdwarf_get_xu_hash_entry()\fP means this is not an actual entry such must be skipped. .P Hence it makes (some) sense to subtract one making a zero-origin as that is the sense of all but the first row of the offsets table. .P Valid column_index values are zero (0) through \f(CWoffsets_count -1\fP (L-1). .P If it returns DW_DLV_NO_ENTRY something is wrong. .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWsec_offset\fP, (\f(CWbase offset\fP) is set to the base offset of the initial compilation-unit-header section taken from a .dwo object. The base offset is the data from a single section of a .dwo object. .P \f(CWsec_size\fP is set to the length of the original section taken from a .dwo object. This is the length in the applicable section in the .dwp over which the base offset applies. .P An example of use of \f(CWdwarf_get_xu_section_names()\fP and \f(CWdwarf_get_xu_section_offset()\fP follows. .DS .FG "Exampleza dwarf_get_xu_section_names()" \f(CW void exampleza(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned offsets_count, Dwarf_Unsigned index ) { Dwarf_Error err = 0; Dwarf_Unsigned col = 0; /* We use 'offsets_count' returned by a dwarf_get_xu_index_header() call. We use 'index' returned by a dwarf_get_xu_hash_entry() call. */ for (col = 0; col < offsets_count; col++) { Dwarf_Unsigned off = 0; Dwarf_Unsigned len = 0; const char * name = 0; Dwarf_Unsigned num = 0; int res = 0; res = dwarf_get_xu_section_names(xuhdr, col,&num,&name,&err); if (res != DW_DLV_OK) { break; } res = dwarf_get_xu_section_offset(xuhdr, index-1,col,&off,&len,&err); if (res != DW_DLV_OK) { break; } /* Here we have the DW_SECT_ name and number and the base offset and length of the section data applicable to the hash that got us here. Use the values.*/ } } .DE .H 2 "TAG ATTR etc names as strings" These functions turn a value into a string. So applications wanting the string "DW_TAG_compile_unit" given the value 0x11 (the value defined for this TAG) can do so easily. The general form is .in +2 .DS \f(CWint dwarf_get__name( unsigned value, char **s_out, );\fP .DE .in -2 If the \f(CWvalue\fP passed in is known, the function returns \f(CWDW_DLV_OK\fP and places a pointer to the appropriate string into \f(CW*s_out\fP. The string is in static storage and applications must never free the string. If the \f(CWvalue\fP is not known, \f(CWDW_DLV_NO_ENTRY\fP is returned and \f(CW*s_out\fP is not set. \f(CWDW_DLV_ERROR\fP is never returned. \f(CWLibdwarf\fP generates these functions at libdwarf build time by reading dwarf.h. All these follow this pattern rigidly, so the details of each are not repeated for each function. The choice of 'unsigned' for the value type argument (the code value) argument is somewhat arbitrary, 'int' could have been used. The library simply assumes the value passed in is applicable. So, for example, passing a TAG value code to \f(CWdwarf_get_ACCESS_name()\fP is a coding error which libdwarf will process as if it was an accessibility code value. Examples of bad and good usage are: .in +2 .DS .FG "Examplezb dwarf_get_TAG_name()" \f(CW void examplezb(void) { const char * out = 0; int res = 0; /* The following is wrong, do not do it! */ res = dwarf_get_ACCESS_name(DW_TAG_entry_point,&out); /* Nothing one does here with 'res' or 'out' is meaningful. */ /* The following is meaningful.*/ res = dwarf_get_TAG_name(DW_TAG_entry_point,&out); if( res == DW_DLV_OK) { /* Here 'out' is a pointer one can use which points to the string "DW_TAG_entry_point". */ } else { /* Here 'out' has not been touched, it is uninitialized. Do not use it. */ } } \fP .DE .in -2 .H 3 "dwarf_get_ACCESS_name()" Returns an accessibility code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_AT_name()" Returns an attribute code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ATE_name()" Returns a base type encoding name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ADDR_name()" Returns an address type encoding name through the \f(CWs_out\fP pointer. As of this writing only \f(CWDW_ADDR_none\fP is defined in \f(CWdwarf.h\fP. .H 3 "dwarf_get_ATCF_name()" Returns a SUN code flag encoding name through the \f(CWs_out\fP pointer. This code flag is entirely a DWARF extension. .H 3 "dwarf_get_CHILDREN_name()" Returns a child determination name (which is seen in the abbreviations section data) through the \f(CWs_out\fP pointer. The only value this recognizes for a 'yes' value is 1. As a flag value this is not quite correct (any non-zero value means yes) but dealing with this is left up to client code (normally compilers really do emit a value of 1 for a flag). .H 3 "dwarf_get_children_name()" Returns a child determination name through the \f(CWs_out\fP pointer, though this version is really a libdwarf artifact. The standard function is \f(CWdwarf_get_CHILDREN_name()\fP which appears just above. As a flag value this is not quite correct (any non-zero value means yes) but dealing with this is left up to client code (normally compilers really do emit a value of 1 for a flag). .H 3 "dwarf_get_CC_name()" Returns a calling convention case code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_CFA_name()" Returns a call frame information instruction name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_DS_name()" Returns a decimal sign code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_DSC_name()" Returns a discriminant descriptor code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_EH_name()" Returns a GNU exception header code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_END_name()" Returns an endian code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_FORM_name()" Returns an form code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_FRAME_name()" Returns a frame code name through the \f(CWs_out\fP pointer. These are dependent on the particular ABI, so unless the \f(CWdwarf.h\fP used to generate libdwarf matches your ABI these names are unlikely to be very useful and certainly won't be entirely appropriate. .H 3 "dwarf_get_ID_name()" Returns an identifier case code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_INL_name()" Returns an inline code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LANG_name()" Returns a language code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LLE_name()" Returns a split-dwarf loclist code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LNE_name()" Returns a line table extended opcode code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LNS_name()" Returns a line table standard opcode code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_MACINFO_name()" Returns a macro information macinfo code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_MACRO_name()" Returns a DWARF5 macro information macro code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_OP_name()" Returns a DWARF expression operation code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ORD_name()" Returns an array ordering code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_TAG_name()" Returns a TAG name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_VIRTUALITY_name()" Returns a virtuality code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_VIS_name()" Returns a visibility code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_FORM_CLASS_name()" Only different from the others in that it applies to an enum value. It returns the name (for example DW_FORM_CLASS_REFERENCE) through the pointer. .in +2 .DS \f(CWint dwarf_get_FORM_CLASS_name( enum Dwarf_Form_Class fc, char **s_out, );\fP .DE .in -2 If the enum value is out of the valid range it returns \f(CWDW_DLV_NO_ENTRY\fP and ignores \f(CWs_out\fP. .P It never returns \f(CWDW_DLV_ERROR\fP. .H 2 "Section Operations" In checking DWARF in linkonce sections for correctness it has been found useful to have certain section-oriented operations when processing object files. Normally these operations are not needed or useful in a fully-linked executable or shared library. While the code is written with Elf sections in mind, it is quite possible to process non-Elf objects with code that implements certain function pointers (see \f(CWstruct Dwarf_Obj_Access_interface_s\fP). So far no one with such non-elf code has come forward to open-source it. .H 3 "dwarf_get_section_count()" .DS \f(CWint dwarf_get_section_count( Dwarf_Debug dbg) \fP .DE .P Returns a count of the number of object sections found. .P If there is an incomplete or damaged dbg passed in this can return -1; .H 3 "dwarf_get_section_info_by_name()" .DS \f(CWint dwarf_get_section_info_by_name( const char *section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_section_info_by_name()\fP returns \f(CWDW_DLV_OK\fP if the section given by \f(CWsection_name\fP was seen by libdwarf. On success it sets \f(CW*section_addr\fP to the virtual address assigned to the section by the linker or compiler and \f(CW*section_size\fP to the size of the object section. It returns DW_DLV_ERROR on error. .H 3 "dwarf_get_section_info_by_index()" .DS \f(CWint dwarf_get_section_info_by_index( int section_index, const char **section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_section_info_by_index()\fP returns \f(CWDW_DLV_OK\fP if the section given by \f(CWsection_index\fP was seen by libdwarf. \f(CW*section_addr\fP to the virtual address assigned to the section by the linker or compiler and \f(CW*section_size\fP to the size of the object section. No free or deallocate of information returned should be done by callers. .H 2 "Utility Operations" These functions aid in the management of errors encountered when using functions in the \fIlibdwarf\fP library and releasing memory allocated as a result of a \fIlibdwarf\fP operation. .P For clients that wish to encode LEB numbers two interfaces are provided to the producer code's internal LEB function. .H 3 "dwarf_errno()" .DS \f(CWDwarf_Unsigned dwarf_errno( Dwarf_Error error)\fP .DE The function \f(CWdwarf_errno()\fP returns the error number corresponding to the error specified by \f(CWerror\fP. .H 3 "dwarf_errmsg()" .DS \f(CWconst char* dwarf_errmsg( Dwarf_Error error)\fP .DE The function \f(CWdwarf_errmsg()\fP returns a pointer to a null-terminated error message string corresponding to the error specified by \f(CWerror\fP. The string should not be deallocated using \f(CWdwarf_dealloc()\fP. The string should be considered to be a temporary string. That is, the returned pointer may become stale if you do libdwarf calls on the \f(CWDwarf_Debug\fP instance other than \f(CWdwarf_errmsg()\fP or \f(CWdwarf_errno()\fP. So copy the errmsg string ( or print it) but do not depend on the pointer remaining valid past other libdwarf calls to the \f(CWDwarf_Debug\fP instance that detected an error. .H 3 "dwarf_errmsg_by_number()" .DS \f(CWconst char* dwarf_errmsg_by_number( Dwarf_Unside errcode)\fP .DE The function \f(CWdwarf_errmsg_by_number()\fP returns a pointer to a null-terminated error message string corresponding to the error number specified by \f(CWerrcode\fP. The string should not be deallocated or freed. If the \f(CWerrcode\fP is too large for the table of static error strings a string reflecting that fact is returned. .P For some places in the code a \f(CWDwarf_Error()\fP is inconvenient and this function lets dwarfdump report better information in those cases. Function new December 19, 2018. .H 3 "dwarf_get_endian_copy_function()" .DS \f(CWvoid (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/)) (void *, const void * /*src*/, unsigned long /*srclen*/)\fP .DE When reader client code wants to extract endian-dependent integers from dwarf and the existing interfaces won't do that (for example in printing frame instructions as done by dwarfdump) \f(CWdwarf_get_endian_copy_function\fP helps by returning the proper copy function needed, the one libdwarf itself uses. The client code needs a bit of glue to finish the job, as demonstrated by the ASNAR macro in dwarfdump/print_frames.c .P On success this returns a pointer to the correct copy function. .P On failure it returns the null pointer. It's up to the client code to decide how to deal with the situation. In no reasonable case will the null pointer be returned. .P New December 2018. .H 3 "dwarf_get_harmless_error_list()" .DS \f(CWint dwarf_get_harmless_error_list(Dwarf_Debug dbg, unsigned count, const char ** errmsg_ptrs_array, unsigned * newerr_count);\fP .DE The harmless errors are not denoted by error returns from the other libdwarf functions. Instead, this function returns strings of any harmless errors that have been seen in the current object. Clients never need call this, but if a client wishes to report any such errors it may call. Only a fixed number of harmless errors are recorded. It is a circular list, so if more than the current maximum is encountered older harmless error messages are lost. The caller passes in a pointer to an array of pointer-to-char as the argument \f(CWerrmsg_ptrs_array\fP. The caller must provide this array, libdwarf does not provide it. The caller need not initialize the array elements. The caller passes in the number of elements of the array of pointer-to-char thru \f(CWcount\fP. Since the If there are no unreported harmless errors the function returns \f(CWDW_DLV_NO_ENTRY\fP and the function arguments are ignored. Otherwise the function returns \f(CWDW_DLV_OK\fP and uses the arguments. \f(CWlibdwarf\fP assigns error strings to the errmsg_ptrs_array. The MININUM(count-1, number of messages recorded) pointers are assigned to the array. The array is terminated with a NULL pointer. (That is, one array entry is reserved for a NULL pointer). So if \f(CWcount\fP is 5 up to 4 strings may be returned through the array, and one array entry is set to NULL. Because the list is circular and messages may have been dropped the function also returns the actual error count of harmless errors encountered through \f(CWnewerr_count\fP (unless the argument is NULL, in which case it is ignored). Each call to this function resets the circular error buffer and the error count. So think of this call as reporting harmless errors since the last call to it. The pointers returned through \f(CWerrmsg_ptrs_array\fP are only valid till the next call to libdwarf. Do not save the pointers, they become invalid. Copy the strings if you wish to save them. Calling this function neither allocates any space in memory nor frees any space in memory. .H 3 "dwarf_insert_harmless_error()" .DS void dwarf_insert_harmless_error(Dwarf_Debug dbg, char * newerror); .DE This function is used to test \f(CWdwarf_get_harmless_error_list\fP. It simply adds a harmless error string. There is little reason client code should use this function. It exists so that the harmless error functions can be easily tested for correctness and leaks. .H 3 "dwarf_set_harmless_error_list_size()" .DS \f(CWunsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, unsigned maxcount)\fP .DE \f(CWdwarf_set_harmless_error_list_size\fP returns the number of harmless error strings the library is currently set to hold. If \f(CWmaxcount\fP is non-zero the library changes the maximum it will record to be \f(CWmaxcount\fP. It is extremely unwise to make \f(CWmaxcount\fP large because \f(CWlibdwarf\fP allocates space for \f(CWmaxcount\fP strings immediately. .P The set of errors enumerated in Figure \n(aX below were defined in Dwarf 1. These errors are not used by the \f(CWlibdwarf\fP implementation for Dwarf 2 or later. .DS .TS center box, tab(:); lfB lfB l l. SYMBOLIC NAME:DESCRIPTION _ DW_DLE_NE:No error (0) DW_DLE_VMM:Version of DWARF information newer :than libdwarf DW_DLE_MAP:Memory map failure DW_DLE_LEE:Propagation of libelf error DW_DLE_NDS:No debug section DW_DLE_NLS:No line section DW_DLE_ID:Requested information not associated :with descriptor DW_DLE_IOF:I/O failure DW_DLE_MAF:Memory allocation failure DW_DLE_IA:Invalid argument DW_DLE_MDE:Mangled debugging entry DW_DLE_MLE:Mangled line number entry DW_DLE_FNO:File descriptor does not refer :to an open file DW_DLE_FNR:File is not a regular file DW_DLE_FWA:File is opened with wrong access DW_DLE_NOB:File is not an object file DW_DLE_MOF:Mangled object file header DW_DLE_EOLL:End of location list entries DW_DLE_NOLL:No location list section DW_DLE_BADOFF:Invalid offset DW_DLE_EOS:End of section DW_DLE_ATRUNC:Abbreviations section appears :truncated DW_DLE_BADBITC:Address size passed to :dwarf bad .TE .FG "Dwarf Error Codes" .DE The set of errors returned by \f(CWLibdwarf\fP functions is listed below. The list does lengthen: the ones listed here are far from a complete list. Some of the errors are SGI specific. See libdwarf/dwarf_errmsg_list.h for the complete list. .DS .TS center box, tab(:); lfB lfB l. SYMBOLIC NAME (description not shown here) _ DW_DLE_DBG_ALLOC DW_DLE_FSTAT_ERROR DW_DLE_FSTAT_MODE_ERROR DW_DLE_INIT_ACCESS_WRONG DW_DLE_ELF_BEGIN_ERROR DW_DLE_ELF_GETEHDR_ERROR DW_DLE_ELF_GETSHDR_ERROR DW_DLE_ELF_STRPTR_ERROR DW_DLE_DEBUG_INFO_DUPLICATE DW_DLE_DEBUG_INFO_NULL DW_DLE_DEBUG_ABBREV_DUPLICATE DW_DLE_DEBUG_ABBREV_NULL DW_DLE_DEBUG_ARANGES_DUPLICATE DW_DLE_DEBUG_ARANGES_NULL DW_DLE_DEBUG_LINE_DUPLICATE DW_DLE_DEBUG_LINE_NULL DW_DLE_DEBUG_LOC_DUPLICATE DW_DLE_DEBUG_LOC_NULL DW_DLE_DEBUG_MACINFO_DUPLICATE DW_DLE_DEBUG_MACINFO_NULL DW_DLE_DEBUG_PUBNAMES_DUPLICATE DW_DLE_DEBUG_PUBNAMES_NULL DW_DLE_DEBUG_STR_DUPLICATE DW_DLE_DEBUG_STR_NULL DW_DLE_CU_LENGTH_ERROR DW_DLE_VERSION_STAMP_ERROR DW_DLE_ABBREV_OFFSET_ERROR DW_DLE_ADDRESS_SIZE_ERROR DW_DLE_DEBUG_INFO_PTR_NULL DW_DLE_DIE_NULL DW_DLE_STRING_OFFSET_BAD DW_DLE_DEBUG_LINE_LENGTH_BAD DW_DLE_LINE_PROLOG_LENGTH_BAD DW_DLE_LINE_NUM_OPERANDS_BAD DW_DLE_LINE_SET_ADDR_ERROR .TE .FG "Dwarf 2 and later Error Codes" .DE This list of errors is not complete; additional errors have been added. Some of the above errors may be unused. Errors may not have the same meaning in different releases. Since most error codes are returned from only one place (or a very small number of places) in the source it is normally very useful to simply search the \f(CWlibdwarf\fP source to find out where a particular error code is generated. See \f(CWlibdwarf/dwarf_errmsg_list.h\fP for the complete message set with short descriptions. .H 3 "dwarf_dealloc()" .DS \f(CWvoid dwarf_dealloc( Dwarf_Debug dbg, void* space, Dwarf_Unsigned type)\fP .DE The function \f(CWdwarf_dealloc\fP frees the dynamic storage pointed to by \f(CWspace\fP, and allocated to the given \f(CWDwarf_Debug\fP. The argument \f(CWtype\fP is an integer code that specifies the allocation type of the region pointed to by the \f(CWspace\fP. Refer to section 4 for details on \fIlibdwarf\fP memory management. .H 3 "dwarf_encode_leb128()" .DS int dwarf_encode_leb128(Dwarf_Unsigned val, int * nbytes, char * space, int splen); .DE The function \f(CWdwarf_encode_leb128\fP encodes the value \f(CWval\fP in the caller-provided buffer that \f(CWspace\fP points to. The caller-provided buffer must be at least \f(CWsplen\fP bytes long. The function returns \f(CWDW_DLV_OK\fP if the encoding succeeds. If \f(CWsplen\fP is too small to encode the value, \f(CWDW_DLV_ERROR\fP will be returned. If the call succeeds, the number of bytes of \f(CWspace\fP that are used in the encoding are returned through the pointer \f(CWnbytes\fP .H 3 "dwarf_encode_signed_leb128()" .DS int dwarf_encode_signed_leb128(Dwarf_Signed val, int * nbytes, char * space, int splen); .DE The function \f(CWdwarf_encode_signed_leb128\fP is the same as \f(CWdwarf_encode_leb128\fP except that the argument \f(CWval\fP is signed. .H 2 "Finding Memory Leaks" \f(CW \fP If you are using \f(CWdwarf_set_de_alloc_flag(0)\fP to turn off the garbage collection \f(CWdwarfinish()\fP does and you find memory leaks there are a couple specific tools provided that may ease the process of tracking down the errors you have made. .P This chapter is new as of 26 March 2020. .H 3 "Compiling libdwarf -DDEBUG=1" .P The first tool is to build libdwarf with options \f(CW-g -O0 -DDEBUG=1\fP. The -O0 is simply to help a debugger, valgrind or other too identify source lines accurately. The \f(CW-DDEBUG=1\fP Turns on printf statements in dwarf_alloc.c and dwarf_error.c that emit lines like .DS libdwarfdetector ALLOC ret 0x... size libdwarfdetector DEALLOC ret 0x... size libdwarfdetector ALLOC creating error string libdwarfdetector DEALLOC Now destruct error string .DE at each point of particular interest. .P The first two relate to actually malloc/free. The ret 0x... will be a hex address of the pointer yuur code is presented for allocations inside libdwarf. .P The second two relate to allocation/free of a string in Dwarf_Error record when an error record with variable descriptive error information is being built/freed. .P .H 3 "Making use of the output of -DDEBUG=1" A small Python 3 program (alloctrack.py) in the libdwarf regressiontests on SourceForge.net will read through a file with libdwarfdetector lines and report on mismatches in the alloc/dealloc counts for each memory-blob libdwarf created. All other lines are skipped. .P This has been found very useful. .P Since the regression tests are large and you won't otherwise need them a copy of alloctrack.py follows so you need not clone the test code. .DS \f(CW #!/usr/bin/env python3 # Copyright 2020 David Anderson # This Python code is hereby placed into the public domain # for use by anyone for any purpose. # Useful for finding the needle of # a single leaking allocation # in the haystack of all the libdwarfdetector # lines libdwarf can emit if compiled -DDEBUG=1 import sys import os def trackallocs(fi,valdict): line = 0 while True: line = int(line)+1 try: recf = fi.readline() except EOFError: break if len(recf) < 1: # eof break rec = recf.strip() if rec.find("ALLOC") != -1: if rec.find("libdwarfdetector ALLOC ret 0x") != -1: wds = rec.split() off = wds[3] if off in valdict: (allo,deallo) = valdict[off] if int(allo) == 0: r = (1,deallo) valdict[off] = r else: print("Duplicate use of ",off,"line",line) r =(int(allo)+1,deallo) valdict[off] = r else: allo = 1 deallo = 0 r=(allo,deallo) valdict[off] = r continue if rec.find("libdwarfdetector DEALLOC ret 0x") != -1: wds = rec.split() off = wds[3] if off in valdict: (allo,deallo) = valdict[off] if int(deallo) == 0: r = (allo,1) valdict[off] = r else: print("Duplicate use of ",off,"line",line) r = (allo,int(deallo)+1) valdict[off] = r else: allo = 0 deallo = 1 r=(allo,deallo) valdict[off] = r continue if __name__ == '__main__': if len(sys.argv) > 1: fname = sys.argv[1] try: file = open(fname,"r") except IOError as message: print("File could not be opened: ", fname, " ", message) sys.exit(1) else: file = sys.stdin vals = {} trackallocs(file,vals) for s in vals: (allo,deallo) = vals[s] if int(allo) != int(deallo): print("Mismatch on ",s," a vs d: ",allo,deallo) if int(allo) > 1: print("Reuse of ",s," a vs d: ",allo,deallo) \fP .DE .SK .S .TC 1 1 4 .CS libdwarf-20210528/libdwarf/ChangeLog20070000664000175000017500000002742413644370703014371 000000000000002007-12-09 DavidAnderson * dwarf_sort_line.c dwarf_print_lines.c darf_frame.c: Forgot to commit yesterday. Today's commit includes renaming _dwarf_fde_section_offset _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines to dwarf_* name while retaining support for the now obsolete _dwarf_* form. 2007-12-08 DavidAnderson * config.h.in, configure.in: Latest linux libelf.h requires _GNU_SOURCE to get off64_t defined so dwarfdump compiles. Only define _GNU_SOURCE if libelf.h defines off64_t. Regenerated configure. * config.guess, config.sub: Updated to 2.61 * acconfig.h: Deleted, removing autoconf complaint. 2007-11-14 David Anderson * dwarf_frame2.c (gnu_aug_encodings): Now allows 'S' augmentation character in eh_frame. 2007-10-16 David Anderson * dwarf_alloc.c: Reformat a comment. * dwarf_die_deliv.c (dwarf_siblingof): When there is no trailing null-DIE in the section, ensure we don't test the contents of a byte past section end. * dwarf_frame.c: Changed spelling of a local variable so it is easier to grep for and to read. * dwarf_macro.c (free_macro_stack): Was free()ing memory that _dwarf_get_alloc() had supplied, which could lead to core dump. Fixed potential memory leaks (said leaks only possible with an error in the macro data, not with valid macro section data). 2007-10-15 David Anderson * dwarf_alloc.c: The code supporting the special build flag DWARF_SIMPLE_MALLOC was broken and could coredump libdwarf (which did not affect normal use of libdwarf). * dwarf_opaque.h: Remove the field de_simple_malloc_current as it is no longer used. 2007-09-04 David Anderson * pro_forms.c: Add commentary relating to the recent DWARF4 DW_AT_high_pc change. Correct FSF address. * libdwarf2p.1.mm: Document dwarf_add_AT_dataref() and dwarf_add_AT_ref_address(). * libdwarf2p.1.pdf: Regenerate. * dwarf.h: Update FSF address. * dwarf_opaque.h: Add DWARF4 entry (version stamp). Update FSF address. * dwarf_die_deliv.c: Add check for .debug_info version 4 (version stamp). Update FSF address. * libdwarf.h pro_macinfo.h pro_line.h dwarf_incl.h pro_alloc.h pro_section.h libdwarfdefs.h pro_util.h dwarf_vars.h dwarf_funcs.h pro_error.h dwarf_alloc.h pro_arange.h dwarf_arange.h pro_die.h dwarf_global.h pro_expr.h pro_reloc_stream.h pro_incl.h pro_encode_nm.h dwarf_line.h pro_frame.h pro_opaque.h dwarf_error.h dwarf_base_types.h dwarf_abbrev.h pro_types.h pro_reloc_symbolic.h dwarf_weaks.h dwarf_util.h dwarf_loc.h malloc_check.h dwarf_die_deliv.h acconfig.h dwarf_frame.h dwarf_macro.h pro_reloc.h dwarf_types.h pro_funcs.c Makefile.in pro_forms.c pro_line.c dwarf_print_lines.c pro_alloc.c pro_init.c dwarf_addr_finder.c pro_section.c dwarf_form.c dwarf_query.c dwarf_vars.c dwarf_pubtypes.c dwarf_frame3.c dwarf_funcs.c pro_error.c pro_arange.c dwarf_alloc.c dwarf_arange.c pro_die.c dwarf_sort_line.c dwarf_global.c dwarf_init_finish.c pro_weaks.c pro_pubnames.c pro_expr.c pro_reloc_stream.c pro_finish.c pro_encode_nm.c dwarf_line.c pro_frame.c dwarf_error.c dwarf_abbrev.c pro_types.c dwarf_leb.c pro_reloc_symbolic.c dwarf_string.c pro_vars.c dwarf_line2.c dwarf_weaks.c dwarf_frame2.c dwarf_util.c dwarf_loc.c LIBDWARFCOPYRIGHT malloc_check.c dwarf_die_deliv.c dwarf_frame.c dwarf_stubs.c dwarf_macro.c pro_reloc.c dwarf_types.c pro_macinfo.c: Update FSF address. 2007-07-26 David Anderson * pro_frame.c: Added commentary about some missing DWARF3 support. * dwarf_srclines_dealloc.c: File unused, now deleted. 2007-07-04 David Anderson * libdwarf.h: dwarf_get_loclist_entry() is implemented, removed the erroneous 'unimplemented' comment. * libdwarf2.1.mm: Improved the dwarf_get_loclist_entry() documentation. * libdwarf2.1.pdf: regenerated * dwarf_loclist_entry.c: Removed from distribution, the source has nothing of interest. 2007-07-03 David Anderson * libdwarf.h: Add declaration of dwarf_loclist_from_expr(); * dwarf_loc.c: Implement dwarf_loclist_from_expr() and add sign-extension macro calls to case DW_OP_const4s numbers. Removed unused local variables. * dwarf_form.c: Removed unused local variables. * libdwarf2.1.mm: Document dwarf_loclist_from_expr(). * libdwarf2.1.pdf: Regenerated. 2007-07-01 David Anderson * dwarf_frame2.c: Add commentary. * dwarf_frame.c: Add in block_len for DW_CFA_val_expression so libdwarf does not get confused by this frame expression operator. Thanks to Cristian Vlasceanu for providing a test case. 2007-06-29 David Anderson * README: added a note that a few warnings about conversions from pointer to integer are normal at libdwarf compile time. 2007-05-25 David Anderson * dwarf_frame2.c (_dwarf_get_fde_list_internal): Correct cie-list-creation so it adds to the tail of the list. gcc 4.1.2 generates cie-use in an order the code did not properly handle. 2007-05-08 David Anderson * Makefile.in: Now generates pdf files. * mips_extensions.mm: The only changes were to eliminate unsupported macro (.PM) and to try to get correct output from groff. No technical content change intended. The pdf/postscript output remains a little odd though. * libdwarf2.1.mm: Remove troff comment line. 2007-04-18 Chris Quenelle * dwarf_addr_finder.c: repaired comment * dwarf_form.c: add support for DW_AT_SUN_func_offsets * pro_alloc.c: add memory block tracking to find and fix lingering allocations. This is more important for very large and intensive compiles. * pro_die.c: Implement "markers" which are a generic way to do things like relocations. You can set a marker on any die, and when dwarf is produced in binary form, you get back a list of your markers with the offset of each one in the binary output. This is used by the Sun compilers to implement die references that span compile unit blocks. (I may remove this, it might be unused code related to partial_units and comdat support) * pro_die.c: Also check for loops in the die relationships so that if you add a child twice, or other errors, you won't get an infinite loop or a crash. Also start passing a DBG structure to all allocation calls to help with memory block tracking. * pro_expr.c: Add a public function to "reset" an expr. This allows the same expr object to be reused over and over to save memory if you're creating many many expressions for a location list. * pro_finish.c: Free any left over blocks when the user calls dwarf_producer_finish. * pro_forms.c: More support for compressed integer blocks. Modify error diagnostics so that user-defined attributes can be any type. Add support for dwarf_add_AT_ref_address which is just like dwarf_add_AT_address, only it produces a DW_FORM_ref_addr instead of DW_FORM_addr. This is needed for cross-CU die pointers. * pro_incl.h: add macros to control the spelling of relocation types. * pro_init.c: use new macros to control reloc types * pro_line.h: correct minimum instruction length on x86 * pro_opaque.h: add support for markers (see above) and also ability have libdwarf tell the caller where the string constants are so that they can be recorded as strings in case the binary output of libdwarf needs to be converted back into assembly. That's what Dwarf_P_Per_Sect_String_Attrs is about. Remove de_mem_list as it is never used. * pro_reloc_stream.c: repair prototype and comment for _dwarf_pro_reloc_name_stream64, and use relocation type macros. * pro_section.c: support for markers (see above) and for tracking inline string attributes. Add code to sort the attributes so that abbreviation table entries will be reduced. Change treatment of DW_FORM_ref_addr to be more correct. Some support for packing in the middle of sections, this will probably be removed. Also pass DBg structure to more allocations. * pro_util.h: relocation type values can't be zero. 2007-04-10 David Anderson for free() declaration. * dwarf_print_lines.c pro_section.c dwarf_query.c dwarf_alloc.c dwarf_arange.c dwarf_sort_line.c dwarf_global.c dwarf_line.c dwarf_abbrev.c dwarf_srclines_dealloc.c dwarf_frame2.c dwarf_util.c dwarf_loc.c dwarf_die_deliv.c dwarf_frame.c dwarf_macro.c: indent run with standard libdwarf options. 2007-02-20 David Anderson #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "dwarfstring.h" static int errcount; /* int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err) */ static void resetdbg(Dwarf_P_Debug dbg) { memset(dbg,0,sizeof(struct Dwarf_P_Debug_s)); } #if 0 "default_is_stmt" "minimum_instruction_length" "maximum_operations_per_instruction" "opcode_base" "line_base" "line_range" "linetable_version" "segment_selector_size" "segment_size" dbg->de_line_inits.pi_default_is_stmt = (unsigned)v; dbg->de_line_inits.pi_minimum_instruction_length = (unsigned)v; dbg->de_line_inits.pi_maximum_operations_per_instruction = (unsigned)v; dbg->de_line_inits.pi_opcode_base = (unsigned)v; dbg->de_line_inits.pi_line_base = (int)v; dbg->de_line_inits.pi_line_range = (int)v; dbg->de_line_inits.pi_linetable_version = (unsigned)v; dbg->de_line_inits.pi_segment_selector_size = (unsigned)v; dbg->de_line_inits.pi_segment_size = (unsigned)v; #endif /* 0 */ const char * returnvalstr(int res) { if (res == DW_DLV_OK) return "DW_DLV_OK"; if (res == DW_DLV_NO_ENTRY) return "DW_DLV_NO_ENTRY"; if (res == DW_DLV_ERROR) return "DW_DLV_ERROR"; return "Unknown"; } static void check_expected(int exp, int got, int err_exp, int err_got, Dwarf_Signed exp_val, Dwarf_Signed got_val, int line) { if ( exp != got) { ++errcount; printf("Expected res %s, got %s line %d\n", returnvalstr(exp), returnvalstr(got),line); } if ( err_exp != err_got) { ++errcount; printf("Expected err code %d, got %d line %d\n", err_exp,err_got,line); } if ( exp_val != got_val) { ++errcount; printf("Expected value %" DW_PR_DSd ", got %" DW_PR_DSd " line %d\n", exp_val,got_val,line); } } static void test1(Dwarf_P_Debug dbg) { int res = 0; int err = 0; res = _dwarf_log_extra_flagstrings(dbg,"default_is_stmt=1",&err); check_expected(DW_DLV_OK,res,0,err,1, dbg->de_line_inits.pi_default_is_stmt, __LINE__); err = 0; res = _dwarf_log_extra_flagstrings(dbg,0,&err); check_expected(DW_DLV_NO_ENTRY,res,0,err,0,0, __LINE__); err = 0; res = _dwarf_log_extra_flagstrings(dbg,"",&err); check_expected(DW_DLV_NO_ENTRY,res,0,err,0,0, __LINE__); err = 0; resetdbg(dbg); res = _dwarf_log_extra_flagstrings(dbg,",line_base=-1,",&err); check_expected(DW_DLV_OK,res,0,err,-1, dbg->de_line_inits.pi_line_base, __LINE__); err = 0; resetdbg(dbg); res = _dwarf_log_extra_flagstrings(dbg,",,line_base=-1,,",&err); check_expected(DW_DLV_OK,res,0,err,-1, dbg->de_line_inits.pi_line_base, __LINE__); resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg,",,line_base =-1,,",&err); check_expected(DW_DLV_ERROR,res,err, DW_DLE_PRO_INIT_EXTRAS_ERR, dbg->de_line_inits.pi_line_base,0, __LINE__); } static void test2(Dwarf_P_Debug dbg) { int res = 0; int err = 0; resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg, "default_is_stmt=1,line_base=2",&err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_default_is_stmt,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,2, __LINE__); resetdbg(dbg); err = 0; /* intentional typo here */ res = _dwarf_log_extra_flagstrings(dbg, "minimum_instruction_lengty=3," "maximum_operations_per_instruction=4",&err); check_expected(DW_DLV_ERROR,res, err,DW_DLE_PRO_INIT_EXTRAS_UNKNOWN, dbg->de_line_inits.pi_minimum_instruction_length, 0, __LINE__); check_expected(DW_DLV_ERROR,res, err,DW_DLE_PRO_INIT_EXTRAS_UNKNOWN, dbg->de_line_inits.pi_maximum_operations_per_instruction, 0, __LINE__); resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg, "default_is_stmt=1," "minimum_instruction_length=2," "maximum_operations_per_instruction=3," "opcode_base=4," "line_base=5," "line_range=6," "linetable_version=7," "segment_selector_size=8," "segment_size=9", &err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_default_is_stmt,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_minimum_instruction_length,2, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_maximum_operations_per_instruction,3, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_opcode_base,4, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,5, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_range,6, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_linetable_version,7, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_segment_selector_size,8, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_segment_size,9, __LINE__); } static void test3(Dwarf_P_Debug dbg) { int res = 0; int err = 0; /* The following identical to a current dwarfgen.cc use. */ res = _dwarf_log_extra_flagstrings(dbg, "opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4",&err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_opcode_base,13, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_minimum_instruction_length,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,-1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_range,4, __LINE__); } int main() { struct Dwarf_P_Debug_s sdbg; Dwarf_P_Debug dbg = &sdbg; resetdbg(dbg); test1(dbg); resetdbg(dbg); test2(dbg); resetdbg(dbg); test3(dbg); if (errcount) { return 1; } return 0; } libdwarf-20210528/libdwarf/dwarf_elf_defines.h0000664000175000017500000005351113714303161016071 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_ELF_DEFINES_H #define DWARF_ELF_DEFINES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Use the system headers if they are available. */ #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ /* Relocation definitions are in sys/elf_{mach}.h on Solaris. */ #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif /* HAVE_LIBELF_LIBELF_H */ #endif /* HAVE_LIBELF_H */ /* Standard Elf section types. */ #ifndef SHT_NULL #define SHT_NULL 0 #endif #ifndef SHT_PROGBITS #define SHT_PROGBITS 1 #endif #ifndef SHT_SYMTAB #define SHT_SYMTAB 2 #endif #ifndef SHT_STRTAB #define SHT_STRTAB 3 #endif #ifndef SHT_RELA #define SHT_RELA 4 #endif #ifndef SHT_REL #define SHT_REL 9 #endif #ifndef DW_GROUPNUMBER_BASE #define DW_GROUPNUMBER_BASE 1 #endif #ifndef DW_GROUPNUMBER_DWO #define DW_GROUPNUMBER_DWO 2 #endif #ifndef SHF_GROUP #define SHF_GROUP (1 << 9) #endif /* SHF_GROUP */ #ifndef STN_UNDEF #define STN_UNDEF 0 #endif /* STN_UNDEF */ #ifndef SHT_HASH #define SHT_HASH 5 #endif #ifndef SHT_DYNAMIC #define SHT_DYNAMIC 6 #endif #ifndef SHT_NOTE #define SHT_NOTE 7 #endif #ifndef SHT_NOBITS #define SHT_NOBITS 8 #endif #ifndef SHT_REL #define SHT_REL 9 #endif #ifndef SHT_SHLIB #define SHT_SHLIB 10 #endif #ifndef SHT_DYNSYM #define SHT_DYNSYM 11 #endif #ifndef SHT_GROUP #define SHT_GROUP 17 #endif /* SHT_GROUP */ /* Symbol Types, Elf standard. */ #define STT_NOTYPE 0 #define STT_OBJECT 1 #define STT_FUNC 2 #define STT_SECTION 3 #define STT_FILE 4 #ifndef PT_NULL #define PT_NULL 0 #endif #ifndef PT_LOAD #define PT_LOAD 1 #endif #ifndef PT_DYNAMIC #define PT_DYNAMIC 2 #endif #ifndef PT_INTERP #define PT_INTERP 3 #endif #ifndef PT_NOTE #define PT_NOTE 4 #endif #ifndef PT_SHLIB #define PT_SHLIB 5 #endif #ifndef PT_PHDR #define PT_PHDR 6 #endif #ifndef PT_LOPROC #define PT_LOPROC 0x70000000 #endif #ifndef PT_HIPROC #define PT_HIPROC 0x7fffffff #endif #ifndef PF_X #define PF_X (1 << 0) #endif #ifndef PF_W #define PF_W (1 << 1) #endif #ifndef PF_R #define PF_R (1 << 2) #endif #ifndef PF_MASKOS #define PF_MASKOS 0x0ff00000 #endif #ifndef PF_MASKPROC #define PF_MASKPROC 0xf0000000 #endif #ifndef ET_NONE #define ET_NONE 0 #endif #ifndef ET_REL #define ET_REL 1 #endif #ifndef ET_EXEC #define ET_EXEC 2 #endif #ifndef ET_DYN #define ET_DYN 3 #endif #ifndef ET_CORE #define ET_CORE 4 #endif #ifndef ET_NUM #define ET_NUM 5 #endif #ifndef ET_LOOS #define ET_LOOS 0xfe00 #endif #ifndef ET_HIOS #define ET_HIOS 0xfeff #endif #ifndef ET_LOPROC #define ET_LOPROC 0xff00 #endif #ifndef ET_HIPROC #define ET_HIPROC 0xffff #endif #ifndef EM_NONE #define EM_NONE 0 #endif #ifndef EM_M32 #define EM_M32 1 #endif #ifndef EM_SPARC #define EM_SPARC 2 #endif #ifndef EM_386 #define EM_386 3 #endif #ifndef EM_68K #define EM_68K 4 #endif #ifndef EM_88K #define EM_88K 5 #endif #ifndef EM_IAMCU #define EM_IAMCU 6 #endif #ifndef EM_860 #define EM_860 7 #endif #ifndef EM_MIPS #define EM_MIPS 8 #endif #ifndef EM_S370 #define EM_S370 9 #endif #ifndef EM_MIPS_RS3_LE #define EM_MIPS_RS3_LE 10 #endif #ifndef EM_PARISC #define EM_PARISC 15 #endif #ifndef EM_VPP500 #define EM_VPP500 17 #endif #ifndef EM_SPARC32PLUS #define EM_SPARC32PLUS 18 #endif #ifndef EM_960 #define EM_960 19 #endif #ifndef EM_PPC #define EM_PPC 20 #endif #ifndef EM_PPC64 #define EM_PPC64 21 #endif #ifndef EM_S390 #define EM_S390 22 #endif #ifndef EM_SPU #define EM_SPU 23 #endif #ifndef EM_V800 #define EM_V800 36 #endif #ifndef EM_FR20 #define EM_FR20 37 #endif #ifndef EM_RH32 #define EM_RH32 38 #endif #ifndef EM_RCE #define EM_RCE 39 #endif #ifndef EM_ARM #define EM_ARM 40 #endif #ifndef EM_FAKE_ALPHA #define EM_FAKE_ALPHA 41 #endif #ifndef EM_SH #define EM_SH 42 #endif #ifndef EM_SPARCV9 #define EM_SPARCV9 43 #endif #ifndef EM_TRICORE #define EM_TRICORE 44 #endif #ifndef EM_ARC #define EM_ARC 45 #endif #ifndef EM_H8_300 #define EM_H8_300 46 #endif #ifndef EM_H8_300H #define EM_H8_300H 47 #endif #ifndef EM_H8S #define EM_H8S 48 #endif #ifndef EM_H8_500 #define EM_H8_500 49 #endif #ifndef EM_IA_64 #define EM_IA_64 50 #endif #ifndef EM_MIPS_X #define EM_MIPS_X 51 #endif #ifndef EM_COLDFIRE #define EM_COLDFIRE 52 #endif #ifndef EM_68HC12 #define EM_68HC12 53 #endif #ifndef EM_MMA #define EM_MMA 54 #endif #ifndef EM_PCP #define EM_PCP 55 #endif #ifndef EM_NCPU #define EM_NCPU 56 #endif #ifndef EM_NDR1 #define EM_NDR1 57 #endif #ifndef EM_STARCORE #define EM_STARCORE 58 #endif #ifndef EM_ME16 #define EM_ME16 59 #endif #ifndef EM_ST100 #define EM_ST100 60 #endif #ifndef EM_TINYJ #define EM_TINYJ 61 #endif #ifndef EM_X86_64 #define EM_X86_64 62 #endif #ifndef EM_PDSP #define EM_PDSP 63 #endif #ifndef EM_PDP10 #define EM_PDP10 64 #endif #ifndef EM_PDP11 #define EM_PDP11 65 #endif #ifndef EM_FX66 #define EM_FX66 66 #endif #ifndef EM_ST9PLUS #define EM_ST9PLUS 67 #endif #ifndef EM_ST7 #define EM_ST7 68 #endif #ifndef EM_68HC16 #define EM_68HC16 69 #endif #ifndef EM_68HC11 #define EM_68HC11 70 #endif #ifndef EM_68HC08 #define EM_68HC08 71 #endif #ifndef EM_68HC05 #define EM_68HC05 72 #endif #ifndef EM_SVX #define EM_SVX 73 #endif #ifndef EM_ST19 #define EM_ST19 74 #endif #ifndef EM_VAX #define EM_VAX 75 #endif #ifndef EM_CRIS #define EM_CRIS 76 #endif #ifndef EM_JAVELIN #define EM_JAVELIN 77 #endif #ifndef EM_FIREPATH #define EM_FIREPATH 78 #endif #ifndef EM_ZSP #define EM_ZSP 79 #endif #ifndef EM_MMIX #define EM_MMIX 80 #endif #ifndef EM_HUANY #define EM_HUANY 81 #endif #ifndef EM_PRISM #define EM_PRISM 82 #endif #ifndef EM_AVR #define EM_AVR 83 #endif #ifndef EM_FR30 #define EM_FR30 84 #endif #ifndef EM_D10V #define EM_D10V 85 #endif #ifndef EM_D30V #define EM_D30V 86 #endif #ifndef EM_V850 #define EM_V850 87 #endif #ifndef EM_M32R #define EM_M32R 88 #endif #ifndef EM_MN10300 #define EM_MN10300 89 #endif #ifndef EM_MN10200 #define EM_MN10200 90 #endif #ifndef EM_PJ #define EM_PJ 91 #endif #ifndef EM_OPENRISC #define EM_OPENRISC 92 #endif #ifndef EM_ARC_COMPACT #define EM_ARC_COMPACT 93 #endif #ifndef EM_XTENSA #define EM_XTENSA 94 #endif #ifndef EM_VIDEOCORE #define EM_VIDEOCORE 95 #endif #ifndef EM_TMM_GPP #define EM_TMM_GPP 96 #endif #ifndef EM_NS32K #define EM_NS32K 97 #endif #ifndef EM_TPC #define EM_TPC 98 #endif #ifndef EM_SNP1K #define EM_SNP1K 99 #endif #ifndef EM_ST200 #define EM_ST200 100 #endif #ifndef EM_IP2K #define EM_IP2K 101 #endif #ifndef EM_MAX #define EM_MAX 102 #endif #ifndef EM_CR #define EM_CR 103 #endif #ifndef EM_F2MC16 #define EM_F2MC16 104 #endif #ifndef EM_MSP430 #define EM_MSP430 105 #endif #ifndef EM_BLACKFIN #define EM_BLACKFIN 106 #endif #ifndef EM_SE_C33 #define EM_SE_C33 107 #endif #ifndef EM_SEP #define EM_SEP 108 #endif #ifndef EM_ARCA #define EM_ARCA 109 #endif #ifndef EM_UNICORE #define EM_UNICORE 110 #endif #ifndef EM_EXCESS #define EM_EXCESS 111 #endif #ifndef EM_DXP #define EM_DXP 112 #endif #ifndef EM_ALTERA_NIOS2 #define EM_ALTERA_NIOS2 113 #endif #ifndef EM_CRX #define EM_CRX 114 #endif #ifndef EM_XGATE #define EM_XGATE 115 #endif #ifndef EM_C166 #define EM_C166 116 #endif #ifndef EM_M16C #define EM_M16C 117 #endif #ifndef EM_DSPIC30F #define EM_DSPIC30F 118 #endif #ifndef EM_CE #define EM_CE 119 #endif #ifndef EM_M32C #define EM_M32C 120 #endif #ifndef EM_TSK3000 #define EM_TSK3000 131 #endif #ifndef EM_RS08 #define EM_RS08 132 #endif #ifndef EM_SHARC #define EM_SHARC 133 #endif #ifndef EM_ECOG2 #define EM_ECOG2 134 #endif #ifndef EM_SCORE7 #define EM_SCORE7 135 #endif #ifndef EM_DSP24 #define EM_DSP24 136 #endif #ifndef EM_VIDEOCORE3 #define EM_VIDEOCORE3 137 #endif #ifndef EM_LATTICEMICO32 #define EM_LATTICEMICO32 138 #endif #ifndef EM_SE_C17 #define EM_SE_C17 139 #endif #ifndef EM_TI_C6000 #define EM_TI_C6000 140 #endif #ifndef EM_TI_C2000 #define EM_TI_C2000 141 #endif #ifndef EM_TI_C5500 #define EM_TI_C5500 142 #endif #ifndef EM_TI_ARP32 #define EM_TI_ARP32 143 #endif #ifndef EM_TI_PRU #define EM_TI_PRU 144 #endif #ifndef EM_MMDSP_PLUS #define EM_MMDSP_PLUS 160 #endif #ifndef EM_CYPRESS_M8C #define EM_CYPRESS_M8C 161 #endif #ifndef EM_R32C #define EM_R32C 162 #endif #ifndef EM_TRIMEDIA #define EM_TRIMEDIA 163 #endif #ifndef EM_QDSP6 #define EM_QDSP6 164 #endif #ifndef EM_QUALCOMM_DSP6 #define EM_QUALCOMM_DSP6 164 #endif #ifndef EM_8051 #define EM_8051 165 #endif #ifndef EM_STXP7X #define EM_STXP7X 166 #endif #ifndef EM_NDS32 #define EM_NDS32 167 #endif #ifndef EM_ECOG1X #define EM_ECOG1X 168 #endif #ifndef EM_MAXQ30 #define EM_MAXQ30 169 #endif #ifndef EM_XIMO16 #define EM_XIMO16 170 #endif #ifndef EM_MANIK #define EM_MANIK 171 #endif #ifndef EM_CRAYNV2 #define EM_CRAYNV2 172 #endif #ifndef EM_RX #define EM_RX 173 #endif #ifndef EM_METAG #define EM_METAG 174 #endif #ifndef EM_MCST_ELBRUS #define EM_MCST_ELBRUS 175 #endif #ifndef EM_ECOG16 #define EM_ECOG16 176 #endif #ifndef EM_CR16 #define EM_CR16 177 #endif #ifndef EM_ETPU #define EM_ETPU 178 #endif #ifndef EM_SLE9X #define EM_SLE9X 179 #endif #ifndef EM_L10M #define EM_L10M 180 #endif #ifndef EM_K10M #define EM_K10M 181 #endif #ifndef EM_AARCH64 #define EM_AARCH64 183 #endif #ifndef EM_AVR32 #define EM_AVR32 185 #endif #ifndef EM_STM8 #define EM_STM8 186 #endif #ifndef EM_TILE64 #define EM_TILE64 187 #endif #ifndef EM_TILEPRO #define EM_TILEPRO 188 #endif #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif #ifndef EM_CUDA #define EM_CUDA 190 #endif #ifndef EM_TILEGX #define EM_TILEGX 191 #endif #ifndef EM_CLOUDSHIELD #define EM_CLOUDSHIELD 192 #endif #ifndef EM_COREA_1ST #define EM_COREA_1ST 193 #endif #ifndef EM_COREA_2ND #define EM_COREA_2ND 194 #endif #ifndef EM_ARC_COMPACT2 #define EM_ARC_COMPACT2 195 #endif #ifndef EM_OPEN8 #define EM_OPEN8 196 #endif #ifndef EM_RL78 #define EM_RL78 197 #endif #ifndef EM_VIDEOCORE5 #define EM_VIDEOCORE5 198 #endif #ifndef EM_78KOR #define EM_78KOR 199 #endif #ifndef EM_56800EX #define EM_56800EX 200 #endif #ifndef EM_BA1 #define EM_BA1 201 #endif #ifndef EM_BA2 #define EM_BA2 202 #endif #ifndef EM_XCORE #define EM_XCORE 203 #endif #ifndef EM_MCHP_PIC #define EM_MCHP_PIC 204 #endif #ifndef EM_KM32 #define EM_KM32 210 #endif #ifndef EM_KMX32 #define EM_KMX32 211 #endif #ifndef EM_EMX16 #define EM_EMX16 212 #endif #ifndef EM_EMX8 #define EM_EMX8 213 #endif #ifndef EM_KVARC #define EM_KVARC 214 #endif #ifndef EM_CDP #define EM_CDP 215 #endif #ifndef EM_COGE #define EM_COGE 216 #endif #ifndef EM_COOL #define EM_COOL 217 #endif #ifndef EM_NORC #define EM_NORC 218 #endif #ifndef EM_CSR_KALIMBA #define EM_CSR_KALIMBA 219 #endif #ifndef EM_Z80 #define EM_Z80 220 #endif #ifndef EM_VISIUM #define EM_VISIUM 221 #endif #ifndef EM_FT32 #define EM_FT32 222 #endif #ifndef EM_MOXIE #define EM_MOXIE 223 #endif #ifndef EM_AMDGPU #define EM_AMDGPU 224 #endif #ifndef EM_RISCV #define EM_RISCV 243 #endif #ifndef EM_BPF #define EM_BPF 247 #endif /* Standard Elf dynamic tags. */ #ifndef DT_NULL #define DT_NULL 0 #endif #ifndef DT_NEEDED #define DT_NEEDED 1 #endif #ifndef DT_PLTRELSZ #define DT_PLTRELSZ 2 #endif #ifndef DT_PLTGOT #define DT_PLTGOT 3 #endif #ifndef DT_HASH #define DT_HASH 4 #endif #ifndef DT_STRTAB #define DT_STRTAB 5 #endif #ifndef DT_SYMTAB #define DT_SYMTAB 6 #endif #ifndef DT_RELA #define DT_RELA 7 #endif #ifndef DT_REL #define DT_REL 17 #endif #ifndef DT_RELASZ #define DT_RELASZ 8 #endif #ifndef DT_RELAENT #define DT_RELAENT 9 #endif #ifndef DT_STRSZ #define DT_STRSZ 10 #endif #ifndef DT_SYMENT #define DT_SYMENT 11 #endif #ifndef DT_INIT #define DT_INIT 12 #endif #ifndef DT_FINI #define DT_FINI 13 #endif #ifndef DT_SONAME #define DT_SONAME 14 #endif #ifndef DT_RPATH #define DT_RPATH 15 #endif #ifndef DT_SYMBOLIC #define DT_SYMBOLIC 16 #endif #ifndef DT_REL #define DT_REL 17 #endif #ifndef DT_RELSZ #define DT_RELSZ 18 #endif #ifndef DT_RELENT #define DT_RELENT 19 #endif #ifndef DT_PLTREL #define DT_PLTREL 20 #endif #ifndef DT_DEBUG #define DT_DEBUG 21 #endif #ifndef DT_TEXTREL #define DT_TEXTREL 22 #endif #ifndef DT_JMPREL #define DT_JMPREL 23 #endif #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif #ifndef SHN_LORESERVE #define SHN_LORESERVE 0xff00 #endif #ifndef SHN_LOPROC #define SHN_LOPROC 0xff00 #endif #ifndef SHN_HIPROC #define SHN_HIPROC 0xff1f #endif #ifndef SHN_ABS #define SHN_ABS 0xfff1 #endif #ifndef SHN_COMMON #define SHN_COMMON 0xfff2 #endif #ifndef SHN_HIRESERVE #define SHN_HIRESERVE 0xffff #endif #ifndef EV_CURRENT #define EV_CURRENT 1 #endif #ifndef EV_NONE #define EV_NONE 0 #endif #ifndef EI_MAG0 #define EI_MAG0 0 #endif #ifndef EI_MAG1 #define EI_MAG1 1 #endif #ifndef EI_MAG2 #define EI_MAG2 2 #endif #ifndef EI_MAG3 #define EI_MAG3 3 #endif #ifndef EI_CLASS #define EI_CLASS 4 #endif #ifndef EI_DATA #define EI_DATA 5 #endif #ifndef EI_VERSION #define EI_VERSION 6 #endif #ifndef EI_PAD #define EI_PAD 7 #endif #ifndef EI_OSABI #define EI_OSABI 7 #endif #ifndef EI_NIDENT #define EI_NIDENT 16 #endif #ifndef EI_ABIVERSION #define EI_ABIVERSION 8 #endif #ifndef ELFMAG0 #define ELFMAG0 0x7f #endif #ifndef ELFMAG1 #define ELFMAG1 'E' #endif #ifndef ELFMAG2 #define ELFMAG2 'L' #endif #ifndef ELFMAG3 #define ELFMAG3 'F' #endif #ifndef ELFCLASSNONE #define ELFCLASSNONE 0 #endif #ifndef ELFCLASS32 #define ELFCLASS32 1 #endif #ifndef ELFCLASS64 #define ELFCLASS64 2 #endif #ifndef ELFDATANONE #define ELFDATANONE 0 #endif #ifndef ELFDATA2LSB #define ELFDATA2LSB 1 #endif #ifndef ELFDATA2MSB #define ELFDATA2MSB 2 #endif #ifndef ELFOSABI_NONE #define ELFOSABI_NONE 0 #endif #ifndef ELFOSABI_SYSV #define ELFOSABI_SYSV 0 #endif #ifndef ELFOSABI_HPUX #define ELFOSABI_HPUX 1 #endif #ifndef ELFOSABI_NETBSD #define ELFOSABI_NETBSD 2 #endif #ifndef ELFOSABI_GNU #define ELFOSABI_GNU 3 #endif #ifndef ELFOSABI_LINUX #define ELFOSABI_LINUX ELFOSABI_GNU #endif #ifndef ELFOSABI_SOLARIS #define ELFOSABI_SOLARIS 6 #endif #ifndef ELFOSABI_AIX #define ELFOSABI_AIX 7 #endif #ifndef ELFOSABI_IRIX #define ELFOSABI_IRIX 8 #endif #ifndef ELFOSABI_FREEBSD #define ELFOSABI_FREEBSD 9 #endif #ifndef ELFOSABI_TRU64 #define ELFOSABI_TRU64 10 #endif #ifndef ELFOSABI_MODESTO #define ELFOSABI_MODESTO 11 #endif #ifndef ELFOSABI_OPENBSD #define ELFOSABI_OPENBSD 12 #endif #ifndef ELFOSABI_ARM_AEABI #define ELFOSABI_ARM_AEABI 64 #endif #ifndef ELFOSABI_ARM #define ELFOSABI_ARM 97 #endif #ifndef ELFOSABI_STANDALONE #define ELFOSABI_STANDALONE 255 #endif /* for the producer code. */ #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #ifndef R_QUALCOMM_REL32 #define R_QUALCOMM_REL32 6 #endif /* For Freebsd: */ #ifndef R_PPC64_ADDR32 #define R_PPC64_ADDR32 1 #endif #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* The following two probably useless. */ #ifndef R_X86_64_PC32_BND #define R_X86_64_PC32_BND 39 #endif #ifndef R_X86_64_PLT32_BND #define R_X86_64_PLT32_BND 40 #endif /* Seen in a Linux Kernel. Means 'nothing to do' */ #ifndef R_X86_64_NONE #define R_X86_64_NONE 0 #endif /* R_X86_64_NONE */ #ifndef R_386_32 #define R_386_32 1 #endif /* R_386_32 */ #ifndef R_386_GOTPC #define R_386_GOTPC 10 #endif /* R_386_GOTPC */ #ifndef R_386_PC32 #define R_386_PC32 2 #endif /* R_386_PC32 */ #ifndef R_386_TLS_DTPOFF32 #define R_386_TLS_DTPOFF32 36 #endif /* R_386_TLS_DTPOFF32 */ #ifndef R_386_TLS_LDO_32 #define R_386_TLS_LDO_32 32 #endif /* R_386_TLS_LDO_32 */ #ifndef R_390_32 #define R_390_32 4 #endif /* R_390_32 */ #ifndef R_390_64 #define R_390_64 22 #endif /* R_390_64 */ #ifndef R_390_TLS_LDO32 #define R_390_TLS_LDO32 52 #endif /* R_390_TLS_LDO32 */ #ifndef R_390_TLS_LDO64 #define R_390_TLS_LDO64 53 #endif /* R_390_TLS_LDO64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 258 #endif /* R_AARCH64_ABS32 */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 257 #endif /* R_AARCH64_ABS64 */ #ifndef R_ARM_ABS32 #define R_ARM_ABS32 2 #endif /* R_ARM_ABS32 */ #ifndef R_ARM_TLS_LDO32 #define R_ARM_TLS_LDO32 106 #endif /* R_ARM_TLS_LDO32 */ #ifndef R_IA64_DIR32LSB #define R_IA64_DIR32LSB 0x25 #endif /* R_IA64_DIR32LSB */ #ifndef R_IA64_DIR64LSB #define R_IA64_DIR64LSB 0x27 #endif /* R_IA64_DIR64LSB */ #ifndef R_IA64_DTPREL32LSB #define R_IA64_DTPREL32LSB 0xb5 #endif /* R_IA64_DTPREL32LSB */ #ifndef R_IA64_DTPREL64LSB #define R_IA64_DTPREL64LSB 0xb7 #endif /* R_IA64_DTPREL64LSB */ #ifndef R_IA64_REL32LSB #define R_IA64_REL32LSB 0x6d #endif /* R_IA64_REL32LSB */ #ifndef R_IA64_SECREL32LSB #define R_IA64_SECREL32LSB 0x65 #endif /* R_IA64_SECREL32LSB */ #ifndef R_IA64_SECREL64LSB #define R_IA64_SECREL64LSB 0x67 #endif /* R_IA64_SECREL64LSB */ #ifndef R_MIPS_32 #define R_MIPS_32 2 #endif /* R_MIPS_32 */ #ifndef R_MIPS_64 #define R_MIPS_64 18 #endif /* R_MIPS_64 */ #ifndef R_MIPS_TLS_DTPREL32 #define R_MIPS_TLS_DTPREL32 39 #endif /* R_MIPS_TLS_DTPREL32 */ #ifndef R_MIPS_TLS_DTPREL64 #define R_MIPS_TLS_DTPREL64 41 #endif /* R_MIPS_TLS_DTPREL64 */ #ifndef R_PPC64_ADDR64 #define R_PPC64_ADDR64 38 #endif /* R_PPC64_ADDR64 */ #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif /* R_PPC64_DTPREL32 */ #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif /* R_PPC64_DTPREL64 */ #ifndef R_PPC_ADDR32 #define R_PPC_ADDR32 1 #endif /* R_PPC_ADDR32 */ #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* R_PPC_DTPREL32 */ #ifndef R_QUALCOMM_REL32 #define R_QUALCOMM_REL32 6 #endif /* R_QUALCOMM_REL32 */ #ifndef R_SH_DIR32 #define R_SH_DIR32 1 #endif /* R_SH_DIR32 */ #ifndef R_SH_TLS_DTPOFF32 #define R_SH_TLS_DTPOFF32 150 #endif /* R_SH_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF32 #define R_SPARC_TLS_DTPOFF32 76 #endif /* R_SPARC_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF64 #define R_SPARC_TLS_DTPOFF64 77 #endif /* R_SPARC_TLS_DTPOFF64 */ #ifndef R_SPARC_UA32 #define R_SPARC_UA32 23 #endif /* R_SPARC_UA32 */ #ifndef R_SPARC_UA64 #define R_SPARC_UA64 54 #endif /* R_SPARC_UA64 */ #ifndef R_X86_64_32 #define R_X86_64_32 10 #endif /* R_X86_64_32 */ #ifndef R_X86_64_64 #define R_X86_64_64 1 #endif /* R_X86_64_64 */ #ifndef R_X86_64_PC64 #define R_X86_64_PC64 24 #endif /* R_X86_64_PC64 */ #ifndef R_X86_64_DTPOFF32 #define R_X86_64_DTPOFF32 21 #endif /* R_X86_64_DTPOFF32 */ #ifndef R_X86_64_DTPOFF64 #define R_X86_64_DTPOFF64 17 #endif /* R_X86_64_DTPOFF64 */ #ifndef R_X86_64_PC32 #define R_X86_64_PC32 2 #endif /* R_X86_64_PC32 */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ELF_DEFINES_H */ libdwarf-20210528/libdwarf/pro_error.h0000644000175000017500000000304713743575426014472 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Handle error passing in the name of the Dwarf_P_Debug User must supply {} around the macro. Putting the {} here leads to macro uses that don't look like C. The error argument to dwarf_error is hard coded here as 'error' */ #define DWARF_P_DBG_ERROR(dbg,errval,retval) \ _dwarf_p_error(dbg,error,errval); return(retval); struct Dwarf_Error_s { Dwarf_Signed er_errval; }; void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, Dwarf_Unsigned errval); libdwarf-20210528/libdwarf/dwarf_gnu_index.c0000664000175000017500000005431214004650177015606 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is for accessing .debug_gnu_pubnames and .debug_gnu_pubtypes. It has nothing to do with .gdb_index. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_gnu_index.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 #if 0 static void dump_block(const char *msg,int bn, int lno, struct Dwarf_Gnu_IBlock_s *b) { printf("BLOCK dump block %d %s line %d\n", bn,msg,lno); printf("head : 0x%lx\n", (unsigned long)b->ib_head); printf("index : %lu\n", (unsigned long)b->ib_index); printf("blk len offset : 0x%lx\n", (unsigned long)b->ib_block_length_offset); printf("block length : %lu 0x%lx\n", (unsigned long)b->ib_block_length, (unsigned long)b->ib_block_length); printf("offset size : %u\n", b->ib_offset_size); printf("extension size : %u\n", b->ib_extension_size); printf("version : %u\n", b->ib_version); printf("built entries? : %s\n", b->ib_counted_entries?"yes":"no"); printf("debug_info offset: 0x%lx\n", (unsigned long)b->ib_offset_in_debug_info); printf("debug_info size : %lu 0x%lx\n", (unsigned long)b->ib_size_in_debug_info, (unsigned long)b->ib_size_in_debug_info); printf("data offset : 0x%lx\n", (unsigned long)b->ib_b_data_offset); printf("entries offset : 0x%lx\n", (unsigned long)b->ib_b_offset); printf("entries ptr : 0x%lx\n", (unsigned long)b->ib_b_data); printf("entries length : %lu 0x%lx\n", (unsigned long)b->ib_b_entrylength, (unsigned long)b->ib_b_entrylength); printf("entry count : %lu\n", (unsigned long)b->ib_entry_count); printf("entries array : 0x%lx\n", (unsigned long)b->ib_entryarray); } #endif /* We could use dwarf_get_real_section_name() to determine the real name (perhaps ending in .dwo) but for now we just use the standard name here. */ static void get_pubxx_fields(Dwarf_Debug dbg, Dwarf_Bool for_gnu_pubnames, struct Dwarf_Section_s **sec_out, const char **sec_name_out, int *errnum_out, const char **errstr_out) { if (!dbg) { return; } if (for_gnu_pubnames) { if (sec_name_out) { *sec_name_out = ".debug_gnu_pubnames"; } if (sec_out) { *sec_out = &dbg->de_debug_gnu_pubnames; } if (errnum_out) { *errnum_out = DW_DLE_GNU_PUBNAMES_ERROR; } if (errstr_out) { *errstr_out = "DW_DLE_GNU_PUBNAMES_ERROR"; } } else { if (sec_name_out) { *sec_name_out = ".debug_gnu_pubtypes"; } if (sec_out) { *sec_out = &dbg->de_debug_gnu_pubtypes; } if (errnum_out) { *errnum_out = DW_DLE_GNU_PUBTYPES_ERROR; } if (errstr_out) { *errstr_out = "DW_DLE_GNU_PUBTYPES_ERROR"; } } } static int load_pub_section(Dwarf_Debug dbg, Dwarf_Bool for_gnu_pubnames, Dwarf_Error *error) { struct Dwarf_Section_s * sec = 0; int res; get_pubxx_fields(dbg,for_gnu_pubnames,&sec,0,0,0); res = _dwarf_load_section(dbg,sec,error); return res; } static int scan_block_entries(Dwarf_Debug dbg, Dwarf_Bool for_gnu_pubnames, Dwarf_Unsigned *count_out, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; Dwarf_Small *startptr = 0; Dwarf_Small *curptr = 0; Dwarf_Small *endptr = 0; Dwarf_Unsigned seclen = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned filesize = 0; Dwarf_Unsigned blockoffset = 0; int errnum = 0; const char * errstr = 0; const char * secname = 0; get_pubxx_fields(dbg,for_gnu_pubnames,&sec,&secname, &errnum,&errstr); filesize = dbg->de_filesize; startptr = sec->dss_data; curptr = startptr; seclen = sec->dss_size; endptr = startptr + seclen; if (filesize) { if (seclen >= filesize) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m,(char*)errstr); dwarfstring_append_printf_u(&m, ": section length %u" " is larger than the file size in", seclen); dwarfstring_append(&m,(char*)secname); _dwarf_error_string(dbg,error,errnum, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } for (;;) { Dwarf_Unsigned length = 0; unsigned int offsetsize = 0; unsigned int extensize = 0; if (curptr == endptr) { *count_out = count; return DW_DLV_OK; } /* Not sure how the coders think about the initial value. But the last 4 bytes are zero, ignore those. Unclear 64bit is not allowed. */ READ_AREA_LENGTH_CK(dbg,length,Dwarf_Unsigned, curptr,offsetsize,extensize,error,seclen,endptr); ++count; curptr += length -offsetsize - extensize; curptr += 4; blockoffset += length; blockoffset +=4; } /* NOTREACHED */ *count_out = count; return DW_DLV_OK; } static int count_entries_in_block(struct Dwarf_Gnu_IBlock_s * gib, struct DGI_Entry_s* entries, Dwarf_Error* error) { Dwarf_Small *curptr = gib->ib_b_data; Dwarf_Small *endptr = curptr + gib->ib_b_entrylength; Dwarf_Unsigned entrycount = 0; Dwarf_Half offsetsize = gib->ib_offset_size; struct DGI_Entry_s *curentry = 0; Dwarf_Debug dbg = 0; Dwarf_Gnu_Index_Head head = 0; Dwarf_Bool for_pubnames = 0; char *strptr = 0; head = gib->ib_head; for_pubnames = head->gi_is_pubnames; dbg = head->gi_dbg; for ( ; curptr < endptr; ++entrycount) { Dwarf_Unsigned infooffset = 0; Dwarf_Unsigned offset = 0; char flagbyte = 0; READ_UNALIGNED_CK(dbg,offset, Dwarf_Unsigned,curptr, offsetsize,error,endptr); infooffset = offset; curptr += offsetsize; if (entries) { curentry = entries +entrycount; curentry->ge_debug_info_offset = infooffset; } /* Ensure flag and start-of-string possible. */ if ((curptr+2) >= endptr) { int errnum = 0; const char *secname = 0; const char*errstr = 0; dwarfstring m; get_pubxx_fields(dbg,for_pubnames,0,&secname, &errnum,&errstr); dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m,"%s: " "Past end of current block reading strings", (char *)errstr); dwarfstring_append_printf_s(&m," in %s", (char *)secname); _dwarf_error_string(dbg,error,errnum, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } flagbyte = *curptr; curptr += 1; strptr = (char *)curptr; if (curentry) { curentry->ge_flag_byte = flagbyte; curentry->ge_string = (char *)strptr; } for ( ; *curptr ;++curptr,++offset ) { if (curptr >= endptr) { int errnum = 0; const char*secname = 0; const char*errstr = 0; dwarfstring m; get_pubxx_fields(dbg,for_pubnames, 0,&secname,&errnum,&errstr); dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m,"%s: " "Past end of current block reading strings", (char *)errstr); dwarfstring_append_printf_s(&m," in section %s", (char*)secname); _dwarf_error_string(dbg,error,errnum, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } /* string-terminating null byte */ curptr += 1; } if (!entries) { gib->ib_entry_count = entrycount; } else if (gib->ib_entry_count != entrycount) { int err = 0; const char *errstr = 0; const char *secname = 0; char buf[120]; dwarfstring m; buf[0] = 0; get_pubxx_fields(dbg,for_pubnames,0,&secname, &err,&errstr); dwarfstring_constructor_static(&m,buf,sizeof(buf)); dwarfstring_append(&m,(char *)errstr); dwarfstring_append_printf_s(&m,":mismatch counts " "creating %s" "block_entries.", (char *)secname); dwarfstring_append_printf_u(&m," Origcount %u", gib->ib_entry_count); dwarfstring_append_printf_u(&m," new count %u", entrycount); _dwarf_error_string(dbg,error,err, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } return DW_DLV_OK; } static int fill_in_blocks(Dwarf_Gnu_Index_Head head, Dwarf_Error *error) { Dwarf_Unsigned i = 0; Dwarf_Unsigned dataoffset = 0; #if 0 Dwarf_Unsigned blockindex = 0; Dwarf_Unsigned blockoffset = 0; Dwarf_Unsigned listoffset = 0; #endif Dwarf_Small * endptr = 0; Dwarf_Small * curptr = 0; Dwarf_Small * baseptr = 0; Dwarf_Bool is_for_pubnames = head->gi_is_pubnames; Dwarf_Debug dbg = head->gi_dbg; Dwarf_Unsigned seclen = head->gi_section_length; baseptr = head->gi_section_data; endptr = baseptr + head->gi_section_length; for ( ;i < head->gi_blockcount; ++i) { Dwarf_Unsigned length = 0; unsigned int offsetsize = 0; unsigned int extensize = 0; Dwarf_Half version = 0; Dwarf_Unsigned offset_into_debug_info = 0; Dwarf_Unsigned length_of_CU_in_debug_info = 0; struct Dwarf_Gnu_IBlock_s *gib = 0; int res = 0; gib = head->gi_blockarray+i; /* gib is a blank slate ready to be filled */ curptr = baseptr+ dataoffset; READ_AREA_LENGTH_CK(dbg,length,Dwarf_Unsigned, curptr,offsetsize,extensize,error,seclen,endptr); if (!length) { /* Must be end of the section */ if (curptr != endptr) { const char *errstr = 0; int errnum = 0; const char *secname = 0; dwarfstring m; /* Something is very wrong */ get_pubxx_fields(dbg,is_for_pubnames, 0,&secname,&errnum, &errstr); dwarfstring_constructor(&m); dwarfstring_append(&m,(char *)errstr); dwarfstring_append_printf_s(&m,": encountered zero" " area length before end of %s", (char*)secname); _dwarf_error_string(dbg,error,errnum, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } return DW_DLV_OK; } gib->ib_index = i; gib->ib_head = head; gib->ib_offset_size = offsetsize; gib->ib_block_length = length; gib->ib_block_length_offset = dataoffset; dataoffset += offsetsize + extensize; gib->ib_b_data_offset = dataoffset; READ_UNALIGNED_CK(dbg,version,Dwarf_Half,curptr, DWARF_HALF_SIZE,error,endptr); curptr += DWARF_HALF_SIZE; dataoffset += DWARF_HALF_SIZE; gib->ib_version = version; READ_UNALIGNED_CK(dbg,offset_into_debug_info, Dwarf_Unsigned,curptr, offsetsize,error,endptr); curptr += offsetsize; dataoffset += offsetsize; gib->ib_offset_in_debug_info = offset_into_debug_info; READ_UNALIGNED_CK(dbg,length_of_CU_in_debug_info, Dwarf_Unsigned,curptr, offsetsize,error,endptr); gib->ib_size_in_debug_info = length_of_CU_in_debug_info; dataoffset += offsetsize; curptr += offsetsize; gib->ib_b_data = curptr; gib->ib_b_offset = dataoffset; gib->ib_b_entrylength = length - (2 + (2*offsetsize)); /* Followed by 4 bytes of zeroes */ gib->ib_b_entrylength -= 4; /* Set for next block., add in4 for ending zeros */ dataoffset = gib->ib_block_length_offset + length + 4; res = count_entries_in_block(gib,0,error); if (res != DW_DLV_OK) { return res; } } return DW_DLV_OK; } static int fill_in_entries(Dwarf_Gnu_Index_Head head, struct Dwarf_Gnu_IBlock_s *gib, Dwarf_Error *error) { Dwarf_Unsigned count = gib->ib_entry_count; struct DGI_Entry_s * entryarray = 0; Dwarf_Bool for_gnu_pubnames = head->gi_is_pubnames; char buf[150]; int res = 0; Dwarf_Debug dbg = 0; dbg = head->gi_dbg; buf[0] = 0; entryarray = (struct DGI_Entry_s*)calloc(count, sizeof(struct DGI_Entry_s)); if (!entryarray) { int err = 0; const char *errstr = 0; const char *secname = 0; dwarfstring m; get_pubxx_fields(dbg,for_gnu_pubnames,0,&secname, &err,&errstr); dwarfstring_constructor_static(&m,buf,sizeof(buf)); dwarfstring_append(&m,(char *)errstr); dwarfstring_append_printf_s(&m,": Unable to allocate " "block_entries. Out of memory creating %s record.", (char *)secname); _dwarf_error_string(dbg,error,err, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } res = count_entries_in_block(gib, entryarray,error); if (res != DW_DLV_OK) { free(entryarray); return res; } gib->ib_entryarray = entryarray; entryarray = 0; return DW_DLV_OK; } int dwarf_get_gnu_index_head(Dwarf_Debug dbg, /* The following arg false to select gnu_pubtypes */ Dwarf_Bool for_gnu_pubnames , Dwarf_Gnu_Index_Head * index_head_out, Dwarf_Unsigned * index_block_count_out, Dwarf_Error * error) { Dwarf_Unsigned count = 0; Dwarf_Gnu_Index_Head head = 0; struct Dwarf_Gnu_IBlock_s *iblock_array; char buf[100]; int res = 0; if (!dbg) { _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: in " "dwarf_get_gnu_index_head"); return DW_DLV_ERROR; } res = load_pub_section(dbg,for_gnu_pubnames,error); if (res != DW_DLV_OK) { return res; } /* We want this loaded for error checking by callers in case they had no reason to load already. */ res = _dwarf_load_debug_info(dbg,error); if (res == DW_DLV_ERROR) { return res; } /* if count zero, returns DW_DLV_NO_ENTRY */ res = scan_block_entries(dbg,for_gnu_pubnames,&count,error); if (res != DW_DLV_OK) { return res; } head = (Dwarf_Gnu_Index_Head) _dwarf_get_alloc(dbg,DW_DLA_GNU_INDEX_HEAD,1); if (!head) { dwarfstring m; int err = 0; const char *errstr = 0; const char *secname = 0; get_pubxx_fields(dbg,for_gnu_pubnames,0,&secname, &err,&errstr); dwarfstring_constructor_static(&m,buf,sizeof(buf)); dwarfstring_append(&m,(char *)errstr); dwarfstring_append_printf_s(&m,": Unable to allocate " "a header record. Out of memory creating %s record.", (char *)secname); _dwarf_error_string(dbg,error,err, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } head->gi_dbg = dbg; head->gi_section_data = for_gnu_pubnames? dbg->de_debug_gnu_pubnames.dss_data: dbg->de_debug_gnu_pubtypes.dss_data; head->gi_section_length = for_gnu_pubnames? dbg->de_debug_gnu_pubnames.dss_size: dbg->de_debug_gnu_pubtypes.dss_size; head->gi_is_pubnames = for_gnu_pubnames; iblock_array = calloc(count,sizeof(struct Dwarf_Gnu_IBlock_s)); if (!iblock_array) { dwarfstring m; int err = 0; const char *errstr = 0; get_pubxx_fields(dbg,for_gnu_pubnames,0,0, &err,&errstr); dwarfstring_constructor_static(&m,buf,sizeof(buf)); dwarfstring_append(&m,(char *)errstr); dwarfstring_append_printf_u(&m,": Unable to allocate " " %u block records. Out of memory.",count); _dwarf_error_string(dbg,error,err, dwarfstring_string(&m)); dwarfstring_destructor(&m); dwarf_gnu_index_dealloc(head); return DW_DLV_ERROR; } head->gi_blockarray = iblock_array; head->gi_blockcount = count; res = fill_in_blocks(head,error); if (res != DW_DLV_OK) { return res; } *index_head_out = head; *index_block_count_out = count; return DW_DLV_OK; } /* Frees all resources used for the indexes. */ void _dwarf_free_gnu_index_head_content(Dwarf_Gnu_Index_Head head) { if (!head) { return; } if (head->gi_blockarray) { Dwarf_Unsigned i = 0; struct Dwarf_Gnu_IBlock_s *block = head->gi_blockarray; for ( ; i < head->gi_blockcount; ++i,block++) { if (block->ib_entryarray) { free(block->ib_entryarray); block->ib_entryarray = 0; } block->ib_entry_count = 0; } free(head->gi_blockarray); head->gi_blockarray = 0; head->gi_blockcount = 0; } } void dwarf_gnu_index_dealloc(Dwarf_Gnu_Index_Head head) { Dwarf_Debug dbg; if (!head) { return; } dbg = head->gi_dbg; if (!dbg) { return; } _dwarf_free_gnu_index_head_content(head); dwarf_dealloc(dbg,head,DW_DLA_GNU_INDEX_HEAD); } void _dwarf_gnu_index_head_destructor(void *incoming) { Dwarf_Gnu_Index_Head head = 0; head = (Dwarf_Gnu_Index_Head)incoming; if (!head) { return; } _dwarf_free_gnu_index_head_content(head); return; } int dwarf_get_gnu_index_block(Dwarf_Gnu_Index_Head head, Dwarf_Unsigned number, Dwarf_Unsigned * block_length, Dwarf_Half * version, Dwarf_Unsigned * offset_into_debug_info, Dwarf_Unsigned * size_of_debug_info_area, Dwarf_Unsigned * count_of_entries, Dwarf_Error * error) { struct Dwarf_Gnu_IBlock_s *gib = 0; if (!head) { _dwarf_error_string(0,error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: in " "dwarf_get_gnu_index_block"); return DW_DLV_ERROR; } if (number >= head->gi_blockcount) { return DW_DLV_NO_ENTRY; } gib = head->gi_blockarray + number; if (block_length) { *block_length = gib->ib_block_length; } if (version) { *version = gib->ib_version; } if (offset_into_debug_info) { *offset_into_debug_info = gib->ib_offset_in_debug_info; } if (size_of_debug_info_area) { *size_of_debug_info_area = gib->ib_size_in_debug_info; } if (count_of_entries) { *count_of_entries = gib->ib_entry_count; } return DW_DLV_OK; } int dwarf_get_gnu_index_block_entry(Dwarf_Gnu_Index_Head head, Dwarf_Unsigned blocknumber, Dwarf_Unsigned entrynumber, Dwarf_Unsigned * offset_in_debug_info, const char ** name_string, unsigned char * flagbyte, unsigned char * staticorglobal, unsigned char * typeofentry, Dwarf_Error * error) { struct Dwarf_Gnu_IBlock_s *gib = 0; struct DGI_Entry_s *be = 0; if (!head) { _dwarf_error_string(0,error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: in " "dwarf_get_gnu_index_block_entry"); } if (blocknumber >= head->gi_blockcount) { return DW_DLV_NO_ENTRY; } gib = head->gi_blockarray + blocknumber; if (!gib->ib_counted_entries) { int res = 0; gib->ib_counted_entries = TRUE; res = fill_in_entries(head,gib,error); if (res != DW_DLV_OK) { return res; } } if (entrynumber >= gib->ib_entry_count) { return DW_DLV_NO_ENTRY; } be = gib->ib_entryarray + entrynumber; if (offset_in_debug_info) { *offset_in_debug_info = be->ge_debug_info_offset; } if (name_string) { *name_string = be->ge_string; } if (flagbyte) { *flagbyte = be->ge_flag_byte; } if (staticorglobal) { if (be->ge_flag_byte &0x80) { /* value 1, of course... */ *staticorglobal = DW_GNUIVIS_global; } else { *staticorglobal = DW_GNUIVIS_static; } } if (typeofentry) { /* DW_GNUIKIND_ */ unsigned v = be->ge_flag_byte & 0x70; v = v>>4; *typeofentry = v; } return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_elf_rel_detector.h0000664000175000017500000000323013763460606017134 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_ELF_REL_DETECTOR_H #define DWARF_ELF_REL_DETECTOR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ unsigned _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine); unsigned _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ELF_REL_DETECTOR_H */ libdwarf-20210528/libdwarf/pro_expr.h0000664000175000017500000000303114012266121014265 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This is really a sanity limit. It could be increased as necesary for long dwarf expressions. Originally it was 20, and expressions longer than that are now pretty routine. 24 January 2021 */ #define MAXIMUM_LOC_EXPR_LENGTH 300 struct Dwarf_P_Expr_s { Dwarf_Small ex_byte_stream[MAXIMUM_LOC_EXPR_LENGTH]; Dwarf_P_Debug ex_dbg; Dwarf_Unsigned ex_next_byte_offset; Dwarf_Unsigned ex_reloc_sym_index; Dwarf_Unsigned ex_reloc_offset; }; libdwarf-20210528/libdwarf/ChangeLog20130000664000175000017500000003014513644370703014360 000000000000002013-12-26 David Anderson * pro_section.c, pro_types.c, pro_vars.c, pro_weaks.c, pro_forms.c, pro_frame.c,pro_funcs.c,pro_init.c,pro_line.c,pro_macinfo.c, pro_pubnames.c,pro_reloc.c,pro_reloc_stream.c,pro_reloc_symbolic.c, pro_expr.h,pro_macinfo.h,pro_reloc.h,pro_reloc_stream.h, pro_reloc_symbolic.h,pro_section.h,pro_types.h,pro_util.h: Remove trailing whitespace from the code. 2013-11-24 David Anderson * pro_expr.c(dwarf_add_expr_gen): Moved use of a pointer to be after where the pointer tested for NULL. * pro_forms.c(local_add_AT_address): Moved use of a pointer to be after where the pointer tested for NULL. Both bugs found by the STACK code analysis tool from MIT. 2013-10-31 David Anderson * dwarf_error.c: Added DW_DLE_AT_FIXUP_NULL and DW_DLE_AT_FIXUP_DUP. * libdwarf.h.in: Added those two defines plus dwarf_add_AT_reference_b() and dwarf_fixup_AT_reference_die() for CLASS REFERENCE attribute handling. Also, dwarf_add_AT_with_ref_sig8() for refsig8 references. * libdwarf2p.1.mm: version 1.34 20 October. Document new interfaces. Fixed typo in dwarf_add_AT_targ_address_b() documentation. * libdwarf2p.1.pdf: Regenerated. * pro_die.c. Added commentary. * pro_forms.c: Added reference support with dwarf_add_AT_reference_b() and refactoring to avoid duplicating code. Added dwarf_add_AT_with_ref_sig8() * pro_section.c: now only adds DW_AT_sibling automatically if it was not present already. Still only adds it in the same automatically-selected places. Some renaming of local variables for clarity around line 1743. One line reformatted, it was looking very odd, line 2217. 2013-10-17 David Anderson * dwarf_error.c: Add DW_DLE_DEBUGPUBTYPES_ERROR string. * libdwarf.h.in: Add DW_DLE_DEBUGPUBTYPES_ERROR and fix DW_DLE_LAST. Add dwarf_add_pubtype() interface. * libdwarf2.1.mm: References to Dwarf_Pubtype changed to Dwarf_Type, using the same interface type as for .debug_types (an SGI extension). Now at rev 2.15. Clarified that pubnames and pubtypes only apply to .debug_info. * libdwarf2.1.pdf: Regenerated. * pro_opaque.h: Added DEBUG_PUBTYPES and updated NUM_DEBUG_SECTIONS. * pro_pubnames.c: Added dwarf_add_pubtype() support. * pro_section.c: Added support for pubtypes. 2013-10-14 David Anderson * libdwarf.h.in: Dwarf_Callback_Func_c, Dwarf_Callback_Func_b and Dwarf_Callback_Func name argument was lacking a const qualifier leading to compiler warnings. Now has const qualifier. 2013-08-15 David Anderson * dwarf_alloc.c: Now uses dwarf_printf instead of printf. And frees the dwarf_printf dp_buffer if appropriate. * dwarf_line.c, dwarf_print_lines.c: Now use dwarf_printf instead of printf. * dwarf_line.c: Update copyright year. * dwarf_opaque.h: Add de_printf_callback to Dwarf_Debug struct. Add dwarf_printf to function prototypes. * dwarf_util.c: Implement dwarf_printf. * libdwarf.h.in: Now specifies struct Dwarf_Printf_Callback_Info_s and dwarf_register_printf_callback(); * libdwarf2.1.mm: Version 2.14. Fixed three tables with too-long lines. Documented the new printf callback registration functions. * libdwarf2.1.pdf: Regenerated. 2013-08-13 David Anderson * dwarf_init_finish.c: * dwarf_query.c: Added dwarf_highpc_b() so consumers can deal with DW_AT_high_pc with form constant (a feature of DWARF4). * libdwarf.h.in: Added dwarf_highpc_b(), dwarf_add_AT_any_value_sleb(), dwarf_add_AT_any_value_uleb(). to give producers more flexibility. Moved the Dwarf_Form_Class declaration closer to the head of the file so the new function prototypes can reference it. * libdwarf2.1.mm: Version 2.13. Added dwarf_highpc_b(). * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Version 1.33. Documents dwarf_add_AT_any_value_sleb() and dwarf_add_AT_any_value_uleb(). Fixes a one-character typo that was truncating the document severely. * libdwarf2p.1.pdf: Regenerated. * pro_forms.c: Implements dwarf_add_AT_any_value_sleb() and dwarf_add_AT_any_value_uleb(). 2013-08-09 David Anderson * dwarf_init_finish.c: Spelling, change _dwarf_assume_string_bad-> _dwarf_assume_string_in_bound to reflect the actual meaning. * dwarf_alloc.c: Change a debug message for DWARF_SIMPLE_MALLOC to write to stdout, not stderr. All non-fatal messages now print to stdout. * libdwarf2.1.mm: Now version 2.12. Corrected the description of dwarf_set_stringcheck(). * libdwarf2.1.pdf: Regenerated. 2013-08-08 David Anderson * dwarf_form.c: When a FORM_string attribute is in debug_types it is now correctly dealt with. 2013-08-07 David Anderson * dwarf_init_finish.c: Changed a nonfatal error to write it to stdout instead of stderr to make it easier to understand the context of the error (which involves the number of debug sections, not something anyone should ever see). 2013-07-28 David Anderson * dwarf_abbrev.c, dwarf_frame.c, dwarf_frame3.c,dwarf_line.c, pro_reloc_stream.c, pro_section.c: Rename local variables to avoid compiler warnings about local variables reusing outer scope (including global) names. * dwarf_elf_access.c: Add AARCH64 support. * dwarf_reloc_arm.h: Add AARCH64 support. * libdwarf2.1.mm: dwarf_highpc() documentation admits it does not work properly for DWARF4 in all cases. dwarf_highpc() needs to be fixed. * libdwarf2.1.pdf: Regenerated 2013-06-08 David Anderson * libdwarf2.1.mm: Improved the documentation of dwarf_highpc() function to suggest how to interpret the value (pc or offset). * libdwarf2.1.pdf: Regenerated. 2013-03-08 David Anderson * dwarf_elf_access.c: Now we handle K10M and L10M as having relocations named as in x86, x86_64. 2013-02-07 David Anderson * dwarf_elf_access.c: FreeBSD did not have R_PPC64_ADDR32 as a relocation name, so changed one name to be the name usable in Ubuntu and FreeBSD, R_PPC_ADDR32. 2013-02-01 David Anderson * libdwarf2.1.mm: Improved the documentation of the badly-named functions dwarf_whatform() and dwarf_whatform_direct(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h.in: The arguments to dwarf_whatform[_direct]() are renamed for clarity. They are commented out, so this is just improving documentation. 2013-01-20 David Anderson * libdwarf.h: Removed. * libdwarf.h.in: Added. Identical content to standard libdwarf. * configure.in: Generates libdwarf.h. Notices if struct _Elf in libelf.h and generates libdwarf.h appropriately. * configure: Regenerated * README now mentions the libdwarf.h generation at configure time. 2013-01-28 David Anderson * dwarf_frame.c: Fix a macro so it does not test unsigned numbers as being less than zero. Fixes a compiler warning. * malloc_check.c: Add void as the parameter list of a parameter-less function. Fixes a compiler warning. 2013-01-26 David Anderson * libdwarf.h: Remove the lc_number3 field to restore interface binary compatibility with earlier releases. * dwarf_loc.c, dwarf_loc.h: No longer uses the removed lc_number3 or lr_number3 fields. 2013-01-25 David Anderson * dwarf_alloc.c: Changed some local names to avoid compiler warnings about redefining names in inner contexts. * dwarf_frame2.c: Changed some local names to avoid compiler warnings about redefining names in inner contexts. Added const to some declarations to avoid warnings about const being cast away. * dwarf_init_finish.c: Added const to some declarations to avoid warnings about const being cast away. Changed some local names to avoid compiler warnings about redefining names in inner contexts. * dwarf_line.c, dwarf_print_lines.c: Added const to some declarations to avoid warnings about const being cast away. Added static to function definition to reflect its use and to avoid warning about lack of a visible prototype. * gennames.c: Using C89/90 void to declare functions with no arguments to avoid compiler warnings about using old style declarations. Changed some local names to avoid compiler warnings about redefining names in inner contexts. Added const to some declarations to avoid warnings about const being cast away. * pro_incl.h: WRITE_UNALIGNED macros now cast with const to avoid warnings about const being cast away. * pro_macinfo.c,pro_section.c,pro_section.h: Added const to some declarations to avoid warnings about const being cast away. 2013-01-25 David Anderson * common.c: Add 'const' on string declarations to avoid compiler warnings. * dwarf_loc.h: Add the new field lc_number3 to handle DW_OP_GNU_const_type properly. * dwarf_loc.c: Handle DW_OP_GNU_const_type properly. * libdwarf.h: Add lr_number3 so we can handle DW_OP_GNU_const_type properly. This destroys binary compatibility. Not a good idea. See Jan 26, above. 2013-01-25 David Anderson * dwarf_loc.c: Use cc_length_size, not cc_length to get the offset size. Nasty bug. * dwarf_opaque.h: Change commentary to clarify the cc_length field content to hopefully avoid making that mistake again. 2013-01-15 David Anderson * dwarf.h: defines for some added DW_OP_GNU operators * dwarf_loc.c: Added support for some DW_OP_GNU operators. * config.h.in, configure.in: Define and set HAVE_STRUCT_UNDERSCORE_ELF as FreeBSD names struct _Elf instead of struct Elf. * configure: Regenerated. * dwarf_alloc.c: Initialize a local var at declaration, add const to array of strings type declaration. * dwarf_alloc.h: Change ah_structs_per_chunk to Dwarf_Sword to eliminate a compiler warning. * dwarf_arange.c: Change a couple Dwarf_Unsigned to Dwarf_Signed to eliminate a compiler warning. * dwarf_die_deliv.c: Change local to Dwarf_Unsigned to eliminate signed compare warning (and actually signed was wrong anyway!). * dwarf_error.c: Fix comparison to eliminate signed/unsigned compare warning. * dwarf_form.c: Index variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_frame.c: Local variables changed to unsigned to eliminate signed/unsigned comparison warnings. * dwarf_frame3.c: Local variables changed to unsigned to eliminate signed/unsigned comparison warnings. * dwarf_init_finish.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_leb.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_line.c: Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * dwarf_loc.c: Delete two unused local variables. * dwarf_loc.c: Delete two unused local variables. * dwarf_macro.c: Fixed comparisons eliminate signed/unsigned comparison warning. * dwarf_opaque.h: Changed cc_abbrev_offset and de_fde_count to unsigned (which they should have been all along) to eliminate signed/unsigned comparison warnings. * dwarf_print_lines.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_util.c: Add include of pro_encode_nm.h to avoid a compiler warning. Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * libdwarf.h: Add ability to handle struct _Elf. * pro_alloc.c: Move an include of malloc.h as it is not needed if stdlib.h is present. * pro_forms.c: Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * pro_util.h: Add specific allowance for FreeBSD include and relocation. libdwarf-20210528/libdwarf/dwarf_reloc_arm.h0000644000175000017500000003034013743575426015603 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_ARM_H #define DWARF_RELOC_ARM_H /* Definitions for ARM */ #define DWARF_RELOC_ARM #ifndef EM_AARCH64 #define EM_AARCH64 183 /* Arm 64 */ #endif /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for ARM */ #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS32 2 #define R_ARM_REL32 3 #define R_ARM_LDR_PC_G0 4 #define R_ARM_ABS16 5 #define R_ARM_ABS12 6 #define R_ARM_THM_ABS5 7 #define R_ARM_ABS8 8 #define R_ARM_SBREL32 9 #define R_ARM_THM_CALL 10 #define R_ARM_THM_PC8 11 #define R_ARM_BREL_ADJ 12 #define R_ARM_TLS_DESC 13 #define R_ARM_THM_SWI8 14 #define R_ARM_XPC25 15 #define R_ARM_THM_XPC22 16 #define R_ARM_TLS_DTPMOD32 17 #define R_ARM_TLS_DTPOFF32 18 #define R_ARM_TLS_TPOFF32 19 #define R_ARM_COPY 20 #define R_ARM_GLOB_DAT 21 #define R_ARM_JUMP_SLOT 22 #define R_ARM_RELATIVE 23 #define R_ARM_GOTOFF32 24 #define R_ARM_BASE_PREL 25 #define R_ARM_GOT_BREL 26 #define R_ARM_PLT32 27 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_THM_JUMP24 30 #define R_ARM_BASE_ABS 31 #define R_ARM_ALU_PCREL_7_0 32 #define R_ARM_ALU_PCREL_15_8 33 #define R_ARM_ALU_PCREL_23_15 34 #define R_ARM_LDR_SBREL_11_0_NC 35 #define R_ARM_ALU_SBREL_19_12_NC 36 #define R_ARM_ALU_SBREL_27_20_CK 37 #define R_ARM_TARGET1 38 #define R_ARM_SBREL31 39 #define R_ARM_V4BX 40 #define R_ARM_TARGET2 41 #define R_ARM_PREL31 42 #define R_ARM_MOVW_ABS_NC 43 #define R_ARM_MOVT_ABS 44 #define R_ARM_MOVW_PREL_NC 45 #define R_ARM_MOVT_PREL 46 #define R_ARM_THM_MOVW_ABS_NC 47 #define R_ARM_THM_MOVT_ABS 48 #define R_ARM_THM_MOVW_PREL_NC 49 #define R_ARM_THM_MOVT_PREL 50 #define R_ARM_THM_JUMP19 51 #define R_ARM_THM_JUMP6 52 #define R_ARM_THM_ALU_PREL_11_0 53 #define R_ARM_THM_PC12 54 #define R_ARM_ABS32_NOI 55 #define R_ARM_REL32_NOI 56 #define R_ARM_ALU_PC_G0_NC 57 #define R_ARM_ALU_PC_G0 58 #define R_ARM_ALU_PC_G1_NC 59 #define R_ARM_ALU_PC_G1 60 #define R_ARM_ALU_PC_G2 61 #define R_ARM_LDR_PC_G1 62 #define R_ARM_LDR_PC_G2 63 #define R_ARM_LDRS_PC_G0 64 #define R_ARM_LDRS_PC_G1 65 #define R_ARM_LDRS_PC_G2 66 #define R_ARM_LDC_PC_G0 67 #define R_ARM_LDC_PC_G1 68 #define R_ARM_LDC_PC_G2 69 #define R_ARM_ALU_SB_G0_NC 70 #define R_ARM_ALU_SB_G0 71 #define R_ARM_ALU_SB_G1_NC 72 #define R_ARM_ALU_SB_G1 73 #define R_ARM_ALU_SB_G2 74 #define R_ARM_LDR_SB_G0 75 #define R_ARM_LDR_SB_G1 76 #define R_ARM_LDR_SB_G2 77 #define R_ARM_LDRS_SB_G0 78 #define R_ARM_LDRS_SB_G1 79 #define R_ARM_LDRS_SB_G2 80 #define R_ARM_LDC_SB_G0 81 #define R_ARM_LDC_SB_G1 82 #define R_ARM_LDC_SB_G2 83 #define R_ARM_MOVW_BREL_NC 84 #define R_ARM_MOVT_BREL 85 #define R_ARM_MOVW_BREL 86 #define R_ARM_THM_MOVW_BREL_NC 87 #define R_ARM_THM_MOVT_BREL 88 #define R_ARM_THM_MOVW_BREL 89 #define R_ARM_TLS_GOTDESC 90 #define R_ARM_TLS_CALL 91 #define R_ARM_TLS_DESCSEQ 92 #define R_ARM_THM_TLS_CALL 93 #define R_ARM_PLT32_ABS 94 #define R_ARM_GOT_ABS 95 #define R_ARM_GOT_PREL 96 #define R_ARM_GOT_BREL12 97 #define R_ARM_GOTOFF12 98 #define R_ARM_GOTRELAX 99 #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_JUMP11 102 #define R_ARM_THM_JUMP8 103 #define R_ARM_TLS_GD32 104 #define R_ARM_TLS_LDM32 105 #define R_ARM_TLS_LDO32 106 #define R_ARM_TLS_IE32 107 #define R_ARM_TLS_LE32 108 #define R_ARM_TLS_LDO12 109 #define R_ARM_TLS_LE12 110 #define R_ARM_TLS_IE12GP 111 #define R_ARM_ME_TOO 128 #define R_ARM_THM_TLS_DESCSEQ16 129 #define R_ARM_THM_TLS_DESCSEQ32 130 #define R_ARM_RXPC25 249 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 #define R_ARM_RREL32 252 #define R_ARM_RABS32 253 #define R_ARM_RPC24 254 #define R_ARM_RBASE 255 /* Keep this the last entry. */ #define R_ARM_NUM 256 #endif /* _WIN32 */ /* ARM relocations defined by the ABIs */ static const char *reloc_type_names_ARM[] = { "R_ARM_NONE", /* 00 */ "R_ARM_PC24", /* 01 */ "R_ARM_ABS32", /* 02 */ "R_ARM_REL32", /* 03 */ "R_ARM_LDR_PC_G0", /* 04 */ "R_ARM_ABS16", /* 05 */ "R_ARM_ABS12", /* 06 */ "R_ARM_THM_ABS5", /* 07 */ "R_ARM_ABS8", /* 08 */ "R_ARM_SBREL32", /* 09 */ "R_ARM_THM_CALL", /* 10 */ "R_ARM_THM_PC8", /* 11 */ "R_ARM_BREL_ADJ", /* 12 */ "R_ARM_TLS_DESC", /* 13 */ "R_ARM_THM_SWI8", /* 14 */ "R_ARM_XPC25", /* 15 */ "R_ARM_THM_XPC22", /* 16 */ "R_ARM_TLS_DTPMOD32", /* 17 */ "R_ARM_TLS_DTPOFF32", /* 18 */ "R_ARM_TLS_TPOFF32", /* 19 */ "R_ARM_COPY", /* 20 */ "R_ARM_GLOB_DAT", /* 21 */ "R_ARM_JUMP_SLOT", /* 22 */ "R_ARM_RELATIVE", /* 23 */ "R_ARM_GOTOFF32", /* 24 */ "R_ARM_BASE_PREL", /* 25 */ "R_ARM_GOT_BREL", /* 26 */ "R_ARM_PLT32", /* 27 */ "R_ARM_CALL", /* 28 */ "R_ARM_JUMP24", /* 29 */ "R_ARM_THM_JUMP24", /* 30 */ "R_ARM_BASE_ABS", /* 31 */ "R_ARM_ALU_PCREL_7_0", /* 32 */ "R_ARM_ALU_PCREL_15_8", /* 33 */ "R_ARM_ALU_PCREL_23_15", /* 34 */ "R_ARM_LDR_SBREL_11_0_NC", /* 35 */ "R_ARM_ALU_SBREL_19_12_NC", /* 36 */ "R_ARM_ALU_SBREL_27_20_CK", /* 37 */ "R_ARM_TARGET1", /* 38 */ "R_ARM_SBREL31", /* 39 */ "R_ARM_V4BX", /* 40 */ "R_ARM_TARGET2", /* 41 */ "R_ARM_PREL31", /* 42 */ "R_ARM_MOVW_ABS_NC", /* 43 */ "R_ARM_MOVT_ABS", /* 44 */ "R_ARM_MOVW_PREL_NC", /* 45 */ "R_ARM_MOVT_PREL", /* 46 */ "R_ARM_THM_MOVW_ABS_NC", /* 47 */ "R_ARM_THM_MOVT_ABS", /* 48 */ "R_ARM_THM_MOVW_PREL_NC", /* 49 */ "R_ARM_THM_MOVT_PREL", /* 50 */ "R_ARM_THM_JUMP19", /* 51 */ "R_ARM_THM_JUMP6", /* 52 */ "R_ARM_THM_ALU_PREL_11_0", /* 53 */ "R_ARM_THM_PC12", /* 54 */ "R_ARM_ABS32_NOI", /* 55 */ "R_ARM_REL32_NOI", /* 56 */ "R_ARM_ALU_PC_G0_NC", /* 57 */ "R_ARM_ALU_PC_G0", /* 58 */ "R_ARM_ALU_PC_G1_NC", /* 59 */ "R_ARM_ALU_PC_G1", /* 60 */ "R_ARM_ALU_PC_G2", /* 61 */ "R_ARM_LDR_PC_G1", /* 62 */ "R_ARM_LDR_PC_G2", /* 63 */ "R_ARM_LDRS_PC_G0", /* 64 */ "R_ARM_LDRS_PC_G1", /* 65 */ "R_ARM_LDRS_PC_G2", /* 66 */ "R_ARM_LDC_PC_G0", /* 67 */ "R_ARM_LDC_PC_G1", /* 68 */ "R_ARM_LDC_PC_G2", /* 69 */ "R_ARM_ALU_SB_G0_NC", /* 70 */ "R_ARM_ALU_SB_G0", /* 71 */ "R_ARM_ALU_SB_G1_NC", /* 72 */ "R_ARM_ALU_SB_G1", /* 73 */ "R_ARM_ALU_SB_G2", /* 74 */ "R_ARM_LDR_SB_G0", /* 75 */ "R_ARM_LDR_SB_G1", /* 76 */ "R_ARM_LDR_SB_G2", /* 77 */ "R_ARM_LDRS_SB_G0", /* 78 */ "R_ARM_LDRS_SB_G1", /* 79 */ "R_ARM_LDRS_SB_G2", /* 80 */ "R_ARM_LDC_SB_G0", /* 81 */ "R_ARM_LDC_SB_G1", /* 82 */ "R_ARM_LDC_SB_G2", /* 83 */ "R_ARM_MOVW_BREL_NC", /* 84 */ "R_ARM_MOVT_BREL", /* 85 */ "R_ARM_MOVW_BREL", /* 86 */ "R_ARM_THM_MOVW_BREL_NC", /* 87 */ "R_ARM_THM_MOVT_BREL", /* 88 */ "R_ARM_THM_MOVW_BREL", /* 89 */ "R_ARM_TLS_GOTDESC", /* 90 */ "R_ARM_TLS_CALL", /* 91 */ "R_ARM_TLS_DESCSEQ", /* 92 */ "R_ARM_THM_TLS_CALL", /* 93 */ "R_ARM_PLT32_ABS", /* 94 */ "R_ARM_GOT_ABS", /* 95 */ "R_ARM_GOT_PREL", /* 96 */ "R_ARM_GOT_BREL12", /* 97 */ "R_ARM_GOTOFF12", /* 98 */ "R_ARM_GOTRELAX", /* 99 */ "R_ARM_GNU_VTENTRY", /* 100 */ "R_ARM_GNU_VTINHERIT", /* 101 */ "R_ARM_THM_JUMP11", /* 102 */ "R_ARM_THM_JUMP8", /* 103 */ "R_ARM_TLS_GD32", /* 104 */ "R_ARM_TLS_LDM32", /* 105 */ "R_ARM_TLS_LDO32", /* 106 */ "R_ARM_TLS_IE32", /* 107 */ "R_ARM_TLS_LE32", /* 108 */ "R_ARM_TLS_LDO12", /* 109 */ "R_ARM_TLS_LE12", /* 110 */ "R_ARM_TLS_IE12GP", /* 111 */ "R_ARM_TLS_MOVT_TPOFF32", /* 112 */ /* "R_ARM_PRIVATE_0" */ "R_ARM_TLS_MOVW_TPOFF32", /* 113 */ /* "R_ARM_PRIVATE_1" */ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 114 */ /* "R_ARM_PRIVATE_2" */ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 115 */ /* "R_ARM_PRIVATE_3" */ "R_ARM_PRIVATE_4", /* 116 */ "R_ARM_PRIVATE_5", /* 117 */ "R_ARM_PRIVATE_6", /* 118 */ "R_ARM_PRIVATE_7", /* 119 */ "R_ARM_PRIVATE_8", /* 120 */ "R_ARM_PRIVATE_9", /* 121 */ "R_ARM_PRIVATE_10", /* 122 */ "R_ARM_PRIVATE_11", /* 123 */ "R_ARM_PRIVATE_12", /* 124 */ "R_ARM_PRIVATE_13", /* 125 */ "R_ARM_PRIVATE_14", /* 126 */ "R_ARM_PRIVATE_15", /* 127 */ "R_ARM_ME_TOO", /* 128 */ "R_ARM_THM_TLS_DESCSEQ16", /* 129 */ "R_ARM_THM_TLS_DESCSEQ32", /* 130 */ }; #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 0x101 #endif #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 0x102 #endif #endif /* DWARF_RELOC_ARM_H */ libdwarf-20210528/libdwarf/COPYING0000644000175000017500000000221513743575426013337 00000000000000The files: libdwarf.h dwarf.h and all the .h and .c files in this implementation of libdwarf are copyrighted according to the file LIBDWARFCOPYRIGHT (which mentions the LGPL version 2.1). Each file mentions the LGPL. The full text of the LGPL 2.1 is provided in LGPL.txt Another copyright used here in some files is the two-clause BSD license, (FreeBSD license). The libdwarf documentation: libdwarf2.1.mm is based on material submitted to the UI PLSIG as proposed interfaces for dwarf, but completely rewritten. Copyright ownership is therefore SGI (but see the document for details) and it seems clear that the intent was there was to be free copying with no fees. libdwarf2p.1.mm is documentation of a set of interfaces (not part of the UI PLSIG proposals) and the document was written from scratch at SGI. Copyright ownership is therefore SGI (but see the document for details) and it seems clear that the intent was there was to be free copying with no fees. 17 March 2014:Updated to remove reference to dwarf.v2.mm. libdwarf-20210528/libdwarf/dwarf_elf_reloc_aarch64.h0000664000175000017500000003600013644370703017072 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_aarch64(unsigned long); #ifndef R_AARCH64_NONE #define R_AARCH64_NONE 0 #endif /* R_AARCH64_NONE */ #ifndef R_AARCH64_P32_ABS32 #define R_AARCH64_P32_ABS32 1 #endif /* R_AARCH64_P32_ABS32 */ #ifndef R_AARCH64_P32_COPY #define R_AARCH64_P32_COPY 180 #endif /* R_AARCH64_P32_COPY */ #ifndef R_AARCH64_P32_GLOB_DAT #define R_AARCH64_P32_GLOB_DAT 181 #endif /* R_AARCH64_P32_GLOB_DAT */ #ifndef R_AARCH64_P32_JUMP_SLOT #define R_AARCH64_P32_JUMP_SLOT 182 #endif /* R_AARCH64_P32_JUMP_SLOT */ #ifndef R_AARCH64_P32_RELATIVE #define R_AARCH64_P32_RELATIVE 183 #endif /* R_AARCH64_P32_RELATIVE */ #ifndef R_AARCH64_P32_TLS_DTPMOD #define R_AARCH64_P32_TLS_DTPMOD 184 #endif /* R_AARCH64_P32_TLS_DTPMOD */ #ifndef R_AARCH64_P32_TLS_DTPREL #define R_AARCH64_P32_TLS_DTPREL 185 #endif /* R_AARCH64_P32_TLS_DTPREL */ #ifndef R_AARCH64_P32_TLS_TPREL #define R_AARCH64_P32_TLS_TPREL 186 #endif /* R_AARCH64_P32_TLS_TPREL */ #ifndef R_AARCH64_P32_TLSDESC #define R_AARCH64_P32_TLSDESC 187 #endif /* R_AARCH64_P32_TLSDESC */ #ifndef R_AARCH64_P32_IRELATIVE #define R_AARCH64_P32_IRELATIVE 188 #endif /* R_AARCH64_P32_IRELATIVE */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 257 #endif /* R_AARCH64_ABS64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 258 #endif /* R_AARCH64_ABS32 */ #ifndef R_AARCH64_ABS16 #define R_AARCH64_ABS16 259 #endif /* R_AARCH64_ABS16 */ #ifndef R_AARCH64_PREL64 #define R_AARCH64_PREL64 260 #endif /* R_AARCH64_PREL64 */ #ifndef R_AARCH64_PREL32 #define R_AARCH64_PREL32 261 #endif /* R_AARCH64_PREL32 */ #ifndef R_AARCH64_PREL16 #define R_AARCH64_PREL16 262 #endif /* R_AARCH64_PREL16 */ #ifndef R_AARCH64_MOVW_UABS_G0 #define R_AARCH64_MOVW_UABS_G0 263 #endif /* R_AARCH64_MOVW_UABS_G0 */ #ifndef R_AARCH64_MOVW_UABS_G0_NC #define R_AARCH64_MOVW_UABS_G0_NC 264 #endif /* R_AARCH64_MOVW_UABS_G0_NC */ #ifndef R_AARCH64_MOVW_UABS_G1 #define R_AARCH64_MOVW_UABS_G1 265 #endif /* R_AARCH64_MOVW_UABS_G1 */ #ifndef R_AARCH64_MOVW_UABS_G1_NC #define R_AARCH64_MOVW_UABS_G1_NC 266 #endif /* R_AARCH64_MOVW_UABS_G1_NC */ #ifndef R_AARCH64_MOVW_UABS_G2 #define R_AARCH64_MOVW_UABS_G2 267 #endif /* R_AARCH64_MOVW_UABS_G2 */ #ifndef R_AARCH64_MOVW_UABS_G2_NC #define R_AARCH64_MOVW_UABS_G2_NC 268 #endif /* R_AARCH64_MOVW_UABS_G2_NC */ #ifndef R_AARCH64_MOVW_UABS_G3 #define R_AARCH64_MOVW_UABS_G3 269 #endif /* R_AARCH64_MOVW_UABS_G3 */ #ifndef R_AARCH64_MOVW_SABS_G0 #define R_AARCH64_MOVW_SABS_G0 270 #endif /* R_AARCH64_MOVW_SABS_G0 */ #ifndef R_AARCH64_MOVW_SABS_G1 #define R_AARCH64_MOVW_SABS_G1 271 #endif /* R_AARCH64_MOVW_SABS_G1 */ #ifndef R_AARCH64_MOVW_SABS_G2 #define R_AARCH64_MOVW_SABS_G2 272 #endif /* R_AARCH64_MOVW_SABS_G2 */ #ifndef R_AARCH64_LD_PREL_LO19 #define R_AARCH64_LD_PREL_LO19 273 #endif /* R_AARCH64_LD_PREL_LO19 */ #ifndef R_AARCH64_ADR_PREL_LO21 #define R_AARCH64_ADR_PREL_LO21 274 #endif /* R_AARCH64_ADR_PREL_LO21 */ #ifndef R_AARCH64_ADR_PREL_PG_HI21 #define R_AARCH64_ADR_PREL_PG_HI21 275 #endif /* R_AARCH64_ADR_PREL_PG_HI21 */ #ifndef R_AARCH64_ADR_PREL_PG_HI21_NC #define R_AARCH64_ADR_PREL_PG_HI21_NC 276 #endif /* R_AARCH64_ADR_PREL_PG_HI21_NC */ #ifndef R_AARCH64_ADD_ABS_LO12_NC #define R_AARCH64_ADD_ABS_LO12_NC 277 #endif /* R_AARCH64_ADD_ABS_LO12_NC */ #ifndef R_AARCH64_LDST8_ABS_LO12_NC #define R_AARCH64_LDST8_ABS_LO12_NC 278 #endif /* R_AARCH64_LDST8_ABS_LO12_NC */ #ifndef R_AARCH64_TSTBR14 #define R_AARCH64_TSTBR14 279 #endif /* R_AARCH64_TSTBR14 */ #ifndef R_AARCH64_CONDBR19 #define R_AARCH64_CONDBR19 280 #endif /* R_AARCH64_CONDBR19 */ #ifndef R_AARCH64_JUMP26 #define R_AARCH64_JUMP26 282 #endif /* R_AARCH64_JUMP26 */ #ifndef R_AARCH64_CALL26 #define R_AARCH64_CALL26 283 #endif /* R_AARCH64_CALL26 */ #ifndef R_AARCH64_LDST16_ABS_LO12_NC #define R_AARCH64_LDST16_ABS_LO12_NC 284 #endif /* R_AARCH64_LDST16_ABS_LO12_NC */ #ifndef R_AARCH64_LDST32_ABS_LO12_NC #define R_AARCH64_LDST32_ABS_LO12_NC 285 #endif /* R_AARCH64_LDST32_ABS_LO12_NC */ #ifndef R_AARCH64_LDST64_ABS_LO12_NC #define R_AARCH64_LDST64_ABS_LO12_NC 286 #endif /* R_AARCH64_LDST64_ABS_LO12_NC */ #ifndef R_AARCH64_MOVW_PREL_G0 #define R_AARCH64_MOVW_PREL_G0 287 #endif /* R_AARCH64_MOVW_PREL_G0 */ #ifndef R_AARCH64_MOVW_PREL_G0_NC #define R_AARCH64_MOVW_PREL_G0_NC 288 #endif /* R_AARCH64_MOVW_PREL_G0_NC */ #ifndef R_AARCH64_MOVW_PREL_G1 #define R_AARCH64_MOVW_PREL_G1 289 #endif /* R_AARCH64_MOVW_PREL_G1 */ #ifndef R_AARCH64_MOVW_PREL_G1_NC #define R_AARCH64_MOVW_PREL_G1_NC 290 #endif /* R_AARCH64_MOVW_PREL_G1_NC */ #ifndef R_AARCH64_MOVW_PREL_G2 #define R_AARCH64_MOVW_PREL_G2 291 #endif /* R_AARCH64_MOVW_PREL_G2 */ #ifndef R_AARCH64_MOVW_PREL_G2_NC #define R_AARCH64_MOVW_PREL_G2_NC 292 #endif /* R_AARCH64_MOVW_PREL_G2_NC */ #ifndef R_AARCH64_MOVW_PREL_G3 #define R_AARCH64_MOVW_PREL_G3 293 #endif /* R_AARCH64_MOVW_PREL_G3 */ #ifndef R_AARCH64_LDST128_ABS_LO12_NC #define R_AARCH64_LDST128_ABS_LO12_NC 299 #endif /* R_AARCH64_LDST128_ABS_LO12_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G0 #define R_AARCH64_MOVW_GOTOFF_G0 300 #endif /* R_AARCH64_MOVW_GOTOFF_G0 */ #ifndef R_AARCH64_MOVW_GOTOFF_G0_NC #define R_AARCH64_MOVW_GOTOFF_G0_NC 301 #endif /* R_AARCH64_MOVW_GOTOFF_G0_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G1 #define R_AARCH64_MOVW_GOTOFF_G1 302 #endif /* R_AARCH64_MOVW_GOTOFF_G1 */ #ifndef R_AARCH64_MOVW_GOTOFF_G1_NC #define R_AARCH64_MOVW_GOTOFF_G1_NC 303 #endif /* R_AARCH64_MOVW_GOTOFF_G1_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G2 #define R_AARCH64_MOVW_GOTOFF_G2 304 #endif /* R_AARCH64_MOVW_GOTOFF_G2 */ #ifndef R_AARCH64_MOVW_GOTOFF_G2_NC #define R_AARCH64_MOVW_GOTOFF_G2_NC 305 #endif /* R_AARCH64_MOVW_GOTOFF_G2_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G3 #define R_AARCH64_MOVW_GOTOFF_G3 306 #endif /* R_AARCH64_MOVW_GOTOFF_G3 */ #ifndef R_AARCH64_GOTREL64 #define R_AARCH64_GOTREL64 307 #endif /* R_AARCH64_GOTREL64 */ #ifndef R_AARCH64_GOTREL32 #define R_AARCH64_GOTREL32 308 #endif /* R_AARCH64_GOTREL32 */ #ifndef R_AARCH64_GOT_LD_PREL19 #define R_AARCH64_GOT_LD_PREL19 309 #endif /* R_AARCH64_GOT_LD_PREL19 */ #ifndef R_AARCH64_LD64_GOTOFF_LO15 #define R_AARCH64_LD64_GOTOFF_LO15 310 #endif /* R_AARCH64_LD64_GOTOFF_LO15 */ #ifndef R_AARCH64_ADR_GOT_PAGE #define R_AARCH64_ADR_GOT_PAGE 311 #endif /* R_AARCH64_ADR_GOT_PAGE */ #ifndef R_AARCH64_LD64_GOT_LO12_NC #define R_AARCH64_LD64_GOT_LO12_NC 312 #endif /* R_AARCH64_LD64_GOT_LO12_NC */ #ifndef R_AARCH64_LD64_GOTPAGE_LO15 #define R_AARCH64_LD64_GOTPAGE_LO15 313 #endif /* R_AARCH64_LD64_GOTPAGE_LO15 */ #ifndef R_AARCH64_TLSGD_ADR_PREL21 #define R_AARCH64_TLSGD_ADR_PREL21 512 #endif /* R_AARCH64_TLSGD_ADR_PREL21 */ #ifndef R_AARCH64_TLSGD_ADR_PAGE21 #define R_AARCH64_TLSGD_ADR_PAGE21 513 #endif /* R_AARCH64_TLSGD_ADR_PAGE21 */ #ifndef R_AARCH64_TLSGD_ADD_LO12_NC #define R_AARCH64_TLSGD_ADD_LO12_NC 514 #endif /* R_AARCH64_TLSGD_ADD_LO12_NC */ #ifndef R_AARCH64_TLSGD_MOVW_G1 #define R_AARCH64_TLSGD_MOVW_G1 515 #endif /* R_AARCH64_TLSGD_MOVW_G1 */ #ifndef R_AARCH64_TLSGD_MOVW_G0_NC #define R_AARCH64_TLSGD_MOVW_G0_NC 516 #endif /* R_AARCH64_TLSGD_MOVW_G0_NC */ #ifndef R_AARCH64_TLSLD_ADR_PREL21 #define R_AARCH64_TLSLD_ADR_PREL21 517 #endif /* R_AARCH64_TLSLD_ADR_PREL21 */ #ifndef R_AARCH64_TLSLD_ADR_PAGE21 #define R_AARCH64_TLSLD_ADR_PAGE21 518 #endif /* R_AARCH64_TLSLD_ADR_PAGE21 */ #ifndef R_AARCH64_TLSLD_ADD_LO12_NC #define R_AARCH64_TLSLD_ADD_LO12_NC 519 #endif /* R_AARCH64_TLSLD_ADD_LO12_NC */ #ifndef R_AARCH64_TLSLD_MOVW_G1 #define R_AARCH64_TLSLD_MOVW_G1 520 #endif /* R_AARCH64_TLSLD_MOVW_G1 */ #ifndef R_AARCH64_TLSLD_MOVW_G0_NC #define R_AARCH64_TLSLD_MOVW_G0_NC 521 #endif /* R_AARCH64_TLSLD_MOVW_G0_NC */ #ifndef R_AARCH64_TLSLD_LD_PREL19 #define R_AARCH64_TLSLD_LD_PREL19 522 #endif /* R_AARCH64_TLSLD_LD_PREL19 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G2 #define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G2 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1 #define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC #define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0 #define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC #define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_HI12 #define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_HI12 */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12 #define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC #define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 #endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 #endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 #endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 #endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 #endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 #endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 #endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 #endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 #define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 #endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 */ #ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC #define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 #endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC */ #ifndef R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 #define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 #endif /* R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 */ #ifndef R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC #define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 #endif /* R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC */ #ifndef R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 #define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 #endif /* R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G2 #define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G2 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1 #define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1_NC #define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1_NC */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0 #define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0_NC #define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0_NC */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_HI12 #define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 #endif /* R_AARCH64_TLSLE_ADD_TPREL_HI12 */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12 #define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 #endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12_NC #define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 #endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12 #define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 #endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 #endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12 #define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 #endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 #endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12 #define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 #endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 #endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12 #define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 #endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 #endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSDESC_LD_PREL19 #define R_AARCH64_TLSDESC_LD_PREL19 560 #endif /* R_AARCH64_TLSDESC_LD_PREL19 */ #ifndef R_AARCH64_TLSDESC_ADR_PREL21 #define R_AARCH64_TLSDESC_ADR_PREL21 561 #endif /* R_AARCH64_TLSDESC_ADR_PREL21 */ #ifndef R_AARCH64_TLSDESC_ADR_PAGE21 #define R_AARCH64_TLSDESC_ADR_PAGE21 562 #endif /* R_AARCH64_TLSDESC_ADR_PAGE21 */ #ifndef R_AARCH64_TLSDESC_LD64_LO12 #define R_AARCH64_TLSDESC_LD64_LO12 563 #endif /* R_AARCH64_TLSDESC_LD64_LO12 */ #ifndef R_AARCH64_TLSDESC_ADD_LO12 #define R_AARCH64_TLSDESC_ADD_LO12 564 #endif /* R_AARCH64_TLSDESC_ADD_LO12 */ #ifndef R_AARCH64_TLSDESC_OFF_G1 #define R_AARCH64_TLSDESC_OFF_G1 565 #endif /* R_AARCH64_TLSDESC_OFF_G1 */ #ifndef R_AARCH64_TLSDESC_OFF_G0_NC #define R_AARCH64_TLSDESC_OFF_G0_NC 566 #endif /* R_AARCH64_TLSDESC_OFF_G0_NC */ #ifndef R_AARCH64_TLSDESC_LDR #define R_AARCH64_TLSDESC_LDR 567 #endif /* R_AARCH64_TLSDESC_LDR */ #ifndef R_AARCH64_TLSDESC_ADD #define R_AARCH64_TLSDESC_ADD 568 #endif /* R_AARCH64_TLSDESC_ADD */ #ifndef R_AARCH64_TLSDESC_CALL #define R_AARCH64_TLSDESC_CALL 569 #endif /* R_AARCH64_TLSDESC_CALL */ #ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12 #define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 #endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 #endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 #endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 #endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC */ #ifndef R_AARCH64_COPY #define R_AARCH64_COPY 1024 #endif /* R_AARCH64_COPY */ #ifndef R_AARCH64_GLOB_DAT #define R_AARCH64_GLOB_DAT 1025 #endif /* R_AARCH64_GLOB_DAT */ #ifndef R_AARCH64_JUMP_SLOT #define R_AARCH64_JUMP_SLOT 1026 #endif /* R_AARCH64_JUMP_SLOT */ #ifndef R_AARCH64_RELATIVE #define R_AARCH64_RELATIVE 1027 #endif /* R_AARCH64_RELATIVE */ #ifndef R_AARCH64_TLS_DTPMOD #define R_AARCH64_TLS_DTPMOD 1028 #endif /* R_AARCH64_TLS_DTPMOD */ #ifndef R_AARCH64_TLS_DTPREL #define R_AARCH64_TLS_DTPREL 1029 #endif /* R_AARCH64_TLS_DTPREL */ #ifndef R_AARCH64_TLS_TPREL #define R_AARCH64_TLS_TPREL 1030 #endif /* R_AARCH64_TLS_TPREL */ #ifndef R_AARCH64_TLSDESC #define R_AARCH64_TLSDESC 1031 #endif /* R_AARCH64_TLSDESC */ #ifndef R_AARCH64_IRELATIVE #define R_AARCH64_IRELATIVE 1032 #endif /* R_AARCH64_IRELATIVE */ libdwarf-20210528/libdwarf/dwarf_frame.c0000664000175000017500000030067214004650464014722 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* Using Arange as a way to build a list */ #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \ do { \ if ((fde) == NULL) { \ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);\ return DW_DLV_ERROR; \ } \ (dbg)= (fde)->fd_dbg; \ if ((dbg) == NULL) { \ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\ return DW_DLV_ERROR; \ } } while (0) #define MIN(a,b) (((a) < (b))? a:b) #if 0 /* FOR DEBUGGING */ static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ static int dwarf_initialize_fde_table(Dwarf_Debug dbg, struct Dwarf_Frame_s *fde_table, unsigned table_real_data_size, Dwarf_Error * error); static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table); static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base, unsigned first, unsigned last,int initial_value); static void dwarf_init_reg_rules_dw( struct Dwarf_Regtable_Entry_s *base, unsigned first, unsigned last,int initial_value); static void dwarf_init_reg_rules_dw3( struct Dwarf_Regtable_Entry3_s *base, unsigned first, unsigned last,int initial_value); #if 0 /* FOR DEBUGGING */ /* Only used for debugging libdwarf. */ static void dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule); #endif int dwarf_get_frame_section_name(Dwarf_Debug dbg, const char **sec_name, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_frame; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, const char **sec_name, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_frame_eh_gnu; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } /* This function is the heart of the debug_frame stuff. Don't even think of reading this without reading both the Libdwarf and consumer API carefully first. This function basically executes frame instructions contained in a Cie or an Fde, but does in a number of different ways depending on the information sought. Start_instr_ptr points to the first byte of the frame instruction stream, and final_instr_ptr to the to the first byte after the last. The offsets returned in the frame instructions are factored. That is they need to be multiplied by either the code_alignment_factor or the data_alignment_factor, as appropriate to obtain the actual offset. This makes it possible to expand an instruction stream without the corresponding Cie. However, when an Fde frame instr sequence is being expanded there must be a valid Cie with a pointer to an initial table row. If successful, returns DW_DLV_OK And sets returned_count thru the pointer if make_instr is true. If make_instr is false returned_count should NOT be used by the caller (returned_count is set to 0 thru the pointer by this routine...) If unsuccessful, returns DW_DLV_ERROR and sets returned_error to the error code It does not do a whole lot of input validation being a private function. Please make sure inputs are valid. (1) If make_instr is true, it makes a list of pointers to Dwarf_Frame_Op structures containing the frame instructions executed. A pointer to this list is returned in ret_frame_instr. Make_instr is true only when a list of frame instructions is to be returned. In this case since we are not interested in the contents of the table, the input Cie can be NULL. This is the only case where the input Cie can be NULL. (2) If search_pc is true, frame instructions are executed till either a location is reached that is greater than the search_pc_val provided, or all instructions are executed. At this point the last row of the table generated is returned in a structure. A pointer to this structure is supplied in table. (3) This function is also used to create the initial table row defined by a Cie. In this case, the Dwarf_Cie pointer cie, is NULL. For an FDE, however, cie points to the associated Cie. (4) If search_pc is true and (has_more_rows and subsequent_pc are non-null) then: has_more_rows is set true if there are instruction bytes following the detection of search_over. If all the instruction bytes have been seen then *has_more_rows is set false. If *has_more_rows is true then *subsequent_pc is set to the pc value that is the following row in the table. make_instr - make list of frame instr? 0/1 ret_frame_instr - Ptr to list of ptrs to frame instrs search_pc - Search for a pc value? 0/1 search_pc_val - Search for this pc value initial_loc - Initial code location value. start_instr_ptr - Ptr to start of frame instrs. final_instr_ptr - Ptr just past frame instrs. table - Ptr to struct with last row. cie - Ptr to Cie used by the Fde. Different cies may have distinct address-sizes, so the cie is used, not de_pointer_size. */ int _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Frame_Op ** ret_frame_instr, Dwarf_Bool search_pc, Dwarf_Addr search_pc_val, Dwarf_Addr initial_loc, Dwarf_Small * start_instr_ptr, Dwarf_Small * final_instr_ptr, Dwarf_Frame table, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error *error) { /* The following macro depends on macreg and machigh_reg both being unsigned to avoid unintended behavior and to avoid compiler warnings when high warning levels are turned on. */ #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg) \ do { \ if ((macreg) >= (machigh_reg)) { \ SER(DW_DLE_DF_REG_NUM_TOO_HIGH); \ } \ } /*CONSTCOND */ while (0) /* SER === SIMPLE_ERROR_RETURN */ #define SER(code) \ free(localregtab); \ _dwarf_error(dbg,error,code); \ return DW_DLV_ERROR /* Sweeps the frame instructions. */ Dwarf_Small *instr_ptr = 0; /* Register numbers not limited to just 255, thus not using Dwarf_Small. */ typedef unsigned reg_num_type; Dwarf_Unsigned factored_N_value = 0; Dwarf_Signed signed_factored_N_value = 0; Dwarf_Addr current_loc = initial_loc; /* code location/ pc-value corresponding to the frame instructions. Starts at zero when the caller has no value to pass in. */ /* Must be min de_pointer_size bytes and must be at least 4 */ Dwarf_Unsigned adv_loc = 0; unsigned reg_count = dbg->de_frame_reg_rules_entry_count; struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count, sizeof(struct Dwarf_Reg_Rule_s)); struct Dwarf_Reg_Rule_s cfa_reg; /* This is used to end executing frame instructions. */ /* Becomes true when search_pc is true and current_loc */ /* is greater than search_pc_val. */ Dwarf_Bool search_over = false; Dwarf_Addr possible_subsequent_pc = 0; /* Used by the DW_FRAME_advance_loc instr */ /* to hold the increment in pc value. */ Dwarf_Addr adv_pc = 0; Dwarf_Half address_size = (cie)? cie->ci_address_size: dbg->de_pointer_size; /* Counts the number of frame instructions executed. */ Dwarf_Unsigned instr_count = 0; /* These contain the current fields of the current frame instruction. */ Dwarf_Small fp_base_op = 0; Dwarf_Small fp_extended_op = 0; reg_num_type fp_register = 0; /* The value in fp_offset may be signed, though we call it unsigned. This works ok for 2-s complement arithmetic. */ Dwarf_Unsigned fp_offset = 0; Dwarf_Off fp_instr_offset = 0; /* Stack_table points to the row (Dwarf_Frame ie) being pushed or popped by a remember or restore instruction. Top_stack points to the top of the stack of rows. */ Dwarf_Frame stack_table = NULL; Dwarf_Frame top_stack = NULL; /* These are used only when make_instr is true. Curr_instr is a pointer to the current frame instruction executed. Curr_instr_ptr, head_instr_list, and curr_instr_list are used to form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is used to deallocate the structs used to form the chain. Head_instr_block points to a contiguous list of pointers to the Dwarf_Frame_Op structs executed. */ Dwarf_Frame_Op *curr_instr = 0; Dwarf_Chain curr_instr_item = 0; Dwarf_Chain head_instr_chain = NULL; Dwarf_Chain tail_instr_chain = NULL; Dwarf_Frame_Op *head_instr_block = 0; /* These are the alignment_factors taken from the Cie provided. When no input Cie is provided they are set to 1, because only factored offsets are required. */ Dwarf_Signed code_alignment_factor = 1; Dwarf_Signed data_alignment_factor = 1; /* This flag indicates when an actual alignment factor is needed. So if a frame instruction that computes an offset using an alignment factor is encountered when this flag is set, an error is returned because the Cie did not have a valid augmentation. */ Dwarf_Bool need_augmentation = false; Dwarf_Unsigned i = 0; /* Initialize first row from associated Cie. Using temp regs explicitly */ if (!localregtab) { SER(DW_DLE_ALLOC_FAIL); } { struct Dwarf_Reg_Rule_s *t1reg = localregtab; if (cie != NULL && cie->ci_initial_table != NULL) { unsigned minregcount = 0; unsigned curreg = 0; struct Dwarf_Reg_Rule_s *t2reg = cie->ci_initial_table->fr_reg; if (reg_count != cie->ci_initial_table->fr_reg_count) { /* Should never happen, it makes no sense to have the table sizes change. There is no real allowance for the set of registers to change dynamically in a single Dwarf_Debug (except the size can be set near initial Dwarf_Debug creation time). */ SER(DW_DLE_FRAME_REGISTER_COUNT_MISMATCH); } minregcount = MIN(reg_count,cie->ci_initial_table->fr_reg_count); for ( ; curreg < minregcount ; curreg++, t1reg++, t2reg++) { *t1reg = *t2reg; } cfa_reg = cie->ci_initial_table->fr_cfa_rule; } else { dwarf_init_reg_rules_ru(localregtab,0,reg_count, dbg->de_frame_rule_initial_value); dwarf_init_reg_rules_ru(&cfa_reg,0, 1, dbg->de_frame_rule_initial_value); } } /* The idea here is that the code_alignment_factor and data_alignment_factor which are needed for certain instructions are valid only when the Cie has a proper augmentation string. So if the augmentation is not right, only Frame instruction can be read. */ if (cie != NULL && cie->ci_augmentation != NULL) { code_alignment_factor = cie->ci_code_alignment_factor; data_alignment_factor = cie->ci_data_alignment_factor; } else { need_augmentation = !make_instr; } instr_ptr = start_instr_ptr; while ((instr_ptr < final_instr_ptr) && (!search_over)) { Dwarf_Small instr = 0; Dwarf_Small opcode = 0; reg_num_type reg_no = 0; fp_instr_offset = instr_ptr - start_instr_ptr; instr = *(Dwarf_Small *) instr_ptr; instr_ptr += sizeof(Dwarf_Small); fp_base_op = (instr & 0xc0) >> 6; if ((instr & 0xc0) == 0x00) { opcode = instr; /* is really extended op */ fp_extended_op = (instr & (~(0xc0))) & 0xff; } else { opcode = instr & 0xc0; /* is base op */ fp_extended_op = 0; } fp_register = 0; fp_offset = 0; switch (opcode) { case DW_CFA_advance_loc: { /* base op */ fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK; if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_pc = adv_pc * code_alignment_factor; possible_subsequent_pc = current_loc + adv_pc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_offset: { /* base op */ int adres = 0; reg_no = (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK); ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } fp_register = reg_no; fp_offset = factored_N_value; if (need_augmentation) { SER( DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; break; } case DW_CFA_restore: { /* base op */ reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK); ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); fp_register = reg_no; if (cie != NULL && cie->ci_initial_table != NULL) localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; else if (!make_instr) { SER(DW_DLE_DF_MAKE_INSTR_NO_INIT); } break; } case DW_CFA_set_loc: { Dwarf_Addr new_loc = 0; int adres = 0; adres=_dwarf_read_unaligned_ck_wrapper(dbg, &new_loc, instr_ptr, address_size, final_instr_ptr,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } instr_ptr += address_size; if (new_loc != 0 && current_loc != 0) { /* Pre-relocation or before current_loc is set the test comparing new_loc and current_loc makes no sense. Testing for non-zero (above) is a way (fallible) to check that current_loc, new_loc are already relocated. */ if (new_loc <= current_loc) { /* Within a frame, address must increase. Seemingly it has not. Seems to be an error. */ SER(DW_DLE_DF_NEW_LOC_LESS_OLD_LOC); } } search_over = search_pc && (new_loc > search_pc_val); /* If gone past pc needed, retain old pc. */ possible_subsequent_pc = new_loc; if (!search_over) { current_loc = possible_subsequent_pc; } fp_offset = new_loc; break; } case DW_CFA_advance_loc1: { int adres = 0; adres=_dwarf_read_unaligned_ck_wrapper(dbg, &adv_loc, instr_ptr, sizeof(Dwarf_Small), final_instr_ptr,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } instr_ptr += sizeof(Dwarf_Small); fp_offset = adv_loc; if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_advance_loc2: { int adres = 0; adres=_dwarf_read_unaligned_ck_wrapper(dbg, &adv_loc, instr_ptr, DWARF_HALF_SIZE, final_instr_ptr,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } instr_ptr += DWARF_HALF_SIZE; fp_offset = adv_loc; if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_advance_loc4: { int adres = 0; adres=_dwarf_read_unaligned_ck_wrapper(dbg, &adv_loc, instr_ptr, DWARF_32BIT_SIZE, final_instr_ptr,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } instr_ptr += DWARF_32BIT_SIZE; fp_offset = adv_loc; if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_MIPS_advance_loc8: { int adres = 0; adres=_dwarf_read_unaligned_ck_wrapper(dbg, &adv_loc, instr_ptr, DWARF_64BIT_SIZE, final_instr_ptr,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } instr_ptr += DWARF_64BIT_SIZE; fp_offset = adv_loc; if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_offset_extended: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = factored_N_value; break; } case DW_CFA_restore_extended: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); if (cie != NULL && cie->ci_initial_table != NULL) { localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; } else { if (!make_instr) { SER(DW_DLE_DF_MAKE_INSTR_NO_INIT); } } fp_register = reg_no; break; } case DW_CFA_undefined: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); localregtab[reg_no].ru_is_off = 0; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = dbg->de_frame_undefined_value_number; localregtab[reg_no].ru_offset_or_block_len = 0; fp_register = reg_no; break; } case DW_CFA_same_value: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); localregtab[reg_no].ru_is_off = 0; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = dbg->de_frame_same_value_number; localregtab[reg_no].ru_offset_or_block_len = 0; fp_register = reg_no; break; } case DW_CFA_register: { Dwarf_Unsigned lreg; reg_num_type reg_noA = 0; reg_num_type reg_noB = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_noA = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_noB = (reg_num_type) lreg; if (reg_noB > reg_count) { SER(DW_DLE_DF_REG_NUM_TOO_HIGH); } localregtab[reg_noA].ru_is_off = 0; localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_noA].ru_register = reg_noB; localregtab[reg_noA].ru_offset_or_block_len = 0; fp_register = reg_noA; fp_offset = reg_noB; break; } case DW_CFA_remember_state: { stack_table = (Dwarf_Frame) _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); if (stack_table == NULL) { SER(DW_DLE_DF_ALLOC_FAIL); } for (i = 0; i < reg_count; i++) stack_table->fr_reg[i] = localregtab[i]; stack_table->fr_cfa_rule = cfa_reg; if (top_stack != NULL) stack_table->fr_next = top_stack; top_stack = stack_table; break; } case DW_CFA_restore_state: { if (top_stack == NULL) { SER(DW_DLE_DF_POP_EMPTY_STACK); } stack_table = top_stack; top_stack = stack_table->fr_next; for (i = 0; i < reg_count; i++) localregtab[i] = stack_table->fr_reg[i]; cfa_reg = stack_table->fr_cfa_rule; dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); break; } case DW_CFA_def_cfa: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_register = reg_no; cfa_reg.ru_offset_or_block_len = factored_N_value; fp_register = reg_no; fp_offset = factored_N_value; break; } case DW_CFA_def_cfa_register: { Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); cfa_reg.ru_register = reg_no; /* Do NOT set ru_offset_or_block_len or ru_is_off here. See dwarf2/3 spec. */ fp_register = reg_no; break; } case DW_CFA_def_cfa_offset: { int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = factored_N_value; fp_offset = factored_N_value; break; } /* This is for Metaware with augmentation string HC We do not really know what to do with it. */ case DW_CFA_METAWARE_info: { int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } /* Not really known what the value means or is. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = factored_N_value; break; } case DW_CFA_nop: { break; } /* DWARF3 ops begin here. */ case DW_CFA_def_cfa_expression: { /* A single DW_FORM_block representing a dwarf expression. The form block establishes the way to compute the CFA. */ Dwarf_Unsigned block_len = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &block_len,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } cfa_reg.ru_is_off = 0; /* arbitrary */ cfa_reg.ru_value_type = DW_EXPR_EXPRESSION; cfa_reg.ru_offset_or_block_len = block_len; cfa_reg.ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; } break; case DW_CFA_expression: { /* An unsigned leb128 value is the first operand (a register number). The second operand is single DW_FORM_block representing a dwarf expression. The evaluator pushes the CFA on the evaluation stack then evaluates the expression to compute the value of the register contents. */ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned block_len = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &block_len,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } localregtab[lreg].ru_is_off = 0; /* arbitrary */ localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; fp_register = reg_no; instr_ptr += block_len; } break; case DW_CFA_offset_extended_sf: { /* The first operand is an unsigned leb128 register number. The second is a signed factored offset. Identical to DW_CFA_offset_extended except the second operand is signed */ Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_sword_wrapper(dbg, &instr_ptr,final_instr_ptr, &signed_factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = signed_factored_N_value; } break; case DW_CFA_def_cfa_sf: { /* The first operand is an unsigned leb128 register number. The second is a signed leb128 factored offset. Identical to DW_CFA_def_cfa except that the second operand is signed and factored. */ Dwarf_Unsigned lreg; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_sword_wrapper(dbg, &instr_ptr,final_instr_ptr, &signed_factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_register = reg_no; cfa_reg.ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = signed_factored_N_value; } break; case DW_CFA_def_cfa_offset_sf: { /* The operand is a signed leb128 operand representing a factored offset. Identical to DW_CFA_def_cfa_offset excep the operand is signed and factored. */ int adres = 0; adres = _dwarf_leb128_sword_wrapper(dbg, &instr_ptr,final_instr_ptr, &signed_factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_offset = signed_factored_N_value; } break; case DW_CFA_val_offset: { /* The first operand is an unsigned leb128 register number. The second is a factored unsigned offset. Makes the register be a val_offset(N) rule with N = factored_offset*data_alignment_factor. */ Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; fp_offset = factored_N_value; break; } case DW_CFA_val_offset_sf: { /* The first operand is an unsigned leb128 register number. The second is a factored signed offset. Makes the register be a val_offset(N) rule with N = factored_offset*data_alignment_factor. */ Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_sword_wrapper(dbg, &instr_ptr,final_instr_ptr, &signed_factored_N_value,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } if (need_augmentation) { SER(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; localregtab[reg_no].ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_offset = signed_factored_N_value; } break; case DW_CFA_val_expression: { /* The first operand is an unsigned leb128 register number. The second is a DW_FORM_block representing a DWARF expression. The rule for the register number becomes a val_expression(E) rule. */ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned block_len = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &block_len,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } localregtab[lreg].ru_is_off = 0; /* arbitrary */ localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; fp_register = reg_no; } break; /* END DWARF3 new ops. */ #ifdef DW_CFA_GNU_window_save case DW_CFA_GNU_window_save: { /* No information: this just tells unwinder to restore the window registers from the previous frame's window save area */ break; } #endif #ifdef DW_CFA_GNU_args_size /* Single uleb128 is the current arg area size in bytes. No register exists yet to save this in. the value of must be added to an x86 register to get the correct stack pointer. https://lists.nongnu.org/archive/html/ libunwind-devel/2016-12/msg00004.html https://refspecs.linuxfoundation.org/ LSB_3.0.0/LSB-PDA/LSB-PDA.junk/dwarfext.html */ case DW_CFA_GNU_args_size: { UNUSEDARG Dwarf_Unsigned lreg = 0; int adres = 0; adres = _dwarf_leb128_uword_wrapper(dbg, &instr_ptr,final_instr_ptr, &lreg,error); if (adres != DW_DLV_OK) { free(localregtab); return adres; } /* We have nowhere to store lreg. FIXME This is the total size of arguments pushed on the stack. */ break; } #endif default: /* ERROR, we have an opcode we know nothing about. Memory leak here, but an error like this is not supposed to happen so we ignore the leak. These used to be ignored, now we notice and report. */ SER(DW_DLE_DF_FRAME_DECODING_ERROR); } if (make_instr) { instr_count++; curr_instr = (Dwarf_Frame_Op *) _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1); if (curr_instr == NULL) { SER(DW_DLE_DF_ALLOC_FAIL); } curr_instr->fp_base_op = fp_base_op; curr_instr->fp_extended_op = fp_extended_op; curr_instr->fp_register = fp_register; curr_instr->fp_offset = fp_offset; curr_instr->fp_instr_offset = fp_instr_offset; curr_instr_item = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_instr_item == NULL) { SER(DW_DLE_DF_ALLOC_FAIL); } curr_instr_item->ch_item = curr_instr; curr_instr_item->ch_itemtype = DW_DLA_FRAME_OP; if (head_instr_chain == NULL) head_instr_chain = tail_instr_chain = curr_instr_item; else { tail_instr_chain->ch_next = curr_instr_item; tail_instr_chain = curr_instr_item; } } } /* If frame instruction decoding was right we would stop exactly at final_instr_ptr. */ if (instr_ptr > final_instr_ptr) { SER(DW_DLE_DF_FRAME_DECODING_ERROR); } /* If search_over is set the last instr was an advance_loc so we are not done with rows. */ if ((instr_ptr == final_instr_ptr) && !search_over) { if (has_more_rows) { *has_more_rows = false; } if (subsequent_pc) { *subsequent_pc = 0; } } else { if (has_more_rows) { *has_more_rows = true; } if (subsequent_pc) { *subsequent_pc = possible_subsequent_pc; } } /* Fill in the actual output table, the space the caller passed in. */ if (table) { struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg; struct Dwarf_Reg_Rule_s *t3reg = localregtab; unsigned minregcount = MIN(table->fr_reg_count,reg_count); unsigned curreg = 0; table->fr_loc = current_loc; for (; curreg < minregcount ; curreg++, t3reg++, t2reg++) { *t2reg = *t3reg; } /* CONSTCOND */ /* Do not update the main table with the cfa_reg. Just leave cfa_reg as cfa_reg. */ table->fr_cfa_rule = cfa_reg; } /* Dealloc anything remaining on stack. */ for (; top_stack != NULL;) { stack_table = top_stack; top_stack = top_stack->fr_next; dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); } if (make_instr) { /* Allocate array of Dwarf_Frame_Op structs. */ head_instr_block = (Dwarf_Frame_Op *) _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count); if (head_instr_block == NULL) { SER(DW_DLE_DF_ALLOC_FAIL); } /* Store Dwarf_Frame_Op instances in this array and deallocate the structs that chain the Dwarf_Frame_Op instances. */ curr_instr_item = head_instr_chain; for (i = 0; i < instr_count; i++) { void *item = curr_instr_item->ch_item; int itemtype = curr_instr_item->ch_itemtype; Dwarf_Chain prev_instr = 0; /* This copies the structs, not pointers */ *(head_instr_block + i) = *(Dwarf_Frame_Op *)item; prev_instr = curr_instr_item; curr_instr_item = curr_instr_item->ch_next; /* Now the pointed-to are space to dealloc */ dwarf_dealloc(dbg, item, itemtype); dwarf_dealloc(dbg, prev_instr, DW_DLA_CHAIN); } *ret_frame_instr = head_instr_block; *returned_count = (Dwarf_Signed) instr_count; } else { *returned_count = 0; } free(localregtab); return DW_DLV_OK; #undef ERROR_IF_REG_NUM_TOO_HIGH #undef SER } /* Depending on version, either read the return address register as a ubyte or as an leb number. The form of this value changed for DWARF3. */ int _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, int version, Dwarf_Debug dbg, Dwarf_Byte_Ptr section_end, unsigned long *size, Dwarf_Unsigned *return_address_register, Dwarf_Error *error) { Dwarf_Unsigned uvalue = 0; Dwarf_Unsigned leb128_length = 0; if (version == 1) { if (frame_ptr >= section_end) { _dwarf_error(NULL, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } *size = 1; uvalue = *(unsigned char *) frame_ptr; *return_address_register = uvalue; return DW_DLV_OK; } DECODE_LEB128_UWORD_LEN_CK(frame_ptr,uvalue,leb128_length, dbg,error,section_end); *size = leb128_length; *return_address_register = uvalue; return DW_DLV_OK; } /* Trivial consumer function. */ int dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie * cie_returned, Dwarf_Error * error) { if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } *cie_returned = fde->fd_cie; return DW_DLV_OK; } int dwarf_get_cie_index( Dwarf_Cie cie, Dwarf_Signed* indx, Dwarf_Error* error ) { if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } *indx = cie->ci_index; return DW_DLV_OK; } /* For g++ .eh_frame fde and cie. the cie id is different as the definition of the cie_id in an fde is the distance back from the address of the value to the cie. Or 0 if this is a true cie. Non standard dwarf, designed this way to be convenient at run time for an allocated (mapped into memory as part of the running image) section. */ int dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_fde_list_internal(dbg, cie_data, cie_element_count, fde_data, fde_element_count, dbg->de_debug_frame_eh_gnu.dss_data, dbg->de_debug_frame_eh_gnu.dss_index, dbg->de_debug_frame_eh_gnu.dss_size, /* cie_id_value */ 0, /* use_gnu_cie_calc= */ 1, error); return res; } /* For standard dwarf .debug_frame cie_id is -1 in a cie, and is the section offset in the .debug_frame section of the cie otherwise. Standard dwarf */ int dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_fde_list_internal(dbg, cie_data, cie_element_count, fde_data, fde_element_count, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, DW_CIE_ID, /* use_gnu_cie_calc= */ 0, error); return res; } /* Only works on dwarf sections, not eh_frame because based on DW_AT_MIPS_fde. Given a Dwarf_Die, see if it has a DW_AT_MIPS_fde attribute and if so use that to get an fde offset. Then create a Dwarf_Fde to return thru the ret_fde pointer. Also creates a cie (pointed at from the Dwarf_Fde). */ int dwarf_get_fde_for_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Fde * ret_fde, Dwarf_Error * error) { Dwarf_Attribute attr; Dwarf_Unsigned fde_offset = 0; Dwarf_Signed signdval = 0; Dwarf_Fde new_fde = 0; unsigned char *fde_ptr = 0; unsigned char *fde_start_ptr = 0; unsigned char *fde_end_ptr = 0; unsigned char *cie_ptr = 0; Dwarf_Unsigned cie_id = 0; /* Fields for the current Cie being read. */ int res = 0; int resattr = 0; int sdatares = 0; struct cie_fde_prefix_s prefix; struct cie_fde_prefix_s prefix_c; if (die == NULL) { _dwarf_error(NULL, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error); if (resattr != DW_DLV_OK) { return resattr; } /* why is this formsdata? FIX */ sdatares = dwarf_formsdata(attr, &signdval, error); if (sdatares != DW_DLV_OK) { return sdatares; } res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error); if (res != DW_DLV_OK) { return res; } fde_offset = signdval; fde_start_ptr = dbg->de_debug_frame.dss_data; fde_ptr = fde_start_ptr + fde_offset; fde_end_ptr = fde_start_ptr + dbg->de_debug_frame.dss_size; /* First read in the 'common prefix' to figure out what we are to do with this entry. */ memset(&prefix_c, 0, sizeof(prefix_c)); memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, fde_ptr, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, &prefix, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } fde_ptr = prefix.cf_addr_after_prefix; cie_id = prefix.cf_cie_id; /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame.dss_data has no eh_frame relevance. */ res = dwarf_create_fde_from_after_start(dbg, &prefix, fde_start_ptr, fde_ptr, fde_end_ptr, /* use_gnu_cie_calc= */ 0, /* Dwarf_Cie = */ 0, &new_fde, error); if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } /* DW_DLV_OK */ /* now read the cie corresponding to the fde */ cie_ptr = new_fde->fd_section_ptr + cie_id; res = dwarf_read_cie_fde_prefix(dbg, cie_ptr, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, &prefix_c, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) return res; cie_ptr = prefix_c.cf_addr_after_prefix; cie_id = prefix_c.cf_cie_id; if (cie_id == (Dwarf_Unsigned)DW_CIE_ID) { int res2 = 0; Dwarf_Cie new_cie = 0; /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame.dss_data has no eh_frame relevance. */ res2 = dwarf_create_cie_from_after_start(dbg, &prefix_c, fde_start_ptr, cie_ptr, fde_end_ptr, /* cie_count= */ 0, /* use_gnu_cie_calc= */ 0, &new_cie, error); if (res2 == DW_DLV_ERROR) { dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); return res; } else if (res2 == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); return res; } new_fde->fd_cie = new_cie; } else { _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE); return DW_DLV_ERROR; } *ret_fde = new_fde; return DW_DLV_OK; } /* A dwarf consumer operation, see the consumer library documentation. */ int dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr * low_pc, Dwarf_Unsigned * func_length, Dwarf_Ptr * fde_bytes, Dwarf_Unsigned * fde_byte_length, Dwarf_Off * cie_offset, Dwarf_Signed * cie_index, Dwarf_Off * fde_offset, Dwarf_Error * error) { Dwarf_Debug dbg; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } /* We have always already done the section load here, so no need to load the section. We did the section load in order to create the Dwarf_Fde pointer passed in here. */ if (low_pc != NULL) *low_pc = fde->fd_initial_location; if (func_length != NULL) *func_length = fde->fd_address_range; if (fde_bytes != NULL) *fde_bytes = fde->fd_fde_start; if (fde_byte_length != NULL) *fde_byte_length = fde->fd_length; if (cie_offset != NULL) *cie_offset = fde->fd_cie_offset; if (cie_index != NULL) *cie_index = fde->fd_cie_index; if (fde_offset != NULL) *fde_offset = fde->fd_fde_start - fde->fd_section_ptr; return DW_DLV_OK; } /* IRIX specific function. The exception tables have C++ destructor information and are at present undocumented. */ int dwarf_get_fde_exception_info(Dwarf_Fde fde, Dwarf_Signed * offset_into_exception_tables, Dwarf_Error * error) { Dwarf_Debug dbg; dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } *offset_into_exception_tables = fde->fd_offset_into_exception_tables; return DW_DLV_OK; } /* A consumer code function. Given a CIE pointer, return the normal CIE data thru pointers. Special augmentation data is not returned here. */ int dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned * bytes_in_cie, Dwarf_Small * ptr_to_version, char **augmenter, Dwarf_Unsigned * code_alignment_factor, Dwarf_Signed * data_alignment_factor, Dwarf_Half * return_address_register, Dwarf_Ptr * initial_instructions, Dwarf_Unsigned * initial_instructions_length, Dwarf_Error * error) { Dwarf_Half offset_size = 0; return dwarf_get_cie_info_b(cie, bytes_in_cie, ptr_to_version, augmenter, code_alignment_factor, data_alignment_factor, return_address_register, initial_instructions, initial_instructions_length, &offset_size, error); } int dwarf_get_cie_info_b(Dwarf_Cie cie, Dwarf_Unsigned * bytes_in_cie, Dwarf_Small * ptr_to_version, char **augmenter, Dwarf_Unsigned * code_alignment_factor, Dwarf_Signed * data_alignment_factor, Dwarf_Half * return_address_register, Dwarf_Ptr * initial_instructions, Dwarf_Unsigned * initial_instructions_length, Dwarf_Half * offset_size, Dwarf_Error * error) { Dwarf_Debug dbg = 0; if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } dbg = cie->ci_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL); return DW_DLV_ERROR; } if (ptr_to_version != NULL) *ptr_to_version = cie->ci_cie_version_number; if (augmenter != NULL) *augmenter = cie->ci_augmentation; if (code_alignment_factor != NULL) *code_alignment_factor = cie->ci_code_alignment_factor; if (data_alignment_factor != NULL) *data_alignment_factor = cie->ci_data_alignment_factor; if (return_address_register != NULL) *return_address_register = cie->ci_return_address_register; if (initial_instructions != NULL) *initial_instructions = cie->ci_cie_instr_start; if (initial_instructions_length != NULL) { *initial_instructions_length = cie->ci_length + cie->ci_length_size + cie->ci_extension_size - (cie->ci_cie_instr_start - cie->ci_cie_start); } if (offset_size) { *offset_size = cie->ci_length_size; } *bytes_in_cie = (cie->ci_length); return DW_DLV_OK; } /* Return the register rules for all registers at a given pc. */ static int _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Frame table, Dwarf_Half cfa_reg_col_num, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Cie cie = 0; Dwarf_Signed icount = 0; int res = 0; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } if (pc_requested < fde->fd_initial_location || pc_requested >= fde->fd_initial_location + fde->fd_address_range) { _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); return DW_DLV_ERROR; } cie = fde->fd_cie; if (cie->ci_initial_table == NULL) { Dwarf_Small *instrstart = cie->ci_cie_instr_start; Dwarf_Small *instrend = instrstart +cie->ci_length + cie->ci_length_size + cie->ci_extension_size - (cie->ci_cie_instr_start - cie->ci_cie_start); if (instrend > cie->ci_cie_end) { _dwarf_error(dbg, error,DW_DLE_CIE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } cie->ci_initial_table = (Dwarf_Frame)_dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); if (cie->ci_initial_table == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dwarf_init_reg_rules_ru(cie->ci_initial_table->fr_reg, 0, cie->ci_initial_table->fr_reg_count, dbg->de_frame_rule_initial_value); dwarf_init_reg_rules_ru(&cie->ci_initial_table->fr_cfa_rule, 0,1,dbg->de_frame_rule_initial_value); res = _dwarf_exec_frame_instr( /* make_instr= */ false, /* ret_frame_instr= */ NULL, /* search_pc */ false, /* search_pc_val */ 0, /* location */ 0, instrstart, instrend, cie->ci_initial_table, cie, dbg, cfa_reg_col_num, &icount, NULL,NULL, error); if (res != DW_DLV_OK) { return res; } } { Dwarf_Small *instr_end = fde->fd_fde_instr_start + fde->fd_length + fde->fd_length_size + fde->fd_extension_size - (fde->fd_fde_instr_start - fde->fd_fde_start); if (instr_end > fde->fd_fde_end) { _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } res = _dwarf_exec_frame_instr( /* make_instr= */ false, /* ret_frame_instr= */ NULL, /* search_pc */ true, /* search_pc_val */ pc_requested, fde->fd_initial_location, fde->fd_fde_instr_start, instr_end, table, cie, dbg, cfa_reg_col_num, &icount, has_more_rows, subsequent_pc, error); } if (res != DW_DLV_OK) { return res; } return DW_DLV_OK; } /* A consumer call for efficiently getting the register info for all registers in one call. The output table rules array is size DW_REG_TABLE_SIZE. The frame info rules array in fde_table is of size DW_REG_TABLE_SIZE too. This interface really only works well with MIPS/IRIX where DW_FRAME_CFA_COL is zero (in that case it's safe). It is also restricted to the case where DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM == dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX). If this condition is not met calling this routine can result in incorrect output or in memory corruption. It is much better to use dwarf_get_fde_info_for_all_regs3() instead of this interface. */ int dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable * reg_table, Dwarf_Addr * row_pc, Dwarf_Error * error) { /* Table size: DW_REG_TABLE_SIZE */ struct Dwarf_Frame_s fde_table; Dwarf_Signed i = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry_s *out_rule = NULL; int res = 0; Dwarf_Debug dbg = 0; /* For this interface the size is fixed at compile time. */ int output_table_real_data_size = DW_REG_TABLE_SIZE; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) return res; /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number,NULL,NULL, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } out_rule = ®_table->rules[0]; rule = &fde_table.fr_reg[0]; for (i = 0; i < output_table_real_data_size; i++, ++out_rule, ++rule) { out_rule->dw_offset_relevant = rule->ru_is_off; out_rule->dw_value_type = rule->ru_value_type; out_rule->dw_regnum = rule->ru_register; out_rule->dw_offset = rule->ru_offset_or_block_len; } dwarf_init_reg_rules_dw(®_table->rules[0],i,DW_REG_TABLE_SIZE, dbg->de_frame_undefined_value_number); /* The test is just in case it's not inside the table. For non-MIPS it could be outside the table and that is just fine, it was really a mistake to put it in the table in 1993. */ /* CONSTCOND */ if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) { out_rule = ®_table->rules[dbg->de_frame_cfa_col_number]; out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off; out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type; out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register; out_rule->dw_offset = fde_table.fr_cfa_rule.ru_offset_or_block_len; } if (row_pc != NULL) *row_pc = fde_table.fr_loc; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* A consumer call for efficiently getting the register info for all registers in one call. The output table rules array is size output_table_real_data_size. (normally DW_REG_TABLE_SIZE). The frame info rules array in fde_table is normally of size DW_FRAME_LAST_REG_NUM. */ int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable3 * reg_table, Dwarf_Addr * row_pc, Dwarf_Error * error) { struct Dwarf_Frame_s fde_table; Dwarf_Signed i = 0; int res = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry3_s *out_rule = NULL; Dwarf_Debug dbg = 0; int output_table_real_data_size = reg_table->rt3_reg_table_size; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); output_table_real_data_size = MIN(output_table_real_data_size, dbg->de_frame_reg_rules_entry_count); res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) { return res; } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number, NULL,NULL, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } out_rule = ®_table->rt3_rules[0]; rule = &fde_table.fr_reg[0]; for (i = 0; i < output_table_real_data_size; i++, ++out_rule, ++rule) { out_rule->dw_offset_relevant = rule->ru_is_off; out_rule->dw_value_type = rule->ru_value_type; out_rule->dw_regnum = rule->ru_register; out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len; out_rule->dw_block_ptr = rule->ru_block; } dwarf_init_reg_rules_dw3(®_table->rt3_rules[0],i, reg_table->rt3_reg_table_size, dbg->de_frame_undefined_value_number); reg_table->rt3_cfa_rule.dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off; reg_table->rt3_cfa_rule.dw_value_type = fde_table.fr_cfa_rule.ru_value_type; reg_table->rt3_cfa_rule.dw_regnum = fde_table.fr_cfa_rule.ru_register; reg_table->rt3_cfa_rule.dw_offset_or_block_len = fde_table.fr_cfa_rule.ru_offset_or_block_len; reg_table->rt3_cfa_rule.dw_block_ptr = fde_table.fr_cfa_rule.ru_block; if (row_pc != NULL) *row_pc = fde_table.fr_loc; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* Obsolete as of 2006. Gets the register info for a single register at a given PC value for the FDE specified. This is the old MIPS interface and should no longer be used. Use dwarf_get_fde_info_for_reg3() instead. It can not handle DWARF3 or later properly as it assumes the CFA is representable as a table column. */ int dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset, Dwarf_Addr * row_pc, Dwarf_Error * error) { struct Dwarf_Frame_s fde_table; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int output_table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); output_table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) return res; if (table_column >= output_table_real_data_size) { dwarf_free_fde_table(&fde_table); _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return DW_DLV_ERROR; } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number, NULL,NULL,error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) { /* The problem here is that this interface cannot deal with other sorts of (newer) dwarf frame values. Code must use dwarf_get_fde_info_for_reg3() to get these values correctly. We error rather than return misleading incomplete data. */ dwarf_free_fde_table(&fde_table); _dwarf_error(NULL, error, DW_DLE_FRAME_REGISTER_UNREPRESENTABLE); return DW_DLV_ERROR; } if (table_column == dbg->de_frame_cfa_col_number) { if (register_num) { *register_num = fde_table.fr_cfa_rule.ru_register; } if (offset) { *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len; } if (row_pc) { *row_pc = fde_table.fr_loc; } *offset_relevant = fde_table.fr_cfa_rule.ru_is_off; } else { if (register_num) { *register_num = fde_table.fr_reg[table_column]. ru_register; } if (offset) { *offset = fde_table.fr_reg[table_column]. ru_offset_or_block_len; } if (row_pc) { *row_pc = fde_table.fr_loc; } *offset_relevant = fde_table.fr_reg[table_column].ru_is_off; } dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* In this interface, table_column of DW_FRAME_CFA_COL is not meaningful. Use dwarf_get_fde_info_for_cfa_reg3() to get the CFA. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() (DW_FRAME_CFA_COL3 is a sensible column to use). */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Error * error) { int res = dwarf_get_fde_info_for_reg3_b(fde, table_column, pc_requested, value_type, offset_relevant, register_num, offset_or_block_len, block_ptr, row_pc_out, /* Not looking for the has_more_rows flag nor for the next pc in the frame data. */ NULL,NULL, error); return res; } /* New May 2018. If one is tracking the value of a single table column through a function, this lets us skip to the next pc value easily. if pc_requested is a change from the last pc_requested on this pc, this function returns *has_more_rows and *subsequent_pc (null pointers passed are acceptable, the assignment through the pointer is skipped if the pointer is null). Otherwise *has_more_rows and *subsequent_pc are not set. */ int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { struct Dwarf_Frame_s * fde_table = &(fde->fd_fde_table); int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); if (!fde->fd_have_fde_tab || /* The test is just in case it's not inside the table. For non-MIPS it could be outside the table and that is just fine, it was really a mistake to put it in the table in 1993. */ fde->fd_fde_pc_requested != pc_requested) { if (fde->fd_have_fde_tab) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; } table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, fde_table, table_real_data_size, error); if (res != DW_DLV_OK) { return res; } if (table_column >= table_real_data_size) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return DW_DLV_ERROR; } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, fde_table, dbg->de_frame_cfa_col_number, has_more_rows,subsequent_pc, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; return res; } } if (register_num != NULL) { *register_num = fde_table->fr_reg[table_column].ru_register; } if (offset_or_block_len != NULL) { *offset_or_block_len = fde_table->fr_reg[table_column].ru_offset_or_block_len; } if (row_pc_out != NULL) { *row_pc_out = fde_table->fr_loc; } if (block_ptr) { *block_ptr = fde_table->fr_reg[table_column].ru_block; } /* Without value_type the data cannot be understood, so we insist on it being present, we don't test it. */ *value_type = fde_table->fr_reg[table_column].ru_value_type; *offset_relevant = (fde_table->fr_reg[table_column].ru_is_off); fde->fd_have_fde_tab = true; fde->fd_fde_pc_requested = pc_requested; return DW_DLV_OK; } /* New 2006. For current DWARF, this is a preferred interface. Compared to dwarf_get_fde_info_for_reg() it more correctly deals with the CFA by not making the CFA a column number, which means DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, a special value, not something one uses as an index. See also dwarf_get_fde_info_for_cfa_reg3_b(), which is slightly preferred. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Error * error) { Dwarf_Bool has_more_rows = 0; Dwarf_Addr next_pc = 0; int res = 0; res = dwarf_get_fde_info_for_cfa_reg3_b(fde, pc_requested, value_type, offset_relevant, register_num, offset_or_block_len, block_ptr, row_pc_out, &has_more_rows, &next_pc, error); return res; } /* New June 11,2016. For current DWARF, this is a preferred interface. Has extra arguments has_more_rows and next_pc (compared to dwarf_get_fde_info_for_cfa_reg3()) which can be used to more efficiently traverse frame data (primarily for dwarfdump and like programs). Like dwarf_get_fde_info_for_cfa_reg3() it deals with the CFA by not making the CFA a column number, which means DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, a special value, not something one uses as an index. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() (DW_FRAME_CFA_COL3 is a sensible column to use, and is the default unless '--enable-oldframecol' is used to configure libdwarf). */ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { struct Dwarf_Frame_s fde_table; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, &fde_table, table_real_data_size, error); if (res != DW_DLV_OK) return res; res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number,has_more_rows, subsequent_pc,error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } if (register_num != NULL) *register_num = fde_table.fr_cfa_rule.ru_register; if (offset_or_block_len != NULL) *offset_or_block_len = fde_table.fr_cfa_rule.ru_offset_or_block_len; if (row_pc_out != NULL) { *row_pc_out = fde_table.fr_loc; } if (block_ptr) { *block_ptr = fde_table.fr_cfa_rule.ru_block; } /* Without value_type the data cannot be understood, so we insist on it being present, we don't test it. */ *value_type = fde_table.fr_cfa_rule.ru_value_type; *offset_relevant = fde_table.fr_cfa_rule.ru_is_off; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* Return pointer to the instructions in the dwarf fde. */ int dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr, Dwarf_Unsigned * outaddrlen, Dwarf_Error * error) { Dwarf_Unsigned len = 0; unsigned char *instrs = 0; Dwarf_Debug dbg = 0; if (inFde == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } dbg = inFde->fd_dbg; if (dbg == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } instrs = inFde->fd_fde_instr_start; len = (inFde->fd_fde_start + inFde->fd_length + inFde->fd_length_size + inFde->fd_extension_size) - instrs; *outinstraddr = instrs; *outaddrlen = len; return DW_DLV_OK; } /* Allows getting an fde from its table via an index. With more error checking than simply indexing oneself. */ int dwarf_get_fde_n(Dwarf_Fde * fde_data, Dwarf_Unsigned fde_index, Dwarf_Fde * returned_fde, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned fdecount = 0; if (fde_data == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL); return DW_DLV_ERROR; } FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg); /* Assumes fde_data table has at least one entry. */ fdecount = fde_data[0]->fd_is_eh? dbg->de_fde_count_eh:dbg->de_fde_count; if (fde_index >= fdecount) { return DW_DLV_NO_ENTRY; } *returned_fde = (*(fde_data + fde_index)); return DW_DLV_OK; } /* Lopc and hipc are extensions to the interface to return the range of addresses that are described by the returned fde. */ int dwarf_get_fde_at_pc(Dwarf_Fde * fde_data, Dwarf_Addr pc_of_interest, Dwarf_Fde * returned_fde, Dwarf_Addr * lopc, Dwarf_Addr * hipc, Dwarf_Error * error) { Dwarf_Debug dbg = NULL; Dwarf_Fde fde = NULL; Dwarf_Fde entryfde = NULL; Dwarf_Signed fdecount = 0; if (fde_data == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL); return DW_DLV_ERROR; } /* Assumes fde_data table has at least one entry. */ entryfde = *fde_data; FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg); fdecount = entryfde->fd_is_eh? dbg->de_fde_count_eh:dbg->de_fde_count; { /* The fdes are sorted by their addresses. Binary search to find correct fde. */ Dwarf_Signed low = 0; Dwarf_Signed high = fdecount - 1L; Dwarf_Signed middle = 0; Dwarf_Fde cur_fde; while (low <= high) { middle = (low + high) / 2; cur_fde = fde_data[middle]; if (pc_of_interest < cur_fde->fd_initial_location) { high = middle - 1; } else if (pc_of_interest >= (cur_fde->fd_initial_location + cur_fde->fd_address_range)) { low = middle + 1; } else { fde = fde_data[middle]; break; } } } if (fde) { if (lopc != NULL) *lopc = fde->fd_initial_location; if (hipc != NULL) *hipc = fde->fd_initial_location + fde->fd_address_range - 1; *returned_fde = fde; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* Expands a single frame instruction block from a specific cie into a n array of Dwarf_Frame_Op-s. This depends on having the cfa column set sensibly. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() unless you are using the old MIPS frame interfaces (in which case the default will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ). */ int dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, Dwarf_Unsigned i_length, Dwarf_Frame_Op ** returned_op_list, Dwarf_Signed * returned_op_count, Dwarf_Error * error) { Dwarf_Signed instr_count; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; Dwarf_Small * instr_start = instruction; Dwarf_Small * instr_end = (Dwarf_Small *)instruction + i_length;; if (cie == 0) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } dbg = cie->ci_dbg; if (returned_op_list == 0 || returned_op_count == 0) { _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL); return DW_DLV_ERROR; } if ( instr_end < instr_start) { /* Impossible unless there was wraparond somewhere and we missed it. */ _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } res = _dwarf_exec_frame_instr( /* make_instr= */ true, returned_op_list, /* search_pc */ false, /* search_pc_val */ 0, /* location */ 0, instr_start, instr_end, /* Dwarf_Frame */ NULL, cie, dbg, dbg->de_frame_cfa_col_number, &instr_count, NULL,NULL, error); if (res != DW_DLV_OK) { return (res); } *returned_op_count = instr_count; return DW_DLV_OK; } /* Used by dwarfdump -v to print offsets, for debugging dwarf info. The dwarf_ version is preferred over the obsolete _dwarf version. _dwarf version kept for compatibility. */ /* ARGSUSED 4 */ int _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, Dwarf_Off * fde_off, Dwarf_Off * cie_off, Dwarf_Error * err) { return dwarf_fde_section_offset(dbg,in_fde,fde_off, cie_off,err); } /* ARGSUSED 4 */ int dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, Dwarf_Off * fde_off, Dwarf_Off * cie_off, Dwarf_Error * err) { char *start = 0; char *loc = 0; if (!in_fde) { _dwarf_error(dbg, err, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } start = (char *) in_fde->fd_section_ptr; loc = (char *) in_fde->fd_fde_start; *fde_off = (loc - start); *cie_off = in_fde->fd_cie_offset; return DW_DLV_OK; } /* Used by dwarfdump -v to print offsets, for debugging dwarf info. The dwarf_ version is preferred over the obsolete _dwarf version. _dwarf version kept for compatibility. */ /* ARGSUSED 4 */ int _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, Dwarf_Off * cie_off, Dwarf_Error * err) { return dwarf_cie_section_offset(dbg,in_cie,cie_off,err); } /* ARGSUSED 4 */ int dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, Dwarf_Off * cie_off, Dwarf_Error * err) { char *start = 0; char *loc = 0; if (!in_cie) { _dwarf_error(dbg, err, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } start = (char *) in_cie->ci_section_ptr; loc = (char *) in_cie->ci_cie_start; *cie_off = (loc - start); return DW_DLV_OK; } /* Returns a pointer to target-specific augmentation data thru augdata and returns the length of the data thru augdata_len. It's up to the consumer code to know how to interpret the bytes of target-specific data (endian issues apply too, these are just raw bytes pointed to). See Linux Standard Base Core Specification version 3.0 for the details on .eh_frame info. Returns DW_DLV_ERROR if fde is NULL or some other serious error. Returns DW_DLV_NO_ENTRY if there is no target-specific augmentation data. The bytes pointed to are in the Dwarf_Cie, and as long as that is valid the bytes are there. No 'dealloc' call is needed for the bytes. */ int dwarf_get_cie_augmentation_data(Dwarf_Cie cie, Dwarf_Small ** augdata, Dwarf_Unsigned * augdata_len, Dwarf_Error * error) { if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } if (cie->ci_gnu_eh_augmentation_len == 0) { return DW_DLV_NO_ENTRY; } *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes); *augdata_len = cie->ci_gnu_eh_augmentation_len; return DW_DLV_OK; } /* Returns a pointer to target-specific augmentation data thru augdata and returns the length of the data thru augdata_len. It's up to the consumer code to know how to interpret the bytes of target-specific data (endian issues apply too, these are just raw bytes pointed to). See Linux Standard Base Core Specification version 3.0 for the details on .eh_frame info. Returns DW_DLV_ERROR if fde is NULL or some other serious error. Returns DW_DLV_NO_ENTRY if there is no target-specific augmentation data. The bytes pointed to are in the Dwarf_Fde, and as long as that is valid the bytes are there. No 'dealloc' call is needed for the bytes. */ int dwarf_get_fde_augmentation_data(Dwarf_Fde fde, Dwarf_Small * *augdata, Dwarf_Unsigned * augdata_len, Dwarf_Error * error) { Dwarf_Cie cie = 0; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } if (!fde->fd_gnu_eh_aug_present) { return DW_DLV_NO_ENTRY; } cie = fde->fd_cie; if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes; *augdata_len = fde->fd_gnu_eh_augmentation_len; return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ /* Used solely for debugging libdwarf. */ static void dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule) { printf ("%s type %s (0x%" DW_PR_XZEROS DW_PR_DUx "), is_off %" DW_PR_DUu " reg %" DW_PR_DUu " offset 0x%" DW_PR_XZEROS DW_PR_DUx " blockp 0x%" DW_PR_XZEROS DW_PR_DUx "\n", msg, (reg_rule->ru_value_type == DW_EXPR_OFFSET) ? "DW_EXPR_OFFSET" : (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ? "DW_EXPR_VAL_OFFSET" : (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ? "DW_EXPR_VAL_EXPRESSION" : (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ? "DW_EXPR_EXPRESSION" : "Unknown", (Dwarf_Unsigned) reg_rule->ru_value_type, (Dwarf_Unsigned) reg_rule->ru_is_off, (Dwarf_Unsigned) reg_rule->ru_register, (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len, (Dwarf_Unsigned) reg_rule->ru_block); return; } #endif /* This allows consumers to set the 'initial value' so that an ISA/ABI specific default can be used, dynamically, at run time. Useful for dwarfdump and non-MIPS architectures.. The value defaults to one of DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE but dwarfdump can dump multiple ISA/ABI objects so we may want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_rule_initial_value; dbg->de_frame_rule_initial_value = value; return orig; } /* The following spelling for backwards compatibility. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value) { return dwarf_set_frame_rule_initial_value(dbg,value); } /* This allows consumers to set the array size of the reg rules table so that an ISA/ABI specific value can be used, dynamically, at run time. Useful for non-MIPS architectures. The value defaults to DW_FRAME_LAST_REG_NUM. but dwarfdump can dump multiple ISA/ABI objects so consumers want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count; dbg->de_frame_reg_rules_entry_count = value; /* Take the caller-specified value, but do not let the value be too small. Keep it at least to DW_FRAME_LAST_REG_NUM. This helps prevent libdwarf (mistakenly) indexing outside of of a register array when the ABI reg count is really small. */ if (value < DW_FRAME_LAST_REG_NUM) { dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; } return orig; } /* This allows consumers to set the CFA register value so that an ISA/ABI specific value can be used, dynamically, at run time. Useful for non-MIPS architectures. The value defaults to DW_FRAME_CFA_COL3 and should be higher than any real register in the ABI. Dwarfdump can dump multiple ISA/ABI objects so consumers want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_cfa_col_number; dbg->de_frame_cfa_col_number = value; return orig; } /* Similar to above, but for the other crucial fields for frames. */ Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_same_value_number; dbg->de_frame_same_value_number = value; return orig; } Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_same_value_number; dbg->de_frame_undefined_value_number = value; return orig; } /* Does something only if value passed in is greater than 0 and a size than we can handle (in number of bytes). */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug dbg, Dwarf_Small value ) { Dwarf_Small orig = dbg->de_pointer_size; if (value > 0 && value <= sizeof(Dwarf_Addr)) { dbg->de_pointer_size = value; } return orig; } static int init_reg_rules_alloc(Dwarf_Debug dbg,struct Dwarf_Frame_s *f, unsigned count, Dwarf_Error * error) { f->fr_reg_count = count; f->fr_reg = (struct Dwarf_Reg_Rule_s *) calloc(sizeof(struct Dwarf_Reg_Rule_s), count); if (f->fr_reg == 0) { if (error) { _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL); } return DW_DLV_ERROR; } dwarf_init_reg_rules_ru(f->fr_reg,0, count, dbg->de_frame_rule_initial_value); return DW_DLV_OK; } static int dwarf_initialize_fde_table(Dwarf_Debug dbg, struct Dwarf_Frame_s *fde_table, unsigned table_real_data_size, Dwarf_Error * error) { unsigned entry_size = sizeof(struct Dwarf_Frame_s); memset(fde_table,0,entry_size); fde_table->fr_loc = 0; fde_table->fr_next = 0; return init_reg_rules_alloc(dbg,fde_table, table_real_data_size,error); } static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table) { free(fde_table->fr_reg); fde_table->fr_reg_count = 0; fde_table->fr_reg = 0; } /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR. */ int _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame) { struct Dwarf_Frame_s *fp = frame; if (!dbg) { return DW_DLV_ERROR; } return init_reg_rules_alloc(dbg,fp, dbg->de_frame_reg_rules_entry_count, 0); } void _dwarf_frame_destructor(void *frame) { struct Dwarf_Frame_s *fp = frame; dwarf_free_fde_table(fp); } void _dwarf_fde_destructor(void *f) { struct Dwarf_Fde_s *fde = f; if (fde->fd_have_fde_tab) { dwarf_free_fde_table(&fde->fd_fde_table); fde->fd_have_fde_tab = false; } } static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Reg_Rule_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->ru_is_off = 0; r->ru_value_type = DW_EXPR_OFFSET; r->ru_register = initial_value; r->ru_offset_or_block_len = 0; r->ru_block = 0; } } static void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Regtable_Entry_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->dw_offset_relevant = 0; r->dw_value_type = DW_EXPR_OFFSET; r->dw_regnum = initial_value; r->dw_offset = 0; } } static void dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Regtable_Entry3_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->dw_offset_relevant = 0; r->dw_value_type = DW_EXPR_OFFSET; r->dw_regnum = initial_value; r->dw_offset_or_block_len = 0; r->dw_block_ptr = 0; } } libdwarf-20210528/libdwarf/pro_pubnames.c0000664000175000017500000000533113764007262015135 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "libdwarfdefs.h" #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_section.h" /* This function adds another public name to the list of public names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_pubname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubname_name, dwarf_snk_pubname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_pubname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubname_name, dwarf_snk_pubname, error); return res; } Dwarf_Unsigned dwarf_add_pubtype(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubtype_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, dwarf_snk_pubtype, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_pubtype_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubtype_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, dwarf_snk_pubtype, error); return res; } libdwarf-20210528/libdwarf/test_headersok.c0000664000175000017500000000162714047261550015450 00000000000000/* Just to verify no typos preventing inclusion */ /* This test code is hereby placed in the public domain. */ #include "dwarf_reloc_386.h" #include "dwarf_reloc_mips.h" #include "dwarf_reloc_ppc.h" #include "dwarf_reloc_arm.h" #include "dwarf_reloc_ppc64.h" #include "dwarf_reloc_x86_64.h" /* The assignments and tests are to avoid compiler warnings with -Wall */ int main() { const char *y = reloc_type_names_PPC64[0]; if (!y) { return 1; } y = reloc_type_names_X86_64[0]; if (!y) { return 1; } y = reloc_type_names_ARM[0]; if (!y) { return 1; } y = reloc_type_names_PPC[0]; if (!y) { return 1; } y = reloc_type_names_MIPS[0]; if (!y) { return 1; } y = reloc_type_names_386[0]; if (!y) { return 1; } y = reloc_type_names_386[0]; if (!y) { return 1; } return 0; } libdwarf-20210528/libdwarf/dwarf_alloc.c0000664000175000017500000010471314004651012014706 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* To see the full set of DW_DLA types and nothing else try: grep DW_DLA dwarf_alloc.c | grep 0x */ #include "config.h" #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_alloc.h" /* These files are included to get the sizes of structs for malloc. */ #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarf_global.h" #include "dwarf_arange.h" #include "dwarf_abbrev.h" #include "dwarf_die_deliv.h" #include "dwarf_frame.h" #include "dwarf_loc.h" #include "dwarf_funcs.h" #include "dwarf_types.h" #include "dwarf_vars.h" #include "dwarf_weaks.h" #include "dwarf_harmless.h" #include "dwarf_tsearch.h" #include "dwarf_gdbindex.h" #include "dwarf_gnu_index.h" #include "dwarf_xu_index.h" #include "dwarf_macro5.h" #include "dwarf_debug_names.h" #include "dwarf_rnglists.h" #include "dwarf_dsc.h" #include "dwarfstring.h" #include "dwarf_str_offsets.h" /* if DEBUG is defined a lot of stdout is generated here. */ #undef DEBUG #define TRUE 1 #define FALSE 0 /* Some allocations are simple some not. These reduce the issue of determining which sort of thing to a simple test. See ia_multiply_count Usually when MULTIPLY_NO is set the count is 1, so MULTIPY_CT would work as well. */ #define MULTIPLY_NO 0 #define MULTIPLY_CT 1 #define MULTIPLY_SP 2 /* This translates into de_alloc_hdr into a per-instance size and allows room for a constructor/destructor pointer. Rearranging the DW_DLA values would break binary compatibility so that is not an option. */ struct ial_s { /* In bytes, one struct instance. */ short ia_struct_size; /* Not a count, but a MULTIPLY{_NO,_CT,_SP} value. */ short ia_multiply_count; /* When we really need a constructor/destructor these make applying such quite simple. */ int (*specialconstructor) (Dwarf_Debug, void *); void (*specialdestructor) (void *); }; /* Used as a way to return meaningful errors when the malloc arena is exhausted (when malloc returns NULL). Not normally used. New in December 2014.*/ struct Dwarf_Error_s _dwarf_failsafe_error = { DW_DLE_FAILSAFE_ERRVAL, 0, 1 }; /* If non-zero (the default) de_alloc_tree (see dwarf_alloc.c) is used normally. If zero then dwarf allocations are not tracked by libdwarf and dwarf_finish() cannot clean up any per-Dwarf_Debug allocations the caller forgot to dealloc. */ static signed char global_de_alloc_tree_on = 1; #ifdef HAVE_GLOBAL_ALLOC_SUMS static Dwarf_Unsigned global_allocation_count; static Dwarf_Unsigned global_allocation_total; static Dwarf_Unsigned global_de_alloc_tree_count; static Dwarf_Unsigned global_de_alloc_tree_total; static Dwarf_Unsigned global_de_alloc_tree_early_dealloc_count; static Dwarf_Unsigned global_de_alloc_tree_early_dealloc_size; #endif /* HAVE_GLOBAL_ALLOC_SUMS */ void _dwarf_alloc_tree_counts( UNUSEDARG Dwarf_Unsigned *allocount, UNUSEDARG Dwarf_Unsigned *allosum, UNUSEDARG Dwarf_Unsigned *treecount, UNUSEDARG Dwarf_Unsigned *treesum, UNUSEDARG Dwarf_Unsigned *earlydealloccount, UNUSEDARG Dwarf_Unsigned *earlydeallocsize, UNUSEDARG Dwarf_Unsigned *unused1, UNUSEDARG Dwarf_Unsigned *unused2, UNUSEDARG Dwarf_Unsigned *unused3) { #ifdef HAVE_GLOBAL_ALLOC_SUMS *allocount = global_allocation_count; *allosum = global_allocation_total; *treecount = global_de_alloc_tree_count; *treesum = global_de_alloc_tree_total; *earlydealloccount = global_de_alloc_tree_early_dealloc_count; *earlydeallocsize = global_de_alloc_tree_early_dealloc_size; if (unused1) { *unused1 = 0; } if (unused2) { *unused2 = 0; } if (unused3) { *unused3 = 0; } #endif /* HAVE_GLOBAL_ALLOC_SUMS */ } /* Defined March 7 2020. Allows a caller to avoid most tracking by the de_alloc_tree hash table if called with v of zero. Returns the value the flag was before this call. */ int dwarf_set_de_alloc_flag(int v) { int ov = global_de_alloc_tree_on; global_de_alloc_tree_on = v; return ov; } void _dwarf_error_destructor(void *m) { Dwarf_Error er = (Dwarf_Error)m; dwarfstring *erm = (dwarfstring *)er->er_msg; if (! erm) { return; } #if DEBUG printf("libdwarfdetector DEALLOC Now destruct error " "string %s\n",dwarfstring_string(erm)); #endif dwarfstring_destructor(erm); free(erm); er->er_msg = 0; return; } /* To do destructors we need some extra data in every _dwarf_get_alloc situation. */ /* Here is the extra we malloc for a prefix. */ struct reserve_size_s { void *dummy_rsv1; void *dummy_rsv2; }; /* Here is how we use the extra prefix area. */ struct reserve_data_s { void *rd_dbg; unsigned short rd_length; unsigned short rd_type; }; #define DW_RESERVE sizeof(struct reserve_size_s) static const struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = { /* 0 none */ { 1,MULTIPLY_NO, 0, 0}, /* 0x1 x1 DW_DLA_STRING */ { 1,MULTIPLY_CT, 0, 0}, /* 0x2 DW_DLA_LOC */ { sizeof(Dwarf_Loc),MULTIPLY_NO, 0, 0} , /* x3 DW_DLA_LOCDESC */ { sizeof(Dwarf_Locdesc),MULTIPLY_NO, 0, 0}, /* 0x4 DW_DLA_ELLIST */ /* not used */ { 1,MULTIPLY_NO, 0, 0}, /* 0x5 DW_DLA_BOUNDS */ /* not used */ { 1,MULTIPLY_NO, 0, 0}, /* 0x6 DW_DLA_BLOCK */ { sizeof(Dwarf_Block),MULTIPLY_NO, 0, 0}, /* x7 DW_DLA_DEBUG */ /* the actual dwarf_debug structure */ { 1,MULTIPLY_NO, 0, 0} , /* x8 DW_DLA_DIE */ {sizeof(struct Dwarf_Die_s),MULTIPLY_NO, 0, 0}, /* x9 DW_DLA_LINE */ {sizeof(struct Dwarf_Line_s),MULTIPLY_NO, 0, 0}, /* 0xa 10 DW_DLA_ATTR */ {sizeof(struct Dwarf_Attribute_s),MULTIPLY_NO, 0, 0}, /* 0xb DW_DLA_TYPE *//* not used */ {1,MULTIPLY_NO, 0, 0}, /* 0xc DW_DLA_SUBSCR *//* not used */ {1,MULTIPLY_NO, 0, 0}, /* 0xd 13 DW_DLA_GLOBAL */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 0xe 14 DW_DLA_ERROR */ {sizeof(struct Dwarf_Error_s),MULTIPLY_NO, 0, _dwarf_error_destructor}, /* 0xf DW_DLA_LIST */ {sizeof(Dwarf_Ptr),MULTIPLY_CT, 0, 0}, /* 0x10 DW_DLA_LINEBUF */ /* not used */ {1,MULTIPLY_NO, 0, 0}, /* 0x11 17 DW_DLA_ARANGE */ {sizeof(struct Dwarf_Arange_s),MULTIPLY_NO, 0, 0}, /* 0x12 18 DW_DLA_ABBREV */ {sizeof(struct Dwarf_Abbrev_s),MULTIPLY_NO, 0, 0}, /* 0x13 19 DW_DLA_FRAME_OP */ {sizeof(Dwarf_Frame_Op),MULTIPLY_NO, 0, 0} , /* 0x14 20 DW_DLA_CIE */ {sizeof(struct Dwarf_Cie_s),MULTIPLY_NO, 0, 0}, /* 0x15 DW_DLA_FDE */ {sizeof(struct Dwarf_Fde_s),MULTIPLY_NO, 0, _dwarf_fde_destructor}, /* 0x16 DW_DLA_LOC_BLOCK */ {sizeof(Dwarf_Loc),MULTIPLY_CT, 0, 0}, /* 0x17 DW_DLA_FRAME_BLOCK */ {sizeof(Dwarf_Frame_Op),MULTIPLY_CT, 0, 0}, /* 0x18 DW_DLA_FUNC UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 0x19 DW_DLA_TYPENAME UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 0x1a DW_DLA_VAR UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 0x1b DW_DLA_WEAK UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 0x1c DW_DLA_ADDR */ {1,MULTIPLY_SP, 0, 0}, /* 0x1d DW_DLA_RANGES */ {sizeof(Dwarf_Ranges),MULTIPLY_CT, 0,0 }, /* The following DW_DLA data types are known only inside libdwarf. */ /* 0x1e DW_DLA_ABBREV_LIST */ { sizeof(struct Dwarf_Abbrev_List_s),MULTIPLY_NO, 0, 0}, /* 0x1f DW_DLA_CHAIN */ {sizeof(struct Dwarf_Chain_s),MULTIPLY_NO, 0, 0}, /* 0x20 DW_DLA_CU_CONTEXT */ {sizeof(struct Dwarf_CU_Context_s),MULTIPLY_NO, 0, 0}, /* 0x21 DW_DLA_FRAME */ {sizeof(struct Dwarf_Frame_s),MULTIPLY_NO, _dwarf_frame_constructor, _dwarf_frame_destructor}, /* 0x22 DW_DLA_GLOBAL_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x23 DW_DLA_FILE_ENTRY */ {sizeof(struct Dwarf_File_Entry_s),MULTIPLY_NO, 0, 0}, /* 0x24 DW_DLA_LINE_CONTEXT */ {sizeof(struct Dwarf_Line_Context_s),MULTIPLY_NO, _dwarf_line_context_constructor, _dwarf_line_context_destructor}, /* 0x25 DW_DLA_LOC_CHAIN */ {sizeof(struct Dwarf_Loc_Chain_s),MULTIPLY_NO, 0, 0}, /* 0x26 0x26 DW_DLA_HASH_TABLE */ {sizeof(struct Dwarf_Hash_Table_s),MULTIPLY_NO, 0, 0}, /* The following really use Global struct: used to be unique struct per type, but now merged (11/99). The opaque types are visible in the interface. The types for DW_DLA_FUNC, DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use the global types. */ /* 0x27 DW_DLA_FUNC_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x28 40 DW_DLA_TYPENAME_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x29 41 DW_DLA_VAR_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x2a 42 DW_DLA_WEAK_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x2b 43 DW_DLA_PUBTYPES_CONTEXT DWARF3 */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 0x2c 44 DW_DLA_HASH_TABLE_ENTRY */ {sizeof(struct Dwarf_Hash_Table_Entry_s),MULTIPLY_CT,0,0 }, /* 0x2d - 0x34 reserved */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x2e 46 reserved for future use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x2f 47 reserved for future use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x30 reserved for future internal use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x31 reserved for future internal use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x32 50 reserved for future internal use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x33 51 reserved for future internal use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x34 52 reserved for future internal use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 0x35 53 Used starting July 2020 DW_DLA_GNU_INDEX_HEAD */ {sizeof(struct Dwarf_Gnu_Index_Head_s),MULTIPLY_NO, 0, _dwarf_gnu_index_head_destructor}, /* 0x36 54 Used starting May 2020 DW_DLA_RNGLISTS_HEAD */ {sizeof(struct Dwarf_Rnglists_Head_s),MULTIPLY_NO, 0, _dwarf_rnglists_head_destructor}, /* now, we have types that are public. */ /* 0x37 55. New in June 2014. Gdb. */ {sizeof(struct Dwarf_Gdbindex_s),MULTIPLY_NO, 0, 0}, /* 0x38 56. New in July 2014. */ /* DWARF5 DebugFission dwp file sections .debug_cu_index and .debug_tu_index . */ {sizeof(struct Dwarf_Xu_Index_Header_s),MULTIPLY_NO, 0, 0}, /* These required by new features in DWARF5. Also usable for DWARF2,3,4. */ /* 0x39 57 DW_DLA_LOC_BLOCK_C DWARF5 */ {sizeof(struct Dwarf_Loc_Expr_Op_s),MULTIPLY_CT, 0, 0}, /* 0x3a 58 DW_DLA_LOCDESC_C */ {sizeof(struct Dwarf_Locdesc_c_s),MULTIPLY_CT, _dwarf_locdesc_c_constructor, 0}, /* 0x3b 59 DW_DLA_LOC_HEAD_C */ {sizeof(struct Dwarf_Loc_Head_c_s),MULTIPLY_NO, 0, _dwarf_loclists_head_destructor}, /* 0x3c 60 DW_DLA_MACRO_CONTEXT */ {sizeof(struct Dwarf_Macro_Context_s),MULTIPLY_NO, _dwarf_macro_constructor, _dwarf_macro_destructor}, /* 0x3d 61 DW_DLA_CHAIN_2 */ {sizeof(struct Dwarf_Chain_o),MULTIPLY_NO, 0, 0}, /* 0x3e 62 DW_DLA_DSC_HEAD */ {sizeof(struct Dwarf_Dsc_Head_s),MULTIPLY_NO, 0, _dwarf_dsc_destructor}, /* 0x3f 63 DW_DLA_DNAMES_HEAD */ {sizeof(struct Dwarf_Dnames_Head_s),MULTIPLY_NO, 0, _dwarf_debugnames_destructor}, /* 0x40 64 DW_DLA_STR_OFFSETS */ {sizeof(struct Dwarf_Str_Offsets_Table_s),MULTIPLY_NO, 0,0}, }; /* We are simply using the incoming pointer as the key-pointer. */ static DW_TSHASHTYPE simple_value_hashfunc(const void *keyp) { DW_TSHASHTYPE up = (DW_TSHASHTYPE)(uintptr_t)keyp; return up; } /* We did alloc something but not a fixed-length thing. Instead, it starts with some special data we noted. The incoming pointer is to the caller data, we destruct based on caller, but find the special extra data in a prefix area. */ static void tdestroy_free_node(void *nodep) { char * m = (char *)nodep; char * malloc_addr = m - DW_RESERVE; struct reserve_data_s * reserve = (struct reserve_data_s *)malloc_addr; unsigned type = reserve->rd_type; if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* Internal error, corrupted data. */ return; } if (!reserve->rd_dbg) { /* Unused (corrupted?) node in the tree. Should never happen. */ return; } if (!reserve->rd_type) { /* Unused (corrupted?) node in the tree. Should never happen. */ return; } if (alloc_instance_basics[type].specialdestructor) { alloc_instance_basics[type].specialdestructor(m); } free(malloc_addr); } /* The sort of hash table entries result in very simple helper functions. */ static int simple_compare_function(const void *l, const void *r) { DW_TSHASHTYPE lp = (DW_TSHASHTYPE)(uintptr_t)l; DW_TSHASHTYPE rp = (DW_TSHASHTYPE)(uintptr_t)r; if (lp < rp) { return -1; } if (lp > rp) { return 1; } return 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, DW_DLA_RANGES, 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. */ char * _dwarf_get_alloc(Dwarf_Debug dbg, Dwarf_Small alloc_type, Dwarf_Unsigned count) { char * alloc_mem = 0; Dwarf_Signed basesize = 0; Dwarf_Signed size = 0; unsigned int type = alloc_type; short action = 0; if (dbg == NULL) { #if DEBUG printf("libdwarfdetector ALLOC dbg null " "ret NULL type 0x%x size %lu line %d %s\n", (unsigned)alloc_type,(unsigned long)size, __LINE__,__FILE__); #endif return NULL; } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* internal error */ #if DEBUG printf("libdwarfdetector ALLOC type bad ret null " "ret NULL type 0x%x size %lu line %d %s\n", (unsigned)alloc_type,(unsigned long)size, __LINE__,__FILE__); #endif return NULL; } basesize = alloc_instance_basics[alloc_type].ia_struct_size; action = alloc_instance_basics[alloc_type].ia_multiply_count; if (action == MULTIPLY_NO) { /* Usually count is 1, but do not assume it. */ size = basesize; } else if (action == MULTIPLY_CT) { size = basesize * count; } else { /* MULTIPLY_SP */ /* DW_DLA_ADDR.. count * largest size */ size = count * (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); } size += DW_RESERVE; alloc_mem = malloc(size); if (!alloc_mem) { return NULL; } { char * ret_mem = alloc_mem + DW_RESERVE; void *key = ret_mem; struct reserve_data_s *r = (struct reserve_data_s*)alloc_mem; void *result = 0; memset(alloc_mem, 0, size); /* We are not actually using rd_dbg, we are using rd_type. */ r->rd_dbg = dbg; r->rd_type = alloc_type; r->rd_length = size; if (alloc_instance_basics[type].specialconstructor) { int res = alloc_instance_basics[type]. specialconstructor(dbg, ret_mem); if (res != DW_DLV_OK) { /* We leak what we allocated in _dwarf_find_memory when constructor fails. */ #if DEBUG printf("libdwarfdetector ALLOC constructor fails ret NULL " "type 0x%x size %lu line %d %s\n", (unsigned)alloc_type,(unsigned long)size,__LINE__,__FILE__); #endif return NULL; } } /* See global flag. If zero then caller chooses not to track allocations, so dwarf_finish() is unable to free anything the caller omitted to dealloc. Normally the global flag is non-zero */ #ifdef HAVE_GLOBAL_ALLOC_SUMS global_allocation_count++; global_allocation_total += size; #endif /* HAVE_GLOBAL_ALLOC_SUMS */ /* As of March 14, 2020 it's not necessary to test for alloc type, but instead only call tsearch if de_alloc_tree_on. */ if (global_de_alloc_tree_on) { #ifdef HAVE_GLOBAL_ALLOC_SUMS global_de_alloc_tree_total += size; global_de_alloc_tree_count++; #endif /* HAVE_GLOBAL_ALLOC_SUMS */ result = dwarf_tsearch((void *)key, &dbg->de_alloc_tree,simple_compare_function); if (!result) { /* Something badly wrong. Out of memory. pretend all is well. */ } } #if DEBUG printf("libdwarfdetector ALLOC ret 0x%lx type 0x%x " "size %lu line %d %s\n", (unsigned long)ret_mem,(unsigned)alloc_type, (unsigned long)size,__LINE__,__FILE__); #endif return (ret_mem); } } /* This was once a long list of tests using dss_data and dss_size to see if 'space' was inside a debug section. This tfind approach removes that maintenance headache. */ static int string_is_in_debug_section(Dwarf_Debug dbg,void * space) { /* See dwarf_line.c dwarf_srcfiles() for one way we can wind up with a DW_DLA_STRING string that may or may not be malloc-ed by _dwarf_get_alloc(). dwarf_formstring(), for example, returns strings which point into .debug_info or .debug_types but dwarf_dealloc is never supposed to be applied to strings dwarf_formstring() returns! Lots of calls returning strings have always been documented as requiring dwarf_dealloc(...DW_DLA_STRING) when the code just returns a pointer to a portion of a loaded section! It is too late to change the documentation. */ void *result = 0; result = dwarf_tfind((void *)space, &dbg->de_alloc_tree,simple_compare_function); if (!result) { /* Not in the tree, so not malloc-ed Nothing to delete. */ return TRUE; } /* We found the address in the tree, so it is NOT part of .debug_info or any other dwarf section, but is space malloc-d in _dwarf_get_alloc(). */ return FALSE; } /* These wrappers for dwarf_dealloc enable type-checking at call points. */ void dwarf_dealloc_error(Dwarf_Debug dbg, Dwarf_Error err) { dwarf_dealloc(dbg,err,DW_DLA_ERROR); } void dwarf_dealloc_die( Dwarf_Die die) { Dwarf_Debug dbg = 0; Dwarf_CU_Context context = 0; if (!die) { #ifdef DEBUG printf("DEALLOC die does nothing, die NULL line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif return; } context = die->di_cu_context; if (!context) { #ifdef DEBUG printf("DEALLOC die does nothing, context NULL line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif return; } dbg = context->cc_dbg; dwarf_dealloc(dbg,die,DW_DLA_DIE); } void dwarf_dealloc_attribute(Dwarf_Attribute attr) { Dwarf_Debug dbg = 0; if (!attr) { #ifdef DEBUG printf("DEALLOC does nothing, attr is NULL line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif return; } dbg = attr->ar_dbg; dwarf_dealloc(dbg,attr,DW_DLA_ATTR); } /* This function is used to deallocate a region of memory that was obtained by a call to _dwarf_get_alloc. Note that though dwarf_dealloc() is a public function, _dwarf_get_alloc() isn't. For lists, typically arrays of pointers, it is assumed that the space was allocated by a direct call to malloc, and so a straight free() is done. This is also the case for variable length blocks such as DW_DLA_FRAME_BLOCK and DW_DLA_LOC_BLOCK and DW_DLA_RANGES. For strings, the pointer might point to a string in .debug_info or .debug_string. After this is checked, and if found not to be the case, a free() is done, again on the assumption that a malloc was used to obtain the space. This function does not return anything. The _dwarf_error_destructor() will be called to free the er_msg string (if this is a Dwarf_Error) just before the Dwarf_Error is freed here. See...specialdestructor() below. */ void dwarf_dealloc(Dwarf_Debug dbg, Dwarf_Ptr space, Dwarf_Unsigned alloc_type) { unsigned int type = 0; char * malloc_addr = 0; struct reserve_data_s * r = 0; if (!space) { #ifdef DEBUG printf("DEALLOC does nothing, space NULL line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ return; } if (!dbg) { /* App error, or an app that failed in a dwarf_init*() or dwarf_elf_init*() call. */ #ifdef DEBUG printf( "DEALLOC dbg NULL line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ } if (dbg && dbg->de_alloc_tree) { /* If it's a string in debug_info etc doing (char *)space - DW_RESERVE is totally bogus. */ if (alloc_type == DW_DLA_STRING && string_is_in_debug_section(dbg,space)) { /* A string pointer may point into .debug_info or .debug_string etc. So must not be freed. And strings have no need of a specialdestructor(). Mostly a historical mistake here. Corrected in libdwarf March 14,2020. */ #ifdef DEBUG printf( "DEALLOC string in section, no dealloc " "line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ return; } } /* Otherwise it might be allocated string so it is ok do the (char *)space - DW_RESERVE */ /* If it's a DW_DLA_STRING case and erroneous the following pointer operations might result in a coredump if the pointer is to the beginning of a string section. If not DW_DLA_STRING no correctly written caller could coredump here. */ malloc_addr = (char *)space - DW_RESERVE; r =(struct reserve_data_s *)malloc_addr; if (dbg && dbg != r->rd_dbg) { /* Mixed up or originally a no_dbg alloc */ #ifdef DEBUG printf("DEALLOC find was NULL dbg 0x%lx " "rd_dbg 0x%lx space 0x%lx line %d %s\n", (unsigned long)dbg, (unsigned long)r->rd_dbg, (unsigned long)space, __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ } if (dbg && alloc_type != r->rd_type) { /* Something is mixed up. */ #ifdef DEBUG printf("DEALLOC does nothing, type 0x%lx rd_type 0x%lx" " space 0x%lx line %d %s\n", (unsigned long)alloc_type, (unsigned long)r->rd_type, (unsigned long)space, __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ return; } if (alloc_type == DW_DLA_ERROR) { Dwarf_Error ep = (Dwarf_Error)space; if (ep->er_static_alloc == DE_STATIC) { /* This is special, malloc arena was exhausted or a NULL dbg was used for the error because the real dbg was unavailable. There is nothing to delete, really. Set er_errval to signal that the space was dealloc'd. */ _dwarf_failsafe_error.er_errval = DW_DLE_FAILSAFE_ERRVAL; _dwarf_error_destructor(ep); #ifdef DEBUG printf("DEALLOC does nothing, DE_STATIC line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ return; } if (ep->er_static_alloc == DE_MALLOC) { /* This is special, we had no arena but have a full special area as normal. */ #ifdef DEBUG printf("DEALLOC does free, DE_MALLOC line %d %s\n", __LINE__,__FILE__); fflush(stdout); #endif /* DEBUG*/ #if 0 _dwarf_error_destructor(ep); free(space); return; #endif } /* Was normal alloc, use normal dealloc. */ /* DW_DLA_ERROR has a specialdestructor */ } type = alloc_type; #if DEBUG if (dbg != r->rd_dbg) { printf("DEALLOC dbg != rd_dbg" " going ahead line %d %s\n", __LINE__,__FILE__); fflush(stdout); } #endif #if DEBUG printf("libdwarfdetector DEALLOC ret 0x%lx type 0x%x " "size %lu line %d %s\n", (unsigned long)space,(unsigned)type, (unsigned long)r->rd_length,__LINE__,__FILE__); #endif if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* internal or user app error */ #ifdef DEBUG printf("DEALLOC does nothing, type too big %lu line %d %s\n", (unsigned long)type, __LINE__,__FILE__); #endif /* DEBUG*/ return; } #ifdef HAVE_GLOBAL_ALLOC_SUMS global_de_alloc_tree_early_dealloc_count++; global_de_alloc_tree_early_dealloc_size += r->rd_length; #endif /* HAVE_GLOBAL_ALLOC_SUMS */ if (alloc_instance_basics[type].specialdestructor) { alloc_instance_basics[type].specialdestructor(space); } if (dbg && dbg->de_alloc_tree) { /* The 'space' pointer we get points after the reserve space. The key is 'space' and address to free is just a few bytes before 'space'. */ void *key = space; dwarf_tdelete(key,&dbg->de_alloc_tree, simple_compare_function); /* If dwarf_tdelete returns NULL it might mean a) tree is empty. b) If hashsearch, then a single chain might now be empty, so we do not know of a 'parent node'. c) We did not find that key, we did nothing. In any case, we simply don't worry about it. Not Supposed To Happen. */ } r->rd_dbg = (void *)0xfeadbeef; r->rd_length = 0; r->rd_type = 0; free(malloc_addr); return; } /* Allocates space for a Dwarf_Debug_s struct, since one does not exist. */ Dwarf_Debug _dwarf_get_debug(void) { Dwarf_Debug dbg; dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); if (dbg == NULL) { return (NULL); } memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); /* Set up for a dwarf_tsearch hash table */ /* Leaving initialization on so we can track DW_DLA_STRING even when global_de_alloc_tree_on is zero. */ if (global_de_alloc_tree_on) { dwarf_initialize_search_hash(&dbg->de_alloc_tree, simple_value_hashfunc,0); } return (dbg); } /* This function prints out the statistics collected on allocation of memory chunks. No longer used. */ void dwarf_print_memory_stats(UNUSEDARG Dwarf_Debug dbg) { } /* In the 'rela' relocation case or in case of compressed sections we might have malloc'd space (to ensure it is read-write or to decompress it respectively, or both). In that case, free the space. */ static void malloc_section_free(struct Dwarf_Section_s * sec) { if (sec->dss_data_was_malloc) { free(sec->dss_data); } sec->dss_data = 0; sec->dss_data_was_malloc = 0; } static void freecontextlist(Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis) { Dwarf_CU_Context context = 0; Dwarf_CU_Context nextcontext = 0; for (context = dis->de_cu_context_list; context; context = nextcontext) { Dwarf_Hash_Table hash_table = 0; hash_table = context->cc_abbrev_hash_table; _dwarf_free_abbrev_hash_table_contents(dbg,hash_table); hash_table->tb_entries = 0; nextcontext = context->cc_next; context->cc_next = 0; /* See also local_dealloc_cu_context() in dwarf_die_deliv.c */ dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE); context->cc_abbrev_hash_table = 0; dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); } dis->de_cu_context_list = 0; } /* Used to free all space allocated for this Dwarf_Debug. The caller should assume that the Dwarf_Debug pointer itself is no longer valid upon return from this function. NEVER returns DW_DLV_ERROR. In case of difficulty, this function simply returns quietly. */ int _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) { unsigned g = 0; if (dbg == NULL) { return DW_DLV_NO_ENTRY; } /* To do complete validation that we have no surprising missing or erroneous deallocs it is advisable to do the dwarf_deallocs here that are not things the user can otherwise request. Housecleaning. */ if (dbg->de_cu_hashindex_data) { dwarf_xu_header_free(dbg->de_cu_hashindex_data); dbg->de_cu_hashindex_data = 0; } if (dbg->de_tu_hashindex_data) { dwarf_xu_header_free(dbg->de_tu_hashindex_data); dbg->de_tu_hashindex_data = 0; } if (dbg->de_printf_callback_null_device_handle) { fclose(dbg->de_printf_callback_null_device_handle); dbg->de_printf_callback_null_device_handle = 0; } freecontextlist(dbg,&dbg->de_info_reading); freecontextlist(dbg,&dbg->de_types_reading); /* Housecleaning done. Now really free all the space. */ malloc_section_free(&dbg->de_debug_info); malloc_section_free(&dbg->de_debug_types); malloc_section_free(&dbg->de_debug_abbrev); malloc_section_free(&dbg->de_debug_line); malloc_section_free(&dbg->de_debug_line_str); malloc_section_free(&dbg->de_debug_loc); malloc_section_free(&dbg->de_debug_aranges); malloc_section_free(&dbg->de_debug_macinfo); malloc_section_free(&dbg->de_debug_macro); malloc_section_free(&dbg->de_debug_names); malloc_section_free(&dbg->de_debug_pubnames); malloc_section_free(&dbg->de_debug_str); malloc_section_free(&dbg->de_debug_sup); malloc_section_free(&dbg->de_debug_frame); malloc_section_free(&dbg->de_debug_frame_eh_gnu); malloc_section_free(&dbg->de_debug_pubtypes); malloc_section_free(&dbg->de_debug_funcnames); malloc_section_free(&dbg->de_debug_typenames); malloc_section_free(&dbg->de_debug_varnames); malloc_section_free(&dbg->de_debug_weaknames); malloc_section_free(&dbg->de_debug_ranges); malloc_section_free(&dbg->de_debug_str_offsets); malloc_section_free(&dbg->de_debug_addr); malloc_section_free(&dbg->de_debug_gdbindex); malloc_section_free(&dbg->de_debug_cu_index); malloc_section_free(&dbg->de_debug_tu_index); malloc_section_free(&dbg->de_debug_loclists); malloc_section_free(&dbg->de_debug_rnglists); dwarf_harmless_cleanout(&dbg->de_harmless_errors); _dwarf_dealloc_rnglists_context(dbg); _dwarf_dealloc_loclists_context(dbg); if (dbg->de_printf_callback.dp_buffer && !dbg->de_printf_callback.dp_buffer_user_provided ) { free(dbg->de_printf_callback.dp_buffer); } _dwarf_destroy_group_map(dbg); /* de_alloc_tree might be NULL if global_de_alloc_tree_on is zero. */ if (dbg->de_alloc_tree) { dwarf_tdestroy(dbg->de_alloc_tree,tdestroy_free_node); dbg->de_alloc_tree = 0; } /* first, walk the search and free() contents. */ /* Now do the search tree itself */ if (dbg->de_tied_data.td_tied_search) { dwarf_tdestroy(dbg->de_tied_data.td_tied_search, _dwarf_tied_destroy_free_node); dbg->de_tied_data.td_tied_search = 0; } free((void *)dbg->de_path); dbg->de_path = 0; for (g = 0; g < dbg->de_gnu_global_path_count; ++g) { free((char *)dbg->de_gnu_global_paths[g]); dbg->de_gnu_global_paths[g] = 0; } free((void*)dbg->de_gnu_global_paths); dbg->de_gnu_global_paths = 0; dbg->de_gnu_global_path_count = 0; memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */ free(dbg); return DW_DLV_OK; } /* A special case: we have no dbg, no alloc header etc. So create something out of thin air that we can recognize in dwarf_dealloc. Something with the prefix (prefix space hidden from caller). Only applies to DW_DLA_ERROR, and making up an error record. The allocated space simply leaks. */ struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void) { Dwarf_Error e = 0; Dwarf_Unsigned len = sizeof(struct Dwarf_Error_s) + DW_RESERVE; struct reserve_data_s *base = 0; char *mem = (char *)malloc(len); if (!mem) { return 0; } memset(mem, 0, len); base = (struct reserve_data_s *)mem; base->rd_dbg = 0; base->rd_length = sizeof(struct Dwarf_Error_s); base->rd_type = DW_DLA_ERROR; e = (Dwarf_Error)(mem+DW_RESERVE); e->er_static_alloc = DE_MALLOC; return e; } libdwarf-20210528/libdwarf/dwarf_object_detector.c0000664000175000017500000006361314004647570016774 00000000000000/* Copyright (c) 2018-2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* open() */ #endif /* HAVE_SYS_STAT_H */ #include /* O_RDONLY */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #include typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ #endif /* HAVE_UNISTD_H */ #ifdef HAVE_STRING_H #include /* memcpy, strcpy */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for free() */ #endif /*HAVE_STDLIB_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #include "dwarfstring.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #define TRUE 1 #define FALSE 0 #ifndef O_RDONLY #define O_RDONLY 0 #endif /* TYP, SIZEOFT32 and ASNAR mean we can use correctly-sized arrays of char for the struct members instead of determining a proper integer that size. We are dealing with carefully constructed structs that do not have any alignment-forced (hidden) unused bytes so reading lengths from the real structs works for each variable. */ #define TYP(n,l) char n[l] #define SIZEOFT32 4 #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 #ifndef EI_NIDENT #define EI_NIDENT 16 #define EI_CLASS 4 #define EI_DATA 5 #define EI_VERSION 6 #define ELFCLASS32 1 #define ELFCLASS64 2 #define ELFDATA2LSB 1 #define ELFDATA2MSB 2 #endif /* EI_NIDENT */ #define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/" #define PATHSIZE 2000 #ifndef MH_MAGIC /* mach-o 32bit */ #define MH_MAGIC 0xfeedface #define MH_CIGAM 0xcefaedfe #endif /* MH_MAGIC */ #ifndef MH_MAGIC_64 /* mach-o 64bit */ #define MH_MAGIC_64 0xfeedfacf #define MH_CIGAM_64 0xcffaedfe #endif /* MH_MAGIC_64 */ #if TESTING static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; if (!start) { printf("%s ptr null, ignore. \n",msg); return; } printf("%s 0x%lx ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif static unsigned long magic_copy(unsigned char *d, unsigned len) { unsigned i = 0; unsigned long v = 0; v = d[0]; for (i = 1 ; i < len; ++i) { v <<= 8; v |= d[i]; } return v; } #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #define EI_NIDENT 16 /* An incomplete elf header, good for 32 and 64bit elf */ struct elf_header { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); #ifdef HAVE_CUSTOM_LIBELF /* In the case of custom ELF, use extra space */ TYP(e_custom,64); #endif /* HAVE_CUSTOM_LIBELF */ }; /* Windows. Certain PE objects. The following references may be of interest. https://msdn.microsoft.com/library/windows/\ desktop/ms680547(v=vs.85).aspx #PE format overview and various machine magic numbers https://msdn.microsoft.com/en-us/library/\ ms809762.aspx # describes some details of PE headers, basically an overview https://msdn.microsoft.com/en-us/library/\ windows/desktop/aa383751(v=vs.85).aspx #defines sizes of various types https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680313(v=vs.85).aspx #defines IMAGE_FILE_HEADER and Machine fields (32/64) https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680305(v=vs.85).aspx #defines IMAGE_DATA_DIRECTORY https://msdn.microsoft.com/en-us/library/\ windows/desktop/ms680339(v=vs.85).aspx #Defines IMAGE_OPTIONAL_HEADER and some magic numbers https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680336(v=vs.85).aspx # defines _IMAGE_NT_HEADERS 32 64 https://msdn.microsoft.com/en-us/library/\ windows/desktop/ms680341(v=vs.85).aspx # defines _IMAGE_SECTION_HEADER */ /* ===== START pe structures */ struct dos_header { TYP(dh_mz,2); TYP(dh_dos_data,58); TYP(dh_image_offset,4); }; #define IMAGE_DOS_SIGNATURE_dw 0x5A4D #define IMAGE_DOS_REVSIGNATURE_dw 0x4D5A #define IMAGE_NT_SIGNATURE_dw 0x00004550 #define IMAGE_FILE_MACHINE_I386_dw 0x14c #define IMAGE_FILE_MACHINE_IA64_dw 0x200 #define IMAGE_FILE_MACHINE_AMD64_dw 0x8664 struct pe_image_file_header { TYP(im_machine,2); TYP(im_sectioncount,2); TYP(im_ignoring,(3*4)); TYP(im_opt_header_size,2); TYP(im_ignoringb,2); }; /* ===== END pe structures */ /* For following MacOS file naming convention */ static const char * getseparator (const char *f) { const char *p = 0; const char *q = 0; char c = 0;; p = NULL; q = f; do { c = *q++; if (c == '\\' || c == '/' || c == ':') { p = q; } } while (c); return p; } static const char * getbasename (const char *f) { const char *pseparator = getseparator (f); if (!pseparator) { return f; } return pseparator; } /* Not a standard function, though part of GNU libc since 2008 (I have never examined the GNU version). */ static char * dw_stpcpy(char *dest,const char *src) { const char *cp = src; char *dp = dest; for ( ; *cp; ++cp,++dp) { *dp = *cp; } *dp = 0; return dp; } /* This started like Elf, so check initial fields. */ static int fill_in_elf_fields(struct elf_header *h, unsigned *endian, /* Size of the object file offsets, not DWARF offset size. */ unsigned *objoffsetsize, int *errcode) { unsigned locendian = 0; unsigned locoffsetsize = 0; switch(h->e_ident[EI_CLASS]) { case ELFCLASS32: locoffsetsize = 32; break; case ELFCLASS64: locoffsetsize = 64; break; default: *errcode = DW_DLE_ELF_CLASS_BAD; return DW_DLV_ERROR; } switch(h->e_ident[EI_DATA]) { case ELFDATA2LSB: locendian = DW_ENDIAN_LITTLE; break; case ELFDATA2MSB: locendian = DW_ENDIAN_BIG; break; default: *errcode = DW_DLE_ELF_ENDIAN_BAD; return DW_DLV_ERROR; } if (h->e_ident[EI_VERSION] != 1 /* EV_CURRENT */) { *errcode = DW_DLE_ELF_VERSION_BAD; return DW_DLV_ERROR; } *endian = locendian; *objoffsetsize = locoffsetsize; return DW_DLV_OK; } static char archive_magic[8] = { '!','<','a','r','c','h','>',0x0a }; static int is_archive_magic(struct elf_header *h) { int i = 0; int len = sizeof(archive_magic); const char *cp = (const char *)h; for ( ; i < len; ++i) { if (cp[i] != archive_magic[i]) { return FALSE; } } return TRUE; } /* A bit unusual in that it always sets *is_pe_flag Return of DW_DLV_OK it is a PE file we recognize. */ static int is_pe_object(int fd, unsigned long filesize, unsigned *endian, unsigned *offsetsize, int *errcode) { unsigned dos_sig = 0; unsigned locendian = 0; void (*word_swap) (void *, const void *, unsigned long); unsigned long nt_address = 0; struct dos_header dhinmem; char nt_sig_array[4]; unsigned long nt_sig = 0; struct pe_image_file_header ifh; int res = 0; if (filesize < (sizeof (struct dos_header) + SIZEOFT32 + sizeof(struct pe_image_file_header))) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&dhinmem, 0,sizeof(dhinmem),filesize,errcode); if (res != DW_DLV_OK) { return res; } /* No swap here, want it as in the file */ dos_sig = magic_copy((unsigned char *)dhinmem.dh_mz, sizeof(dhinmem.dh_mz)); if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian load, so we intrepet a match the other way. */ /* BIG ENDIAN. From looking at hex characters in object */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_noswap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_swap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_ENDIAN_BIG; } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { /* raw load, so intrepet a match the other way. */ /* LITTLE ENDIAN */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_swap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_noswap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_ENDIAN_LITTLE; } else { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } ASNAR(word_swap,nt_address, dhinmem.dh_image_offset); if (filesize < nt_address) { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } if (filesize < (nt_address + SIZEOFT32 + sizeof(struct pe_image_file_header))) { *errcode = DW_DLE_FILE_TOO_SMALL; /* Not dos header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&nt_sig_array[0], nt_address, sizeof(nt_sig_array),filesize,errcode); if (res != DW_DLV_OK) { return res; } { unsigned long lsig = 0; ASNAR(word_swap,lsig,nt_sig_array); nt_sig = lsig; } if (nt_sig != IMAGE_NT_SIGNATURE_dw) { *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&ifh, nt_address + SIZEOFT32, sizeof(struct pe_image_file_header), filesize, errcode); if (res != DW_DLV_OK) { return res; } { unsigned long machine = 0; ASNAR(word_swap,machine,ifh.im_machine); switch(machine) { case IMAGE_FILE_MACHINE_I386_dw: *offsetsize = 32; *endian = locendian; return DW_DLV_OK; case IMAGE_FILE_MACHINE_IA64_dw: case IMAGE_FILE_MACHINE_AMD64_dw: *offsetsize = 64; *endian = locendian; return DW_DLV_OK; } } *errcode = DW_DLE_IMAGE_FILE_UNKNOWN_TYPE; return DW_DLV_ERROR; } static int is_mach_o_magic(struct elf_header *h, unsigned *endian, unsigned *offsetsize) { unsigned long magicval = 0; unsigned locendian = 0; unsigned locoffsetsize = 0; /* No swapping here. Need to match size of Mach-o magic field. */ magicval = magic_copy(h->e_ident,4); if (magicval == MH_MAGIC) { locendian = DW_ENDIAN_BIG; locoffsetsize = 32; } else if (magicval == MH_CIGAM) { locendian = DW_ENDIAN_LITTLE; locoffsetsize = 32; }else if (magicval == MH_MAGIC_64) { locendian = DW_ENDIAN_BIG; locoffsetsize = 64; } else if (magicval == MH_CIGAM_64) { locendian = DW_ENDIAN_LITTLE; locoffsetsize = 64; } else { return FALSE; } *endian = locendian; *offsetsize = locoffsetsize; return TRUE; } int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int *errcode) { struct elf_header h; size_t readlen = sizeof(h); int res = 0; off_t fsize = 0; off_t lsval = 0; ssize_t readval = 0; fsize = lseek(fd,0L,SEEK_END); if (fsize < 0) { *errcode = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } if (fsize <= (off_t)readlen) { /* Not a real object file */ *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } lsval = lseek(fd,0L,SEEK_SET); if (lsval < 0) { *errcode = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } readval = read(fd,&h,readlen); if (readval != (ssize_t)readlen) { *errcode = DW_DLE_READ_ERROR; return DW_DLV_ERROR; } if (h.e_ident[0] == 0x7f && h.e_ident[1] == 'E' && h.e_ident[2] == 'L' && h.e_ident[3] == 'F') { /* is ELF */ res = fill_in_elf_fields(&h,endian,offsetsize,errcode); if (res != DW_DLV_OK) { return res; } *ftype = DW_FTYPE_ELF; *filesize = (size_t)fsize; return DW_DLV_OK; } if (is_mach_o_magic(&h,endian,offsetsize)) { *ftype = DW_FTYPE_MACH_O; *filesize = (size_t)fsize; return DW_DLV_OK; } if (is_archive_magic(&h)) { *ftype = DW_FTYPE_ARCHIVE; *filesize = (size_t)fsize; return DW_DLV_OK; } res = is_pe_object(fd,fsize,endian,offsetsize,errcode); if (res == DW_DLV_OK ) { *ftype = DW_FTYPE_PE; *filesize = (size_t)fsize; return DW_DLV_OK; } /* Check for custom ELF format. */ #ifdef HAVE_CUSTOM_LIBELF res = elf_is_custom_format(&h,readlen,&fsize, endian,offsetsize,errcode); if (res == DW_DLV_OK) { *ftype = DW_FTYPE_CUSTOM_ELF; *filesize = (size_t)fsize; return res; } #endif /* HAVE_CUSTOM_LIBELF */ /* Unknown object format. */ return DW_DLV_NO_ENTRY; } int dwarf_object_detector_path_dSYM( const char *path, char *outpath, unsigned long outpath_len, UNUSEDARG char ** gl_pathnames, UNUSEDARG unsigned gl_pathcount, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, unsigned char *pathsource, int *errcode) { char *cp = 0; size_t plen = strlen(path); size_t dsprefixlen = sizeof(DSYM_SUFFIX); int fd = -1; int res = 0; int have_outpath = outpath && outpath_len; if (have_outpath) { /* Looking for MacOS dSYM */ if ((2*plen + dsprefixlen +2) >= outpath_len) { *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; return DW_DLV_ERROR; } cp = dw_stpcpy(outpath,path); cp = dw_stpcpy(cp,DSYM_SUFFIX); dw_stpcpy(cp,getbasename(path)); fd = open(outpath,O_RDONLY|O_BINARY); if (fd < 0) { outpath[0] = 0; return DW_DLV_NO_ENTRY; } *pathsource = DW_PATHSOURCE_dsym; res = dwarf_object_detector_fd(fd, ftype,endian,offsetsize,filesize,errcode); if (res != DW_DLV_OK) { return res; } close(fd); return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int blockmatch(unsigned char *l, unsigned char* r, unsigned length) { unsigned int i = 0; for ( ; i < length; ++i) { if (l[i] != r[i]) { return FALSE; } } return TRUE; } /* The debug version we expect not to have debuglink, checking here if buildid matches. Never returns DW_DLV_ERROR. */ static int match_buildid( unsigned char *crc_base, unsigned buildid_length_base, unsigned char * buildid_base, /* *_base is executable info while *_debug is the debug object. */ unsigned char * crc_debug, unsigned buildid_length_debug, unsigned char *buildid_debug) { if (crc_debug && crc_base) { /* crc available for both */ if (!blockmatch(crc_debug,crc_base,4)) { return DW_DLV_NO_ENTRY; } } if (buildid_length_base != buildid_length_debug) { return DW_DLV_NO_ENTRY; } if (!blockmatch(buildid_base,buildid_debug, buildid_length_base)) { return DW_DLV_NO_ENTRY; } return DW_DLV_OK; } static int _dwarf_debuglink_finder_newpath( char * path_in, unsigned char *crc_in, unsigned buildid_len_in, unsigned char *buildid_in, dwarfstring *m, int * fd_out, int * errcode) { unsigned char lcrc[4]; char *debuglinkpath = 0; /* must be freed */ unsigned char *crc = 0; char *debuglinkfullpath = 0; unsigned debuglinkfullpath_strlen = 0; unsigned buildid_type = 0; char * buildidownername = 0; unsigned char *buildid = 0; unsigned buildid_length = 0; char ** paths = 0; /* must be freed */ unsigned paths_count = 0; Dwarf_Debug dbg = 0; Dwarf_Error error = 0; char *path = path_in; int res = 0; res = dwarf_init_path(path, 0,0, DW_DLC_READ, DW_GROUPNUMBER_ANY, 0,0, &dbg, 0,0,0,&error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,error); error = 0; return DW_DLV_NO_ENTRY; } if (res == DW_DLV_NO_ENTRY) { /* should never happen */ return DW_DLV_NO_ENTRY; } res = dwarf_gnu_debuglink(dbg, &debuglinkpath, &crc, &debuglinkfullpath, &debuglinkfullpath_strlen, &buildid_type, &buildidownername, &buildid, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { *errcode = dwarf_errno(error); dwarf_dealloc_error(dbg,error); dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } else if (res == DW_DLV_NO_ENTRY) { /* There is no debuglink section */ dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } free(paths); paths = 0; memset(&lcrc[0],0,sizeof(lcrc)); if (crc_in && !crc) { res = dwarf_crc32(dbg,lcrc,&error); if (res == DW_DLV_ERROR) { paths = 0; free(debuglinkfullpath); dwarf_dealloc_error(dbg,error); dwarf_finish(dbg,&error); /* Cannot match the crc_in, give up. */ return DW_DLV_NO_ENTRY; } else if (res == DW_DLV_OK) { crc = &lcrc[0]; } } free(debuglinkfullpath); res = match_buildid( /* This is the executable */ crc_in,buildid_len_in,buildid_in, /* pass in local so we can calculate the missing crc */ /* following is the target, ie, debug */ crc,buildid_length,buildid); if (res == DW_DLV_OK) { dwarfstring_append(m,path); *fd_out = dbg->de_fd; dbg->de_owns_fd = FALSE; dwarf_finish(dbg,&error); return DW_DLV_OK; } dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } static int _dwarf_debuglink_finder_internal( char **gl_pathnames, unsigned int gl_pathcount, char * path_in, dwarfstring *m, int * fd_out, int * errcode) { int res = 0; /* This local dbg is opened and then dwarf_finish() here. No dbg in the arguments! */ Dwarf_Debug dbg = 0; char * path = 0; Dwarf_Error error = 0; unsigned int p = 0; char *debuglinkpath = 0; unsigned char *crc = 0; char *debuglinkfullpath = 0; /* must be freed*/ unsigned debuglinkfullpath_strlen = 0; unsigned buildid_type = 0; char * buildidownername = 0; unsigned char *buildid = 0; unsigned buildid_length = 0; char ** paths = 0; /* must be freed */ unsigned paths_count = 0; Dwarf_Unsigned laccess = 0; unsigned int i = 0; path = path_in; /* This path will work. Already know the file is there. */ res = dwarf_init_path(path, 0,0, laccess, DW_GROUPNUMBER_ANY, 0,0, &dbg, 0,0,0,&error); if (res == DW_DLV_ERROR) { *errcode = dwarf_errno(error); dwarf_dealloc_error(dbg,error); error = 0; return res; } if (res == DW_DLV_NO_ENTRY) { return res; } for (p = 0; p < gl_pathcount; ++p) { const char *lpath = 0; lpath = (const char *)gl_pathnames[p]; res = dwarf_add_debuglink_global_path(dbg, lpath, &error); if (res != DW_DLV_OK){ *errcode = dwarf_errno(error); dwarf_dealloc_error(dbg,error); dwarf_finish(dbg,&error); return res; } } res = dwarf_gnu_debuglink(dbg, &debuglinkpath, &crc, &debuglinkfullpath, &debuglinkfullpath_strlen, &buildid_type, &buildidownername, &buildid, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { *errcode = dwarf_errno(error); dwarf_dealloc_error(dbg,error); dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } else if (res == DW_DLV_NO_ENTRY) { /* There is no debuglink section */ dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } for (i =0; i < paths_count; ++i) { char *pa = paths[i]; int pfd = 0; /* First, open the file to determine if it exists. If not, loop again */ pfd = open(pa,O_RDONLY|O_BINARY); if (pfd < 0) { /* This is the usual path. */ continue; } close(pfd); res = _dwarf_debuglink_finder_newpath( pa,crc,buildid_length, buildid, m,fd_out,errcode); if (res == DW_DLV_OK) { free(debuglinkfullpath); free(paths); paths = 0; dwarf_finish(dbg,&error); return DW_DLV_OK; } *errcode = 0; continue; } free(debuglinkfullpath); free(paths); paths = 0; dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } int dwarf_object_detector_path(const char *path, char *outpath, unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int *errcode) { unsigned char pathsource = DW_PATHSOURCE_basic; return dwarf_object_detector_path_b(path, outpath,outpath_len, 0,0, ftype,endian,offsetsize,filesize,&pathsource,errcode); } int dwarf_object_detector_path_b( const char *path, char *outpath, unsigned long outpath_len, char ** gl_pathnames, unsigned gl_pathcount, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, unsigned char *pathsource, int *errcode) { int fd = -1; int res = 0; int have_outpath = outpath && outpath_len; unsigned char lpathsource = DW_PATHSOURCE_basic; if (pathsource) { lpathsource = *pathsource; } if (lpathsource == DW_PATHSOURCE_basic && have_outpath) { /* On return from the following call we could well close the fd above and open a new one. */ int debuglink_fd = -1; unsigned long dllen = 0; dwarfstring m; dwarfstring_constructor(&m); res = _dwarf_debuglink_finder_internal( gl_pathnames,gl_pathcount, (char *)path, &m,&debuglink_fd, errcode); if (res == DW_DLV_ERROR) { dwarfstring_destructor(&m); if (debuglink_fd != -1) { close(debuglink_fd); } return res; } if (res == DW_DLV_NO_ENTRY) { /* We did not find an alternative path */ strcpy(outpath,path); lpathsource = DW_PATHSOURCE_basic; } else { if (debuglink_fd != -1) { close(debuglink_fd); } dllen = dwarfstring_strlen(&m)+1; if (dllen >= outpath_len) { close(debuglink_fd); *errcode = DW_DLE_DEBUGLINK_PATH_SHORT; return DW_DLV_ERROR; } strcpy(outpath,dwarfstring_string(&m)); lpathsource = DW_PATHSOURCE_debuglink; } dwarfstring_destructor(&m); fd = open(outpath,O_RDONLY|O_BINARY); /* fall through to get fsize etc */ } else { lpathsource = DW_PATHSOURCE_basic; fd = open(path,O_RDONLY|O_BINARY); } if (fd < 0) { lpathsource = DW_PATHSOURCE_unspecified; if (pathsource) { *pathsource = lpathsource; } return DW_DLV_NO_ENTRY; } res = dwarf_object_detector_fd(fd, ftype,endian,offsetsize,filesize,errcode); if (res != DW_DLV_OK) { lpathsource = DW_PATHSOURCE_unspecified; } if (pathsource) { *pathsource = lpathsource; } close(fd); return res; } libdwarf-20210528/libdwarf/dwarf_rnglists.c0000664000175000017500000012042613764007262015476 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_rnglists.h" #define SIZEOFT8 1 #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 #define TRUE 1 #define FALSE 0 #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ /* Used in case of error reading the rnglists headers (not referring to Dwarf_Rnglists_Head here), to clean up. */ static void free_rnglists_chain(Dwarf_Debug dbg, Dwarf_Chain head) { Dwarf_Chain cur = head; Dwarf_Chain next = 0; if (!head) { return; } for ( ;cur; cur = next) { next = cur->ch_next; if (cur->ch_item) { free(cur->ch_item); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); } } } static int read_single_rle_entry(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Unsigned dataoffset, Dwarf_Small *enddata, unsigned address_size, unsigned *bytes_count_out, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Error* err) { Dwarf_Unsigned count = 0; unsigned leblen = 0; unsigned code = 0; Dwarf_Unsigned val1 = 0; Dwarf_Unsigned val2 = 0; code = *data; ++data; ++count; switch(code) { case DW_RLE_end_of_list: break; case DW_RLE_base_addressx:{ DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen, dbg,err,enddata); count += leblen; } break; case DW_RLE_startx_endx: case DW_RLE_startx_length: case DW_RLE_offset_pair: { DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen, dbg,err,enddata); count += leblen; DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen, dbg,err,enddata); count += leblen; } break; case DW_RLE_base_address: { READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; } break; case DW_RLE_start_end: { READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; READ_UNALIGNED_CK(dbg,val2, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; } break; case DW_RLE_start_length: { READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen, dbg,err,enddata); count += leblen; } break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: " "The rangelists entry at .debug_rnglists" " offset 0x%x" ,dataoffset); dwarfstring_append_printf_u(&m, " has code 0x%x which is unknown",code); _dwarf_error_string(dbg,err,DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } break; } *bytes_count_out = count; *entry_kind = code; *entry_operand1 = val1; *entry_operand2 = val2; return DW_DLV_OK; } /* Reads the header. Determines the various offsets, including offset of the next header. Does no memory allocations here. */ int _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, Dwarf_Small *end_data, Dwarf_Unsigned offset, Dwarf_Rnglists_Context buildhere, Dwarf_Unsigned *next_offset, Dwarf_Error *error) { Dwarf_Small *startdata = data; Dwarf_Unsigned arealen = 0; int offset_size = 0; int exten_size = 0; Dwarf_Unsigned version = 0; unsigned address_size = 0; unsigned segment_selector_size= 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned localoff = 0; Dwarf_Unsigned lists_len = 0; READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, data,offset_size,exten_size, error, sectionlength,end_data); if (arealen > sectionlength) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_SECTION_SIZE_ERROR: A .debug_rnglists " "area size of 0x%x ",arealen); dwarfstring_append_printf_u(&m, "at offset 0x%x ",offset); dwarfstring_append_printf_u(&m, "is larger than the entire section size of " "0x%x. Corrupt DWARF.",sectionlength); _dwarf_error_string(dbg,error,DW_DLE_SECTION_SIZE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->rc_length = arealen +offset_size+exten_size; buildhere->rc_dbg = dbg; buildhere->rc_index = contextnum; buildhere->rc_header_offset = offset; buildhere->rc_offset_size = offset_size; buildhere->rc_extension_size = exten_size; READ_UNALIGNED_CK(dbg,version,Dwarf_Unsigned,data, SIZEOFT16,error,end_data); if (version != DW_CU_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 " "but we find %u instead.",version); _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->rc_version = version; data += SIZEOFT16; READ_UNALIGNED_CK(dbg,address_size,unsigned,data, SIZEOFT8,error,end_data); if (version != DW_CU_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 " "but we find %u instead.",version); _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (address_size != 4 && address_size != 8 && address_size != 2) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, " DW_DLE_ADDRESS_SIZE_ERROR: The address size " "of %u is not supported.",address_size); _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->rc_address_size = address_size; data++; READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data, SIZEOFT8,error,end_data); buildhere->rc_segment_selector_size = segment_selector_size; data++; READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data, SIZEOFT32,error,end_data); buildhere->rc_offset_entry_count = offset_entry_count; data += SIZEOFT32; if (offset_entry_count ){ buildhere->rc_offsets_array = data; } localoff = data - startdata; lists_len = offset_size *offset_entry_count; data += lists_len; buildhere->rc_offsets_off_in_sect = offset+localoff; buildhere->rc_first_rnglist_offset = offset+localoff+ lists_len; buildhere->rc_rnglists_header = startdata; buildhere->rc_endaddr = startdata +buildhere->rc_length; buildhere->rc_past_last_rnglist_offset = buildhere->rc_header_offset +buildhere->rc_length; *next_offset = buildhere->rc_past_last_rnglist_offset; return DW_DLV_OK; } /* We return a pointer to an array of contexts (not context pointers through *cxt if we succeed and are returning DW_DLV_OK. We never return DW_DLV_NO_ENTRY here. */ static int internal_load_rnglists_contexts(Dwarf_Debug dbg, Dwarf_Rnglists_Context **cxt, Dwarf_Unsigned *count, Dwarf_Error *error) { Dwarf_Unsigned offset = 0; Dwarf_Unsigned nextoffset = 0; Dwarf_Small * data = dbg->de_debug_rnglists.dss_data; Dwarf_Unsigned section_size = dbg->de_debug_rnglists.dss_size; Dwarf_Small * startdata = data; Dwarf_Small * end_data = data +section_size; Dwarf_Chain curr_chain = 0; Dwarf_Chain prev_chain = 0; Dwarf_Chain head_chain = 0; int res = 0; Dwarf_Unsigned chainlength = 0; Dwarf_Rnglists_Context *fullarray = 0; Dwarf_Unsigned i = 0; for ( ; data < end_data ; ) { Dwarf_Rnglists_Context newcontext = 0; /* sizeof the context struct, not sizeof a pointer */ newcontext = malloc(sizeof(*newcontext)); if (!newcontext) { free_rnglists_chain(dbg,head_chain); _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Allocation of " "Rnglists_Context failed"); return DW_DLV_ERROR; } memset(newcontext,0,sizeof(*newcontext)); res = _dwarf_internal_read_rnglists_header(dbg, chainlength, section_size, data,end_data,offset, newcontext,&nextoffset,error); if (res == DW_DLV_ERROR) { free(newcontext); free_rnglists_chain(dbg,head_chain); } curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { free_rnglists_chain(dbg,head_chain); _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: allocating Rnglists_Context" " chain entry"); return DW_DLV_ERROR; } curr_chain->ch_item = newcontext; ++chainlength; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } data = startdata+nextoffset; offset = nextoffset; } fullarray= (Dwarf_Rnglists_Context *)malloc( chainlength *sizeof(Dwarf_Rnglists_Context /*pointer*/)); if (!fullarray) { free_rnglists_chain(dbg,head_chain); _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL,"Allocation of " "Rnglists_Context pointer array failed"); return DW_DLV_ERROR; } curr_chain = head_chain; for (i = 0; i < chainlength; ++i) { fullarray[i] = (Dwarf_Rnglists_Context)curr_chain->ch_item; curr_chain->ch_item = 0; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } /* ASSERT: the chain is entirely dealloc'd and the array of pointers points to individually malloc'd Dwarf_Rnglists_Context_s */ *cxt = fullarray; *count = chainlength; return DW_DLV_OK; } /* Used by dwarfdump to print raw rnglists data. Loads all the .debug_rnglists[.dwo] headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and done exactly once. Harmless to do more than once. With DW_DLV_OK it returns the number of rnglists headers in the section through rnglists_count. */ int dwarf_load_rnglists( Dwarf_Debug dbg, Dwarf_Unsigned *rnglists_count, UNUSEDARG Dwarf_Error *error) { int res = DW_DLV_ERROR; Dwarf_Rnglists_Context *cxt = 0; Dwarf_Unsigned count = 0; if (dbg->de_rnglists_context) { if (rnglists_count) { *rnglists_count = dbg->de_rnglists_context_count; } } if (!dbg->de_debug_rnglists.dss_size) { /* nothing there. */ return DW_DLV_NO_ENTRY; } if (!dbg->de_debug_rnglists.dss_data) { res = _dwarf_load_section(dbg, &dbg->de_debug_rnglists, error); if (res != DW_DLV_OK) { return res; } } res = internal_load_rnglists_contexts(dbg,&cxt,&count,error); if (res == DW_DLV_ERROR) { return res; } dbg->de_rnglists_context = cxt; dbg->de_rnglists_context_count = count; if (rnglists_count) { *rnglists_count = count; } return DW_DLV_OK; } /* Frees the memory in use in all rnglists contexts. Done by dwarf_finish() */ void _dwarf_dealloc_rnglists_context(Dwarf_Debug dbg) { Dwarf_Unsigned i = 0; Dwarf_Rnglists_Context * rngcon = 0; if (!dbg->de_rnglists_context) { return; } rngcon = dbg->de_rnglists_context; for ( ; i < dbg->de_rnglists_context_count; ++i,++rngcon) { Dwarf_Rnglists_Context con = *rngcon; con->rc_offsets_array = 0; con->rc_offset_entry_count = 0; free(con); } free(dbg->de_rnglists_context); dbg->de_rnglists_context = 0; dbg->de_rnglists_context_count = 0; } /* Used by dwarfdump to print raw rnglists data. */ int dwarf_get_rnglist_offset_index_value( Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned offsetentry_index, Dwarf_Unsigned * offset_value_out, Dwarf_Unsigned * global_offset_value_out, Dwarf_Error *error) { Dwarf_Rnglists_Context con = 0; unsigned offset_len = 0; Dwarf_Small *offsetptr = 0; Dwarf_Unsigned targetoffset = 0; if (!dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } if (context_index >= dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_rnglists_context[context_index]; if (offsetentry_index >= con->rc_offset_entry_count) { return DW_DLV_NO_ENTRY; } offset_len = con->rc_offset_size; offsetptr = con->rc_offsets_array + (offsetentry_index*offset_len); READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned, offsetptr, offset_len,error,con->rc_endaddr); if (offset_value_out) { *offset_value_out = targetoffset; } if (global_offset_value_out) { *global_offset_value_out = targetoffset + con->rc_offsets_off_in_sect; } return DW_DLV_OK; } /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_rnglists_index_get_rle_head() or dwarf_rnglists_offset_get_rle_head. */ int dwarf_get_rnglist_head_basics( Dwarf_Rnglists_Head head, Dwarf_Unsigned * rle_count, Dwarf_Unsigned * rle_version, Dwarf_Unsigned * rnglists_index_returned, Dwarf_Unsigned * bytes_total_in_rle, Dwarf_Half * offset_size, Dwarf_Half * address_size, Dwarf_Half * segment_selector_size, Dwarf_Unsigned * overall_offset_of_this_context, Dwarf_Unsigned * total_length_of_this_context, Dwarf_Unsigned * offset_table_offset, Dwarf_Unsigned * offset_table_entrycount, Dwarf_Bool * rnglists_base_present, Dwarf_Unsigned * rnglists_base, Dwarf_Bool * rnglists_base_address_present, Dwarf_Unsigned * rnglists_base_address, Dwarf_Bool * rnglists_debug_addr_base_present, Dwarf_Unsigned * rnglists_debug_addr_base, UNUSEDARG Dwarf_Error *error) { Dwarf_Rnglists_Context rngcontext = 0; *rle_count = head->rh_count; *rle_version = head->rh_version; *rnglists_index_returned = head->rh_index; *bytes_total_in_rle = head->rh_bytes_total; *offset_size = head->rh_offset_size; *address_size = head->rh_address_size; *segment_selector_size = head->rh_segment_selector_size; rngcontext = head->rh_localcontext; if (rngcontext) { *overall_offset_of_this_context = rngcontext->rc_header_offset; *total_length_of_this_context = rngcontext->rc_length; *offset_table_offset = rngcontext->rc_offsets_off_in_sect; *offset_table_entrycount = rngcontext->rc_offset_entry_count; } *rnglists_base_present = head->rh_at_rnglists_base_present; *rnglists_base= head->rh_at_rnglists_base; *rnglists_base_address_present = head->rh_cu_base_address_present; *rnglists_base_address= head->rh_cu_base_address; *rnglists_debug_addr_base_present = head->rh_cu_addr_base_present; *rnglists_debug_addr_base = head->rh_cu_addr_base; return DW_DLV_OK; } /* Used by dwarfdump to print raw rnglists data. Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_rnglists section may contain any number of Range List Table Headers with their details. */ int dwarf_get_rnglist_context_basics( Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned * header_offset, Dwarf_Small * offset_size, Dwarf_Small * extension_size, unsigned * version, /* 5 */ Dwarf_Small * address_size, Dwarf_Small * segment_selector_size, Dwarf_Unsigned * offset_entry_count, Dwarf_Unsigned * offset_of_offset_array, Dwarf_Unsigned * offset_of_first_rangeentry, Dwarf_Unsigned * offset_past_last_rangeentry, UNUSEDARG Dwarf_Error *error) { Dwarf_Rnglists_Context con = 0; if (!dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } if (context_index >= dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_rnglists_context[context_index]; if (header_offset) { *header_offset = con->rc_header_offset; } if (offset_size) { *offset_size = con->rc_offset_size; } if (offset_size) { *extension_size = con->rc_extension_size; } if (version) { *version = con->rc_version; } if (address_size) { *address_size = con->rc_address_size; } if (segment_selector_size) { *segment_selector_size = con->rc_segment_selector_size; } if (offset_entry_count) { *offset_entry_count = con->rc_offset_entry_count; } if (offset_of_offset_array) { *offset_of_offset_array = con->rc_offsets_off_in_sect; } if (offset_of_first_rangeentry) { *offset_of_first_rangeentry = con->rc_first_rnglist_offset; } if (offset_past_last_rangeentry) { *offset_past_last_rangeentry = con->rc_past_last_rnglist_offset; } return DW_DLV_OK; } /* Used by dwarfdump to print raw rnglists data. entry offset is offset_of_first_rangeentry. Stop when the returned *next_entry_offset is == offset_past_last_rangentry (from dwarf_get_rnglist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single rnglist header, meaning a a single Dwarf_Rnglists_Context. */ int dwarf_get_rnglist_rle( Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned entry_offset, Dwarf_Unsigned endoffset, unsigned *entrylen, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Error *err) { Dwarf_Rnglists_Context con = 0; Dwarf_Small *data = 0; Dwarf_Small *enddata = 0; int res = 0; unsigned address_size = 0; if (!dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } data = dbg->de_debug_rnglists.dss_data + entry_offset; enddata = dbg->de_debug_rnglists.dss_data + endoffset; if (contextnumber >= dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_rnglists_context[contextnumber]; address_size = con->rc_address_size; res = read_single_rle_entry(dbg, data,entry_offset,enddata, address_size,entrylen, entry_kind, entry_operand1, entry_operand2, err); return res; } static int _dwarf_which_rnglists_context(Dwarf_Debug dbg, Dwarf_CU_Context ctx, Dwarf_Unsigned rnglist_offset, Dwarf_Unsigned *index, Dwarf_Error *error) { Dwarf_Unsigned count; Dwarf_Rnglists_Context *array; Dwarf_Unsigned i = 0; array = dbg->de_rnglists_context; count = dbg->de_rnglists_context_count; /* Using the slow way, a simple linear search. */ if (!ctx->cc_rnglists_base_present) { /* We look at the location of each rnglist context to find one with the offset the DIE gave us. */ for ( i = 0 ; i < count; ++i) { Dwarf_Rnglists_Context rcx = array[i]; Dwarf_Unsigned rcxoff = rcx->rc_header_offset; Dwarf_Unsigned rcxend = rcxoff + rcx->rc_length; if (rnglist_offset < rcxoff){ continue; } if (rnglist_offset < rcxend ){ *index = i; return DW_DLV_OK; } } { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: rnglist ran off end " " finding target offset of" " 0x%" DW_PR_XZEROS DW_PR_DUx ,rnglist_offset); dwarfstring_append(&m, " Not found anywhere in .debug_rnglists " "data. Corrupted data?"); _dwarf_error_string(dbg,error, DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } else { /* We have a DW_AT_rnglists_base (cc_rangelists_base), let's use it. */ Dwarf_Unsigned lookfor = 0;; lookfor = ctx->cc_rnglists_base; for ( i = 0 ; i < count; ++i) { dwarfstring m; Dwarf_Rnglists_Context rcx = array[i]; if (rcx->rc_offsets_off_in_sect == lookfor){ *index = i; return DW_DLV_OK; } if (rcx->rc_offsets_off_in_sect < lookfor){ continue; } dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: rnglists base of " " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor); dwarfstring_append_printf_u(&m, " was not found though we are now at base " " 0x%" DW_PR_XZEROS DW_PR_DUx , rcx->rc_offsets_off_in_sect); _dwarf_error_string(dbg,error, DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: rnglist base of " " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor); dwarfstring_append(&m, " was not found anywhere in .debug_rnglists " "data. Corrupted data?"); _dwarf_error_string(dbg,error, DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } return DW_DLV_ERROR; } int dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h) { Dwarf_Debug dbg = h->rh_dbg; dwarf_dealloc(dbg,h,DW_DLA_RNGLISTS_HEAD); return DW_DLV_OK; } /* Caller will eventually free as appropriate. */ static int alloc_rle_and_append_to_list(Dwarf_Debug dbg, Dwarf_Rnglists_Head rctx, Dwarf_Rnglists_Entry *e_out, Dwarf_Error *error) { Dwarf_Rnglists_Entry e = 0; e = malloc(sizeof(struct Dwarf_Rnglists_Entry_s)); if (!e) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Out of memory in " "building list of rnglists entries on a DIE."); return DW_DLV_ERROR; } memset(e,0,sizeof(struct Dwarf_Rnglists_Entry_s)); if (rctx->rh_first) { rctx->rh_last->rle_next = e; rctx->rh_last = e; } else { rctx->rh_first = e; rctx->rh_last = e; } rctx->rh_count++; *e_out = e; return DW_DLV_OK; } /* Read the group of rangelists entries, and finally build an array of Dwarf_Rnglists_Entry records. Attach to rctx here. Since on error the caller will destruct the rctx and we ensure to attach allocations there the caller will destruct the allocations here in case we return DW_DLV_ERROR*/ static int build_array_of_rle(Dwarf_Debug dbg, Dwarf_Rnglists_Head rctx, Dwarf_Error *error) { int res = 0; Dwarf_Small * data = rctx->rh_rlepointer; Dwarf_Unsigned dataoffset = rctx->rh_rlearea_offset; Dwarf_Small *enddata = rctx->rh_end_data_area; unsigned address_size = rctx->rh_address_size; Dwarf_Unsigned bytescounttotal= 0; Dwarf_Unsigned latestbaseaddr = 0; Dwarf_Bool foundbaseaddr = FALSE; int done = FALSE; Dwarf_Bool no_debug_addr_available = FALSE; if (rctx->rh_cu_base_address_present) { /* The CU DIE had DW_AT_low_pc and it is a base address. */ latestbaseaddr = rctx->rh_cu_base_address; foundbaseaddr = TRUE; } for ( ; !done ; ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned val1 = 0; Dwarf_Unsigned val2 = 0; Dwarf_Addr addr1= 0; Dwarf_Addr addr2 = 0; Dwarf_Rnglists_Entry e = 0; res = read_single_rle_entry(dbg, data,dataoffset, enddata, address_size,&entrylen, &code,&val1, &val2,error); if (res != DW_DLV_OK) { return res; } res = alloc_rle_and_append_to_list(dbg,rctx,&e,error); if (res != DW_DLV_OK) { return res; } e->rle_code = code, e->rle_entrylen = entrylen; e->rle_raw1 = val1; e->rle_raw2 = val2; bytescounttotal += entrylen; data += entrylen; if (code == DW_RLE_end_of_list) { done = TRUE; break; } switch(code) { case DW_RLE_base_addressx: if (no_debug_addr_available) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,rctx->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked1 = 0; foundbaseaddr = FALSE; } else { foundbaseaddr = TRUE; e->rle_cooked1 = addr1; latestbaseaddr = addr1; } break; case DW_RLE_startx_endx: if (no_debug_addr_available) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,rctx->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked1 = 0; } else { e->rle_cooked1 = addr1; } if (no_debug_addr_available) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,rctx->rh_context,val2,&addr2, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked2 = 0; return res; } else { e->rle_cooked2 = addr2; } break; case DW_RLE_startx_length: if (no_debug_addr_available) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,rctx->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked2 = 0; e->rle_cooked1 = 0; return res; } else { e->rle_cooked1 = addr1; e->rle_cooked2 = val2+addr1; } break; case DW_RLE_offset_pair: if (foundbaseaddr) { e->rle_cooked1 = val1+latestbaseaddr; e->rle_cooked2 = val2+latestbaseaddr; } else { /* Well, something failed, could be missing debug_addr. */ e->rle_index_failed = TRUE; e->rle_cooked2 = 0; e->rle_cooked1 = 0; } break; case DW_RLE_base_address: foundbaseaddr = TRUE; latestbaseaddr = val1; e->rle_cooked1 = val1; break; case DW_RLE_start_end: e->rle_cooked1 = val1; e->rle_cooked2 = val2; break; case DW_RLE_start_length: e->rle_cooked1 = val1; e->rle_cooked2 = val2+val1; break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, " DW_DLE_RNGLISTS_ERROR: " " The .debug_rnglists " " rangelist code 0x%x is unknown, " " DWARF5 is corrupted.",code); _dwarf_error_string(dbg, error, DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } } if (rctx->rh_count > 0) { Dwarf_Rnglists_Entry* array = 0; Dwarf_Rnglists_Entry cur = 0; Dwarf_Unsigned i = 0; /* Creating an array of pointers. */ array = (Dwarf_Rnglists_Entry*)malloc( rctx->rh_count *sizeof(Dwarf_Rnglists_Entry)); if (!array) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Out of memory in " "turning list of rnglists entries on a DIE" "into a pointer array"); return DW_DLV_ERROR; } cur = rctx->rh_first; for ( ; i < rctx->rh_count; ++i) { array[i] = cur; cur = cur->rle_next; } rctx->rh_rnglists = array; rctx->rh_first = 0; rctx->rh_last = 0; } rctx->rh_bytes_total = bytescounttotal; return DW_DLV_OK; } /* Build a head with all the relevent Entries attached. */ int dwarf_rnglists_get_rle_head( Dwarf_Attribute attr, Dwarf_Half theform, Dwarf_Unsigned attr_val, Dwarf_Rnglists_Head *head_out, Dwarf_Unsigned *entries_count_out, Dwarf_Unsigned *global_offset_of_rle_set, Dwarf_Error *error) { int res = 0; Dwarf_Unsigned rnglists_contextnum = 0; Dwarf_Small *table_base = 0; Dwarf_Small *table_entry = 0; Dwarf_Small *enddata = 0; Dwarf_Rnglists_Context *array = 0; Dwarf_Rnglists_Context rctx = 0; Dwarf_Unsigned entrycount = 0; unsigned offsetsize = 0; Dwarf_Unsigned rle_global_offset = 0; Dwarf_Rnglists_Head lhead = 0; Dwarf_CU_Context ctx = 0; struct Dwarf_Rnglists_Head_s shead; Dwarf_Unsigned offset_in_rnglists = 0; Dwarf_Debug dbg = 0; Dwarf_Bool is_rnglistx = FALSE; memset(&shead,0,sizeof(shead)); ctx = attr->ar_cu_context; dbg = ctx->cc_dbg; array = dbg->de_rnglists_context; if (theform == DW_FORM_rnglistx) { is_rnglistx = TRUE; } /* ASSERT: the 3 pointers just set are non-null */ /* the context cc_rnglists_base gives the offset of the array. of offsets (if cc_rnglists_base_present) */ offset_in_rnglists = attr_val; if (is_rnglistx) { if (ctx->cc_rnglists_base_present) { offset_in_rnglists = ctx->cc_rnglists_base; } else { /* FIXME: check in tied file for a cc_rnglists_base */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: rnglists table index of" " %u" ,attr_val); dwarfstring_append(&m, " is unusable unless it is in a tied file." " Possibly libdwarf is incomplete.FIXME"); _dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } else { offset_in_rnglists = attr_val; } res = _dwarf_which_rnglists_context(dbg,ctx, offset_in_rnglists, &rnglists_contextnum,error); if (res != DW_DLV_OK) { return res; } rctx = array[rnglists_contextnum]; table_base = rctx->rc_offsets_array; entrycount = rctx->rc_offset_entry_count; offsetsize = rctx->rc_offset_size; enddata = rctx->rc_endaddr; if (is_rnglistx && attr_val >= entrycount) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_RNGLISTS_ERROR: rnglists table index of" " %u" ,attr_val); dwarfstring_append_printf_u(&m, " too large for table of %u " "entries.",entrycount); _dwarf_error_string(dbg,error, DW_DLE_RNGLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } shead.rh_context = ctx; shead.rh_localcontext = rctx; shead.rh_index = rnglists_contextnum; shead.rh_version = rctx->rc_version; shead.rh_offset_size = offsetsize; shead.rh_address_size = rctx->rc_address_size; shead.rh_segment_selector_size = rctx->rc_segment_selector_size; /* DW_AT_rnglists_base from CU */ shead.rh_at_rnglists_base_present = ctx->cc_rnglists_base_present; shead.rh_at_rnglists_base = ctx->cc_rnglists_base; /* DW_AT_low_pc, if present. From CU */ shead.rh_cu_base_address_present = ctx->cc_low_pc_present; shead.rh_cu_base_address = ctx->cc_low_pc; /* base address DW_AT_addr_base of our part of .debug_addr, from CU */ shead.rh_cu_addr_base = ctx->cc_addr_base; shead.rh_cu_addr_base_present = ctx->cc_addr_base_present; if (is_rnglistx) { Dwarf_Unsigned table_entryval = 0; table_entry = attr_val*offsetsize + table_base; /* No malloc here yet so no leak if the macro returns DW_DLV_ERROR */ READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned, table_entry,offsetsize,error,enddata); rle_global_offset = rctx->rc_offsets_off_in_sect + table_entryval; } else { rle_global_offset = attr_val; } shead.rh_rlepointer = rctx->rc_offsets_array + rctx->rc_offset_entry_count*offsetsize; shead.rh_end_data_area = enddata; shead.rh_rlearea_offset = rle_global_offset; shead.rh_rlepointer = rle_global_offset + dbg->de_debug_rnglists.dss_data; lhead = (Dwarf_Rnglists_Head) _dwarf_get_alloc(dbg,DW_DLA_RNGLISTS_HEAD,1); if (!lhead) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "Allocating a Dwarf_Rnglists_Head struct fails" " in libdwarf function " "dwarf_rnglists_index_get_rle_head()"); return DW_DLV_ERROR; } shead.rh_dbg = dbg; *lhead = shead; res = build_array_of_rle(dbg,lhead,error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg,lhead,DW_DLA_RNGLISTS_HEAD); return res; } if (global_offset_of_rle_set) { *global_offset_of_rle_set = rle_global_offset; } /* Caller needs the head pointer else there will be leaks. */ *head_out = lhead; if (entries_count_out) { *entries_count_out = lhead->rh_count; } return DW_DLV_OK; } /* This version is the only one that can be used properly. The first public version of this did NOT allow any null arguments, but the documentation in libdwarf2.1.mm showed null args. As of 18 Aug 2020 this ignores null pointer inputs for the various pointers-returning-values (rle_value_out etc). */ int dwarf_get_rnglists_entry_fields_a( Dwarf_Rnglists_Head head, Dwarf_Unsigned entrynum, unsigned *entrylen, unsigned *rle_value_out, Dwarf_Unsigned *raw1, Dwarf_Unsigned *raw2, Dwarf_Bool *debug_addr_unavailable, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, UNUSEDARG Dwarf_Error *err) { Dwarf_Rnglists_Entry e = 0; if (entrynum >= head->rh_count) { return DW_DLV_NO_ENTRY; } e = head->rh_rnglists[entrynum]; if (entrylen) { *entrylen = e->rle_entrylen; } if (rle_value_out) { *rle_value_out = e->rle_code; } if (raw1) { *raw1 = e->rle_raw1; } if (raw2) { *raw2 = e->rle_raw2; } if (debug_addr_unavailable) { *debug_addr_unavailable = e->rle_index_failed; } if (cooked1) { *cooked1 = e->rle_cooked1; } if (cooked2) { *cooked2 = e->rle_cooked2; } return DW_DLV_OK; } /* This is missing a crucial bit, debug_addr_unavailable = e->rle_index_failed, so the results cannot be reliably used. DO NOT USE */ int dwarf_get_rnglists_entry_fields( Dwarf_Rnglists_Head head, Dwarf_Unsigned entrynum, unsigned *entrylen, unsigned *code, Dwarf_Unsigned *raw1, Dwarf_Unsigned *raw2, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, UNUSEDARG Dwarf_Error *err) { Dwarf_Rnglists_Entry e = 0; if (entrynum >= head->rh_count) { return DW_DLV_NO_ENTRY; } e = head->rh_rnglists[entrynum]; *entrylen = e->rle_entrylen; *code = e->rle_code; *raw1 = e->rle_raw1; *raw2 = e->rle_raw2; *cooked1 = e->rle_cooked1; *cooked2 = e->rle_cooked2; return DW_DLV_OK; } /* Deals with both fully and partially build head */ static void _dwarf_free_rnglists_head(Dwarf_Rnglists_Head head) { if (head->rh_first) { /* partially built head. */ /* ASSERT: rh_rnglists is NULL */ Dwarf_Rnglists_Entry cur = head->rh_first; Dwarf_Rnglists_Entry next = 0; for ( ; cur ; cur = next) { next = cur->rle_next; free(cur); } head->rh_first = 0; head->rh_last = 0; head->rh_count = 0; } else { /* ASSERT: rh_first and rh_last are NULL */ /* fully built head. */ Dwarf_Unsigned i = 0; /* Deal with the array form. */ for ( ; i < head->rh_count; ++i) { free(head->rh_rnglists[i]); } free(head->rh_rnglists); head->rh_rnglists = 0; } } void _dwarf_rnglists_head_destructor(void *head) { Dwarf_Rnglists_Head h = head; _dwarf_free_rnglists_head(h); } libdwarf-20210528/libdwarf/dwarf_line.h0000664000175000017500000004436114053207571014565 00000000000000/* Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2015 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define DW_EXTENDED_OPCODE 0 /* This is used as the starting value for an algorithm to get the minimum difference between 2 values. UINT_MAX is used as our approximation to infinity. */ #define MAX_LINE_DIFF UINT_MAX /* This is for a sanity check on line table extended opcodes. It is entirely arbitrary, and 100 is surely too small if someone was inserting strings in the opcode. */ #define DW_LNE_LEN_MAX 100 /* This structure is used to build a list of all the files that are used in the current compilation unit. All of the fields execpt fi_next have meanings that are obvious from section 6.2.4 of the Libdwarf Doc. Because of DW_LNE_define_file we make this a list, not an array. */ struct Dwarf_File_Entry_s { struct Dwarf_File_Entry_s *fi_next; /* Points to string naming the file: DW_LNCT_path. */ Dwarf_Small *fi_file_name; /* Points to string naming the source, with \n endings and null terminated (UTF-8). Embedded source. */ Dwarf_Small *fi_llvm_source; /* Index into the list of directories of the directory in which this file exits. For DWARF5, values are 0 to N-1 For DWARF4 etc values are 1 to N so the test for overrun differs. */ Dwarf_Unsigned fi_dir_index; /* Time of last modification of the file. */ Dwarf_Unsigned fi_time_last_mod; /* Length in bytes of the file. */ Dwarf_Unsigned fi_file_length; Dwarf_Small * fi_gnu_subprogram_name; Dwarf_Unsigned fi_gnu_decl_file; Dwarf_Unsigned fi_gnu_decl_line; Dwarf_Form_Data16 fi_md5_value; char fi_dir_index_present; char fi_time_last_mod_present; char fi_file_length_present; char fi_md5_present; char fi_gnu_decl_file_present; char fi_gnu_decl_line_present; }; /* Part of two-level line tables support. */ struct Dwarf_Subprog_Entry_s { Dwarf_Small *ds_subprog_name; Dwarf_Unsigned ds_decl_file; Dwarf_Unsigned ds_decl_line; }; typedef struct Dwarf_Subprog_Entry_s *Dwarf_Subprog_Entry; struct Dwarf_Unsigned_Pair_s { Dwarf_Unsigned up_first; Dwarf_Unsigned up_second; }; /* This structure provides the context in which the fields of a Dwarf_Line structure are interpreted. They come from the statement program prologue. **Updated by dwarf_srclines in dwarf_line.c. lc_magic will be DW_CONTEXT_MAGIC unless there is a serious programming error somewhere. It's set zero when a Line_Context is deallocated. Any other value indicates there is bug somewhere. */ #define DW_CONTEXT_MAGIC 0xd00d1111 struct Dwarf_Line_Context_s { unsigned lc_magic; /* lc_new_style_access is non-zero if this was allocated via a dwarf_srclines_b() call or equivalent. Otherwise this is 0. */ unsigned char lc_new_style_access; Dwarf_Unsigned lc_unit_length; /* all versions */ /* The section offset (in .debug_line or .debug_line.dwo of the line table */ Dwarf_Unsigned lc_section_offset; /* 2 for DWARF2, 3 for DWARF3, 4 for DWARF4, 5 for DWARF5. 0xf006 for experimental two-level line tables. */ Dwarf_Half lc_version_number; /* all versions */ /* Total length of the line data for this CU */ Dwarf_Unsigned lc_total_length; /* all versions */ /* Length of the initial length field itself. */ Dwarf_Half lc_length_field_length; /* all versions */ /* address size and segment sizefields new in DWARF5 header. */ Dwarf_Small lc_address_size; /* DWARF5 */ Dwarf_Small lc_segment_selector_size; /* DWARF5 */ Dwarf_Unsigned lc_header_length; /* all versions */ Dwarf_Unsigned lc_prologue_length; Dwarf_Unsigned lc_actuals_table_offset; Dwarf_Unsigned lc_logicals_table_offset; Dwarf_Small lc_minimum_instruction_length; /* all versions */ Dwarf_Ubyte lc_maximum_ops_per_instruction; /*DWARF5*/ /* Start and end of this CU line area. pf_line_ptr_start + pf_total_length + pf_length_field_length == pf_line_ptr_end. Meaning lc_line_ptr_start is before the length info. */ Dwarf_Small *lc_line_ptr_start; Dwarf_Small *lc_line_ptr_end; /* Start of the lines themselves. */ Dwarf_Small *lc_line_ptr_lines; /* Used to check that decoding of the line prologue is done right. */ Dwarf_Small *lc_line_prologue_start; Dwarf_Small lc_default_is_stmt; /* all versions */ Dwarf_Sbyte lc_line_base; /* all versions */ Dwarf_Small lc_line_range; /* all versions */ /* Highest std opcode (+1). */ Dwarf_Small lc_opcode_base; /* all versions */ /* pf_opcode_base -1 entries (each a count, normally the value of each entry is 0 or 1). */ Dwarf_Small *lc_opcode_length_table; /* all versions */ /* The number to treat as standard ops. This is a special accomodation of gcc using the new standard opcodes but not updating the version number. It's legal dwarf2, but much better for the user to understand as dwarf3 when 'it looks ok'. */ Dwarf_Small lc_std_op_count; /* ======== includes =========*/ /* Points to the portion of .debug_line section that contains a list of strings naming the included directories. Do not free(). No free even DWARF5? An array of pointers to strings. */ /* DWARF 2,3,4: does not name the current dir of the compilation. DWARF5: Initial entry is the dir of the compilation. */ Dwarf_Small **lc_include_directories; /* Count of the number of included directories. */ Dwarf_Unsigned lc_include_directories_count; /* count of uleb pairs */ Dwarf_Unsigned lc_directory_entry_format_count; /* DWARF5 */ Dwarf_Unsigned lc_directory_entry_values_count; /* DWARF5 */ /* This must be freed,malloc space, an array of the values of each entry. DWARF5 */ struct Dwarf_Unsigned_Pair_s * lc_directory_format_values; /* ======== end includes =========*/ /* ======== file names =========*/ Dwarf_Unsigned lc_file_name_format_count; /* DWARF5 */ Dwarf_Unsigned * lc_file_name_format; /* DWARF5 */ Dwarf_Unsigned lc_file_entry_values_count; /* DWARF5 */ /* This must be freed,malloc space, an array of the values of each entry. */ struct Dwarf_Unsigned_Pair_s * lc_file_format_values; /* DWARF5 */ /* Points to a singly-linked list of entries providing info about source files for the current set of Dwarf_Line structures. The initial entry on the list is 'file 1' per DWARF2,3,4 rules. And so on. lc_last_entry points at the last entry in the list (so we can easily expand the list). It's a list (not a table) since we may encounter DW_LNE_define_file entries. For Dwarf5 the initial entry is 'file 0' and must match the CU-DIE DW_AT_name string. */ Dwarf_File_Entry lc_file_entries; Dwarf_File_Entry lc_last_entry; /* Count of number of source files for this set of Dwarf_Line structures. */ Dwarf_Unsigned lc_file_entry_count; /* all versions */ /* Values Easing the process of indexing through lc_file_entries. */ Dwarf_Unsigned lc_file_entry_baseindex; Dwarf_Unsigned lc_file_entry_endindex; /* ======== end file names =========*/ /* Points to an array of subprogram entries. With Two level line tables this may be non-zero. An array of Dwarf_Subprogram_Entry_s structs. */ Dwarf_Subprog_Entry lc_subprogs; /* Count of the number of subprogram entries With Two level line tables this may be non-zero. */ Dwarf_Unsigned lc_subprogs_count; /* Count of the number of lines for this cu. */ Dwarf_Unsigned lc_line_count; /* Points to name of compilation directory. That string is in a .debug section (DWARF 2,3,4) so do not free this. For DWARF5 must be the same as lc_include_directories[0] */ Dwarf_Small *lc_compilation_directory; Dwarf_Debug lc_dbg; /* zero table count is skeleton, or just missing names. 1 is standard table. 2 means two-level table (experimental) Other is a bug somewhere. */ Dwarf_Small lc_table_count; Dwarf_Bool lc_is_single_table; /* For standard line tables the logicals are the only tables and linecount_actuals is 0. */ Dwarf_Line *lc_linebuf_logicals; Dwarf_Unsigned lc_linecount_logicals; /* Non-zero only if two-level table with actuals */ Dwarf_Line *lc_linebuf_actuals; Dwarf_Unsigned lc_linecount_actuals; }; /* The line table set of registers. The state machine state variables. Using names from the DWARF documentation but preceded by lr_. */ struct Dwarf_Line_Registers_s { Dwarf_Addr lr_address; /* DWARF2 */ Dwarf_Unsigned lr_file ; /* DWARF2 */ Dwarf_Unsigned lr_line ; /* DWARF2 */ Dwarf_Unsigned lr_column ; /* DWARF2 */ Dwarf_Bool lr_is_stmt; /* DWARF2 */ Dwarf_Bool lr_basic_block; /* DWARF2 */ Dwarf_Bool lr_end_sequence; /* DWARF2 */ Dwarf_Bool lr_prologue_end; /* DWARF3 */ Dwarf_Bool lr_epilogue_begin; /* DWARF3 */ Dwarf_Small lr_isa; /* DWARF3 */ Dwarf_Unsigned lr_op_index; /* DWARF4, operation within VLIW instruction. */ Dwarf_Unsigned lr_discriminator; /* DWARF4 */ Dwarf_Unsigned lr_call_context; /* EXPERIMENTAL */ Dwarf_Unsigned lr_subprogram; /* EXPERIMENTAL */ }; typedef struct Dwarf_Line_Registers_s *Dwarf_Line_Registers; void _dwarf_set_line_table_regs_default_values( Dwarf_Line_Registers regs, unsigned lineversion, Dwarf_Bool is_stmt); /* This structure defines a row of the line table. All of the fields except li_offset have the exact same meaning that is defined in Section 6.2.2 of the Libdwarf Document. li_offset is used by _dwarf_addr_finder() which is called by rqs(1), an sgi utility for 'moving' shared libraries as if the static linker (ld) had linked the shared library at the newly-specified address. Most libdwarf-using apps will ignore li_offset and _dwarf_addr_finder(). */ struct Dwarf_Line_s { Dwarf_Addr li_address; /* pc value of machine instr */ union addr_or_line_s { struct li_inner_s { /* New as of DWARF4 */ Dwarf_Unsigned li_discriminator; /* int identifying src file li_file is a number 1-N, indexing into a conceptual source file table as described in dwarf2/3 spec line table doc. (see Dwarf_File_Entry lc_file_entries; and Dwarf_Unsigned lc_file_entry_count;) */ Dwarf_Unsigned li_file; /* In single-level table is line number in source file. 1-N In logicals table is not used. In actuals table is index into logicals table. 1-N*/ Dwarf_Unsigned li_line; Dwarf_Half li_column; /*source file column number 1-N */ Dwarf_Small li_isa; /*New as of DWARF4. */ /* Two-level line tables. Is index from logicals table into logicals table. 1-N */ Dwarf_Unsigned li_call_context; /* Two-level line tables. is index into subprograms table. 1-N */ Dwarf_Unsigned li_subprogram; /* To save space, use bit flags. */ /* indicate start of stmt */ unsigned li_is_stmt:1; /* indicate start basic block */ unsigned li_basic_block:1; /* first post sequence instr */ unsigned li_end_sequence:1; unsigned li_prologue_end:1; unsigned li_epilogue_begin:1; /* Mark a line record as being DW_LNS_set_address. */ unsigned li_is_addr_set:1; } li_l_data; #ifdef __sgi /* SGI IRIX ONLY */ Dwarf_Off li_offset; /* for SGI IRIX rqs only*/ #endif /* __sgi */ } li_addr_line; Dwarf_Line_Context li_context; /* assoc Dwarf_Line_Context_s */ /* Set only on the actuals table of a two-level line table. Assists in the dealloc code. */ Dwarf_Bool li_is_actuals_table; }; int _dwarf_line_address_offsets(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr ** addrs, Dwarf_Off ** offs, Dwarf_Unsigned * returncount, Dwarf_Error * err); int _dwarf_internal_srclines(Dwarf_Die die, Dwarf_Bool old_interface, Dwarf_Unsigned * version, Dwarf_Small * table_count, Dwarf_Line_Context *line_context, Dwarf_Line ** linebuf, Dwarf_Signed * count, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * count_actuals, Dwarf_Bool doaddrs, Dwarf_Bool dolines, Dwarf_Error * error); /* The LOP, WHAT_IS_OPCODE stuff is here so it can be reused in 3 places. Seemed hard to keep the 3 places the same without an inline func or a macro. Handling the line section where the header and the file being processed do not match (unusual, but planned for in the design of .debug_line) is too tricky to recode this several times and keep it right. */ #define LOP_EXTENDED 1 #define LOP_DISCARD 2 #define LOP_STANDARD 3 #define LOP_SPECIAL 4 #define WHAT_IS_OPCODE(type,opcode,base,opcode_length,\ line_ptr,highest_std) \ if ((opcode) < (base)) { \ /* we know we must treat as a standard op \ or a special case. */ \ if ((opcode) == DW_EXTENDED_OPCODE) { \ type = LOP_EXTENDED; \ } else if ((highest_std+1) >= (base)) { \ /* == Standard case: compile of \ dwarf_line.c and object \ have same standard op codes set. \ == Special case: compile of dwarf_line.c \ has things in standard op codes list \ in dwarf.h header not \ in the object: handle this as a standard \ op code in switch below. \ The header special ops overlap the \ object standard ops. \ The new standard op codes will not \ appear in the object. */ \ type = LOP_STANDARD; \ } else { \ /* These are standard opcodes in the object \ ** that were not defined in the header \ ** at the time dwarf_line.c \ ** was compiled. Provides the ability of \ ** out-of-date dwarf reader to read newer \ ** line table data transparently. \ */ \ type = LOP_DISCARD; \ } \ } else { \ /* Is a special op code. */ \ type = LOP_SPECIAL; \ } /* The following is from the dwarf definition of 'ubyte' and is specifically mentioned in section 6.2.5.1, page 54 of the Rev 2.0.0 dwarf specification. */ #define MAX_LINE_OP_CODE 255 /* Operand counts per standard operand. The initial zero is for DW_LNS_copy. This is an economical way to verify we understand the table of standard-opcode-lengths in the line table prologue. */ #define STANDARD_OPERAND_COUNT_DWARF2 9 #define STANDARD_OPERAND_COUNT_DWARF3 12 /* For two-level line tables, we have three additional standard opcodes. */ #define STANDARD_OPERAND_COUNT_TWO_LEVEL 15 void _dwarf_print_header_issue(Dwarf_Debug dbg, const char *specific_msg, Dwarf_Small *data_start, Dwarf_Signed value, unsigned index, unsigned tabv, unsigned linetabv, int *err_count_out); int _dwarf_decode_line_string_form(Dwarf_Debug dbg, Dwarf_Unsigned attrnum, Dwarf_Unsigned form, Dwarf_Unsigned offset_size, Dwarf_Small **line_ptr, Dwarf_Small *line_ptr_end, char **return_str, Dwarf_Error * error); int _dwarf_decode_line_udata_form(Dwarf_Debug dbg, Dwarf_Unsigned attrnum, Dwarf_Unsigned form, Dwarf_Small **line_ptr, Dwarf_Unsigned *return_val, Dwarf_Small *line_end_ptr, Dwarf_Error * error); void _dwarf_report_bad_lnct( Dwarf_Debug dbg, Dwarf_Unsigned ltype, int dlecode, const char * dlename, Dwarf_Error *err); void _dwarf_update_chain_list( Dwarf_Chain chain_line, Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain); void _dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head, int count); int _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m); void _dwarf_line_context_destructor(void *m); void _dwarf_print_line_context_record(Dwarf_Debug dbg, Dwarf_Line_Context line_context); void _dwarf_context_src_files_destroy(Dwarf_Line_Context context); int _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe); libdwarf-20210528/libdwarf/dwarf_alloc.h0000664000175000017500000000374713644370703014736 00000000000000/* Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* #define DWARF_SIMPLE_MALLOC 1 */ char * _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned); Dwarf_Debug _dwarf_get_debug(void); int _dwarf_free_all_of_one_debug(Dwarf_Debug); struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void); void _dwarf_error_destructor(void *); /* Intended for use in memory use investigations. Not a public function. */ void _dwarf_alloc_tree_counts(Dwarf_Unsigned *allocount, Dwarf_Unsigned *allosum, Dwarf_Unsigned *treecount, Dwarf_Unsigned *treesum, Dwarf_Unsigned *earlydealloccount, Dwarf_Unsigned *earlydeallocsize, Dwarf_Unsigned *unused1, Dwarf_Unsigned *unused2, Dwarf_Unsigned *unused3); /* ALLOC_AREA_INDEX_TABLE_MAX is the size of the struct ial_s index_into_allocated array in dwarf_alloc.c */ #define ALLOC_AREA_INDEX_TABLE_MAX 65 libdwarf-20210528/libdwarf/pro_section.c0000664000175000017500000036374514004054326014776 00000000000000/* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_util.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_line.h" #include "pro_frame.h" #include "pro_die.h" #include "pro_macinfo.h" #include "pro_types.h" #include "pro_dnames.h" #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif /* SHN_UNDEF */ #ifndef SHF_MIPS_NOSTRIP /* if this is not defined, we probably don't need it: just use 0 */ #define SHF_MIPS_NOSTRIP 0 #endif #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ #define SIZEOFT32 4 struct Dwarf_Sort_Abbrev_s { Dwarf_Unsigned dsa_attr; Dwarf_Unsigned dsa_form; Dwarf_Signed dsa_implicitvalue; Dwarf_P_Attribute dsa_attrp; }; /* Must match up with pro_section.h defines of DEBUG_INFO etc and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela" see pro_incl.h */ const char *_dwarf_rel_section_names[] = { REL_SEC_PREFIX ".debug_info", REL_SEC_PREFIX ".debug_line", /* Nothing here refers to anything. */ REL_SEC_PREFIX ".debug_abbrev", REL_SEC_PREFIX ".debug_frame", REL_SEC_PREFIX ".debug_aranges", REL_SEC_PREFIX ".debug_pubnames", REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */ REL_SEC_PREFIX ".debug_typenames", /* sgi extension */ REL_SEC_PREFIX ".debug_varnames", /* sgi extension */ REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */ REL_SEC_PREFIX ".debug_macinfo", REL_SEC_PREFIX ".debug_loc", REL_SEC_PREFIX ".debug_ranges", REL_SEC_PREFIX ".debug_types", /* new in DWARF4 */ REL_SEC_PREFIX ".debug_pubtypes", /* new in DWARF3 */ REL_SEC_PREFIX ".debug_names", /* DWARF5 aka dnames */ /* Nothing here refers to anything.*/ REL_SEC_PREFIX ".debug_str", REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ /* DWARF5. Nothing referselsewhere */ REL_SEC_PREFIX ".debug_line_str", REL_SEC_PREFIX ".debug_macro", /* DWARF5. */ REL_SEC_PREFIX ".debug_loclists", /* DWARF5. */ REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ REL_SEC_PREFIX ".debug_sup", /* DWARF5. No relocs on this */ }; /* names of sections. Ensure that it matches the defines in pro_section.h, in the same order Must match also _dwarf_rel_section_names above */ const char *_dwarf_sectnames[] = { ".debug_info", ".debug_line", ".debug_abbrev", ".debug_frame", ".debug_aranges", ".debug_pubnames", ".debug_funcnames", /* sgi extension */ ".debug_typenames", /* sgi extension */ ".debug_varnames", /* sgi extension */ ".debug_weaknames", /* sgi extension */ ".debug_macinfo", ".debug_loc", ".debug_ranges", ".debug_types", /* new in DWARF4 */ ".debug_pubtypes", /* new in DWARF3 */ ".debug_names", /* new in DWARF5. aka dnames */ ".debug_str", ".debug_line_str", /* new in DWARF5 */ ".debug_macro", /* new in DWARF5 */ ".debug_loclists", /* new in DWARF5 */ ".debug_rnglists", /* new in DWARF5 */ ".debug_sup", /* new in DWARF5 */ }; static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */ 1, /* DW_LNS_advance_pc */ 1, /* DW_LNS_advance_line */ 1, /* DW_LNS_set_file */ 1, /* DW_LNS_set_column */ 0, /* DW_LNS_negate_stmt */ 0, /* DW_LNS_set_basic_block */ 0, /* DW_LNS_const_add_pc */ 1, /* DW_LNS_fixed_advance_pc */ /* The following for DWARF3 and DWARF4, though GNU uses these in DWARF2 as well. */ 0, /* DW_LNS_set_prologue_end */ 0, /* DW_LNS_set_epilogue_begin */ 1, /* DW_LNS_set_isa */ }; /* struct to hold relocation entries. Its maintained as a linked list of relocation structs, and will then be written at as a whole into the relocation section. Whether its 32 bit or 64 bit will be obtained from Dwarf_Debug pointer. */ typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; struct Dwarf_P_Rel_s { Dwarf_P_Rel dr_next; void *dr_rel_datap; }; typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; struct Dwarf_P_Rel_Head_s { struct Dwarf_P_Rel_s *drh_head; struct Dwarf_P_Rel_s *drh_tail; }; static int _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugsup(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s len %ld ",msg,len); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif #if 0 static void print_single_abbrev(Dwarf_P_Abbrev c, unsigned idx) { unsigned j = 0; printf(" %2u idx %2u tag 0x%x attrct %2u\n",idx, (unsigned)c->abb_idx, (unsigned)c->abb_tag, (unsigned)c->abb_n_attr); for ( ; j < (unsigned)c->abb_n_attr; ++j) { printf(" %2u attr 0x%2x form 0x%2x impl val %" DW_PR_DSd "\n", j, (unsigned)c->abb_attrs[j], (unsigned)c->abb_forms[j]); (unsigned)c->abb_implicits[j]); } } static void print_curabbrev(const char *where, Dwarf_P_Abbrev curabbrev) { Dwarf_P_Abbrev ca = 0; unsigned i = 0; for (ca = curabbrev; ca ; ca = ca->abb_next,++i) { printf("ABBREV %u from %s\n",i,where); print_single_abbrev(ca,i); } } #endif /* These macros used as return value for _dwarf_pro_get_opc. */ #define OPC_INCS_ZERO -1 #define OPC_OUT_OF_RANGE -2 #define LINE_OUT_OF_RANGE -3 /* Given address advance and line advance, it gives either special opcode, or a number < 0 FIXME: Check all three negative values. Are any negatives really hard errors? */ static int _dwarf_pro_get_opc( struct Dwarf_P_Line_Inits_s *inits, Dwarf_Unsigned addr_adv, int line_adv) { int line_base = inits->pi_line_base; int line_range =inits->pi_line_range; Dwarf_Unsigned factored_adv = 0; factored_adv = addr_adv / inits->pi_minimum_instruction_length; if (line_adv == 0 && factored_adv == 0) { return OPC_INCS_ZERO; } if (line_adv >= line_base && line_adv < line_base + line_range) { int opc = 0; opc = (line_adv - line_base) + (factored_adv * line_range) + inits->pi_opcode_base; if (opc > 255) { return OPC_OUT_OF_RANGE; } return opc; } return LINE_OUT_OF_RANGE; } /* OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total. Which may be 4,8, or 12 bytes! 4 is standard DWARF2. 8 is non-standard MIPS-IRIX 64-bit. 12 is standard DWARF3 for 64 bit offsets. Used in various routines: local variable names must match the names here. */ #define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size) /* Return TRUE if we need the section, FALSE otherwise If any of the 'line-data-related' calls were made including file or directory entries, produce .debug_line . */ static int dwarf_need_debug_line_section(Dwarf_P_Debug dbg) { if (dbg->de_output_version > 4) { return FALSE; } if (dbg->de_lines == NULL && dbg->de_file_entries == NULL && dbg->de_inc_dirs == NULL) { return FALSE; } return TRUE; } /* DWARF5 only. */ static int dwarf_need_debug_names_section(Dwarf_P_Debug dbg) { if (dbg->de_output_version < 5) { return FALSE; } if (!dbg->de_dnames) { return FALSE; } if (!dbg->de_dnames->dn_create_section) { return FALSE; } return TRUE; } /* Convert debug information to a format such that it can be written on disk. Called exactly once per execution. This is the traditional interface. Bad interface design. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_Signed count = 0; int res = 0; res = dwarf_transform_to_disk_form_a(dbg, &count,error); if (res == DW_DLV_ERROR) { return DW_DLV_NOCOUNT; } return count; } /* Convert debug information to a format such that it can be written on disk. Called exactly once per execution. This is the interface design used with the consumer interface, so easier for callers to work with. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg, Dwarf_Signed *count, Dwarf_Error * error) { /* Section data in written out in a number of buffers. Each _generate_*() function returns a cumulative count of buffers for all the sections. dwarf_get_section_bytes() returns pointers to these buffers one at a time. */ Dwarf_Signed nbufs = 0; int sect = 0; int err = 0; Dwarf_Unsigned du = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* Create dwarf section headers */ for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) { long flags = 0; switch (sect) { case DEBUG_SUP: if (!dbg->de_debug_sup.ds_version) { continue; } break; case DEBUG_INFO: if (dbg->de_dies == NULL) { continue; } break; case DEBUG_LINE: if (dwarf_need_debug_line_section(dbg) == FALSE) { continue; } break; case DEBUG_ABBREV: if (dbg->de_dies == NULL) { continue; } break; case DEBUG_FRAME: if (dbg->de_frame_cies == NULL) { continue; } flags = SHF_MIPS_NOSTRIP; break; case DEBUG_ARANGES: if (dbg->de_arange == NULL) { continue; } break; case DEBUG_PUBNAMES: if (dbg->de_simple_name_headers[dwarf_snk_pubname]. sn_head == NULL) { continue; } break; case DEBUG_PUBTYPES: if (dbg->de_simple_name_headers[dwarf_snk_pubtype]. sn_head == NULL) { continue; } break; case DEBUG_STR: if (dbg->de_debug_str->ds_data == NULL) { continue; } break; case DEBUG_FUNCNAMES: if (dbg->de_simple_name_headers[dwarf_snk_funcname]. sn_head == NULL) { continue; } break; case DEBUG_TYPENAMES: if (dbg->de_simple_name_headers[dwarf_snk_typename]. sn_head == NULL) { continue; } break; case DEBUG_VARNAMES: if (dbg->de_simple_name_headers[dwarf_snk_varname]. sn_head == NULL) { continue; } break; case DEBUG_WEAKNAMES: if (dbg->de_simple_name_headers[dwarf_snk_weakname]. sn_head == NULL) { continue; } break; case DEBUG_MACINFO: if (dbg->de_first_macinfo == NULL) { continue; } break; case DEBUG_NAMES: /* DWARF5 */ if (dwarf_need_debug_names_section(dbg) == FALSE) { continue; } break; case DEBUG_LOC: /* Not handled yet. */ continue; case DEBUG_RANGES: /* Not handled yet. */ continue; case DEBUG_TYPES: /* Not handled yet. */ continue; case DEBUG_MACRO: /* Not handled yet. */ continue; case DEBUG_LOCLISTS: /* Not handled yet. */ continue; case DEBUG_RNGLISTS: /* Not handled yet. */ continue; case DEBUG_LINE_STR: if (dwarf_need_debug_line_section(dbg) == FALSE) { continue; } /* Not handled yet. */ continue; default: /* logic error: missing a case */ DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } { int new_base_elf_sect = 0; if (dbg->de_callback_func) { new_base_elf_sect = dbg->de_callback_func(_dwarf_sectnames[sect], /* rec size */ 1, SECTION_TYPE, flags, SHN_UNDEF, 0, &du, dbg->de_user_data, &err); } if (new_base_elf_sect == -1) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } dbg->de_elf_sects[sect] = new_base_elf_sect; dbg->de_sect_name_idx[sect] = du; } } nbufs = 0; /* Changing the order in which the sections are generated may cause problems because of relocations. */ if (dbg->de_debug_sup.ds_version) { int res = _dwarf_pro_generate_debugsup(dbg, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dwarf_need_debug_line_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debugline(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_frame_cies) { int res = _dwarf_pro_generate_debugframe(dbg,&nbufs,error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_first_macinfo) { /* For DWARF 2,3,4 only */ /* Need new code for DWARF5 macro info. FIXME*/ int res = _dwarf_pro_transform_macro_info_to_disk(dbg, &nbufs,error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_dies) { int res= _dwarf_pro_generate_debuginfo(dbg, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_debug_str->ds_data) { int res = _dwarf_pro_generate_debug_str(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_debug_line_str->ds_data) { int res = _dwarf_pro_generate_debug_line_str(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_arange) { int res = _dwarf_transform_arange_to_disk(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_output_version < 5) { if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_pubname, DEBUG_PUBNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_pubtype, DEBUG_PUBTYPES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_funcname, DEBUG_FUNCNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_typename, DEBUG_TYPENAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_varname, DEBUG_VARNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_weakname, DEBUG_WEAKNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } } if (dwarf_need_debug_names_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_names(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } #if 0 /* FIXME: TODO new sections */ if (dwarf_need_debug_macro_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_macro(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dwarf_need_debug_loclists_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_loclists(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dwarf_need_debug_rnglists_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_rnglists(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } #endif { Dwarf_Signed new_chunks = 0; int res = 0; res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR, DW_DLV_ERROR); } nbufs += new_chunks; } *count = nbufs; return DW_DLV_OK; } static int write_fixed_size(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned size, unsigned * size_out, Dwarf_Error* error) { unsigned char *data = 0; GET_CHUNK_ERR(dbg, elfsectno, data, size, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val, sizeof(val), size); *size_out = size; return DW_DLV_OK; } static int write_ubyte(unsigned val, Dwarf_P_Debug dbg, int elfsectno, unsigned *len_out, Dwarf_Error* error) { Dwarf_Ubyte db = val; unsigned char *data = 0; unsigned len = sizeof(Dwarf_Ubyte); GET_CHUNK_ERR(dbg, elfsectno, data, len, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), len); *len_out = 1; return DW_DLV_OK;; } static int pretend_write_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, unsigned *uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; int nbytes = 0; int res = 0; res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR , DW_DLV_ERROR); } *uval_len_out = nbytes; return DW_DLV_OK; } static int write_sval(Dwarf_Signed val, Dwarf_P_Debug dbg, int elfsectno, unsigned *sval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; unsigned char *data = 0; int nbytes = 0; int res = _dwarf_pro_encode_signed_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } GET_CHUNK(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); *sval_len_out = nbytes; return DW_DLV_OK; } /* This one does not allocate a chunk, uses an already existing chunk. data points into that existing chunk. */ static int append_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, unsigned char *data, unsigned * uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; int nbytes = 0; int res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } memcpy((void *) data, (const void *) buff1, nbytes); *uval_len_out = nbytes; return DW_DLV_OK; } static int write_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, unsigned * uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; unsigned char *data = 0; int nbytes = 0; int res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } GET_CHUNK_ERR(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); *uval_len_out = nbytes; return DW_DLV_OK; } static unsigned write_opcode_uval(int opcode, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned val, unsigned *len_out, Dwarf_Error* error) { unsigned ublen = 0; int res = 0; unsigned uvlen = 0; res = write_ubyte(opcode,dbg,elfsectno,&ublen,error); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = write_uval(val,dbg,elfsectno,&uvlen,error); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } *len_out = ublen +uvlen; return DW_DLV_OK; } static int determine_form_size(Dwarf_P_Debug dbg, unsigned format_count, struct Dwarf_P_Line_format_s *format, unsigned *size_out, Dwarf_Bool write_out, unsigned char *data, Dwarf_Error *error) { unsigned calculated_size = 0; unsigned n = 0; int res = 0; /* entry format itself */ calculated_size += sizeof_ubyte(dbg); /* Space for the format details. */ for (n = 0; n < format_count; ++n) { struct Dwarf_P_Line_format_s *lf = format+n; unsigned val_len = 0; unsigned val_len2 = 0; if (write_out) { res = append_uval(lf->def_content_type, dbg, data, &val_len,error); } else { res = pretend_write_uval(lf->def_content_type, dbg, &val_len,error); } data += val_len; if (res != DW_DLV_OK) { return res; } if (write_out) { res = append_uval(lf->def_form_code, dbg, data, &val_len2,error); } else { res = pretend_write_uval(lf->def_form_code, dbg, &val_len2,error); } if (res != DW_DLV_OK) { return res; } data += val_len2; calculated_size += val_len + val_len2; } *size_out = calculated_size; return DW_DLV_OK; } static int determine_file_content_size(Dwarf_P_Debug dbg, Dwarf_P_F_Entry entry_list, Dwarf_Unsigned format_count, struct Dwarf_P_Line_format_s *format, unsigned *size_out, Dwarf_Bool write_out, unsigned char *data, Dwarf_Error *error) { unsigned calculated_size = 0; unsigned count_len = 0; Dwarf_P_F_Entry cur = 0; Dwarf_P_F_Entry nxt = 0; unsigned n = 0; int res = 0; Dwarf_Unsigned offset_size = 0; offset_size = dbg->de_dwarf_offset_size; res = pretend_write_uval(format_count,dbg, &count_len,error); if (res != DW_DLV_OK) { return res; } calculated_size += count_len; cur = entry_list; for (n = 0; cur; n++,cur = nxt) { unsigned f = 0; nxt = cur->dfe_next; for ( ; f < format_count; f++) { struct Dwarf_P_Line_format_s *lf = format+f; unsigned ctype = lf->def_content_type; unsigned cform = lf->def_form_code; switch (ctype) { case DW_LNCT_path: { switch(cform) { case DW_FORM_string: { unsigned slen = strlen(cur->dfe_name) +1; calculated_size += slen; if (write_out) { strcpy((char *)data, cur->dfe_name); data += slen; } } break; case DW_FORM_strp: { unsigned slen = strlen(cur->dfe_name) +1; if (write_out) { Dwarf_Unsigned stroffset = 0; res = _dwarf_insert_or_find_in_debug_str( dbg, cur->dfe_name, _dwarf_hash_debug_str, slen, &stroffset,error); if (res != DW_DLV_OK) { return res; } WRITE_UNALIGNED(dbg, (void *) data, (const void *) &stroffset, sizeof(stroffset), offset_size); data += offset_size; } calculated_size += offset_size; } break; case DW_FORM_line_strp: { unsigned slen = strlen(cur->dfe_name) +1; if (write_out) { Dwarf_Unsigned stroffset = 0; res = _dwarf_insert_or_find_in_debug_str( dbg, cur->dfe_name, _dwarf_hash_debug_line_str, slen, &stroffset,error); if (res != DW_DLV_OK) { return res; } WRITE_UNALIGNED(dbg, (void *) data, (const void *) &stroffset, sizeof(stroffset), offset_size); data += offset_size; } calculated_size += offset_size; } break; case DW_FORM_strp_sup: /* Following in dwo only. */ case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); break; } } break; case DW_LNCT_directory_index: { switch(cform) { case DW_FORM_data1: calculated_size += 1; if (write_out) { unsigned char ub = cur->dfe_index; *data = ub; data += 1; } break; case DW_FORM_data2: calculated_size += DWARF_HALF_SIZE; if (write_out) { Dwarf_Half uh = cur->dfe_index; memcpy(data,&uh,DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; } break; case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_index, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_index, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_timestamp: { switch(cform) { case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_timestamp, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_timestamp, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; case DW_FORM_data4: { calculated_size += DWARF_32BIT_SIZE; if (write_out) { ASNOUT(data,cur->dfe_timestamp, DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } } break; case DW_FORM_data8: /* As of 2017 there is no 8 byte timestamp defined, though it does have to happen. before 2038. */ calculated_size += DWARF_64BIT_SIZE; if (write_out) { Dwarf_Unsigned u8 = cur->dfe_index; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &u8, sizeof(u8), DWARF_64BIT_SIZE); data += DWARF_64BIT_SIZE; } break; case DW_FORM_block: case DW_FORM_exprloc: default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_size: { switch(cform) { case DW_FORM_data1: calculated_size += 1; if (write_out) { unsigned char ub = cur->dfe_index; *data = ub; data += 1; } break; case DW_FORM_data2: calculated_size += DWARF_HALF_SIZE; if (write_out) { Dwarf_Half uh = cur->dfe_index; memcpy(data,&uh,DWARF_HALF_SIZE); } break; case DW_FORM_data4: calculated_size += DWARF_32BIT_SIZE; if (write_out) { ASNOUT(data,cur->dfe_index, DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } break; case DW_FORM_data8: calculated_size += DWARF_64BIT_SIZE; if (write_out) { Dwarf_Unsigned u8 = cur->dfe_index; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &u8, sizeof(u8), DWARF_64BIT_SIZE); data += DWARF_64BIT_SIZE; } break; case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_size, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_size, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_MD5: { switch(cform) { case DW_FORM_data16: if (write_out) { memcpy(data,cur->dfe_md5, sizeof(cur->dfe_md5)); data += 16; } calculated_size += 16; break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_CODE_UNKNOWN, DW_DLV_ERROR); } } } *size_out = calculated_size; return DW_DLV_OK; } static int calculate_size_of_line_header5(Dwarf_P_Debug dbg, struct Dwarf_P_Line_Inits_s *inits, unsigned *prolog_size_out, Dwarf_Error *error) { unsigned prolog_size = 0; int offset_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; int res = 0; prolog_size += OFFSET_PLUS_EXTENSION_SIZE + sizeof_uhalf(dbg) + /* version # */ sizeof_ubyte(dbg) + /* address_size */ sizeof_ubyte(dbg) + /* segment_selector_size */ offset_size + /* header length */ sizeof_ubyte(dbg) + /* min_instr length */ sizeof_ubyte(dbg) + /* maximum_operations_per_instruction */ sizeof_ubyte(dbg) + /* default is_stmt */ sizeof_ubyte(dbg) + /* linebase */ sizeof_ubyte(dbg) + /* linerange */ sizeof_ubyte(dbg); /* opcode base */ /* For maximum_operations_per_instruction. */ prolog_size += sizeof_ubyte(dbg); /* standard_opcode_lengths table len */ prolog_size += inits->pi_opcode_base-1; { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_directory_entry_format_count, inits->pi_incformats, &fsize,FALSE,0,error); if (res != DW_DLV_OK) { return res; } prolog_size += fsize; } { unsigned dir_count_len = 0; res = determine_file_content_size(dbg, dbg->de_inc_dirs, dbg->de_line_inits.pi_directory_entry_format_count, dbg->de_line_inits.pi_incformats, &dir_count_len, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += dir_count_len; } { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_file_entry_format_count, inits->pi_fileformats, &fsize, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += fsize; } { unsigned file_count_len = 0; res = determine_file_content_size(dbg, dbg->de_file_entries, dbg->de_line_inits.pi_file_entry_format_count, dbg->de_line_inits.pi_fileformats, &file_count_len, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += file_count_len; } *prolog_size_out = prolog_size; return DW_DLV_OK; } /* For DWARF 2,3,4 */ static int calculate_size_of_line_header4(Dwarf_P_Debug dbg, struct Dwarf_P_Line_Inits_s *inits, unsigned *prolog_size_out, UNUSEDARG Dwarf_Error *error) { Dwarf_P_F_Entry curdir = 0; Dwarf_P_F_Entry curentry = 0; unsigned prolog_size = 0; int offset_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; prolog_size += OFFSET_PLUS_EXTENSION_SIZE + sizeof_uhalf(dbg) + /* version # */ offset_size + /* header length */ sizeof_ubyte(dbg) + /* min_instr length */ sizeof_ubyte(dbg) + /* default is_stmt */ sizeof_ubyte(dbg) + /* linebase */ sizeof_ubyte(dbg) + /* linerange */ sizeof_ubyte(dbg); /* opcode base */ if (inits->pi_linetable_version == DW_LINE_VERSION4) { /* For maximum_operations_per_instruction. */ prolog_size += sizeof_ubyte(dbg); } /* standard_opcode_lengths table len */ prolog_size += inits->pi_opcode_base-1; /* include directories */ curdir = dbg->de_inc_dirs; while (curdir) { prolog_size += strlen(curdir->dfe_name) + 1; curdir = curdir->dfe_next; } prolog_size++; /* last null following last directory entry. */ /* file entries */ curentry = dbg->de_file_entries; while (curentry) { prolog_size += strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; curentry = curentry->dfe_next; } prolog_size++; /* last null byte */ *prolog_size_out = prolog_size; return DW_DLV_OK; } /* Generate debug_line section Dwarf2, dwarf3 headers are the same (DW3 acknowledges 64bit). DWARF4 adds the maximum_operations_per_instruction field. DWARF5 adds address size and address selector size and replaces the entire directories/files list with very different stuff. */ static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Signed * nbufs, Dwarf_Error * error) { Dwarf_P_F_Entry curdir = 0; Dwarf_P_F_Entry curentry = 0; Dwarf_P_Line curline = 0; Dwarf_P_Line prevline = 0; struct Dwarf_P_Line_Inits_s *inits = 0; /* all data named cur* are used to loop thru linked lists */ int sum_bytes = 0; unsigned prolog_size = 0; unsigned char *data = 0; /* holds disk form data */ int elfsectno = 0; unsigned char *start_line_sec = 0; /* pointer to the buffer at section start */ /* temps for memcpy */ Dwarf_Unsigned du = 0; Dwarf_Ubyte db = 0; Dwarf_Half dh = 0; int res = 0; Dwarf_Half version = dbg->de_output_version; int offset_size = dbg->de_dwarf_offset_size; Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_Ubyte address_size = dbg->de_pointer_size; sum_bytes = 0; elfsectno = dbg->de_elf_sects[DEBUG_LINE]; inits = &dbg->de_line_inits; if (version < 5) { res = calculate_size_of_line_header4(dbg,inits,&prolog_size, error); } else if (version == 5) { res = calculate_size_of_line_header5(dbg,inits,&prolog_size, error); } else { _dwarf_p_error(dbg, error,DW_DLE_VERSION_STAMP_ERROR ); return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } /* Allocate a chunk, put address in 'data' */ GET_CHUNK_ERR(dbg, elfsectno, data, prolog_size, error); start_line_sec = data; /* Copy the prologue data into 'data' */ /* total_length */ du = 0; if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } /* We will adjust this later, we do not know the full length of the line_section content for this cu yet. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; dh = inits->pi_linetable_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, sizeof(dh), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; if (version == 5 ) { /* address size, seg sel size now */ db = inits->pi_address_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(db)); data += sizeof(db); db = inits->pi_segment_size; /* segment selector size */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(db)); data += sizeof(db); } { /* header length (called prolog length in DWARF2) This we do know, we calculated the prolog length already and it is prolog_size so just */ Dwarf_Unsigned sofar = data - start_line_sec; du = prolog_size - sofar - offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; } db = inits->pi_minimum_instruction_length; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); if (inits->pi_linetable_version == 4 || inits->pi_linetable_version == 5) { db = inits->pi_maximum_operations_per_instruction; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); } db = inits->pi_default_is_stmt; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_line_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_line_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_opcode_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, inits->pi_opcode_base-1, inits->pi_opcode_base-1); data += inits->pi_opcode_base-1; if (version < 5) { /* copy over include directories */ curdir = dbg->de_inc_dirs; while (curdir) { strcpy((char *) data, curdir->dfe_name); data += strlen(curdir->dfe_name) + 1; curdir = curdir->dfe_next; } *data = '\0'; /* last null */ data++; /* copy file entries */ curentry = dbg->de_file_entries; while (curentry) { strcpy((char *) data, curentry->dfe_name); data += strlen(curentry->dfe_name) + 1; /* copies of leb numbers, no endian issues */ memcpy((void *) data, (const void *) curentry->dfe_args, curentry->dfe_nbytes); data += curentry->dfe_nbytes; curentry = curentry->dfe_next; } *data = '\0'; data++; } else if (version == 5) { { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_directory_entry_format_count, inits->pi_incformats, &fsize, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += fsize; } { unsigned dir_count_len = 0; res = determine_file_content_size(dbg, dbg->de_inc_dirs, inits->pi_directory_entry_format_count, inits->pi_incformats, &dir_count_len, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += dir_count_len; } { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_file_entry_format_count, inits->pi_fileformats, &fsize, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += fsize; } { unsigned file_count_len = 0; res = determine_file_content_size(dbg, dbg->de_file_entries, dbg->de_line_inits.pi_file_entry_format_count, dbg->de_line_inits.pi_fileformats, &file_count_len, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += file_count_len; } } { Dwarf_Unsigned sofar = data - start_line_sec; if (sofar != prolog_size) { /* We miscalculated something. */ _dwarf_p_error(dbg, error, DW_DLE_LINE_HEADER_LENGTH_BOTCH); return DW_DLV_ERROR; } sum_bytes += prolog_size; } curline = dbg->de_lines; prevline = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (prevline == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } _dwarf_pro_reg_init(dbg,prevline); /* generate opcodes for line numbers */ while (curline) { int opc = 0; int no_lns_copy = 0; /* if lns copy opcode does not need to be generated, if special opcode or end sequence */ Dwarf_Unsigned addr_adv = 0; int line_adv = 0; /* supposed to be a reasonably small number, so the size should not be a problem. ? */ no_lns_copy = 0; if (curline->dpl_opc != 0) { int inst_bytes = 0; /* no of bytes in extended opcode */ unsigned writelen = 0; switch (curline->dpl_opc) { case DW_LNE_end_sequence: /* Advance pc to end of text section. */ addr_adv = curline->dpl_address - prevline->dpl_address; if (addr_adv > 0) { res = write_opcode_uval(DW_LNS_advance_pc,dbg, elfsectno, addr_adv/inits->pi_minimum_instruction_length, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; } /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write length of extended opcode */ inst_bytes = sizeof(Dwarf_Ubyte); res = write_uval(inst_bytes,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write extended opcode */ res = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* reset value to original values */ _dwarf_pro_reg_init(dbg,prevline); no_lns_copy = 1; /* this is set only for end_sequence, so that a dw_lns_copy is not generated */ break; case DW_LNE_set_address: /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write length of extended opcode */ inst_bytes = sizeof(Dwarf_Ubyte) + address_size; res = write_uval(inst_bytes,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write extended opcode */ res = write_ubyte(DW_LNE_set_address,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* reloc for address */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_LINE, sum_bytes, /* r_offset */ curline->dpl_r_symidx, dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR); } /* write offset (address) */ du = curline->dpl_address; res = write_fixed_size(du,dbg,elfsectno, address_size,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; no_lns_copy = 1; break; case DW_LNE_define_file: /* Not supported, all add-file entries are added via dbg -> de_file_entries, which adds to the line table header. */ no_lns_copy = 1; break; case DW_LNE_set_discriminator: {/* DWARF4 */ unsigned val_len = 0; /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write len of opcode + value here. */ res = pretend_write_uval(curline->dpl_discriminator, dbg, &val_len,error); if (res != DW_DLV_OK) { return res; } val_len++; res = write_uval(val_len +1,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write opcode */ res = write_ubyte(DW_LNE_set_discriminator, dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write the value itself. */ res = write_uval(curline->dpl_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; no_lns_copy = 1; } break; } } else { unsigned writelen = 0; if (inits->pi_opcode_base >12) { /* We have the newer standard opcodes DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end, DW_LNS_set_isa, we do not write them if not in the table. DWARF3 and DWARF4 */ /* Should we check if a change? These reset automatically in the line processing/reading engine, so I think no check of prevline is wanted. */ if (curline->dpl_epilogue_begin) { res = write_ubyte(DW_LNS_set_epilogue_begin,dbg, elfsectno,&writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } if (curline->dpl_prologue_end) { res = write_ubyte(DW_LNS_set_prologue_end,dbg, elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } if (curline->dpl_isa != prevline->dpl_isa) { res = write_opcode_uval(DW_LNS_set_isa,dbg, elfsectno, curline->dpl_isa, &writelen ,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } } if (curline->dpl_file != prevline->dpl_file) { db = DW_LNS_set_file; res = write_opcode_uval(db,dbg, elfsectno, curline->dpl_file,&writelen ,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_file = curline->dpl_file; } if (curline->dpl_column != prevline->dpl_column) { db = DW_LNS_set_column; res = write_opcode_uval(db,dbg, elfsectno, curline->dpl_column , &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_column = curline->dpl_column; } if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { res = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_is_stmt = curline->dpl_is_stmt; } if (curline->dpl_basic_block == true && prevline->dpl_basic_block == false) { res = write_ubyte(DW_LNS_set_basic_block,dbg, elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = curline->dpl_basic_block; } if (curline->dpl_discriminator) { /* This is dwarf4, but because it is an extended op not a standard op, we allow it without testing version. GNU seems to set this from time to time. */ unsigned val_len = 0; /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write len of opcode + value here. */ res = pretend_write_uval(curline->dpl_discriminator, dbg, &val_len,error); if (res != DW_DLV_OK) { return res; } val_len ++; res = write_uval(val_len +1,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write opcode */ res = write_ubyte(DW_LNE_set_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write the value itself. */ res = write_uval(curline->dpl_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } addr_adv = curline->dpl_address - prevline->dpl_address; line_adv = (int) (curline->dpl_line - prevline->dpl_line); if ((addr_adv % MIN_INST_LENGTH) != 0) { DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR); } opc = _dwarf_pro_get_opc(inits,addr_adv, line_adv); if (opc > 0) { /* Use special opcode. */ no_lns_copy = 1; res = write_ubyte(opc,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; prevline->dpl_line = curline->dpl_line; } else { /* opc says use standard opcodes. */ if (addr_adv > 0) { db = DW_LNS_advance_pc; res = write_opcode_uval(db,dbg, elfsectno, addr_adv/inits->pi_minimum_instruction_length, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; } if (line_adv != 0) { db = DW_LNS_advance_line; res = write_ubyte(db,dbg, elfsectno, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; res = write_sval(line_adv,dbg, elfsectno, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_line = curline->dpl_line; } } } /* ends else for opc <= 0 */ if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq generate a matrix line */ unsigned writelen = 0; res = write_ubyte(DW_LNS_copy,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; } curline = curline->dpl_next; } /* write total length field */ du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE; { start_line_sec += extension_size; WRITE_UNALIGNED(dbg, (void *) start_line_sec, (const void *) &du, sizeof(du), offset_size); } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* Generate debug_frame section */ static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno = 0; int i = 0; int firsttime = 1; Dwarf_P_Cie curcie = 0; Dwarf_P_Fde curfde = 0; unsigned char *data = 0; Dwarf_Unsigned du = 0; Dwarf_Ubyte db = 0; long *cie_offs = 0; /* Holds byte offsets for links to fde's */ unsigned long cie_length = 0; int cie_no = 0; Dwarf_Ubyte offset_size = dbg->de_dwarf_offset_size; Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_Ubyte address_size = dbg->de_pointer_size; Dwarf_Unsigned cur_off = 0;/* current offset of written data, held for relocation info */ elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; curcie = dbg->de_frame_cies; cie_length = 0; cie_offs = (long *) _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); if (cie_offs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Generate cie number as we go along. This writes all CIEs first before any FDEs, which is rather different from the order a compiler might like (which might be each CIE followed by its FDEs then the next CIE, and so on). */ cie_no = 1; while (curcie) { char *code_al = 0; int codeal_bytes = 0; char *data_al = 0; int data_align_bytes = 0; int pad = 0; /* Pad for padding to align cies and fdes */ int res = 0; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; char buff3[ENCODE_SPACE_NEEDED]; char *augmentation = 0; char *augmented_al = 0; long augmented_fields_length = 0; int irix_auglen_v0 = 0; Dwarf_Half version = curcie->cie_version; res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, &codeal_bytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Before April 1999, the following was using an unsigned encode. That worked ok even though the decoder used the correct signed leb read, but doing the encode correctly (according to the dwarf spec) saves space in the output file and is completely compatible. Note the actual stored amount on MIPS was 10 bytes (!) to store the value -4. (hex)fc ffffffff ffffffff 01 The libdwarf consumer consumed all 10 bytes too! old version res = _dwarf_pro_encode_leb128_nm(curcie->cie_data_align, below is corrected signed version. */ res = _dwarf_pro_encode_signed_leb128_nm( curcie->cie_data_align, &data_align_bytes, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } code_al = buff1; data_al = buff2; /* get the correct offset */ if (firsttime) { cie_offs[cie_no - 1] = 0; firsttime = 0; } else { cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE; } cie_no++; augmentation = curcie->cie_aug; cie_length = offset_size + /* cie_id */ sizeof(Dwarf_Ubyte) + /* cie version */ strlen(curcie->cie_aug) + 1 + /* augmentation */ codeal_bytes + /* code alignment factor */ data_align_bytes + /* data alignment factor */ sizeof(Dwarf_Ubyte) + /* return reg address */ curcie->cie_inst_bytes; if (dbg->de_irix_exc_augmentation && (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) { /* IRIX specific. */ augmented_fields_length = 0; res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, &irix_auglen_v0, buff3, sizeof(buff3)); augmented_al = buff3; if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } cie_length += irix_auglen_v0 ; /* augmentation length */ } if (version >= 4) { /* address size, segment selector size */ cie_length += 1 +1; } pad = (int) PADDING(cie_length, address_size); cie_length += pad; /* Now we have the cie length with padding, allocate a buffer for that plus the header length. */ GET_CHUNK_ERR(dbg, elfsectno, data, cie_length + OFFSET_PLUS_EXTENSION_SIZE, error); if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } du = cie_length; /* total length of cie */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* cie-id is a special value. */ du = DW_CIE_ID; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; db = curcie->cie_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); strcpy((char *) data, curcie->cie_aug); data += strlen(curcie->cie_aug) + 1; if (curcie->cie_version >= 4) { /* emit address-size, segment selector size */ db = dbg->de_pointer_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = dbg->de_segment_selector_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); } memcpy((void *) data, (const void *) code_al, codeal_bytes); data += codeal_bytes; memcpy((void *) data, (const void *) data_al, data_align_bytes); data += data_align_bytes; db = curcie->cie_ret_reg; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); if (dbg->de_irix_exc_augmentation && strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { /* IRIX only */ memcpy((void *) data, (const void *) augmented_al, irix_auglen_v0); data += irix_auglen_v0; } memcpy((void *) data, (const void *) curcie->cie_inst, curcie->cie_inst_bytes); data += curcie->cie_inst_bytes; for (i = 0; i < pad; i++) { *data = DW_CFA_nop; data++; } curcie = curcie->cie_next; } /* calculate current offset */ cur_off = cie_offs[cie_no - 2] + cie_length + OFFSET_PLUS_EXTENSION_SIZE; /* write out fde's */ curfde = dbg->de_frame_fdes; while (curfde) { Dwarf_P_Frame_Pgm curinst = 0; long fde_length = 0; int pad2 = 0; Dwarf_P_Cie cie_ptr = 0; Dwarf_Unsigned cie_index = 0; /* index is a global in string.h, so don't name anything index. */ Dwarf_Unsigned indx = 0; int oet_length = 0; int afl_length = 0; int res = 0; int v0_augmentation = 0; char afl_buff[ENCODE_SPACE_NEEDED]; /* Find the CIE associated with this fde. */ cie_ptr = dbg->de_frame_cies; cie_index = curfde->fde_cie; indx = 1; /* The cie_index of the first cie is 1, not 0. */ while (cie_ptr && indx < cie_index) { cie_ptr = cie_ptr->cie_next; indx++; } if (cie_ptr == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR); } fde_length = curfde->fde_n_bytes + OFFSET_PLUS_EXTENSION_SIZE + /* cie pointer */ address_size + /* initial loc */ address_size; /* address range */ if (dbg->de_irix_exc_augmentation && strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { v0_augmentation = 1; oet_length = DWARF_32BIT_SIZE; /* encode the length of augmented fields. */ res = _dwarf_pro_encode_leb128_nm(oet_length, &afl_length, afl_buff, sizeof(afl_buff)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } fde_length += afl_length + /* augmented field length */ oet_length; /* exception_table offset */ } if (curfde->fde_die) { /* IRIX/MIPS extension: Using fde offset, generate DW_AT_MIPS_fde attribute for the die corresponding to this fde. */ res = _dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error); if (res != DW_DLV_OK) { return res; } } /* store relocation for cie pointer */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, cur_off + OFFSET_PLUS_EXTENSION_SIZE /* r_offset */, dbg->de_sect_name_idx[DEBUG_FRAME], dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res ); } /* store relocation information for initial location */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, cur_off + OFFSET_PLUS_EXTENSION_SIZE + address_size /* r_offset */, curfde->fde_r_symidx, dwarf_drt_data_reloc, address_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } /* Store the relocation information for the offset_into_exception_info field, if the offset is valid (0 is a valid offset). */ if (v0_augmentation && curfde->fde_offset_into_exception_tables >= 0) { res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, /* r_offset, where in cie this field starts */ cur_off + OFFSET_PLUS_EXTENSION_SIZE + offset_size + 2 * address_size + afl_length, curfde->fde_exception_table_symbol, dwarf_drt_segment_rel, DWARF_32BIT_SIZE); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } } /* adjust for padding */ pad2 = (int) PADDING(fde_length, address_size); fde_length += pad2; /* write out fde */ GET_CHUNK(dbg, elfsectno, data, fde_length + OFFSET_PLUS_EXTENSION_SIZE, error); du = fde_length; { if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } /* length */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* offset to cie */ du = cie_offs[curfde->fde_cie - 1]; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; du = curfde->fde_initloc; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), address_size); data += address_size; if (dbg->de_relocate_pair_by_symbol && curfde->fde_end_symbol != 0 && curfde->fde_addr_range == 0) { /* symbolic reloc, need reloc for length What if we really know the length? If so, should use the other part of 'if'. */ Dwarf_Unsigned val = 0; res = dbg->de_relocate_pair_by_symbol(dbg, DEBUG_FRAME, cur_off + 2 * offset_size + address_size, /* r_offset */ curfde->fde_r_symidx, curfde->fde_end_symbol, dwarf_drt_first_of_length_pair, address_size); if (res != DW_DLV_OK) { { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* arrange pre-calc so assem text can do .word end - begin + val (gets val from stream) */ val = curfde->fde_end_symbol_offset - curfde->fde_initloc; WRITE_UNALIGNED(dbg, data, (const void *) &val, sizeof(val), address_size); data += address_size; } else { du = curfde->fde_addr_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), address_size); data += address_size; } } if (v0_augmentation) { /* IRIX only. */ /* write the encoded augmented field length. */ Dwarf_Signed dsw = 0; memcpy((void *) data, (const void *) afl_buff, afl_length); data += afl_length; /* write the offset_into_exception_tables field. */ dsw = (Dwarf_Signed) curfde->fde_offset_into_exception_tables; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, sizeof(dsw), DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } curinst = curfde->fde_inst; if (curfde->fde_block) { unsigned long size = curfde->fde_inst_block_size; memcpy((void *) data, (const void *) curfde->fde_block, size); data += size; } else { while (curinst) { db = curinst->dfp_opcode; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); memcpy((void *) data, (const void *) curinst->dfp_args, curinst->dfp_nbytes); data += curinst->dfp_nbytes; curinst = curinst->dfp_next; } } /* padding */ for (i = 0; i < pad2; i++) { *data = DW_CFA_nop; data++; } cur_off += fde_length + offset_size; curfde = curfde->fde_next; } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* These functions remember all the markers we see along with the right offset in the .debug_info section so that we can dump them all back to the user with the section info. */ static int marker_init(Dwarf_P_Debug dbg, unsigned count) { dbg->de_marker_n_alloc = count; dbg->de_markers = NULL; if (count > 0) { dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc); if (dbg->de_markers == NULL) { dbg->de_marker_n_alloc = 0; return DW_DLV_ERROR; } } return DW_DLV_OK; } static int marker_add(Dwarf_P_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned marker) { if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) { unsigned n = dbg->de_marker_n_used++; dbg->de_markers[n].ma_offset = offset; dbg->de_markers[n].ma_marker = marker; return DW_DLV_OK; } return DW_DLV_ERROR; } Dwarf_Signed dwarf_get_die_markers(Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, /* pointer to a pointer */ Dwarf_Unsigned * marker_count, Dwarf_Error * error) { int res = 0; res = dwarf_get_die_markers_a(dbg,marker_list,marker_count, error); if (res == DW_DLV_ERROR) { return DW_DLV_BADADDR; } return 0; } int dwarf_get_die_markers_a(Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, /* pointer to a pointer */ Dwarf_Unsigned * marker_count, Dwarf_Error * error) { if (marker_list == NULL || marker_count == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); } *marker_list = dbg->de_markers; *marker_count = dbg->de_marker_n_used; return DW_DLV_OK; } /* These functions provide the offsets of DW_FORM_string attributes in the section section_index. These information will enable a producer app that is generating assembly text output to easily emit those attributes in ascii form without having to decode the byte stream. */ static int string_attr_init (Dwarf_P_Debug dbg, Dwarf_Signed section_index, unsigned count) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; sect_sa->sect_sa_n_alloc = count; sect_sa->sect_sa_list = NULL; if (count > 0) { sect_sa->sect_sa_section_number = section_index; sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc); if (sect_sa->sect_sa_list == NULL) { sect_sa->sect_sa_n_alloc = 0; return DW_DLV_ERROR; } } return DW_DLV_OK; } static int string_attr_add (Dwarf_P_Debug dbg, Dwarf_Signed section_index, Dwarf_Unsigned offset, Dwarf_P_Attribute attr) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) { unsigned n = sect_sa->sect_sa_n_used++; sect_sa->sect_sa_list[n].sa_offset = offset; sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes; return DW_DLV_OK; } return DW_DLV_ERROR; } int dwarf_get_string_attributes_count(Dwarf_P_Debug dbg, Dwarf_Unsigned * count_of_sa_sections, int *drd_buffer_version, UNUSEDARG Dwarf_Error *error) { int i = 0; unsigned int count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) { ++count; } } *count_of_sa_sections = (Dwarf_Unsigned) count; *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; return DW_DLV_OK; } int dwarf_get_string_attributes_info(Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *sect_sa_buffer_count, Dwarf_P_String_Attr *sect_sa_buffer, UNUSEDARG Dwarf_Error *error) { int i = 0; int next = dbg->de_sect_sa_next_to_return; for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i]; if (sect_sa->sect_sa_n_used > 0) { dbg->de_sect_sa_next_to_return = i + 1; *elf_section_index = sect_sa->sect_sa_section_number; *sect_sa_buffer_count = sect_sa->sect_sa_n_used; *sect_sa_buffer = sect_sa->sect_sa_list; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } static int has_sibling_die_already(Dwarf_P_Die d) { Dwarf_P_Attribute a = 0; for (a = d->di_attrs; a ; a = a->ar_next) { if (a->ar_attribute == DW_AT_sibling) { return TRUE; } } return FALSE; } /* For DW_FORM_strp we need to set the symindex so we need to check that such applies. */ static int if_relocatable_string_form(Dwarf_P_Debug dbg, Dwarf_P_Attribute curattr, int *debug_str_reloc, Dwarf_Error *error) { if (curattr->ar_rel_type == R_MIPS_NONE) { *debug_str_reloc = 0; return DW_DLV_OK; } if (curattr->ar_attribute_form != DW_FORM_strp) { _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); return DW_DLV_ERROR; } if (curattr->ar_rel_type != dbg->de_offset_reloc) { _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); return DW_DLV_ERROR; } *debug_str_reloc = 1; return DW_DLV_OK; } /* Tries to see if given attribute and form combination of the attr exists in the given abbreviation. abbrevs and attrs are sorted in attrnum order. */ static int _dwarf_pro_match_attr(Dwarf_P_Attribute attr, Dwarf_P_Abbrev abbrev, int no_attr) { int i = 0; Dwarf_P_Attribute curatp = attr; for (i = 0; i < no_attr && curatp; i++,curatp = curatp->ar_next ) { if (curatp->ar_attribute != abbrev->abb_attrs[i] || curatp->ar_attribute_form != abbrev->abb_forms[i]) { return 0; } /* If either is implicit_const need special check for matching val. */ if (curatp->ar_attribute_form == DW_FORM_implicit_const) { if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { if (curatp->ar_implicit_const != abbrev->abb_implicits[i]) { return 0; } } else { return 0; } } else { if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { return 0; } } } return 1; } static int verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s *sortab, int attrcount) { int k = 0; unsigned preva = 0; struct Dwarf_Sort_Abbrev_s *ab = sortab; if (attrcount < 2) { return DW_DLV_OK; } for (k = 0; k < attrcount; ++k,++ab) { if (k) { if (preva >= ab->dsa_attr) { return DW_DLV_ERROR; } } preva = ab->dsa_attr; } return DW_DLV_OK; } static int abcompare(const void *l_in, const void *r_in) { struct Dwarf_Sort_Abbrev_s *l = (struct Dwarf_Sort_Abbrev_s *)l_in; struct Dwarf_Sort_Abbrev_s *r = (struct Dwarf_Sort_Abbrev_s *)r_in; if (l->dsa_attr < r->dsa_attr) { return -1; } if (l->dsa_attr > r->dsa_attr) { return +1; } /* ASSERT: This never happens in correct dwarf. */ return 0; } /* Handles abbreviations. It takes a die, searches through current list of abbreviations for a matching one. If it finds one, it returns a pointer to the abbrev through the ab_out pointer, and if it does not, it returns a new abbrev through the ab_out pointer. The die->die_attrs are sorted by attribute and the curabbrev attrs are too. It is up to the user of this function to link it up to the abbreviation head. If it is a new abbrev abb_idx has 0. */ static int _dwarf_pro_getabbrev(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_P_Abbrev head, Dwarf_P_Abbrev*ab_out,Dwarf_Error *error) { Dwarf_P_Abbrev curabbrev = 0; Dwarf_P_Attribute curattr = 0; int match = 0; Dwarf_Unsigned *forms = 0; Dwarf_Unsigned *attrs = 0; Dwarf_Signed *implicits = 0; int attrcount = die->di_n_attr; curabbrev = head; /* Loop thru the currently known abbreviations needed to see if we can share an existing abbrev. */ while (curabbrev) { if ((die->di_tag == curabbrev->abb_tag) && ((die->di_child != NULL && curabbrev->abb_children == DW_CHILDREN_yes) || (die->di_child == NULL && curabbrev->abb_children == DW_CHILDREN_no)) && (attrcount == curabbrev->abb_n_attr)) { /* There is a chance of a match, basic characterists match. Now Check the attrs and forms. */ curattr = die->di_attrs; match = _dwarf_pro_match_attr(curattr, curabbrev, (int) curabbrev->abb_n_attr); if (match == 1) { /* This tag/children/abbrev-list matches the incoming die needs exactly. Reuse this abbreviation. */ *ab_out = curabbrev; return DW_DLV_OK; } } curabbrev = curabbrev->abb_next; } /* no match, create new abbreviation */ if (attrcount) { forms = (Dwarf_Unsigned *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Unsigned) * attrcount); if (forms == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } attrs = (Dwarf_Unsigned *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Unsigned) * attrcount); if (attrs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } implicits = (Dwarf_Signed *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Signed) * attrcount); if (implicits == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } } curattr = die->di_attrs; if (forms && attrs && attrcount) { struct Dwarf_Sort_Abbrev_s *sortab = 0; struct Dwarf_Sort_Abbrev_s *ap = 0; int k = 0; int res = 0; sortab = (struct Dwarf_Sort_Abbrev_s *) malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); if (!sortab) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } /* ASSERT curattr->ar_next chain length == attrcount */ ap = sortab; for ( ; curattr; ++ap, curattr = curattr->ar_next) { ap->dsa_attr = curattr->ar_attribute; ap->dsa_form = curattr->ar_attribute_form; ap->dsa_implicitvalue = curattr->ar_implicit_const; ap->dsa_attrp = 0; } qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), abcompare); ap = sortab; k = 0; res = verify_ab_no_dups(sortab,attrcount); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg,DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR); } for ( ; k < attrcount; ++k,++ap) { attrs[k] = ap->dsa_attr; forms[k] = ap->dsa_form; implicits[k] = ap->dsa_implicitvalue; } free(sortab); } curabbrev = (Dwarf_P_Abbrev) _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); if (curabbrev == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } if (die->di_child == NULL) { curabbrev->abb_children = DW_CHILDREN_no; } else { curabbrev->abb_children = DW_CHILDREN_yes; } curabbrev->abb_tag = die->di_tag; curabbrev->abb_attrs = attrs; curabbrev->abb_forms = forms; curabbrev->abb_implicits = implicits; curabbrev->abb_n_attr = attrcount; curabbrev->abb_idx = 0; curabbrev->abb_next = NULL; *ab_out = curabbrev; return DW_DLV_OK; } /* Generate debug_info and debug_abbrev sections */ /* DWARF 2,3,4 */ static int generate_debuginfo_header_2(Dwarf_P_Debug dbg, unsigned *abbrev_offset_io, unsigned char **data_io, int *cu_header_size_out, Dwarf_Small **abbr_off_ptr_out, Dwarf_Half version, int extension_size, Dwarf_Ubyte address_size, Dwarf_Error * error) { unsigned abbrev_offset = 0; unsigned char * data = 0; int offset_size = dbg->de_dwarf_offset_size; int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; int cu_header_size = 0; Dwarf_Unsigned du = 0; Dwarf_Small *abbr_off_ptr = 0; /* write cu header. abbrev_offset used to generate relocation record below */ abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + DWARF_HALF_SIZE ; cu_header_size = abbrev_offset + offset_size + sizeof(Dwarf_Ubyte); GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, error); if (extension_size) { /* This for a dwarf-standard 64bit offset. */ DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } abbr_off_ptr = data; du = 0; /* length of debug_info, not counting this field itself (unknown at this point). */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, sizeof(version), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; du = 0;/* offset into abbrev table, not yet known. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, sizeof(address_size), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); /* We have filled the chunk we got with GET_CHUNK. At this point we no longer dare use "data" as a pointer any longer except to refer to that first small chunk for the cu header to update the section length. */ *abbrev_offset_io = abbrev_offset; *data_io = data; *cu_header_size_out = cu_header_size; *abbr_off_ptr_out = abbr_off_ptr; return DW_DLV_OK; } /* DWARF 5 */ static int generate_debuginfo_header_5(Dwarf_P_Debug dbg, unsigned *abbrev_offset_io, unsigned char **data_io, int *cu_header_size_out, Dwarf_Small **abbr_off_ptr_out, Dwarf_Half version, Dwarf_Ubyte unit_type, int extension_size, Dwarf_Ubyte address_size, Dwarf_Error *error) { int offset_size = dbg->de_dwarf_offset_size; unsigned abbrev_offset = 0; unsigned char * data = 0; int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; int cu_header_size = 0; Dwarf_Unsigned du = 0; Dwarf_Small *abbr_off_ptr = 0; /* write cu header. abbrev_offset used to generate relocation record below */ abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + DWARF_HALF_SIZE + /* version stamp */ sizeof(unit_type) + sizeof(Dwarf_Ubyte); cu_header_size = abbrev_offset + offset_size; GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, error); if (extension_size) { /* Impossible in DW5, really, is for IRIX64. But we allow it. */ DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } abbr_off_ptr = data; du = 0; /* length of debug_info, not counting this field itself (unknown at this point). */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, sizeof(version), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &unit_type, sizeof(unit_type), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, sizeof(address_size), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); du = 0;/* offset into abbrev table, not yet known. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* We have filled the chunk we got with GET_CHUNK. At this point we no longer dare use "data" as a pointer any longer except to refer to that first small chunk for the cu header to update the section length. */ *abbrev_offset_io = abbrev_offset; *data_io = data; *cu_header_size_out = cu_header_size; *abbr_off_ptr_out = abbr_off_ptr; return DW_DLV_OK; } /* Write out debug_abbrev section */ static int write_out_debug_abbrev(Dwarf_P_Debug dbg, Dwarf_P_Abbrev abbrev_head, Dwarf_Error * error) { Dwarf_P_Abbrev curabbrev = abbrev_head; unsigned char *data = 0; int res = 0; int abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; while (curabbrev) { int idx = 0; unsigned lebcount = 0; Dwarf_Ubyte db = 0; res = write_uval(curabbrev->abb_idx,dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } res = write_uval(curabbrev->abb_tag,dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } db = curabbrev->abb_children; res = write_ubyte(db,dbg,abbrevsectno,&lebcount,error); if (res != DW_DLV_OK) { return res; } /* add attributes and forms */ for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { res =write_uval(curabbrev->abb_attrs[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } res =write_uval(curabbrev->abb_forms[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } if (curabbrev->abb_forms[idx] == DW_FORM_implicit_const){ res =write_sval(curabbrev->abb_implicits[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } } } /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */ GET_CHUNK_ERR(dbg, abbrevsectno, data, 2, error); *data = 0; data++; *data = 0; curabbrev = curabbrev->abb_next; } /* one zero, for end of cu, see dwarf2 sec 7.5.3 */ GET_CHUNK_ERR(dbg, abbrevsectno, data, 1, error); *data = 0; return DW_DLV_OK; } static int sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die, Dwarf_Error *error) { struct Dwarf_Sort_Abbrev_s *sortab = 0; struct Dwarf_Sort_Abbrev_s *ap = 0; Dwarf_P_Attribute at = 0; Dwarf_P_Attribute sorted_attrlist = 0; Dwarf_P_Attribute sorted_tail = 0; int attrcount = die->di_n_attr; int res = 0; unsigned ct = 0; int k = 0; if (attrcount < 2) { return DW_DLV_OK; } sortab = (struct Dwarf_Sort_Abbrev_s *) malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); if (!sortab) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } /* ASSERT at->ar_next chain length == attrcount */ ap = sortab; at = die->di_attrs; for ( ; at; ++ap, at = at->ar_next) { ap->dsa_attr = at->ar_attribute; ap->dsa_form = at->ar_attribute_form; ap->dsa_attrp = at; ++ct; } qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), abcompare); res = verify_ab_no_dups(sortab,attrcount); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR); } ap = sortab; k = 0; for ( ; k < attrcount; ++k,++ap) { Dwarf_P_Attribute localptr = ap->dsa_attrp; if (!sorted_attrlist) { sorted_attrlist = localptr; sorted_tail = sorted_attrlist; localptr->ar_next = 0; continue; } sorted_tail->ar_next = localptr; sorted_tail = localptr; localptr->ar_next = 0; } /* Now replace the list with the same pointers but in order sorted by attribute. */ die->di_attrs = sorted_attrlist; free(sortab); return DW_DLV_OK; } static int _dwarf_pro_generate_debugsup(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno = 0; unsigned char *data = 0; Dwarf_Half version = 0; unsigned int uleblen = 0; int leblen = 0; unsigned i = 0; unsigned name_len = 0; Dwarf_Unsigned alloc_size = 0; int res = 0; elfsectno = dbg->de_elf_sects[DEBUG_SUP]; res = pretend_write_uval(dbg->de_debug_sup.ds_checksum_len, dbg, &uleblen,error); if (res != DW_DLV_OK) { return res; } version = dbg->de_debug_sup.ds_version; name_len = strlen(dbg->de_debug_sup.ds_filename) +1; alloc_size = DWARF_HALF_SIZE + 1 + name_len + uleblen + dbg->de_debug_sup.ds_checksum_len; GET_CHUNK_ERR(dbg, elfsectno, data, alloc_size, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *)&version, DWARF_HALF_SIZE, DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; *data = dbg->de_debug_sup.ds_is_supplementary; ++data; for (i = 0 ; i < name_len ; ++i,++data) { *data = *(unsigned char *)(dbg->de_debug_sup.ds_filename +i); } res = _dwarf_pro_encode_leb128_nm( dbg->de_debug_sup.ds_checksum_len, &leblen, (char *)data,(int)uleblen); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUG_SUP_ERROR, DW_DLV_ERROR); } data += uleblen; memcpy(data,dbg->de_debug_sup.ds_checksum, dbg->de_debug_sup.ds_checksum_len); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_info = 0; unsigned char *data = 0; int cu_header_size = 0; Dwarf_P_Abbrev curabbrev = 0; Dwarf_P_Abbrev abbrev_head = 0; Dwarf_P_Abbrev abbrev_tail = 0; Dwarf_P_Die curdie = 0; Dwarf_P_Die first_child = 0; Dwarf_Unsigned dw = 0; Dwarf_Unsigned du = 0; Dwarf_Half dh = 0; Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ int n_abbrevs = 0; unsigned abbrev_offset = 0; int res = 0; unsigned marker_count = 0; unsigned string_attr_count = 0; unsigned string_attr_offset = 0; Dwarf_Small *abbr_off_ptr = 0; int offset_size = dbg->de_dwarf_offset_size; /* extension_size is oddly names. The standard calls for a 64bit offset to have a 4 byte 0xffff while original IRIX64 did not. So if dbg->de_64bit_extension set this is a standard DWARF 64bit offset and if de_64bit_extension not set this is non-standard IRIX64 64 bit offset. */ Dwarf_Half version = dbg->de_output_version; int extension_size = dbg->de_64bit_extension ? 4 : 0; /* For now just assume DW_UT_compile FIXME */ Dwarf_Ubyte unit_type = DW_UT_compile; Dwarf_Ubyte address_size = 0; elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; address_size = dbg->de_pointer_size; if (version < 5) { res = generate_debuginfo_header_2(dbg, &abbrev_offset, &data, &cu_header_size, &abbr_off_ptr, version, extension_size, address_size, error); if (res != DW_DLV_OK) { return res; } } else if (version == 5) { res = generate_debuginfo_header_5(dbg, &abbrev_offset, &data, &cu_header_size, &abbr_off_ptr, version, unit_type, extension_size, address_size, error); if (res != DW_DLV_OK) { return res; } } else { DWARF_P_DBG_ERROR(dbg, DW_DLE_VERSION_STAMP_ERROR, DW_DLV_ERROR); } curdie = dbg->de_dies; /* Create AT_macro_info if appropriate */ if (version < 5) { if (dbg->de_first_macinfo != NULL) { res = _dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error); if (res != DW_DLV_OK) { return res; } } } else { /* FIXME need to add code to emit DWARF5 macro data. */ #if 0 res = _dwarf_pro_add_AT_macro5_info(dbg, curdie, 0, error); #endif } /* Create AT_stmt_list attribute if necessary */ if (dwarf_need_debug_line_section(dbg) == TRUE) { res =_dwarf_pro_add_AT_stmt_list(dbg, curdie, error); if (res != DW_DLV_OK) { return res; } } die_off = cu_header_size; /* Relocation for abbrev offset in cu header store relocation record in linked list */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_INFO, abbrev_offset /* r_offset */, dbg->de_sect_name_idx[DEBUG_ABBREV], dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 0: only top level dies, add at_sibling attribute to those dies with children, but if and only if there is no sibling attribute already. */ first_child = curdie->di_child; while (first_child && first_child->di_right) { if (first_child->di_child) { if (!has_sibling_die_already(first_child)) { dwarf_add_AT_reference(dbg, first_child, DW_AT_sibling, first_child->di_right, error); } } first_child = first_child->di_right; } /* Pass 1: create abbrev info, get die offsets, calc relocations */ abbrev_head = abbrev_tail = NULL; marker_count = 0; string_attr_count = 0; while (curdie != NULL) { int nbytes = 0; Dwarf_P_Attribute curattr = 0; char *space = 0; int cres = 0; char buff1[ENCODE_SPACE_NEEDED]; curdie->di_offset = die_off; if (curdie->di_marker != 0) { marker_count++; } cres =sort_die_attrs(dbg,curdie,error); if (cres != DW_DLV_OK) { /* DW_DLV_NO_ENTRY is impossible. */ return cres; } /* Find or create a final abbrev record for the debug_abbrev section we will write (below). */ cres = _dwarf_pro_getabbrev(dbg,curdie, abbrev_head,&curabbrev,error); if (cres != DW_DLV_OK) { return cres; } if (abbrev_head == NULL) { n_abbrevs = 1; curabbrev->abb_idx = n_abbrevs; abbrev_tail = abbrev_head = curabbrev; } else { /* Check if it is a new abbreviation, if yes, add to tail */ if (curabbrev->abb_idx == 0) { n_abbrevs++; curabbrev->abb_idx = n_abbrevs; abbrev_tail->abb_next = curabbrev; abbrev_tail = curabbrev; } } /* We know the abbrev number to use now. So create the bytes of the leb with the value and save those bytes in di_abbrev, we will emit in Pass 2 (below). */ cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, buff1, sizeof(buff1)); if (cres != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } space = _dwarf_p_get_alloc(dbg, nbytes); if (space == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } memcpy(space, buff1, nbytes); curdie->di_abbrev = space; curdie->di_abbrev_nbytes = nbytes; die_off += nbytes; /* The abbrev and DIE attr lists match, so the die abbrevs are in the correct order, curdie->di_attrs. */ /* Now we attach the attributes list to the die. */ curattr = curdie->di_attrs; while (curattr) { if (curattr->ar_rel_type != R_MIPS_NONE) { int rres=0; switch (curattr->ar_attribute) { case DW_AT_stmt_list: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_LINE]; break; case DW_AT_MIPS_fde: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_FRAME]; break; case DW_AT_macro_info: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_MACINFO]; break; /* See also: pro_forms.c for same strings attribute list. */ case DW_AT_comp_dir: case DW_AT_const_value: case DW_AT_linkage_name: /* DWARF5 */ case DW_AT_MIPS_abstract_name: case DW_AT_MIPS_linkage_name: case DW_AT_name: case DW_AT_producer: { int is_debug_str = 0; int nres = if_relocatable_string_form(dbg,curattr, &is_debug_str,error); if (nres != DW_DLV_OK) { return res; } if (is_debug_str) { curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_STR]; } } break; default: break; } rres = dbg->de_relocate_by_name_symbol(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,/* r_offset */ curattr->ar_rel_symidx, dwarf_drt_data_reloc, curattr->ar_reloc_len); if (rres != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } } if (curattr->ar_attribute_form == DW_FORM_string) { string_attr_count++; } die_off += curattr->ar_nbytes; curattr = curattr->ar_next; } /* Depth first access to all the DIEs. */ if (curdie->di_child) { curdie = curdie->di_child; } else { while (curdie != NULL && curdie->di_right == NULL) { curdie = curdie->di_parent; /* See -nonrootsibling- below */ if (curdie != NULL) { die_off++; } } if (curdie != NULL) { curdie = curdie->di_right; } } } /* end while (curdie != NULL), the per-die loop */ res = marker_init(dbg, marker_count); if (res == DW_DLV_ERROR) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } res = string_attr_init(dbg, DEBUG_INFO, string_attr_count); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 2: Write out the die information Here 'data' is a temporary, one block for each GET_CHUNK. 'data' is overused. */ curdie = dbg->de_dies; while (curdie != NULL) { Dwarf_P_Attribute curattr; if (curdie->di_marker != 0) { res = marker_add(dbg, curdie->di_offset, curdie->di_marker); if (res == DW_DLV_ERROR) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } } /* Index to abbreviation table */ GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, curdie->di_abbrev_nbytes, error); memcpy((void *) data, (const void *) curdie->di_abbrev, curdie->di_abbrev_nbytes); /* Attribute values - need to fill in all form attributes */ curattr = curdie->di_attrs; string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes; while (curattr) { GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, (unsigned long) curattr->ar_nbytes, error); switch (curattr->ar_attribute_form) { case DW_FORM_ref1: { Dwarf_Ubyte db = 0; if (curattr->ar_ref_die->di_offset > (unsigned) 0xff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } db = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); break; } case DW_FORM_ref2: { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } dh = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, sizeof(dh), DWARF_HALF_SIZE); break; } case DW_FORM_ref_addr: { /* curattr->ar_ref_die == NULL! DW_FORM_ref_addr doesn't take a CU-offset. This is different than other refs. This value will be set by the user of the producer library using a relocation. No need to set a value here. */ break; } case DW_FORM_ref4: { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffffffff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dw, sizeof(dw), DWARF_32BIT_SIZE); break; } case DW_FORM_ref8: du = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), DWARF_64BIT_SIZE); break; case DW_FORM_ref_udata: { /* unsigned leb128 offset */ int nbytesx; char buff1[ENCODE_SPACE_NEEDED]; res = _dwarf_pro_encode_leb128_nm(curattr-> ar_ref_die-> di_offset, &nbytesx, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } memcpy(data, buff1, nbytesx); break; } default: if (curattr->ar_nbytes) { memcpy((void *) data, (const void *) curattr->ar_data, curattr->ar_nbytes); } break; } if (curattr->ar_attribute_form == DW_FORM_string) { string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr); } string_attr_offset += curattr->ar_nbytes; curattr = curattr->ar_next; } /* depth first search */ if (curdie->di_child) { curdie = curdie->di_child; } else { while (curdie != NULL && curdie->di_right == NULL) { /* -nonrootsibling- A null die should only be written for terminating siblings, not the root. Adding a terminating die for the root will cause, after object files are linked, warnings to be generated with newer versions of readelf. */ if (!curdie->di_parent) { /* The parent is not a DIE so ending a sibling chain makes no sense (wastes a byte). */ break; } GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, 1, error); *data = '\0'; curdie = curdie->di_parent; } if (curdie != NULL) curdie = curdie->di_right; } } /* end while (curdir != NULL) */ /* Write out debug_info size, now that we know it This is back-patching the CU header we created above. */ du = die_off - OFFSET_PLUS_EXTENSION_SIZE; WRITE_UNALIGNED(dbg, (void *) abbr_off_ptr, (const void *) &du, sizeof(du), offset_size); data = 0; /* Emphasize not usable now */ res = write_out_debug_abbrev(dbg, abbrev_head, error); if (res != DW_DLV_OK) { return res; } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed *nbufs, Dwarf_Error * error UNUSEDARG) { #if 0 int elfsectno_of_debug_names = dbg->de_elf_sects[DEBUG_NAMES]; FIXME: Needs implementation unsigned char *data = 0; GET_CHUNK(dbg, elfsectno_of_debug_names, data, dbg->de_debug_names->ds_nbytes, error); memcpy(data,dbg->de_debug_names->ds_data, dbg->de_debug_names->ds_nbytes); #endif *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_str = 0; unsigned char *data = 0; elfsectno_of_debug_str = dbg->de_elf_sects[DEBUG_STR]; GET_CHUNK(dbg, elfsectno_of_debug_str, data, dbg->de_debug_str->ds_nbytes,error); memcpy(data,dbg->de_debug_str->ds_data, dbg->de_debug_str->ds_nbytes); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_line_str = 0; unsigned char *data = 0; elfsectno_of_debug_line_str = dbg->de_elf_sects[DEBUG_LINE_STR]; GET_CHUNK(dbg, elfsectno_of_debug_line_str, data, dbg->de_debug_line_str->ds_nbytes, error); memcpy(data,dbg->de_debug_line_str->ds_data, dbg->de_debug_line_str->ds_nbytes); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* Get a buffer of section data. section_idx is the elf-section number that this data applies to. length shows length of returned data This is the original format. Hard to check for error. */ /*ARGSUSED*/ /* pretend all args used */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed dwarf_section, Dwarf_Signed * section_idx, Dwarf_Unsigned * length, Dwarf_Error * error) { Dwarf_Ptr s_bytes = 0; int res = 0; res = dwarf_get_section_bytes_a(dbg, dwarf_section, section_idx, length, &s_bytes, error); if (res == DW_DLV_ERROR) { return (Dwarf_Ptr)DW_DLV_BADADDR; } if (res == DW_DLV_NO_ENTRY) { return NULL; } return s_bytes; } /* Get a buffer of section data. section_idx is the elf-section number that this data applies to. length shows length of returned data This is the September 2016 format. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed dwarf_section, Dwarf_Signed * section_idx, Dwarf_Unsigned * length, Dwarf_Ptr * section_bytes, Dwarf_Error * error) { Dwarf_Ptr buf = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } *section_bytes = 0; *length = 0; if (dbg->de_debug_sects == 0) { /* no more data !! */ return DW_DLV_NO_ENTRY; } if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { /* no data ever entered !! */ return DW_DLV_NO_ENTRY; } *section_idx = dbg->de_debug_sects->ds_elf_sect_no; *length = dbg->de_debug_sects->ds_nbytes; buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; /* Here is the iterator so the next call gets the next section. */ dbg->de_debug_sects = dbg->de_debug_sects->ds_next; /* We may want to call the section stuff more than once: see dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ *section_bytes = buf; return DW_DLV_OK; } /* No errors possible. */ void dwarf_reset_section_bytes(Dwarf_P_Debug dbg) { dbg->de_debug_sects = dbg->de_first_debug_sect; /* No need to reset; commented out decrement. dbg->de_n_debug_sect = ???; */ dbg->de_reloc_next_to_return = 0; dbg->de_sect_sa_next_to_return = 0; } /* Storage handler. Gets either a new chunk of memory, or a pointer in existing memory, from the linked list attached to dbg at de_debug_sects, depending on size of nbytes Assume dbg not null, checked in top level routine Returns a pointer to the allocated buffer space for the lib to fill in, predincrements next-to-use count so the space requested is already counted 'used' when this returns (ie, reserved). */ Dwarf_Small * _dwarf_pro_buffer(Dwarf_P_Debug dbg, int elfsectno, unsigned long nbytes) { Dwarf_P_Section_Data cursect = 0; cursect = dbg->de_current_active_section; /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must not match any legit section number. test to have just two clauses (no NULL pointer test) See dwarf_producer_init(). */ if ((cursect->ds_elf_sect_no != elfsectno) || ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc) ) { /* Either the elf section has changed or there is not enough space in the current section. Create a new Dwarf_P_Section_Data_s for the chunk. and have space 'on the end' for the buffer itself so we just do one malloc (not two). */ unsigned long space = nbytes; if (nbytes < CHUNK_SIZE) space = CHUNK_SIZE; cursect = (Dwarf_P_Section_Data) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Section_Data_s) + space); if (cursect == NULL) { return (NULL); } /* _dwarf_p_get_alloc zeroes the space... */ cursect->ds_data = (char *) cursect + sizeof(struct Dwarf_P_Section_Data_s); cursect->ds_orig_alloc = space; cursect->ds_elf_sect_no = elfsectno; cursect->ds_nbytes = nbytes;/* reserve this number of bytes of space for caller to fill in */ /* Now link on the end of the list, and mark this one as the current one */ if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { /* The only entry is the special one for 'no entry' so delete that phony one while adding this initial real one. */ dbg->de_debug_sects = cursect; dbg->de_current_active_section = cursect; dbg->de_first_debug_sect = cursect; } else { dbg->de_current_active_section->ds_next = cursect; dbg->de_current_active_section = cursect; } dbg->de_n_debug_sect++; return ((Dwarf_Small *) cursect->ds_data); } /* There is enough space in the current buffer */ { Dwarf_Small *space_for_caller = (Dwarf_Small *) (cursect->ds_data + cursect->ds_nbytes); cursect->ds_nbytes += nbytes; return space_for_caller; } } libdwarf-20210528/libdwarf/pro_reloc_symbolic.h0000644000175000017500000000314713743575426016347 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); libdwarf-20210528/libdwarf/dwarf_line.c0000664000175000017500000022315014053206635014553 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarfstring.h" #include "dwarf_debuglink.h" /* Line Register Set initial conditions. */ static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = { /* Dwarf_Addr lr_address */ 0, /* Dwarf_Unsigned lr_file */ 1, /* Dwarf_Unsigned lr_line */ 1, /* Dwarf_Unsigned lr_column */ 0, /* Dwarf_Bool lr_is_stmt */ false, /* Dwarf_Bool lr_basic_block */ false, /* Dwarf_Bool lr_end_sequence */ false, /* Dwarf_Bool lr_prologue_end */ false, /* Dwarf_Bool lr_epilogue_begin */ false, /* Dwarf_Small lr_isa */ 0, /* Dwarf_Unsigned lr_op_index */ 0, /* Dwarf_Unsigned lr_discriminator */ 0, /* Dwarf_Unsigned lr_call_context */ 0, /* Dwarf_Unsigned lr_subprogram */ 0, }; void _dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs, UNUSEDARG unsigned lineversion, Dwarf_Bool is_stmt) { *regs = _dwarf_line_table_regs_default_values; if (lineversion == DW_LINE_VERSION5) { /* In DWARF5 change the default this way. We are ignoring the DWARF5 Section 2.14 considering 0 a special value meaning no file. The DWARF5 standard is self-contradictory on this, considered as a whole. So with default 0 and numbering files from 0 things work ok. */ regs->lr_file = 0; } regs->lr_is_stmt = is_stmt; } static int is_path_separator(Dwarf_Small s) { if (s == '/') { return 1; } #ifdef HAVE_WINDOWS_PATH if (s == '\\') { return 1; } #endif return 0; } /* Return 0 if false, 1 if true. If HAVE_WINDOWS_PATH is defined we attempt to handle windows full paths: \\something or C:cwdpath.c */ int _dwarf_file_name_is_full_path(Dwarf_Small *fname) { Dwarf_Small firstc = *fname; if (is_path_separator(firstc)) { /* Full path. */ return 1; } if (!firstc) { return 0; } /* This is a windows path test, but we do have a few windows paths in our regression tests... This is extremely unlikely to cause UN*X/POSIX users any problems. */ if ((firstc >= 'A' && firstc <= 'Z') || (firstc >= 'a' && firstc <= 'z')) { Dwarf_Small secondc = fname[1]; if (secondc == ':') { return 1; } } /* End Windows style */ return 0; } #include "dwarf_line_table_reader_common.h" /* With this routine we ensure the file full path is calculated identically for dwarf_srcfiles() and dwarf_filename() As of March 14 2020 this *always* does an allocation for the string. dwarf_dealloc is crucial to do no matter what. So we have consistency. dwarf_finish() will do the dealloc if nothing else does. Unless the calling application did the call dwarf_set_de_alloc_flag(0). _dwarf_pathjoinl() takes care of / and Windows \ */ static int create_fullest_file_path(Dwarf_Debug dbg, Dwarf_File_Entry fe, Dwarf_Line_Context line_context, char ** name_ptr_out, Dwarf_Error *error) { Dwarf_Unsigned dirno = 0; char *full_name = 0; char *file_name = 0; /* Large enough that almost never will any malloc be needed by dwarfstring. Arbitrary size. */ static char targbuf[300]; static char nbuf[300]; dwarfstring targ; dwarfstring nxt; unsigned linetab_version = line_context->lc_version_number; dirno = fe->fi_dir_index; file_name = (char *) fe->fi_file_name; if (!file_name) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return DW_DLV_ERROR; } if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) { char *tmp = 0; dwarfstring_constructor_static(&targ, targbuf,sizeof(targbuf)); dwarfstring_constructor_static(&nxt, nbuf,sizeof(nbuf)); dwarfstring_append(&nxt,file_name); _dwarf_pathjoinl(&targ,&nxt); tmp = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, dwarfstring_strlen(&targ)+1); if (tmp) { strcpy(tmp,dwarfstring_string(&targ)); *name_ptr_out = tmp; dwarfstring_destructor(&targ); dwarfstring_destructor(&nxt); return DW_DLV_OK; } dwarfstring_destructor(&targ); dwarfstring_destructor(&nxt); _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } { int need_dir = FALSE; unsigned include_dir_offset = 1; static char compdirbuf[300]; static char incdirbuf[300]; static char filenamebuf[300]; dwarfstring compdir; dwarfstring incdir; dwarfstring filename; dwarfstring_constructor_static(&targ, targbuf,sizeof(targbuf)); dwarfstring_constructor_static(&compdir, compdirbuf,sizeof(compdirbuf)); dwarfstring_constructor_static(&incdir, incdirbuf,sizeof(incdirbuf)); dwarfstring_constructor_static(&filename, filenamebuf,sizeof(filenamebuf)); if (line_context->lc_compilation_directory) { char * comp_dir_name = (char *)line_context->lc_compilation_directory; dwarfstring_append(&compdir,comp_dir_name); } if (dirno > line_context->lc_include_directories_count) { dwarfstring_destructor(&targ); dwarfstring_destructor(&incdir); dwarfstring_destructor(&compdir); dwarfstring_destructor(&filename); _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD); return DW_DLV_ERROR; } if (linetab_version == DW_LINE_VERSION5) { include_dir_offset = 0; need_dir = TRUE; } else if (dirno > 0 && fe->fi_dir_index > 0) { include_dir_offset = 1; need_dir = TRUE; } if (need_dir) { char *inc_dir_name = (char *)line_context->lc_include_directories[ fe->fi_dir_index - include_dir_offset]; if (!inc_dir_name) { /* This should never ever happen except in case of a corrupted object file. */ inc_dir_name = ""; } dwarfstring_append(&incdir,inc_dir_name); } dwarfstring_append(&filename,file_name); if (dwarfstring_strlen(&incdir) > 0 && _dwarf_file_name_is_full_path( (Dwarf_Small*)dwarfstring_string(&incdir))) { _dwarf_pathjoinl(&targ,&incdir); _dwarf_pathjoinl(&targ,&filename); } else { if (dwarfstring_strlen(&compdir) > 0) { _dwarf_pathjoinl(&targ,&compdir); } if (dwarfstring_strlen(&incdir) > 0) { _dwarf_pathjoinl(&targ,&incdir); } _dwarf_pathjoinl(&targ,&filename); } full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, dwarfstring_strlen(&targ) +1); if (!full_name) { dwarfstring_destructor(&targ); dwarfstring_destructor(&incdir); dwarfstring_destructor(&compdir); dwarfstring_destructor(&filename); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } strcpy(full_name,dwarfstring_string(&targ)); *name_ptr_out = full_name; dwarfstring_destructor(&targ); dwarfstring_destructor(&incdir); dwarfstring_destructor(&compdir); dwarfstring_destructor(&filename); } return DW_DLV_OK; } static void report_bogus_stmt_list_form(Dwarf_Debug dbg, Dwarf_Half attrform, Dwarf_Error *error) { dwarfstring m; dwarfstring f; const char *formname = 0; dwarfstring_constructor(&f); dwarf_get_FORM_name(attrform,&formname); if (!formname) { dwarfstring_append_printf_u(&f,"Invalid Form Code " " 0x" DW_PR_DUx,attrform); } else { dwarfstring_append(&f,(char *)formname); } dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_LINE_OFFSET_WRONG_FORM: form %s " "instead of an allowed section offset form.", dwarfstring_string(&f)); _dwarf_error_string(dbg, error, DW_DLE_LINE_OFFSET_WRONG_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); dwarfstring_destructor(&f); } /* Although source files is supposed to return the source files in the compilation-unit, it does not look for any in the statement program. In other words, it ignores those defined using the extended opcode DW_LNE_define_file. We do not know of a producer that uses DW_LNE_define_file. In DWARF2,3,4 the array of sourcefiles is represented differently than DWARF5. DWARF 2,3,4, and experimental line table: Subtract 1 from the DW_AT_decl_file etc to index into the array of names. zero means there is no file. DWARF 5: DW_AT_decl_file etc numbers should be directly used to index into the array of names. Do not subtract anything. For further information see the discussion of dwarf_srcfiles() in libdwarf2.1.pdf version 3.16 and later, Section 6.14 around page 117. */ int dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed * srcfilecount, Dwarf_Error * error) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; const char * const_comp_name = 0; /* Pointer to name of compilation directory. */ const char * const_comp_dir = 0; Dwarf_Small *comp_dir = 0; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; /* This points to a block of char *'s, each of which points to a file name. */ char **ret_files = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; Dwarf_CU_Context context = 0; Dwarf_Line_Context line_context = 0; /* Used to chain the file names. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Half attrform = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; unsigned i = 0; int res = DW_DLV_ERROR; Dwarf_Small *section_start = 0; /* ***** BEGIN CODE ***** */ /* Reset error. */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } if (dbg->de_debug_line.dss_index == 0) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return res; } if (!dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return DW_DLV_NO_ENTRY; } section_start = dbg->de_debug_line.dss_data; lres = dwarf_whatform(stmt_list_attr,&attrform,error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (attrform == DW_FORM_addr) { Dwarf_Addr addr = 0; /* DW_AT_producer 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2.9) generated DW_FORM_addr for DW_AT_stmt_list! */ lres = dwarf_formaddr(stmt_list_attr,&addr,error); if (lres != DW_DLV_OK) { if (lres == DW_DLV_ERROR) { report_bogus_stmt_list_form(dbg, attrform,error); dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); } return lres; } line_offset = (Dwarf_Unsigned)addr; } else if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 && attrform != DW_FORM_sec_offset && attrform != DW_FORM_GNU_ref_alt) { report_bogus_stmt_list_form(dbg, attrform,error); dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return DW_DLV_ERROR; } else { /* standard setup. */ lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } } if (line_offset >= dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } line_ptr = dbg->de_debug_line.dss_data + line_offset; { Dwarf_Unsigned fission_offset = 0; Dwarf_Unsigned fission_size = 0; int resl = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if (resl != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resl; } line_ptr += fission_offset; if (line_ptr > dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); return DW_DLV_ERROR; } } dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); stmt_list_attr = 0; resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir, &const_comp_name,error); if (resattr == DW_DLV_ERROR) { return resattr; } /* Horrible cast away const to match historical interfaces. */ comp_dir = (Dwarf_Small *)const_comp_dir; line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } line_context->lc_new_style_access = false; /* We are in dwarf_srcfiles() */ { Dwarf_Small *line_ptr_out = 0; int dres = 0; dres = _dwarf_read_line_table_header(dbg, context, section_start, line_ptr, dbg->de_debug_line.dss_size, &line_ptr_out, line_context, NULL, NULL,error, 0); if (dres == DW_DLV_ERROR) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return dres; } if (dres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return dres; } } /* For DWARF5, use of DW_AT_comp_dir not needed. Line table file names and directories start with comp_dir and name. */ line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_srcfiles() */ { Dwarf_File_Entry fe = 0; Dwarf_File_Entry fe2 =line_context->lc_file_entries; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; res = dwarf_srclines_files_indexes(line_context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } for (i = baseindex; i < endindex; ++i,fe2 = fe->fi_next ) { int sres = 0; char *name_out = 0; fe = fe2; sres = create_fullest_file_path(dbg,fe,line_context, &name_out,error); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); /* This can leak some strings */ return sres; } curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_chain->ch_item = name_out; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } } if (!head_chain) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); *srcfiles = NULL; *srcfilecount = 0; return DW_DLV_NO_ENTRY; } /* We are in dwarf_srcfiles() */ if (line_context->lc_file_entry_count == 0) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); *srcfiles = NULL; *srcfilecount = 0; return DW_DLV_NO_ENTRY; } ret_files = (char **) _dwarf_get_alloc(dbg, DW_DLA_LIST, line_context->lc_file_entry_count); if (ret_files == NULL) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_chain = head_chain; for (i = 0; i < line_context->lc_file_entry_count; i++) { *(ret_files + i) = curr_chain->ch_item; curr_chain->ch_item = 0; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } /* Our chain is not recorded in the line_context so the line_context destructor will not destroy our list of strings or our strings. Our caller has to do the deallocations. */ *srcfiles = ret_files; *srcfilecount = line_context->lc_file_entry_count; dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); return DW_DLV_OK; } /* Return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR doaddrs is true iff this is being called for SGI IRIX rqs processing (ie, not a normal libdwarf dwarf_srclines or two-level user call at all). dolines is true iff this is called by a dwarf_srclines call. In case of error or NO_ENTRY in this code we use the dwarf_srcline_dealloc(line_context) and dealloc of DW_DLA_LINE_CONTEXT from the new interface for uniformity here. */ int _dwarf_internal_srclines(Dwarf_Die die, Dwarf_Bool is_new_interface, Dwarf_Unsigned * version, Dwarf_Small * table_count, /* returns 0,1, or 2 */ Dwarf_Line_Context *line_context_out, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Bool doaddrs, Dwarf_Bool dolines, Dwarf_Error * error) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; /* This points to the last byte of the .debug_line portion for the current cu. */ Dwarf_Small *line_ptr_end = 0; /* For two-level line tables, this points to the first byte of the actuals table (and the end of the logicals table) for the current cu. */ Dwarf_Small *line_ptr_actuals = 0; Dwarf_Small *section_start = 0; Dwarf_Small *section_end = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; const char * const_comp_name = 0; /* Pointer to name of compilation directory. */ const char * const_comp_dir = NULL; Dwarf_Small *comp_dir = NULL; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; /* Pointer to a Dwarf_Line_Context_s structure that contains the context such as file names and include directories for the set of lines being generated. This is always recorded on an DW_LNS_end_sequence operator, on all special opcodes, and on DW_LNS_copy. */ Dwarf_Line_Context line_context = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned fission_offset = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; Dwarf_Half address_size = 0; Dwarf_Small * orig_line_ptr = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_line.dss_size) { return DW_DLV_NO_ENTRY; } address_size = _dwarf_get_address_size(dbg, die); resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } section_start = dbg->de_debug_line.dss_data; section_end = section_start +dbg->de_debug_line.dss_size; { Dwarf_Unsigned fission_size = 0; int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if (resf != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resf; } line_ptr += fission_offset; if (line_ptr > section_end) { _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); return DW_DLV_ERROR; } } section_start = dbg->de_debug_line.dss_data; section_end = section_start +dbg->de_debug_line.dss_size; orig_line_ptr = section_start + line_offset + fission_offset; line_ptr = orig_line_ptr; dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); if ((line_offset + fission_offset) > dbg->de_debug_line.dss_size) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (line_ptr > section_end) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } /* If die has DW_AT_comp_dir attribute, get the string that names the compilation directory. */ resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir, &const_comp_name,error); if (resattr == DW_DLV_ERROR) { return resattr; } /* Horrible cast to match historic interfaces. */ comp_dir = (Dwarf_Small *)const_comp_dir; line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } line_context->lc_new_style_access = is_new_interface; line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_internal_srclines() */ { Dwarf_Small *newlinep = 0; int resp = _dwarf_read_line_table_header(dbg, cu_context, section_start, line_ptr, dbg->de_debug_line.dss_size, &newlinep, line_context, NULL,NULL, error, 0); if (resp == DW_DLV_ERROR) { if (is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return resp; } if (resp == DW_DLV_NO_ENTRY) { if (is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return resp; } line_ptr_end = line_context->lc_line_ptr_end; line_ptr = newlinep; if (line_context->lc_actuals_table_offset > 0) { line_ptr_actuals = line_context->lc_line_prologue_start + line_context->lc_actuals_table_offset; } } if (line_ptr_actuals == 0) { /* ASSERT: lc_table_count == 1 or lc_table_count == 0 */ int err_count_out = 0; /* Normal style (single level) line table. */ Dwarf_Bool is_actuals_table = false; Dwarf_Bool local_is_single_table = true; res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { if (is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return res; } if (linebuf) *linebuf = line_context->lc_linebuf_logicals; if (linecount) *linecount = line_context->lc_linecount_logicals; if (linebuf_actuals) { *linebuf_actuals = NULL; } if (linecount_actuals) { *linecount_actuals = 0; } } else { Dwarf_Bool is_actuals_table = false; Dwarf_Bool local2_is_single_table = false; int err_count_out = 0; line_context->lc_is_single_table = false; /* Two-level line table. First read the logicals table. */ res = read_line_table_program(dbg, line_ptr, line_ptr_actuals, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local2_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { if (is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return res; } if (linebuf) { *linebuf = line_context->lc_linebuf_logicals; } else { } if (linecount) { *linecount = line_context->lc_linecount_logicals; } if (is_new_interface) { /* ASSERT: linebuf_actuals == NULL */ is_actuals_table = true; /* The call requested an actuals table and one is present. So now read that one. */ res = read_line_table_program(dbg, line_ptr_actuals, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local2_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return res; } if (linebuf_actuals) { *linebuf_actuals = line_context->lc_linebuf_actuals; } if (linecount_actuals != NULL) { *linecount_actuals = line_context->lc_linecount_actuals; } } } if (!is_new_interface && linecount && (linecount == 0 ||*linecount == 0) && (linecount_actuals == 0 || *linecount_actuals == 0)) { /* Here we have no actual lines of any kind. In other words, it looks like a debugfission line table skeleton or a caller not prepared for skeletons or two-level reading.. In that case there are no line entries so the context had nowhere to be recorded. Hence we have to delete it else we would leak the context. */ dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return DW_DLV_OK; } *table_count = line_context->lc_table_count; if (version != NULL) { *version = line_context->lc_version_number; } *line_context_out = line_context; return DW_DLV_OK; } int dwarf_get_ranges_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_ranges; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_aranges_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_aranges; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_line_section_name_from_die(Dwarf_Die die, const char **section_name_out, Dwarf_Error * error) { /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; struct Dwarf_Section_s *sec = 0; /* ***** BEGIN CODE ***** */ if (error) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; sec = &dbg->de_debug_line; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_string_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_str; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_srclines(Dwarf_Die die, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Error * error) { Dwarf_Unsigned version = 0; Dwarf_Line_Context line_context = 0; Dwarf_Small table_count = 0; Dwarf_Bool is_new_interface = false; int res = _dwarf_internal_srclines(die, is_new_interface, &version, &table_count, &line_context, linebuf, linecount, /* linebuf_actuals */ 0, /*linecount_actuals*/0, /* addrlist= */ false, /* linelist= */ true, error); return res; } int dwarf_srclines_two_level(Dwarf_Die die, Dwarf_Unsigned * version, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Error * error) { Dwarf_Line_Context line_context = 0; Dwarf_Small table_count = 0; Dwarf_Bool is_new_interface = false; int res = _dwarf_internal_srclines(die, is_new_interface, version, &table_count, &line_context, linebuf, linecount, linebuf_actuals, linecount_actuals, /* addrlist= */ false, /* linelist= */ true, error); return res; } /* New October 2015. */ int dwarf_srclines_b(Dwarf_Die die, Dwarf_Unsigned * version_out, Dwarf_Small * table_count, Dwarf_Line_Context * line_context, Dwarf_Error * error) { Dwarf_Signed linecount_actuals = 0; Dwarf_Line *linebuf = 0; Dwarf_Line *linebuf_actuals = 0; Dwarf_Signed linecount = 0; Dwarf_Bool is_new_interface = true; int res = 0; Dwarf_Unsigned tcount = 0; res = _dwarf_internal_srclines(die, is_new_interface, version_out, table_count, line_context, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, /* addrlist= */ false, /* linelist= */ true, error); if (res == DW_DLV_OK) { (*line_context)->lc_new_style_access = true; } if (linecount_actuals ) { tcount++; } if (linecount ) { tcount++; } *table_count = tcount; return res; } /* New October 2015. */ int dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context, Dwarf_Line** linebuf, Dwarf_Signed * linecount, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if (!line_context->lc_new_style_access) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *linebuf = line_context->lc_linebuf_logicals; *linecount = line_context->lc_linecount_logicals; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context line_context, Dwarf_Line** linebuf, Dwarf_Signed * linecount, Dwarf_Line** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if (!line_context->lc_new_style_access) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *linebuf = line_context->lc_linebuf_logicals; *linecount = line_context->lc_linecount_logicals; *linebuf_actuals = line_context->lc_linebuf_actuals; *linecount_actuals = line_context->lc_linecount_actuals; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_table_offset(Dwarf_Line_Context line_context, Dwarf_Unsigned * offset, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if ( line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *offset = line_context->lc_section_offset; return DW_DLV_OK; } /* New October 2015. */ /* If the CU DIE has no DW_AT_comp_dir then the pointer pushed back to *compilation_directory will be NULL. For DWARF5 the line table header has the compilation directory. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context, const char ** compilation_directory, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if (line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *compilation_directory = (const char *)line_context->lc_compilation_directory; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context line_context, Dwarf_Signed * count_out, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if (line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *count_out = line_context->lc_subprogs_count; return DW_DLV_OK; } /* New October 2015. */ /* Index says which to return. Valid indexes are 1-lc_subprogs_count */ int dwarf_srclines_subprog_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned *decl_file, Dwarf_Unsigned *decl_line, Dwarf_Error *error) { /* Negative values not sensible. Leaving traditional signed interfaces. */ Dwarf_Unsigned index = (Dwarf_Unsigned)index_in; Dwarf_Subprog_Entry sub = 0; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } if (index < 1 || index > line_context->lc_subprogs_count) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return DW_DLV_ERROR; } sub = line_context->lc_subprogs + (index-1); *name = (const char *)sub->ds_subprog_name; *decl_file = sub->ds_decl_file; *decl_line = sub->ds_decl_line; return DW_DLV_OK; } /* New October 2015. See also dwarf_srclines_files_indexes() */ int dwarf_srclines_files_count(Dwarf_Line_Context line_context, Dwarf_Signed *count_out, Dwarf_Error *error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } /* Negative values not sensible. Leaving traditional signed interfaces. */ *count_out = (Dwarf_Signed)line_context->lc_file_entry_count; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_files_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Error * error) { return dwarf_srclines_files_data_b( line_context,index_in,name,directory_index, last_mod_time,file_length,0,error); } /* New March 2018 making iteration through file names. */ int dwarf_srclines_files_indexes(Dwarf_Line_Context line_context, Dwarf_Signed *baseindex, Dwarf_Signed *file_count, Dwarf_Signed *endindex, Dwarf_Error * error) { if (line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *baseindex = line_context->lc_file_entry_baseindex; *file_count = line_context->lc_file_entry_count; *endindex = line_context->lc_file_entry_endindex; return DW_DLV_OK; } /* New March 2018 adding DWARF5 data. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** data16ptr, Dwarf_Error * error) { Dwarf_File_Entry fi = 0; Dwarf_Signed i =0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional signed interfaces. */ Dwarf_Signed index = index_in; int res = 0; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } /* Special accomodation of the special gnu experimental version number (a high number) so we cannot just say '5 or greater'. This is awkward, but at least if there is a version 6 or later it still allows the experimental table. */ res = dwarf_srclines_files_indexes(line_context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } fi = line_context->lc_file_entries; if (index < baseindex || index >= endindex) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return DW_DLV_ERROR; } for ( i = baseindex;i < index; i++) { fi = fi->fi_next; if (!fi) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_HEADER_CORRUPT); return DW_DLV_ERROR; } } if (name) { *name = (const char *)fi->fi_file_name; } if (directory_index) { *directory_index = fi->fi_dir_index; } if (last_mod_time) { *last_mod_time = fi->fi_time_last_mod; } if (file_length) { *file_length = fi->fi_file_length; } if (data16ptr) { if (fi->fi_md5_present) { *data16ptr = &fi->fi_md5_value; } else { *data16ptr = 0; } } return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *count = line_context->lc_include_directories_count; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Error * error) { /* It never made sense that the srclines used a signed count. But that cannot be fixed in interfaces for compatibility. So we adjust here. */ Dwarf_Unsigned index = index_in; unsigned int version = 0; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } version = line_context->lc_version_number; if (version == DW_LINE_VERSION5) { if (index >= line_context->lc_include_directories_count) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return DW_DLV_ERROR; } *name = (const char *) (line_context->lc_include_directories[index]); } else { if (index < 1 || index > line_context->lc_include_directories_count) { _dwarf_error(line_context->lc_dbg, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return DW_DLV_ERROR; } *name = (const char *) (line_context->lc_include_directories[index-1]); } return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_version(Dwarf_Line_Context line_context, Dwarf_Unsigned *version_out, Dwarf_Small *table_count_out, Dwarf_Error *error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *version_out = line_context->lc_version_number; *table_count_out = line_context->lc_table_count; return DW_DLV_OK; } /* Every line table entry (except DW_DLE_end_sequence, which is returned using dwarf_lineendsequence()) potentially has the begin-statement flag marked 'on'. This returns thru *return_bool, the begin-statement flag. */ int dwarf_linebeginstatement(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL || return_bool == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *return_bool = (line->li_addr_line.li_l_data.li_is_stmt); return DW_DLV_OK; } /* At the end of any contiguous line-table there may be a DW_LNE_end_sequence operator. This returns non-zero thru *return_bool if and only if this 'line' entry was a DW_LNE_end_sequence. Within a compilation unit or function there may be multiple line tables, each ending with a DW_LNE_end_sequence. Each table describes a contiguous region. Because compilers may split function code up in arbitrary ways compilers may need to emit multiple contigous regions (ie line tables) for a single function. See the DWARF3 spec section 6.2. */ int dwarf_lineendsequence(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *return_bool = (line->li_addr_line.li_l_data.li_end_sequence); return DW_DLV_OK; } /* Each 'line' entry has a line-number. If the entry is a DW_LNE_end_sequence the line-number is meaningless (see dwarf_lineendsequence(), just above). */ int dwarf_lineno(Dwarf_Line line, Dwarf_Unsigned * ret_lineno, Dwarf_Error * error) { if (line == NULL || ret_lineno == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *ret_lineno = (line->li_addr_line.li_l_data.li_line); return DW_DLV_OK; } /* Each 'line' entry has a file-number, an index into the file table. If the entry is a DW_LNE_end_sequence the index is meaningless (see dwarf_lineendsequence(), just above). The file number returned is an index into the file table produced by dwarf_srcfiles(), but care is required: the li_file begins with 1 for DWARF2,3,4 files, so that the li_file returned here is 1 greater than its index into the dwarf_srcfiles() output array. And entries from DW_LNE_define_file don't appear in the dwarf_srcfiles() output so file indexes from here may exceed the size of the dwarf_srcfiles() output array size. */ int dwarf_line_srcfileno(Dwarf_Line line, Dwarf_Unsigned * ret_fileno, Dwarf_Error * error) { if (line == NULL || ret_fileno == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } /* li_file must be <= line->li_context->lc_file_entry_count else it is trash. li_file 0 means not attributable to any source file per dwarf2/3 spec. For DWARF5, li_file < lc_file_entry_count */ *ret_fileno = (line->li_addr_line.li_l_data.li_file); return DW_DLV_OK; } /* Each 'line' entry has an is_addr_set attribute. If the entry is a DW_LNE_set_address, return TRUE through the *is_addr_set pointer. */ int dwarf_line_is_addr_set(Dwarf_Line line, Dwarf_Bool *is_addr_set, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *is_addr_set = (line->li_addr_line.li_l_data.li_is_addr_set); return DW_DLV_OK; } /* Each 'line' entry has a line-address. If the entry is a DW_LNE_end_sequence the adddress is one-beyond the last address this contigous region covers, so the address is not inside the region, but is just outside it. */ int dwarf_lineaddr(Dwarf_Line line, Dwarf_Addr * ret_lineaddr, Dwarf_Error * error) { if (line == NULL || ret_lineaddr == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *ret_lineaddr = (line->li_address); return DW_DLV_OK; } /* Obsolete: do not use this function. December 2011: For reasons lost in the mists of history, this returned -1, not zero (through the pointer ret_lineoff), if the column was zero. That was always bogus, even in DWARF2. It is also bogus that the column value is signed, but it is painful to change the argument type in 2011, so leave it. */ int dwarf_lineoff(Dwarf_Line line, Dwarf_Signed * ret_lineoff, Dwarf_Error * error) { if (line == NULL || ret_lineoff == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *ret_lineoff = ( (line->li_addr_line.li_l_data.li_column == 0) ? -1 : line->li_addr_line.li_l_data.li_column); return DW_DLV_OK; } /* Each 'line' entry has a column-within-line (offset within the line) where the source text begins. If the entry is a DW_LNE_end_sequence the line-number is meaningless (see dwarf_lineendsequence(), just above). Lines of text begin at column 1. The value 0 means the line begins at the left edge of the line. (See the DWARF3 spec, section 6.2.2). So 0 and 1 mean essentially the same thing. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line line, Dwarf_Unsigned * ret_lineoff, Dwarf_Error * error) { if (line == NULL || ret_lineoff == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *ret_lineoff = line->li_addr_line.li_l_data.li_column; return DW_DLV_OK; } static int dwarf_filename(Dwarf_Line_Context context, Dwarf_Signed fileno_in, char **ret_filename, Dwarf_Error *error) { Dwarf_Signed i = 0; Dwarf_File_Entry file_entry = 0; Dwarf_Debug dbg = context->lc_dbg; int res = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional signed interfaces in place. */ Dwarf_Signed fileno = fileno_in; unsigned linetab_version = context->lc_version_number; res = dwarf_srclines_files_indexes(context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } if (fileno >= endindex) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "DW_DLE_NO_FILE_NAME: the file number is %d ", fileno); dwarfstring_append_printf_u(&m, "( this is a DWARF 0x%x linetable)", linetab_version); dwarfstring_append_printf_i(&m, " yet the highest allowed file name index is %d.", endindex-1); _dwarf_error_string(dbg, error, DW_DLE_NO_FILE_NAME, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } else { if (linetab_version <= DW_LINE_VERSION4 || linetab_version == EXPERIMENTAL_LINE_TABLES_VERSION) { if (!fileno) { return DW_DLV_NO_ENTRY; } /* else ok */ } /* else DW_LINE_VERSION5 so file index 0 is fine */ } file_entry = context->lc_file_entries; /* zero fileno allowed for DWARF5 table. For DWARF4, zero fileno handled above. */ for (i = baseindex; i < fileno ; i++) { file_entry = file_entry->fi_next; } res = create_fullest_file_path(dbg, file_entry,context, ret_filename,error); return res; } int dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } if (line->li_context == NULL) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); return DW_DLV_ERROR; } return dwarf_filename(line->li_context, line->li_addr_line.li_l_data.li_file, ret_linesrc, error); } /* Every line table entry potentially has the basic-block-start flag marked 'on'. This returns thru *return_bool, the basic-block-start flag. */ int dwarf_lineblock(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *return_bool = (line->li_addr_line.li_l_data.li_basic_block); return DW_DLV_OK; } /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line line, Dwarf_Bool * prologue_end, Dwarf_Bool * epilogue_begin, Dwarf_Unsigned * isa, Dwarf_Unsigned * discriminator, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *prologue_end = line->li_addr_line.li_l_data.li_prologue_end; *epilogue_begin = line->li_addr_line.li_l_data.li_epilogue_begin; *isa = line->li_addr_line.li_l_data.li_isa; *discriminator = line->li_addr_line.li_l_data.li_discriminator; return DW_DLV_OK; } int dwarf_linelogical(Dwarf_Line line, Dwarf_Unsigned * logical, Dwarf_Error* error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *logical = line->li_addr_line.li_l_data.li_line; return DW_DLV_OK; } int dwarf_linecontext(Dwarf_Line line, Dwarf_Unsigned * context, Dwarf_Error* error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *context = (line->li_addr_line.li_l_data.li_call_context); return DW_DLV_OK; } int dwarf_line_subprogno(Dwarf_Line line, Dwarf_Unsigned * subprog, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } *subprog = (line->li_addr_line.li_l_data.li_subprogram); return DW_DLV_OK; } int dwarf_line_subprog(Dwarf_Line line, char ** subprog_name, char ** decl_filename, Dwarf_Unsigned * decl_line, Dwarf_Error * error) { Dwarf_Unsigned subprog_no; Dwarf_Subprog_Entry subprog; Dwarf_Debug dbg; int res; if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } if (line->li_context == NULL) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); return DW_DLV_ERROR; } dbg = line->li_context->lc_dbg; subprog_no = line->li_addr_line.li_l_data.li_subprogram; if (subprog_no == 0) { *subprog_name = NULL; *decl_filename = NULL; *decl_line = 0; return DW_DLV_OK; } if (subprog_no > line->li_context->lc_subprogs_count) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return DW_DLV_ERROR; } /* Adjusting for 1 origin subprog no */ subprog = &line->li_context->lc_subprogs[subprog_no - 1]; *subprog_name = (char *)subprog->ds_subprog_name; *decl_line = subprog->ds_decl_line; res = dwarf_filename(line->li_context, subprog->ds_decl_file, decl_filename, error); if (res != DW_DLV_OK) { *decl_filename = NULL; return res; } return DW_DLV_OK; } /* This is another line_context_destructor. */ static void delete_line_context_itself(Dwarf_Line_Context context) { Dwarf_Debug dbg = 0; Dwarf_File_Entry fe = 0; if (context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is wrong. */ return; } dbg = context->lc_dbg; fe = context->lc_file_entries; while (fe) { Dwarf_File_Entry fenext = fe->fi_next; fe->fi_next = 0; free(fe); fe = fenext; } context->lc_file_entries = 0; context->lc_file_entry_count = 0; context->lc_file_entry_baseindex = 0; context->lc_file_entry_endindex = 0; if (context->lc_subprogs) { free(context->lc_subprogs); context->lc_subprogs = 0; } free(context->lc_directory_format_values); context->lc_directory_format_values = 0; free(context->lc_file_format_values); context->lc_file_format_values = 0; if (context->lc_include_directories) { free(context->lc_include_directories); context->lc_include_directories = 0; } context->lc_magic = 0xdead; dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT); } /* It's impossible for callers of dwarf_srclines() to get to and free all the resources (in particular, the li_context and its lc_file_entries). So this function, new July 2005, does it. As of September 2015 this will now delete either table of a two-level line table. In the two-level case one calls it once each on both the logicals and actuals tables. (in either order, the order is not critical). Once the logicals table is dealloced any use of the actuals table will surely result in chaos. Just do the two calls one after the other. In the standard single-table case (DWARF 2,3,4) one calls it just once on the linebuf. Old style dealloc. Should never be used with dwarf_srclines_b(), but if it is there are no bad consequences.. Those using standard DWARF should use dwarf_srclines_b() and dwarf_srclines_dealloc_b() instead of dwarf_srclines and dwarf_srclines_dealloc() as that gives access to various bits of useful information. */ void dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf, Dwarf_Signed count) { Dwarf_Signed i = 0; /* alternate_data_count is a failsafe to prevent duplicate frees when there is inappropriate mixing of new interface and this old routine */ Dwarf_Bool alternate_data_count = 0; struct Dwarf_Line_Context_s *line_context = 0; if (!linebuf) { return; } if (count > 0) { /* All these entries share a single line_context, and for two-levels tables each table gets it too. Hence we will dealloc ONLY if !is_actuals_table so for single and two-level tables the space is deallocated. */ line_context = linebuf[0]->li_context; if (line_context && line_context->lc_magic != DW_CONTEXT_MAGIC ) { /* Something is very wrong. */ line_context = 0; } else if (line_context) { if (linebuf == line_context->lc_linebuf_logicals) { line_context->lc_linebuf_logicals = 0; line_context->lc_linecount_logicals = 0; alternate_data_count = line_context->lc_linecount_actuals; /* Ok to delete logicals */ } else if (linebuf == line_context->lc_linebuf_actuals) { /* Ok to delete actuals */ line_context->lc_linebuf_actuals = 0; line_context->lc_linecount_actuals = 0; alternate_data_count = line_context->lc_linecount_logicals; } else { /* Something is wrong very wrong. */ return; } } else { /* Else: impossible. Unless the caller passed in a bogus linebuf. */ line_context = 0; } } /* Here we actually delete a set of lines. */ for (i = 0; i < count; ++i) { dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); } dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); if (line_context && !line_context->lc_new_style_access && !alternate_data_count ) { /* There is nothing left referencing this line_context. */ dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); } return; } /* New October 2015. This should be used to deallocate all lines data that is set up by dwarf_srclines_b(). This and dwarf_srclines_b() are now (October 2015) the preferred routine to use. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context) { Dwarf_Line *linestable = 0; Dwarf_Signed linescount = 0; Dwarf_Signed i = 0; Dwarf_Debug dbg = 0; if (!line_context) { return; } if (line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is wrong. */ return; } dbg = line_context->lc_dbg; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is badly wrong here.*/ return; } linestable = line_context->lc_linebuf_logicals; if (linestable) { linescount = line_context->lc_linecount_logicals; for (i = 0; i < linescount ; ++i) { dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE); } dwarf_dealloc(dbg, linestable, DW_DLA_LIST); } line_context->lc_linebuf_logicals = 0; line_context->lc_linecount_logicals = 0; linestable = line_context->lc_linebuf_actuals; if (linestable) { linescount = line_context->lc_linecount_actuals; for (i = 0; i lc_linebuf_actuals = 0; line_context->lc_linecount_actuals = 0; delete_line_context_itself(line_context); } /* There is an error, so count it. If we are printing errors by command line option, print the details. */ void _dwarf_print_header_issue(Dwarf_Debug dbg, const char *specific_msg, Dwarf_Small *data_start, Dwarf_Signed value, unsigned index, unsigned tabv, unsigned linetabv, int *err_count_out) { if (!err_count_out) { return; } /* Are we in verbose mode */ if (dwarf_cmdline_options.check_verbose_mode){ dwarfstring m1; dwarfstring_constructor(&m1); dwarfstring_append(&m1, "\n*** DWARF CHECK: " ".debug_line: "); dwarfstring_append(&m1,(char *)specific_msg); dwarfstring_append_printf_i(&m1, " %" DW_PR_DSd,value); if (index || tabv || linetabv) { dwarfstring_append_printf_u(&m1, "; Mismatch index %u",index); dwarfstring_append_printf_u(&m1, " stdval %u",tabv); dwarfstring_append_printf_u(&m1, " linetabval %u",linetabv); } if (data_start >= dbg->de_debug_line.dss_data && (data_start < (dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size))) { Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data; dwarfstring_append_printf_u(&m1, " at offset 0x%" DW_PR_XZEROS DW_PR_DUx,off); dwarfstring_append_printf_u(&m1, " ( %" DW_PR_DUu " ) ",off); } else { dwarfstring_append(&m1, " (unknown section location) "); } dwarfstring_append(&m1,"***\n"); _dwarf_printf(dbg,dwarfstring_string(&m1)); dwarfstring_destructor(&m1); } *err_count_out += 1; } void _dwarf_report_bad_lnct( Dwarf_Debug dbg, Dwarf_Unsigned ltype, int dlecode, const char *dlename, Dwarf_Error *err) { dwarfstring m; dwarfstring f2; const char *typename = 0; char tnbuf[40]; char mnbuf[100]; dwarfstring_constructor_static(&f2,tnbuf,sizeof(tnbuf)); dwarf_get_LNCT_name(ltype,&typename); if (!typename) { dwarfstring_append_printf_u(&f2, "Invalid attribute " " 0x" DW_PR_DUx,ltype); } else { dwarfstring_append(&f2,(char *)typename); } dwarfstring_constructor_static(&m,mnbuf,sizeof(mnbuf)); dwarfstring_append_printf_s(&m, "%s: Unexpected DW_LNCT type",(char *)dlename); dwarfstring_append_printf_s(&m, " %s ", dwarfstring_string(&f2)); _dwarf_error_string(dbg, err, dlecode, dwarfstring_string(&m)); dwarfstring_destructor(&m); dwarfstring_destructor(&f2); } static void report_ltype_form_issue(Dwarf_Debug dbg, int ltype, int form, const char *splmsg, Dwarf_Error *error) { dwarfstring m; dwarfstring f2; dwarfstring f; const char *formname = 0; const char *typename = 0; char fnbuf[32]; char f2buf[32]; char mbuf[120]; dwarfstring_constructor_static(&f,fnbuf,sizeof(fnbuf)); dwarfstring_constructor_static(&f2,f2buf,sizeof(f2buf)); dwarf_get_LNCT_name(ltype,&typename); if (!typename) { dwarfstring_append_printf_u(&f2, "Invalid DW_LNCT " " 0x" DW_PR_DUx,ltype); } else { dwarfstring_append(&f2,(char *)typename); } dwarf_get_FORM_name(form,&formname); if (!formname) { dwarfstring_append_printf_u(&f, "Invalid Form Code " " 0x" DW_PR_DUx,form); } else { dwarfstring_append(&f,(char *)formname); } dwarfstring_constructor_static(&m,mbuf,sizeof(mbuf)); dwarfstring_append_printf_s(&m, "DW_DLE_LNCT_FORM_CODE_NOT_HANDLED: form %s " "instead of a specifically " "allowed offset form", dwarfstring_string(&f)); dwarfstring_append_printf_s(&m, " on line type %s", dwarfstring_string(&f2)); if (splmsg) { dwarfstring_append(&m," "); dwarfstring_append(&m,(char *)splmsg); } _dwarf_error_string(dbg, error, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, dwarfstring_string(&m)); dwarfstring_destructor(&m); dwarfstring_destructor(&f); dwarfstring_destructor(&f2); } int _dwarf_decode_line_string_form(Dwarf_Debug dbg, Dwarf_Unsigned ltype, Dwarf_Unsigned form, Dwarf_Unsigned offset_size, Dwarf_Small **line_ptr, Dwarf_Small *line_ptr_end, char **return_str, Dwarf_Error * error) { int res = 0; switch (form) { case DW_FORM_line_strp: { Dwarf_Small *secstart = 0; Dwarf_Small *secend = 0; Dwarf_Small *strptr = 0; Dwarf_Unsigned offset = 0; Dwarf_Small *offsetptr = *line_ptr; res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error); if (res != DW_DLV_OK) { return res; } secstart = dbg->de_debug_line_str.dss_data; secend = secstart + dbg->de_debug_line_str.dss_size; READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, offsetptr, offset_size, error,line_ptr_end); *line_ptr += offset_size; strptr = secstart + offset; res = _dwarf_check_string_valid(dbg, secstart,strptr,secend, DW_DLE_LINE_STRP_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *) strptr; return DW_DLV_OK; } case DW_FORM_string: { Dwarf_Small *secend = line_ptr_end; Dwarf_Small *strptr = *line_ptr; res = _dwarf_check_string_valid(dbg, strptr ,strptr,secend, DW_DLE_LINE_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *)strptr; *line_ptr += strlen((const char *)strptr) + 1; return DW_DLV_OK; } default: report_ltype_form_issue(dbg, ltype, form,0,error); return DW_DLV_ERROR; } } int _dwarf_decode_line_udata_form(Dwarf_Debug dbg, Dwarf_Unsigned ltype, Dwarf_Unsigned form, Dwarf_Small **line_ptr, Dwarf_Unsigned *return_val, Dwarf_Small *line_end_ptr, Dwarf_Error * error) { Dwarf_Unsigned val = 0; Dwarf_Small * lp = *line_ptr; const char *splmsg = 0; /* We will not get here for DW_LNCT_MD5, no need to consider DW_FORM_data16. */ switch (form) { case DW_FORM_udata: if (ltype != DW_LNCT_directory_index && ltype != DW_LNCT_timestamp && ltype != DW_LNCT_GNU_decl_file && ltype != DW_LNCT_GNU_decl_line && ltype != DW_LNCT_size) { break; } DECODE_LEB128_UWORD_CK(lp, val,dbg,error,line_end_ptr); *return_val = val; *line_ptr = lp; return DW_DLV_OK; case DW_FORM_data1: if (ltype != DW_LNCT_directory_index && ltype != DW_LNCT_GNU_decl_file && ltype != DW_LNCT_GNU_decl_line && ltype != DW_LNCT_size) { break; } *return_val = *lp; *line_ptr = lp+1; return DW_DLV_OK; case DW_FORM_data2: if (ltype != DW_LNCT_directory_index && ltype != DW_LNCT_GNU_decl_file && ltype != DW_LNCT_GNU_decl_line && ltype != DW_LNCT_size) { break; } READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, lp,DWARF_HALF_SIZE, error,line_end_ptr); *return_val = val; *line_ptr = lp + DWARF_HALF_SIZE; return DW_DLV_OK; case DW_FORM_data4: if (ltype != DW_LNCT_timestamp && ltype != DW_LNCT_GNU_decl_file && ltype != DW_LNCT_GNU_decl_line && ltype != DW_LNCT_size) { break; } READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, lp,DWARF_32BIT_SIZE, error,line_end_ptr); *return_val = val; *line_ptr = lp + DWARF_32BIT_SIZE; return DW_DLV_OK; case DW_FORM_block: { Dwarf_Unsigned leblen = 0; Dwarf_Unsigned length = 0; Dwarf_Small *dataptr = 0; if (ltype != DW_LNCT_timestamp) { break; } DECODE_LEB128_UWORD_LEN_CK(lp, length, leblen, dbg,error,line_end_ptr); dataptr = lp +leblen; if (length > sizeof(Dwarf_Unsigned)) { splmsg = "FORM_block length bigger than Dwarf_Unsigned"; break; } if (dataptr >= line_end_ptr ) { splmsg = "FORM_block data starts past end of data"; break; } if ((dataptr + length) > line_end_ptr) { splmsg = "FORM_block data runs past end of data"; break; } READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, dataptr,length, error,line_end_ptr); *return_val = val; *line_ptr = dataptr+length; return DW_DLV_OK; } case DW_FORM_data8: if (ltype != DW_LNCT_size && ltype != DW_LNCT_size) { break; } READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, lp,DWARF_64BIT_SIZE, error,line_end_ptr); *return_val = val; *line_ptr = lp + DWARF_64BIT_SIZE; return DW_DLV_OK; } report_ltype_form_issue(dbg, ltype, form,splmsg,error); return DW_DLV_ERROR; } void _dwarf_update_chain_list( Dwarf_Chain chain_line, Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain) { if (*head_chain == NULL) { *head_chain = chain_line; } else { (*curr_chain)->ch_next = chain_line; } *curr_chain = chain_line; } void _dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count) { int i = 0; Dwarf_Chain curr_chain = head; for (i = 0; i < count; i++) { Dwarf_Chain t = curr_chain; void *item = t->ch_item; int itype = t->ch_itemtype; if (item && itype) { /* valid DW_DLA types are never 0 */ dwarf_dealloc(dbg,item,itype); t->ch_item = 0; } curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, t, DW_DLA_CHAIN); } } int _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe) { unsigned int version = context->lc_version_number; if (!context->lc_file_entries) { context->lc_file_entries = fe; } else { context->lc_last_entry->fi_next = fe; } context->lc_last_entry = fe; context->lc_file_entry_count++; /* Here we attempt to write code to make it easy to interate though source file names without having to code specially for DWARF2,3,4 vs DWARF5 */ if (version == DW_LINE_VERSION5) { context->lc_file_entry_baseindex = 0; context->lc_file_entry_endindex = context->lc_file_entry_count; } else { context->lc_file_entry_baseindex = 1; context->lc_file_entry_endindex = context->lc_file_entry_count +1; } return DW_DLV_OK; } int _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m) { Dwarf_Line_Context line_context = (Dwarf_Line_Context)m; /* dwarf_get_alloc ensures the bytes are all zero when m is passed to us. */ line_context->lc_magic = DW_CONTEXT_MAGIC; line_context->lc_dbg = dbg; return DW_DLV_OK; } /* This cleans up a contex record. The lines tables (actuals and logicals) are themselves items that will be dealloc'd either manually or, at closing the libdwarf dbg, automatically. So we DO NOT touch the lines tables here See also: delete_line_context_itself() */ void _dwarf_line_context_destructor(void *m) { Dwarf_Line_Context line_context = (Dwarf_Line_Context)m; if (line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Nothing is safe, do nothing. */ return; } if (line_context->lc_include_directories) { free(line_context->lc_include_directories); line_context->lc_include_directories = 0; line_context->lc_include_directories_count = 0; } if (line_context->lc_file_entries) { Dwarf_File_Entry fe = line_context->lc_file_entries; while(fe) { Dwarf_File_Entry t = fe; fe = t->fi_next; t->fi_next = 0; free(t); } line_context->lc_file_entries = 0; line_context->lc_last_entry = 0; line_context->lc_file_entry_count = 0; line_context->lc_file_entry_baseindex = 0; line_context->lc_file_entry_endindex = 0; } free(line_context->lc_directory_format_values); line_context->lc_directory_format_values = 0; free(line_context->lc_file_format_values); line_context->lc_file_format_values = 0; if (line_context->lc_subprogs) { free(line_context->lc_subprogs); line_context->lc_subprogs = 0; line_context->lc_subprogs_count = 0; } line_context->lc_magic = 0; return; } libdwarf-20210528/libdwarf/dwarf_frame2.c0000664000175000017500000020034214004650531014770 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This implements _dwarf_get_fde_list_internal() and related helper functions for reading cie/fde data. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* using Arange as a way to build a list */ #include "dwarfstring.h" /* For a little information about .eh_frame see https://stackoverflow.com/questions/14091231/ what-do-the-eh-frame-and-eh-frame-hdr-sections-store-exactly http://refspecs.linuxfoundation.org/LSB_3.0.0/ LSB-Core-generic/LSB-Core-generic/ehframechpt.html The above give information about fields and sizes but very very little about content. .eh_frame_hdr contains data for C++ unwinding. Namely tables for fast access into .eh_frame. */ #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING */ /* For debugging only. */ static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, Dwarf_Cie cur_cie_ptr, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Cie head_cie_ptr); static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, Dwarf_Cie head_cie_ptr); static int dwarf_create_cie_from_start(Dwarf_Debug dbg, Dwarf_Small * cie_ptr_val, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_id_value, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Error * error); static int get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, unsigned long *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_end_pointer, char *augmentation, Dwarf_Error *error); static int gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, Dwarf_Half address_size, unsigned char *pers_hand_enc_out, unsigned char *lsda_enc_out, unsigned char *fde_begin_enc_out, Dwarf_Addr * gnu_pers_addr_out, Dwarf_Error *error); static int read_encoded_ptr(Dwarf_Debug dbg, Dwarf_Small * section_pointer, Dwarf_Small * input_field, int gnu_encoding, Dwarf_Small * section_ptr_end, Dwarf_Half address_size, Dwarf_Unsigned * addr, Dwarf_Small ** input_field_out, Dwarf_Error *error); /* Called by qsort to compare FDE entries. Consumer code expects the array of FDE pointers to be in address order. */ static int qsort_compare(const void *elem1, const void *elem2) { const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1; const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2; Dwarf_Addr addr1 = fde1->fd_initial_location; Dwarf_Addr addr2 = fde2->fd_initial_location; if (addr1 < addr2) { return -1; } else if (addr1 > addr2) { return 1; } return 0; } /* Adds 'newone' to the end of the list starting at 'head' and makes the new one current. */ static void chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur) { if (*head == NULL) *head = newone; else { (*cur)->fd_next = newone; } *cur = newone; } /* Adds 'newone' to the end of the list starting at 'head' and makes the new one current. */ static void chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur) { if (*head == NULL) { *head = newone; } else { (*cur)->ci_next = newone; } *cur = newone; } /* The size of the length field plus the value of length must be an integral multiple of the address size. Dwarf4 standard. A constant that gives the number of bytes of the CIE structure, not including the length field itself (where length mod == 0) (see Section 7.2.2). Dwarf3 standard. A uword constant that gives the number of bytes of the CIE structure, not including the length field, itself (length mod == 0). Dwarf2 standard.*/ static void validate_length(Dwarf_Debug dbg, Dwarf_Cie cieptr, Dwarf_Unsigned length, Dwarf_Unsigned length_size, Dwarf_Unsigned extension_size, Dwarf_Small * section_ptr, Dwarf_Small * ciefde_start, const char * cieorfde) { Dwarf_Unsigned address_size = 0; Dwarf_Unsigned length_field_summed = length_size + extension_size; Dwarf_Unsigned total_len = length + length_field_summed; Dwarf_Unsigned mod = 0; if (cieptr) { address_size = cieptr->ci_address_size; } else { address_size = dbg->de_pointer_size; } mod = total_len % address_size; if (mod != 0) { dwarfstring harm; Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr; dwarfstring_constructor(&harm); if (!cieorfde || (strlen(cieorfde) > 3)) { /* Coding error or memory corruption? */ cieorfde = "ERROR!"; } dwarfstring_append_printf_u(&harm, "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE" " len=0x%" DW_PR_XZEROS DW_PR_DUx, length); dwarfstring_append_printf_u(&harm, ", len size=0x%" DW_PR_XZEROS DW_PR_DUx, length_size); dwarfstring_append_printf_u(&harm, ", extn size=0x%" DW_PR_XZEROS DW_PR_DUx, extension_size); dwarfstring_append_printf_u(&harm, ", totl length=0x%" DW_PR_XZEROS DW_PR_DUx, total_len); dwarfstring_append_printf_u(&harm, ", addr size=0x%" DW_PR_XZEROS DW_PR_DUx, address_size); dwarfstring_append_printf_u(&harm, ", mod=0x%" DW_PR_XZEROS DW_PR_DUx " must be zero", mod); dwarfstring_append_printf_s(&harm, " in %s",(char *)cieorfde); dwarfstring_append_printf_u(&harm, ", offset 0x%" DW_PR_XZEROS DW_PR_DUx ".", sectionoffset); dwarf_insert_harmless_error(dbg, dwarfstring_string(&harm)); dwarfstring_destructor(&harm); } return; } #if 0 /* FOR DEBUGGING */ /* For debugging only. */ static void print_prefix(struct cie_fde_prefix_s *prefix, int line) { printf("prefix-print, prefix at 0x%lx, line %d\n", (unsigned long) prefix, line); printf(" start addr 0x%lx after prefix 0x%lx\n", (unsigned long) prefix->cf_start_addr, (unsigned long) prefix->cf_addr_after_prefix); printf(" length 0x%" DW_PR_DUx ", len size %d ext size %d\n", (Dwarf_Unsigned) prefix->cf_length, prefix->cf_local_length_size, prefix->cf_local_extension_size); printf(" cie_id 0x%" DW_PR_DUx " cie_id cie_id_addr 0x%lx\n", (Dwarf_Unsigned) prefix->cf_cie_id, (long) prefix->cf_cie_id_addr); printf (" sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n", (unsigned long) prefix->cf_section_ptr, (Dwarf_Signed) prefix->cf_section_index, (Dwarf_Unsigned) prefix->cf_section_length, (unsigned long) prefix->cf_section_ptr + (unsigned long)prefix->cf_section_length); } #endif /* Make the 'cieptr' consistent across .debug_frame and .eh_frame. Calculate a pointer into section bytes given a cie_id in an FDE header. In .debug_frame, the CIE_pointer is an offset in .debug_frame. In .eh_frame, the CIE Pointer is, when cie_id_value subtracted from the cie_id_addr, the address in memory of a CIE length field. Since cie_id_addr is the address of an FDE CIE_Pointer field, cie_id_value for .eh_frame has to account for the length-prefix. so that the returned cieptr really points to a CIE length field. Whew! Available documentation on this is just a bit ambiguous, but this calculation is correct. */ static Dwarf_Small * get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, Dwarf_Small * section_ptr, Dwarf_Small * cie_id_addr) { Dwarf_Small *cieptr = 0; if (use_gnu_cie_calc) { /* cie_id value is offset, in section, of the cie_id itself, to use vm ptr of the value, less the value, to get to the cie header. */ cieptr = cie_id_addr - cie_id_value; } else { /* Traditional dwarf section offset is in cie_id */ cieptr = section_ptr + cie_id_value; } return cieptr; } /* Internal function called from various places to create lists of CIEs and FDEs. Not directly called by consumer code */ int _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, Dwarf_Error * error) { /* Scans the debug_frame section. */ Dwarf_Small *frame_ptr = section_ptr; Dwarf_Small *section_ptr_end = section_ptr + section_length; /* New_cie points to the Cie being read, and head_cie_ptr and cur_cie_ptr are used for chaining them up in sequence. In case cie's are reused aggressively we need tail_cie_ptr to add to the chain. If we re-use an early cie later on, that does not mean we chain a new cie to the early one, we always chain it to the tail. */ Dwarf_Cie head_cie_ptr = NULL; Dwarf_Cie cur_cie_ptr = NULL; Dwarf_Cie tail_cie_ptr = NULL; Dwarf_Unsigned cie_count = 0; /* Points to a list of contiguous pointers to Dwarf_Cie structures. */ Dwarf_Cie *cie_list_ptr = 0; /* New_fde points to the Fde being created, and head_fde_ptr and cur_fde_ptr are used to chain them up. */ Dwarf_Fde head_fde_ptr = NULL; Dwarf_Fde cur_fde_ptr = NULL; Dwarf_Unsigned fde_count = 0; /* Points to a list of contiguous pointers to Dwarf_Fde structures. */ Dwarf_Fde *fde_list_ptr = NULL; Dwarf_Unsigned i = 0; int res = DW_DLV_ERROR; if (frame_ptr == 0) { return DW_DLV_NO_ENTRY; } /* We create the fde and cie arrays. Processing each CIE as we come to it or as an FDE refers to it. We cannot process 'late' CIEs late as GNU .eh_frame complexities mean we need the whole CIE before we can process the FDE correctly. */ while (frame_ptr < section_ptr_end) { struct cie_fde_prefix_s prefix; /* First read in the 'common prefix' to figure out what we are to do with this entry. */ memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, section_index, section_length, &prefix, error); if (res == DW_DLV_ERROR) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return res; } if (res == DW_DLV_NO_ENTRY) { break; } frame_ptr = prefix.cf_addr_after_prefix; if (frame_ptr >= section_ptr_end) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: following " "a the start of a cie/fde we have run off" " the end of the section. Corrupt Dwarf"); return DW_DLV_ERROR; } if (prefix.cf_cie_id == cie_id_value) { /* This is a CIE. */ Dwarf_Cie cie_ptr_to_use = 0; int resc = 0; resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, cur_cie_ptr, &cie_ptr_to_use, head_cie_ptr); if (resc == DW_DLV_OK) { cur_cie_ptr = cie_ptr_to_use; /* Ok. Seen already. */ } else if (resc == DW_DLV_NO_ENTRY) { /* CIE before its FDE in this case. */ resc = dwarf_create_cie_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, cie_count, use_gnu_cie_calc, &cie_ptr_to_use, error); if (resc != DW_DLV_OK) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resc; } cie_count++; chain_up_cie(cie_ptr_to_use, &head_cie_ptr, &tail_cie_ptr); cur_cie_ptr = tail_cie_ptr; } else { /* res == DW_DLV_ERROR */ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resc; } frame_ptr = cie_ptr_to_use->ci_cie_start + cie_ptr_to_use->ci_length + cie_ptr_to_use->ci_length_size + cie_ptr_to_use->ci_extension_size; continue; } else { /* This is an FDE, Frame Description Entry, see the Dwarf Spec, (section 6.4.1 in DWARF2, DWARF3, DWARF4, ...) Or see the .eh_frame specification, from the Linux Foundation (or other source). */ int resf = DW_DLV_ERROR; Dwarf_Cie cie_ptr_to_use = 0; Dwarf_Fde fde_ptr_to_use = 0; Dwarf_Small *cieptr_val = 0; cieptr_val = get_cieptr_given_offset(prefix.cf_cie_id, use_gnu_cie_calc, section_ptr, prefix.cf_cie_id_addr); resf = dwarf_find_existing_cie_ptr(cieptr_val, cur_cie_ptr, &cie_ptr_to_use, head_cie_ptr); if (resf == DW_DLV_OK) { cur_cie_ptr = cie_ptr_to_use; /* Ok. Seen CIE already. */ } else if (resf == DW_DLV_NO_ENTRY) { resf = dwarf_create_cie_from_start(dbg, cieptr_val, section_ptr, section_index, section_length, section_ptr_end, cie_id_value, cie_count, use_gnu_cie_calc, &cie_ptr_to_use, error); if (resf == DW_DLV_ERROR) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resf; } else if (resf == DW_DLV_NO_ENTRY) { return resf; } ++cie_count; chain_up_cie(cie_ptr_to_use, &head_cie_ptr, &tail_cie_ptr); cur_cie_ptr = tail_cie_ptr; } else { /* DW_DLV_ERROR */ return resf; } resf = dwarf_create_fde_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, use_gnu_cie_calc, cie_ptr_to_use, &fde_ptr_to_use, error); if (resf == DW_DLV_ERROR) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resf; } else if (resf == DW_DLV_NO_ENTRY) { /* impossible. */ return resf; } chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr); fde_count++; /* ASSERT: DW_DLV_OK. */ frame_ptr = cur_fde_ptr->fd_fde_start + cur_fde_ptr->fd_length + cur_fde_ptr->fd_length_size + cur_fde_ptr->fd_extension_size; if (frame_ptr < fde_ptr_to_use->fd_fde_instr_start) { /* Sanity check. With a really short fde instruction set and address_size we think is 8 as it is ELF64 (but is really 4, as in DWARF{2,3} where we have no FDE address_size) we emit an error. This error means things will not go well. */ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg,error, DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH); return DW_DLV_ERROR; } continue; } } /* Now build list of CIEs from the list. If there are no CIEs there should be no FDEs. */ if (cie_count > 0) { cie_list_ptr = (Dwarf_Cie *) _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count); } else { if (fde_count > 0) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE); return DW_DLV_ERROR; } dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return DW_DLV_NO_ENTRY; } if (cie_list_ptr == NULL) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (!head_cie_ptr) { /* Should be impossible. */ _dwarf_error(dbg, error,DW_DLE_DEBUGFRAME_ERROR); return DW_DLV_ERROR; } cur_cie_ptr = head_cie_ptr; for (i = 0; i < cie_count; i++) { *(cie_list_ptr + i) = cur_cie_ptr; cur_cie_ptr = cur_cie_ptr->ci_next; } /* Now build array of FDEs from the list. With orphan CIEs (meaning no FDEs) lets not return DW_DLV_NO_ENTRY */ if (fde_count > 0) { fde_list_ptr = (Dwarf_Fde *) _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count); } /* It is ok if fde_list_ptr is NULL, we just have no fdes. */ cur_fde_ptr = head_fde_ptr; for (i = 0; i < fde_count; i++) { *(fde_list_ptr + i) = cur_fde_ptr; cur_fde_ptr = cur_fde_ptr->fd_next; } /* Return arguments. */ *cie_data = cie_list_ptr; *cie_element_count = cie_count; *fde_data = fde_list_ptr; *fde_element_count = fde_count; if (use_gnu_cie_calc) { dbg->de_fde_data_eh = fde_list_ptr; dbg->de_fde_count_eh = fde_count; dbg->de_cie_data_eh = cie_list_ptr; dbg->de_cie_count_eh = cie_count; } else { dbg->de_fde_data = fde_list_ptr; dbg->de_fde_count = fde_count; dbg->de_cie_data = cie_list_ptr; dbg->de_cie_count = cie_count; } /* Sort the list by the address so that dwarf_get_fde_at_pc() can binary search this list. */ if (fde_count > 0) { qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr), qsort_compare); } return DW_DLV_OK; } /* Internal function, not called by consumer code. 'prefix' has accumulated the info up thru the cie-id and now we consume the rest and build a Dwarf_Cie_s structure. */ int dwarf_create_cie_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small * section_pointer, Dwarf_Small * frame_ptr, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_out, Dwarf_Error * error) { Dwarf_Cie new_cie = 0; /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses -1 (in .debug_frame). .eh_frame not quite identical to .debug_frame */ /* We here default the address size as it is not present in DWARF2 or DWARF3 cie data, below we set it right if it is present. */ Dwarf_Half address_size = dbg->de_pointer_size; Dwarf_Small *augmentation = 0; Dwarf_Half segment_size = 0; Dwarf_Signed data_alignment_factor = -1; Dwarf_Unsigned code_alignment_factor = 4; Dwarf_Unsigned return_address_register = 31; int local_length_size = 0; Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned cie_aug_data_len = 0; Dwarf_Small *cie_aug_data = 0; Dwarf_Addr gnu_personality_handler_addr = 0; unsigned char gnu_personality_handler_encoding = 0; unsigned char gnu_lsda_encoding = 0; unsigned char gnu_fde_begin_encoding = 0; int res = 0; Dwarf_Small version = 0; enum Dwarf_augmentation_type augt = aug_unknown; /* This is a CIE, Common Information Entry: See the dwarf spec, section 6.4.1 */ if (frame_ptr >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: reading a cie" " version byte we have run off" " the end of the section. Corrupt Dwarf"); return DW_DLV_ERROR; } version = *(Dwarf_Small *) frame_ptr; if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: reading an augmentation" " would run off" " the end of the section. Corrupt Dwarf"); return DW_DLV_ERROR; } if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 && version != DW_CIE_VERSION4 && version != DW_CIE_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_FRAME_VERSION_BAD: cie version %u unknown", version); _dwarf_error_string(dbg, error, DW_DLE_FRAME_VERSION_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } frame_ptr++; augmentation = frame_ptr; res = _dwarf_check_string_valid(dbg,section_pointer, frame_ptr,section_ptr_end, DW_DLE_AUGMENTATION_STRING_OFF_END,error); if (res != DW_DLV_OK) { return res; } frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1; if (frame_ptr >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: following any " "augmentation field we have run off " "the end of the section " "with the CIE incomplete. Corrupt Dwarf"); return DW_DLV_ERROR; } augt = _dwarf_get_augmentation_type(dbg, augmentation, use_gnu_cie_calc); if (augt == aug_eh) { /* REFERENCED *//* Not used in this instance */ UNUSEDARG Dwarf_Unsigned exception_table_addr; if ((frame_ptr+local_length_size) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: following " "type field we have run off the end of the section " "with the CIE incomplete. Corrupt Dwarf"); return DW_DLV_ERROR; } /* this is per egcs-1.1.2 as on RH 6.0 */ READ_UNALIGNED_CK(dbg, exception_table_addr, Dwarf_Unsigned, frame_ptr, local_length_size, error,section_ptr_end); frame_ptr += local_length_size; } { Dwarf_Unsigned lreg = 0; unsigned long size = 0; if (version == DW_CIE_VERSION4) { if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: " "We would run off the end of the section " "in a DWARF4 cie header. Corrupt Dwarf"); return DW_DLV_ERROR; } address_size = *((unsigned char *)frame_ptr); if (address_size < 1) { _dwarf_error_string(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO, "DW_DLE_ADDRESS_SIZE_ZERO: bad address size " "for a DWARF4 cie header"); return DW_DLV_ERROR; } if (address_size > sizeof(Dwarf_Addr)) { _dwarf_create_address_size_dwarf_error(dbg, error,address_size, DW_DLE_ADDRESS_SIZE_ERROR, "DW_DLE_ADDRESS_SIZE_ERROR..:"); return DW_DLV_ERROR; } if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: " "Running off the end " " of a CIE header. Corrupt DWARF4"); return DW_DLV_ERROR; } ++frame_ptr; segment_size = *((unsigned char *)frame_ptr); ++frame_ptr; if (segment_size > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); return DW_DLV_ERROR; } } /* Not a great test. But the DECODE* do checking so ok. */ if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Running off the end " " of a CIE header before the code alignment value " "read. Corrupt DWARF"); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error, section_ptr_end); code_alignment_factor = (Dwarf_Unsigned) lreg; res = (Dwarf_Signed) _dwarf_decode_s_leb128_chk(frame_ptr, &leb128_length,&data_alignment_factor,section_ptr_end); if (res != DW_DLV_OK) { return res; } frame_ptr = frame_ptr + leb128_length; if ((frame_ptr+1) >= section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Running off the end " "of a CIE header before the return address register " "number read. Corrupt DWARF"); return DW_DLV_ERROR; } res = _dwarf_get_return_address_reg(frame_ptr, version, dbg,section_ptr_end, &size, &return_address_register,error); if (res != DW_DLV_OK) { return res; } if (return_address_register > dbg->de_frame_reg_rules_entry_count) { _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); return DW_DLV_ERROR; } frame_ptr += size; if ((frame_ptr) > section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Past the end " "of a CIE header before reading " "the augmentation string." " Corrupt DWARF"); return DW_DLV_ERROR; } } switch (augt) { case aug_empty_string: break; case aug_irix_mti_v1: break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned length_of_augmented_fields; /* Decode the length of augmented fields. */ DECODE_LEB128_UWORD_CK(frame_ptr, lreg, dbg,error,section_ptr_end); length_of_augmented_fields = (Dwarf_Unsigned) lreg; /* set the frame_ptr to point at the instruction start. */ frame_ptr += length_of_augmented_fields; } break; case aug_eh:{ int err = 0; unsigned long increment = 0; if (!use_gnu_cie_calc) { /* This should be impossible. */ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment, augt, section_ptr_end, (char *) augmentation,error); if (err == DW_DLV_ERROR) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } frame_ptr += increment; } break; case aug_gcc_eh_z:{ /* Here we have Augmentation Data Length (uleb128) followed by Augmentation Data bytes (not a string). */ int resz = DW_DLV_ERROR; Dwarf_Unsigned adlen = 0; if ((frame_ptr+1) > section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_AUG_DATA_LENGTH_BAD: The " "gcc .eh_frame augmentation data " "cannot be read. Out of room in the section." " Corrupt DWARF."); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(frame_ptr, adlen, dbg,error,section_ptr_end); cie_aug_data_len = adlen; cie_aug_data = frame_ptr; if (adlen) { Dwarf_Small *cie_aug_data_end = cie_aug_data+adlen; if (cie_aug_data_end < cie_aug_data || cie_aug_data_end > section_ptr_end) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_AUG_DATA_LENGTH_BAD: The " "gcc .eh_frame augmentation data " "length of %" DW_PR_DUu " is too long to" " fit in the section.",adlen); _dwarf_error_string(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } resz = gnu_aug_encodings(dbg, (char *) augmentation, cie_aug_data, cie_aug_data_len, address_size, &gnu_personality_handler_encoding, &gnu_lsda_encoding, &gnu_fde_begin_encoding, &gnu_personality_handler_addr, error); if (resz != DW_DLV_OK) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return resz; } frame_ptr += adlen; } break; case aug_armcc: break; default:{ /* We do not understand the augmentation string. No assumption can be made about any fields other than what we have already read. */ frame_ptr = prefix->cf_start_addr + prefix->cf_length + prefix->cf_local_length_size + prefix->cf_local_extension_size; /* FIX -- What are the values of data_alignment_factor, code_alignment_factor, return_address_register and instruction start? They were clearly uninitialized in the previous version and I am leaving them the same way. */ } if ((frame_ptr) > section_ptr_end) { _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: " "Reading an unknown type of augmentation string " "run off the end of the section. Corrupt DWARF."); return DW_DLV_ERROR; } break; } /* End switch on augmentation type. */ new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); if (new_cie == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_cie->ci_cie_version_number = version; new_cie->ci_initial_table = NULL; new_cie->ci_length = (Dwarf_Unsigned) prefix->cf_length; new_cie->ci_length_size = prefix->cf_local_length_size; new_cie->ci_extension_size = prefix->cf_local_extension_size; new_cie->ci_augmentation = (char *) augmentation; new_cie->ci_data_alignment_factor = (Dwarf_Sbyte) data_alignment_factor; new_cie->ci_code_alignment_factor = (Dwarf_Small) code_alignment_factor; new_cie->ci_return_address_register = return_address_register; new_cie->ci_cie_start = prefix->cf_start_addr; if ( frame_ptr > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } new_cie->ci_cie_instr_start = frame_ptr; new_cie->ci_dbg = dbg; new_cie->ci_augmentation_type = augt; new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len; new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data; new_cie->ci_gnu_personality_handler_encoding = gnu_personality_handler_encoding; new_cie->ci_gnu_personality_handler_addr = gnu_personality_handler_addr; new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding; new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding; new_cie->ci_index = cie_count; new_cie->ci_section_ptr = prefix->cf_section_ptr; new_cie->ci_section_end = section_ptr_end; new_cie->ci_cie_end = new_cie->ci_cie_start + new_cie->ci_length + new_cie->ci_length_size+ new_cie->ci_extension_size; if ( new_cie->ci_cie_end > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } /* The Following new in DWARF4 */ new_cie->ci_address_size = address_size; new_cie->ci_segment_size = segment_size; validate_length(dbg,new_cie,new_cie->ci_length, new_cie->ci_length_size, new_cie->ci_extension_size, new_cie->ci_section_ptr, new_cie->ci_cie_start,"cie"); *cie_ptr_out = new_cie; return DW_DLV_OK; } /* Internal function, not called by consumer code. 'prefix' has accumulated the info up thru the cie-id and now we consume the rest and build a Dwarf_Fde_s structure. Can be called with cie_ptr_in NULL from dwarf_frame.c */ int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small * section_pointer, Dwarf_Small * frame_ptr, Dwarf_Small * section_ptr_end, int use_gnu_cie_calc, Dwarf_Cie cie_ptr_in, Dwarf_Fde * fde_ptr_out, Dwarf_Error * error) { Dwarf_Fde new_fde = 0; Dwarf_Cie cieptr = 0; Dwarf_Small *saved_frame_ptr = 0; Dwarf_Small *initloc = frame_ptr; Dwarf_Signed offset_into_exception_tables = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; Dwarf_Small *fde_aug_data = 0; Dwarf_Unsigned fde_aug_data_len = 0; Dwarf_Addr cie_base_offset = prefix->cf_cie_id; Dwarf_Addr initial_location = 0; /* must be min de_pointer_size bytes in size */ Dwarf_Addr address_range = 0; /* must be min de_pointer_size bytes in size */ Dwarf_Half address_size = 0; Dwarf_Unsigned eh_table_value = 0; Dwarf_Bool eh_table_value_set = FALSE; /* Temporary assumption. */ enum Dwarf_augmentation_type augt = aug_empty_string; if (cie_ptr_in) { cieptr = cie_ptr_in; address_size = cieptr->ci_address_size; augt = cieptr->ci_augmentation_type; } if (augt == aug_gcc_eh_z) { /* If z augmentation this is eh_frame, and initial_location and address_range in the FDE are read according to the CIE augmentation string instructions. */ { Dwarf_Small *fp_updated = 0; int res = read_encoded_ptr(dbg, section_pointer, frame_ptr, cieptr-> ci_gnu_fde_begin_encoding, section_ptr_end, address_size, &initial_location, &fp_updated,error); if (res != DW_DLV_OK) { return res; } frame_ptr = fp_updated; /* For the address-range it makes no sense to be pc-relative, so we turn it off with a section_pointer of NULL. Masking off DW_EH_PE_pcrel from the ci_gnu_fde_begin_encoding in this call would also work to turn off DW_EH_PE_pcrel. */ res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, frame_ptr, cieptr->ci_gnu_fde_begin_encoding, section_ptr_end, address_size, &address_range, &fp_updated,error); if (res != DW_DLV_OK) { return res; } frame_ptr = fp_updated; } { Dwarf_Unsigned adlen = 0; DECODE_LEB128_UWORD_CK(frame_ptr, adlen, dbg,error,section_ptr_end); fde_aug_data_len = adlen; fde_aug_data = frame_ptr; frame_ptr += adlen; if (adlen) { if (frame_ptr < fde_aug_data || frame_ptr >= section_ptr_end ) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_AUG_DATA_LENGTH_BAD: The " "gcc .eh_frame augmentation data " "length of %" DW_PR_DUu " is too long to" " fit in the section.",adlen); _dwarf_error_string(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } } } else { if ((frame_ptr + 2*address_size) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, initial_location, Dwarf_Addr, frame_ptr, address_size, error,section_ptr_end); frame_ptr += address_size; READ_UNALIGNED_CK(dbg, address_range, Dwarf_Addr, frame_ptr, address_size, error,section_ptr_end); frame_ptr += address_size; } switch (augt) { case aug_irix_mti_v1: case aug_empty_string: break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned length_of_augmented_fields = 0; DECODE_LEB128_UWORD_CK(frame_ptr, lreg, dbg,error,section_ptr_end); length_of_augmented_fields = (Dwarf_Unsigned) lreg; saved_frame_ptr = frame_ptr; /* The first word is an offset into exception tables. Defined as a 32bit offset even for CC -64. */ if ((frame_ptr + DWARF_32BIT_SIZE) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, offset_into_exception_tables, Dwarf_Addr, frame_ptr, DWARF_32BIT_SIZE, error,section_ptr_end); SIGN_EXTEND(offset_into_exception_tables, DWARF_32BIT_SIZE); frame_ptr = saved_frame_ptr + length_of_augmented_fields; } break; case aug_eh:{ if (!use_gnu_cie_calc) { /* This should be impossible. */ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* gnu eh fde case. we do not need to do anything */ /*REFERENCED*/ /* Not used in this instance of the macro */ if ((frame_ptr + address_size) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, eh_table_value, Dwarf_Unsigned, frame_ptr, address_size, error,section_ptr_end); eh_table_value_set = TRUE; frame_ptr += address_size; } break; case aug_gcc_eh_z:{ /* The Augmentation Data Length is here, followed by the Augmentation Data bytes themselves. */ } break; case aug_armcc: break; case aug_past_last: break; case aug_metaware: /* No special fields. See dwarf_util.h */ break; case aug_unknown: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* End switch on augmentation type */ if ( frame_ptr > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); if (new_fde == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_fde->fd_length = prefix->cf_length; new_fde->fd_length_size = prefix->cf_local_length_size; new_fde->fd_extension_size = prefix->cf_local_extension_size; new_fde->fd_is_eh = use_gnu_cie_calc; new_fde->fd_cie_offset = cie_base_offset; if (cieptr) { new_fde->fd_cie_index = cieptr->ci_index; } new_fde->fd_cie = cieptr; new_fde->fd_initial_location = initial_location; new_fde->fd_initial_loc_pos = initloc; new_fde->fd_address_range = address_range; new_fde->fd_fde_start = prefix->cf_start_addr; new_fde->fd_fde_instr_start = frame_ptr; new_fde->fd_fde_end = prefix->cf_start_addr + prefix->cf_length + prefix->cf_local_length_size + prefix->cf_local_extension_size; if ( new_fde->fd_fde_end > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } new_fde->fd_dbg = dbg; new_fde->fd_offset_into_exception_tables = offset_into_exception_tables; new_fde->fd_eh_table_value = eh_table_value; new_fde->fd_eh_table_value_set = eh_table_value_set; new_fde->fd_section_ptr = prefix->cf_section_ptr; new_fde->fd_section_index = prefix->cf_section_index; new_fde->fd_section_length = prefix->cf_section_length; new_fde->fd_section_end = section_ptr_end; if (augt == aug_gcc_eh_z) { new_fde->fd_gnu_eh_aug_present = TRUE; } new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data; new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len; validate_length(dbg,cieptr,new_fde->fd_length, new_fde->fd_length_size, new_fde->fd_extension_size, new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde"); *fde_ptr_out = new_fde; return DW_DLV_OK; } /* Read in the common cie/fde prefix, including reading the cie-value which shows which this is: cie or fde. */ int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, Dwarf_Small * frame_ptr_in, Dwarf_Small * section_ptr_in, Dwarf_Unsigned section_index_in, Dwarf_Unsigned section_length_in, struct cie_fde_prefix_s *data_out, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Small *frame_ptr = frame_ptr_in; Dwarf_Small *cie_ptr_addr = 0; Dwarf_Unsigned cie_id = 0; Dwarf_Small *section_end = section_ptr_in + section_length_in; if (section_end < (frame_ptr +4)) { dwarfstring m; Dwarf_Unsigned u = (Dwarf_Unsigned)(uintptr_t)(frame_ptr+4) - (Dwarf_Unsigned)(uintptr_t)section_end; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_FRAME_LENGTH_BAD: " "Reading the cie/fde prefix would " "put us %u bytes past the end of the " "frame section. Corrupt Dwarf.",u); _dwarf_error_string(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, frame_ptr, local_length_size, local_extension_size,error, section_length_in,section_end); if (length == 0) { /* nul bytes at end of section, seen at end of egcs eh_frame sections (in a.out). Take this as meaning no more CIE/FDE data. We should be very close to end of section. */ return DW_DLV_NO_ENTRY; } if ((frame_ptr + local_length_size) >= section_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } cie_ptr_addr = frame_ptr; READ_UNALIGNED_CK(dbg, cie_id, Dwarf_Unsigned, frame_ptr, local_length_size,error,section_end); SIGN_EXTEND(cie_id, local_length_size); frame_ptr += local_length_size; data_out->cf_start_addr = frame_ptr_in; data_out->cf_addr_after_prefix = frame_ptr; data_out->cf_length = length; if (length > section_length_in) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } if (cie_ptr_addr+length > section_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } data_out->cf_local_length_size = local_length_size; data_out->cf_local_extension_size = local_extension_size; /* We do not know if it is a CIE or FDE id yet. How we check and what it means depends whether it is .debug_frame or .eh_frame. */ data_out->cf_cie_id = cie_id; /* The address of the CIE_id or FDE_id value in memory. */ data_out->cf_cie_id_addr = cie_ptr_addr; data_out->cf_section_ptr = section_ptr_in; data_out->cf_section_index = section_index_in; data_out->cf_section_length = section_length_in; return DW_DLV_OK; } /* On various errors previously-allocated CIEs and FDEs must be cleaned up. This helps avoid leaks in case of errors. */ static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, Dwarf_Cie head_cie_ptr) { Dwarf_Fde curfde = 0; Dwarf_Cie curcie = 0; Dwarf_Fde nextfde = 0; Dwarf_Cie nextcie = 0; for (curfde = head_fde_ptr; curfde; curfde = nextfde) { nextfde = curfde->fd_next; dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE); } for (curcie = head_cie_ptr; curcie; curcie = nextcie) { Dwarf_Frame frame = curcie->ci_initial_table; nextcie = curcie->ci_next; if (frame) dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME); dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE); } } /* Find the cie whose id value is given: the id value is, per DWARF2/3, an offset in the section. For .debug_frame, zero is a legal offset. For GNU .eh_frame it is not a legal offset. 'cie_ptr' is a pointer into our section, not an offset. */ static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, Dwarf_Cie cur_cie_ptr, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Cie head_cie_ptr) { Dwarf_Cie next = 0; if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) { /* Usually, we use the same cie again and again. */ *cie_ptr_to_use_out = cur_cie_ptr; return DW_DLV_OK; } for (next = head_cie_ptr; next; next = next->ci_next) { if (cie_ptr == next->ci_cie_start) { *cie_ptr_to_use_out = next; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* We have a valid cie_ptr_val that has not been turned into an internal Cie yet. Do so now. Returns DW_DLV_OK or DW_DLV_ERROR, never DW_DLV_NO_ENTRY. 'section_ptr' - Points to first byte of section data. 'section_length' - Length of the section, in bytes. 'section_ptr_end' - Points 1-past last byte of section data. */ static int dwarf_create_cie_from_start(Dwarf_Debug dbg, Dwarf_Small * cie_ptr_val, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_id_value, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Error * error) { struct cie_fde_prefix_s prefix; int res = DW_DLV_ERROR; Dwarf_Small *frame_ptr = cie_ptr_val; if (frame_ptr < section_ptr || frame_ptr >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } /* First read in the 'common prefix' to figure out what * we are to do with this entry. If it is not a cie * we are in big trouble. */ memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, section_index, section_length, &prefix, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { /* error. */ _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); return DW_DLV_ERROR; } if (prefix.cf_cie_id != cie_id_value) { _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); return DW_DLV_ERROR; } frame_ptr = prefix.cf_addr_after_prefix; res = dwarf_create_cie_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, cie_count, use_gnu_cie_calc, cie_ptr_to_use_out, error); return res; } /* This is for gnu eh frames, the 'z' case. We find the letter involved Return the augmentation character and, if applicable, the personality routine address. personality_routine_out - if 'P' is augchar, is personality handler addr. Otherwise is not set. aug_data - if 'P' points to data space of the aug_data_len - length of areas aug_data points to. */ /* It is not clear if this is entirely correct. */ static int gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, Dwarf_Half address_size, unsigned char *pers_hand_enc_out, unsigned char *lsda_enc_out, unsigned char *fde_begin_enc_out, Dwarf_Addr * gnu_pers_addr_out, Dwarf_Error * error) { char *nc = 0; Dwarf_Small *cur_aug_p = aug_data; Dwarf_Small *end_aug_p = aug_data + aug_data_len; for (nc = augmentation; *nc; ++nc) { char c = *nc; switch (c) { case 'z': /* Means that the augmentation data is present. */ continue; case 'S': /* Indicates this is a signal stack frame. Debuggers have to do special handling. We don't need to do more than print this flag at the right time, though (see dwarfdump where it prints the augmentation string). A signal stack frame (in some OS's) can only be unwound (backtraced) by knowing it is a signal stack frame (perhaps by noticing the name of the function for the stack frame if the name can be found somehow) and figuring out (or knowing) how the kernel and libc pushed a structure onto the stack and loading registers from that structure. Totally different from normal stack unwinding. This flag gives an unwinder a big leg up by decoupling the 'hint: this is a stack frame' from knowledge like the function name (the name might be unavailable at unwind time). */ break; case 'L': if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *lsda_enc_out = *(unsigned char *) cur_aug_p; ++cur_aug_p; break; case 'R': /* Followed by a one byte argument giving the pointer encoding for the address pointers in the fde. */ if (cur_aug_p >= end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *fde_begin_enc_out = *(unsigned char *) cur_aug_p; ++cur_aug_p; break; case 'P':{ int res = DW_DLV_ERROR; Dwarf_Small *updated_aug_p = 0; unsigned char encoding = 0; if (cur_aug_p >= end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } encoding = *(unsigned char *) cur_aug_p; *pers_hand_enc_out = encoding; ++cur_aug_p; if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* DW_EH_PE_pcrel makes no sense here, so we turn it off via a section pointer of NULL. */ res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, cur_aug_p, encoding, end_aug_p, address_size, gnu_pers_addr_out, &updated_aug_p, error); if (res != DW_DLV_OK) { return res; } cur_aug_p = updated_aug_p; if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } } break; default: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } } return DW_DLV_OK; } /* Given augmentation character (the encoding) giving the address format, read the address from input_field and return an incremented value 1 past the input bytes of the address. Push the address read back thru the *addr pointer. See LSB (Linux Standard Base) exception handling documents. */ static int read_encoded_ptr(Dwarf_Debug dbg, Dwarf_Small * section_pointer, Dwarf_Small * input_field, int gnu_encoding, Dwarf_Small * section_end, Dwarf_Half address_size, Dwarf_Unsigned * addr, Dwarf_Small ** input_field_updated, Dwarf_Error *error) { int value_type = gnu_encoding & 0xf; Dwarf_Small *input_field_original = input_field; if (gnu_encoding == 0xff) { /* There is no data here. */ *addr = 0; *input_field_updated = input_field; /* Should we return DW_DLV_NO_ENTRY? */ return DW_DLV_OK; } switch (value_type) { case DW_EH_PE_absptr:{ /* value_type is zero. Treat as pointer size of the object. */ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, address_size,error,section_end); *addr = ret_value; *input_field_updated = input_field + address_size; } break; case DW_EH_PE_uleb128:{ Dwarf_Unsigned val = 0; DECODE_LEB128_UWORD_CK(input_field,val,dbg,error,section_end); *addr = val; *input_field_updated = input_field; } break; case DW_EH_PE_udata2:{ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, 2,error,section_end); *addr = ret_value; *input_field_updated = input_field + 2; } break; case DW_EH_PE_udata4:{ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, DWARF_32BIT_SIZE,error,section_end); *addr = ret_value; *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; case DW_EH_PE_udata8:{ Dwarf_Unsigned ret_value = 0; /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, DWARF_64BIT_SIZE,error,section_end); *addr = ret_value; *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; case DW_EH_PE_sleb128:{ Dwarf_Signed val = 0; DECODE_LEB128_SWORD_CK(input_field,val,dbg,error,section_end); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field; } break; case DW_EH_PE_sdata2:{ Dwarf_Unsigned val = 0; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, 2, error,section_end); SIGN_EXTEND(val, 2); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + 2; } break; case DW_EH_PE_sdata4:{ Dwarf_Unsigned val = 0; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, DWARF_32BIT_SIZE,error,section_end); SIGN_EXTEND(val, DWARF_32BIT_SIZE); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; case DW_EH_PE_sdata8:{ Dwarf_Unsigned val = 0; /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, DWARF_64BIT_SIZE,error,section_end); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; default: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; }; /* The ELF ABI for gnu does not document the meaning of DW_EH_PE_pcrel, which is awkward. It apparently means the value we got above is pc-relative (meaning section-relative), so we adjust the value. Section_pointer may be null if it is known DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an address-range value. */ if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) { /* Address (*addr) above is pc relative with respect to a section. Add to the offset the base address (from elf) of section and the distance of the field we are reading from the section-beginning to get the actual address. */ /* ASSERT: input_field_original >= section_pointer */ Dwarf_Unsigned distance = input_field_original - section_pointer; *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance; } return DW_DLV_OK; } /* All augmentation string checking done here now. For .eh_frame, gcc from 3.3 uses the z style, earlier used only "eh" as augmentation. We don't yet handle decoding .eh_frame with the z style extensions like L P. gnu_aug_encodings() does handle L P. These are nasty heuristics, but then that's life as augmentations are implementation specific. */ /* ARGSUSED */ enum Dwarf_augmentation_type _dwarf_get_augmentation_type(UNUSEDARG Dwarf_Debug dbg, Dwarf_Small * augmentation_string, int is_gcc_eh_frame) { enum Dwarf_augmentation_type t = aug_unknown; char *ag_string = (char *) augmentation_string; if (!ag_string[0]) { /* Empty string. We'll just guess that we know what this means: standard dwarf2/3 with no implementation-defined fields. */ t = aug_empty_string; } else if (!strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING)) { /* The string is "mti v1". Used internally at SGI, probably never shipped. Replaced by "z". Treat like 'nothing special'. */ t = aug_irix_mti_v1; } else if (ag_string[0] == 'z') { /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2 were designed as for IRIX CC, but never implemented */ /* If it's gcc, z may be any of several things. "z" or z followed optionally followed by one or more of L R P, each of which means a value may be present. Should be in eh_frame only, I think. */ if (is_gcc_eh_frame) { t = aug_gcc_eh_z; } else if (!ag_string[1]) { /* This is the normal IRIX C++ case, where there is an offset into a table in each fde. The table being for IRIX CC exception handling. */ /* DW_CIE_AUGMENTER_STRING_V0 "z" */ t = aug_irix_exception_table; } /* Else unknown. */ } else if (!strncmp(ag_string, "eh", 2)) { /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least for x86. */ t = aug_eh; } else if (!strcmp(ag_string, "armcc+")) { /* Arm uses this string to mean a bug in in Arm compilers was fixed, changing to the standard calculation of the CFA. See http://sourceware.org/ml/gdb-patches/ 2006-12/msg00249.html for details. */ t = aug_armcc; } else if (!strcmp(ag_string, "HC")) { t = aug_metaware; } else { } return t; } /* Using augmentation, and version read in the augmentation data for GNU eh. Return DW_DLV_OK if we succeeded, DW_DLV_ERR if we fail. On success, update 'size_of_augmentation_data' with the length of the fields that are part of augmentation (so the caller can increment frame_ptr appropriately). 'frame_ptr' points within section. 'section_end' points to end of section area of interest. */ /* ARGSUSED */ static int get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, unsigned long *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_ptr_end, char *augmentation, Dwarf_Error *error) { char *suffix = 0; unsigned long augdata_size = 0; if (augtype == aug_gcc_eh_z) { /* Has leading 'z'. */ UNUSEDARG Dwarf_Unsigned val = 0; Dwarf_Unsigned leb128_length = 0; /* Dwarf_Unsigned eh_value = */ DECODE_LEB128_UWORD_LEN_CK(frame_ptr,val,leb128_length, dbg,error,section_ptr_end); augdata_size += leb128_length; suffix = augmentation + 1; } else { /* Prefix is 'eh'. As in gcc 3.2. No suffix present apparently. */ suffix = augmentation + 2; } if (*suffix) { /* We have no idea what this is as yet. Some extensions beyond dwarf exist which we do not yet handle. */ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *size_of_augmentation_data = augdata_size; return DW_DLV_OK; } /* To properly release all spaced used. Earlier approaches (before July 15, 2005) letting client do the dealloc directly left some data allocated. This is directly called by consumer code. */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, Dwarf_Cie * cie_data, Dwarf_Signed cie_element_count, Dwarf_Fde * fde_data, Dwarf_Signed fde_element_count) { Dwarf_Signed i = 0; for (i = 0; i < cie_element_count; ++i) { Dwarf_Frame frame = cie_data[i]->ci_initial_table; if (frame) { dwarf_dealloc(dbg, frame, DW_DLA_FRAME); } dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); } for (i = 0; i < fde_element_count; ++i) { dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); } if (cie_data) { dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); } if (fde_data) { dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); } } libdwarf-20210528/libdwarf/pro_macinfo.c0000664000175000017500000003274213764007262014745 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #include "libdwarfdefs.h" #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_macinfo.h" /* I don't much like the error strings this generates, since like the rest of libdwarf they are simple strings with no useful numbers in them. But that's not something I can fix without more work than I have time for right now. davea Nov 94. */ /* these are gross overestimates of the number of ** bytes needed to store a number in LEB form. ** Just estimates, and since blocks are reasonable size, ** the end-block waste is small. ** Of course the waste is NOT present on disk. */ #define COMMAND_LEN ENCODE_SPACE_NEEDED #define LINE_LEN ENCODE_SPACE_NEEDED #define BASE_MACINFO_MALLOC_LEN 2048 static int libdwarf_compose_begin(Dwarf_P_Debug dbg, int code, size_t maxlen, int *compose_error_type) { unsigned char *nextchar; struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; if (curblk == 0) { struct dw_macinfo_block_s *newb; size_t len; /* initial allocation */ size_t blen = BASE_MACINFO_MALLOC_LEN; if (blen < maxlen) { blen = 2 * maxlen; } len = sizeof(struct dw_macinfo_block_s) + blen; newb = (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); if (!newb) { *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; return DW_DLV_ERROR; } newb->mb_data = (char *) newb + sizeof(struct dw_macinfo_block_s); newb->mb_avail_len = blen; newb->mb_used_len = 0; newb->mb_macinfo_data_space_len = blen; dbg->de_first_macinfo = newb; dbg->de_current_macinfo = newb; curblk = newb; } else if (curblk->mb_avail_len < maxlen) { struct dw_macinfo_block_s *newb; size_t len; /* no space left in block: allocate a new block */ size_t blen = dbg->de_current_macinfo->mb_macinfo_data_space_len * 2; if (blen < maxlen) { blen = 2 * maxlen; } len = sizeof(struct dw_macinfo_block_s) + blen; newb = (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); if (!newb) { *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; return DW_DLV_ERROR; } newb->mb_data = (char *) newb + sizeof(struct dw_macinfo_block_s); newb->mb_avail_len = blen; newb->mb_used_len = 0; newb->mb_macinfo_data_space_len = blen; dbg->de_first_macinfo->mb_next = newb; dbg->de_current_macinfo = newb; curblk = newb; } /* now curblk has enough room */ dbg->de_compose_avail = curblk->mb_avail_len; dbg->de_compose_used_len = curblk->mb_used_len; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); *nextchar = code; dbg->de_compose_avail--; ++dbg->de_compose_used_len; return DW_DLV_OK; } static void libdwarf_compose_add_string(Dwarf_P_Debug dbg, const char *string, size_t len) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; unsigned char *nextchar; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); len += 1; /* count the null terminator */ memcpy(nextchar, string, len); dbg->de_compose_avail -= len; dbg->de_compose_used_len += len; return; } static int libdwarf_compose_add_line(Dwarf_P_Debug dbg, Dwarf_Unsigned line, int *compose_error_type) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; unsigned char *nextchar; int res; int nbytes; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); /* Put the created leb number directly into the macro buffer If dbg->de_compose_avail is > INT_MAX this will not work as the 'int' will look negative to _dwarf_pro_encode_leb128_nm! */ res = _dwarf_pro_encode_leb128_nm(line, &nbytes, (char *) nextchar, (int) dbg->de_compose_avail); if (res != DW_DLV_OK) { *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; return DW_DLV_ERROR; } dbg->de_compose_avail -= nbytes; dbg->de_compose_used_len += nbytes; return DW_DLV_OK; } /* This function actually 'commits' the space used by the preceeding calls. */ static int libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) { *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; return DW_DLV_ERROR; } curblk->mb_avail_len = dbg->de_compose_avail; curblk->mb_used_len = dbg->de_compose_used_len; return DW_DLV_OK; } int dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned line, char *macname, char *macvalue, Dwarf_Error * error) { size_t len; size_t len2; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (macname == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return DW_DLV_ERROR; } len = strlen(macname) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return DW_DLV_ERROR; } if (macvalue) { len2 = strlen(macvalue) + 1; } else { len2 = 0; } /* 1 for space character we add */ length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1; res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_add_line(dbg, line, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } libdwarf_compose_add_string(dbg, macname, len); libdwarf_compose_add_string(dbg, " ", 1); if (macvalue) { libdwarf_compose_add_string(dbg, " ", 1); libdwarf_compose_add_string(dbg, macvalue, len2); } res = libdwarf_compose_complete(dbg, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } return DW_DLV_OK; } int dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned line, char *macname, Dwarf_Error * error) { size_t len; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (macname == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return DW_DLV_ERROR; } len = strlen(macname) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return DW_DLV_ERROR; } length_est = COMMAND_LEN + LINE_LEN + len; res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_add_line(dbg, line, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } libdwarf_compose_add_string(dbg, macname, len); res = libdwarf_compose_complete(dbg, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } return DW_DLV_OK; } int dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned fileindex, Dwarf_Unsigned linenumber, Dwarf_Error * error) { size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } length_est = COMMAND_LEN + LINE_LEN + LINE_LEN; res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_add_line(dbg, fileindex, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_add_line(dbg, linenumber, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } return DW_DLV_OK; } int dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error) { size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } length_est = COMMAND_LEN; res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, &compose_error_type); if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_complete(dbg, &compose_error_type); if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error, compose_error_type); return res; } return res; } int dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char *string, Dwarf_Error * error) { size_t len; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (string == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return DW_DLV_ERROR; } len = strlen(string) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return DW_DLV_ERROR; } length_est = COMMAND_LEN + LINE_LEN + len; res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } res = libdwarf_compose_add_line(dbg, constant, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return DW_DLV_ERROR; } libdwarf_compose_add_string(dbg, string, len); libdwarf_compose_complete(dbg, &compose_error_type); return DW_DLV_OK; } int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_macinfo section. */ Dwarf_Unsigned mac_num_bytes; /* Points to first byte of .debug_macinfo buffer. */ Dwarf_Small *macinfo; /* Fills in the .debug_macinfo buffer. */ Dwarf_Small *macinfo_ptr; /* Used to scan the section data buffers. */ struct dw_macinfo_block_s *m_prev; struct dw_macinfo_block_s *m_sect; /* Get the size of the debug_macinfo data */ mac_num_bytes = 0; for (m_sect = dbg->de_first_macinfo; m_sect != NULL; m_sect = m_sect->mb_next) { mac_num_bytes += m_sect->mb_used_len; } /* The final entry has a type code of 0 to indicate It is final for this CU Takes just 1 byte. */ mac_num_bytes += 1; GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO], macinfo, (unsigned long) mac_num_bytes, error); macinfo_ptr = macinfo; m_prev = 0; for (m_sect = dbg->de_first_macinfo; m_sect != NULL; m_sect = m_sect->mb_next) { memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len); macinfo_ptr += m_sect->mb_used_len; if (m_prev) { _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); m_prev = 0; } m_prev = m_sect; } *macinfo_ptr = 0; /* the type code of 0 as last entry */ if (m_prev) { _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); m_prev = 0; } dbg->de_first_macinfo = NULL; dbg->de_current_macinfo = NULL; *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_init_finish.c0000664000175000017500000022434714004650110016123 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "memcpy_swap.h" #include "dwarf_harmless.h" #include "dwarfstring.h" /* For consistency, use the HAVE_LIBELF_H symbol */ #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif /* HAVE_LIBELF_LIBELF_H */ #endif /* HAVE_LIBELF_H */ #ifdef HAVE_ZLIB_H #include "zlib.h" #endif #ifndef ELFCOMPRESS_ZLIB #define ELFCOMPRESS_ZLIB 1 #endif /* If your mingw elf.h is missing SHT_RELA and you do not need SHT_RELA support this define should work for you. It is the elf value, hopefully it will not cause trouble. If does not work, try -1 or something else and let us know what works. */ #ifndef SHT_RELA #define SHT_RELA 4 #endif #ifndef SHT_REL #define SHT_REL 9 # endif /* For COMDAT GROUPS. Guarantees we can compile. We hope. */ #ifndef SHT_GROUP #define SHT_GROUP 17 #endif #ifndef SHF_COMPRESSED /* This from ubuntu xenial. Is in top of trunk binutils as of February 2016. Elf Section Flag */ #define SHF_COMPRESSED (1 << 11) #endif #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* Global definition of the function pointer type, typedef in dwarf_opaque.h */ _dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; /* This static is copied to the dbg on dbg init so that the static need not be referenced at run time, preserving better locality of reference. Value is 0 means do the string check. Value non-zero means do not do the check. */ static Dwarf_Small _dwarf_assume_string_in_bounds; static Dwarf_Small _dwarf_apply_relocs = 1; /* Call this after calling dwarf_init but before doing anything else. It applies to all objects, not just the current object. */ int dwarf_set_reloc_application(int apply) { int oldval = _dwarf_apply_relocs; _dwarf_apply_relocs = apply; return oldval; } int dwarf_set_stringcheck(int newval) { int oldval = _dwarf_assume_string_in_bounds; _dwarf_assume_string_in_bounds = newval; return oldval; } static int startswith(const char * input, char* ckfor) { size_t cklen = strlen(ckfor); if (! strncmp(input,ckfor,cklen)) { return TRUE; } return FALSE; } #if 0 static int endswith(const char * input, char* ckfor) { size_t inlen = strlen(input); size_t endlen = strlen(ckfor); const char * endck = 0; if (endlen > inlen) { return FALSE; } endck = input+inlen - endlen; if (! strcmp(endck,ckfor) ) { return TRUE; } return FALSE; } #endif /* Unifies the basic duplicate/empty testing and section data setting to one place. */ static int get_basic_section_data(Dwarf_Debug dbg, struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index, unsigned group_number, Dwarf_Error* error, int duperr, int emptyerr ) { /* There is an elf convention that section index 0 is reserved, and that section is always empty. Non-elf object formats must honor that by ensuring that (when they assign numbers to 'sections' or 'section-like-things') they never assign a real section section-number 0 to dss_index. */ if (secdata->dss_index != 0) { DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR); } if (doas->size == 0) { /* As of 2018 it seems impossible to detect (via dwarfdump) whether emptyerr has any practical effect, whether TRUE or FALSE. */ if (emptyerr == 0 ) { /* Allow empty section. */ return DW_DLV_OK; } /* Know no reason to allow section */ DWARF_DBG_ERROR(dbg, emptyerr, DW_DLV_ERROR); } secdata->dss_index = section_index; secdata->dss_size = doas->size; secdata->dss_group_number = group_number; secdata->dss_addr = doas->addr; secdata->dss_link = doas->link; secdata->dss_entrysize = doas->entrysize; if (_dwarf_get_elf_flags_func_ptr) { /* We do this so we do not need to update the public struct Dwarf_Obj_Access_Section_s and thereby cause binary and source incompatibility. */ Dwarf_Unsigned flags = 0; Dwarf_Unsigned addralign = 0; int res = 0; int interr = 0; struct Dwarf_Obj_Access_Interface_s *o = 0; o = dbg->de_obj_file; res = _dwarf_get_elf_flags_func_ptr( o->object, section_index, &flags,&addralign, &interr); if (res == DW_DLV_ERROR) { /* Should never get here. */ DWARF_DBG_ERROR(dbg, interr, DW_DLV_ERROR); } if (res == DW_DLV_NO_ENTRY) { return res; } secdata->dss_flags = flags; secdata->dss_addralign = addralign; if (flags & SHF_COMPRESSED) { secdata->dss_shf_compressed = TRUE; } /* We are not looking at section bytes so we do not know if the first 4 bytes are ZLIB */ } return DW_DLV_OK; } static void add_relx_data_to_secdata( struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index,int is_rela) { secdata->dss_reloc_index = section_index; secdata->dss_reloc_size = doas->size; secdata->dss_reloc_entrysize = doas->entrysize; secdata->dss_reloc_addr = doas->addr; secdata->dss_reloc_symtab = doas->link; secdata->dss_reloc_link = doas->link; secdata->dss_is_rela = is_rela; } /* Used to add the specific information for a debug related section Called on each section of interest by section name. DWARF_MAX_DEBUG_SECTIONS must be large enough to allow that all sections of interest fit in the table. returns DW_DLV_ERROR or DW_DLV_OK. */ static int add_debug_section_info(Dwarf_Debug dbg, /* Name as seen in object file. */ const char *name, const char *standard_section_name, unsigned obj_sec_num, struct Dwarf_Section_s *secdata, unsigned groupnum, /* The have_dwarf flag is a somewhat imprecise way to determine if there is at least one 'meaningful' DWARF information section present in the object file. If not set on some section we claim (later) that there is no DWARF info present. see 'foundDwarf' in this file */ int duperr,int emptyerr,int have_dwarf, int havezdebug, int *err) { unsigned total_entries = dbg->de_debug_sections_total_entries; if (secdata->dss_is_in_use) { *err = duperr; return DW_DLV_ERROR; } if (total_entries < DWARF_MAX_DEBUG_SECTIONS) { struct Dwarf_dbg_sect_s *debug_section = &dbg->de_debug_sections[total_entries]; secdata->dss_is_in_use = TRUE; debug_section->ds_name = name; debug_section->ds_number = obj_sec_num; debug_section->ds_secdata = secdata; debug_section->ds_groupnumber = groupnum; secdata->dss_name = name; /* Actual name from object file. */ secdata->dss_standard_name = standard_section_name; secdata->dss_number = obj_sec_num; secdata->dss_zdebug_requires_decompress = havezdebug; /* We don't yet know about SHF_COMPRESSED */ debug_section->ds_duperr = duperr; debug_section->ds_emptyerr = emptyerr; debug_section->ds_have_dwarf = have_dwarf; debug_section->ds_have_zdebug = havezdebug; ++dbg->de_debug_sections_total_entries; return DW_DLV_OK; } /* This represents a bug in libdwarf. Mis-setup-DWARF_MAX_DEBUG_SECTIONS. Or possibly a use of section groups that is not supported. */ *err = DW_DLE_TOO_MANY_DEBUG; return DW_DLV_ERROR; } #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("dump_bytes: %s ",msg); for (; cur < end; cur++) { printf("%02x",*cur); } printf("\n"); } static int all_sig8_bits_zero(Dwarf_Sig8 *val) { unsigned u = 0; for ( ; u < sizeof(*val); ++u) { if (val->signature[u] != 0) { return FALSE; } } return TRUE; } #endif /* Return DW_DLV_OK etc. */ static int set_up_section(Dwarf_Debug dbg, /* Section name from object format. Might start with .zdebug not .debug if compressed section. */ const char *secname, /* Standard section name, such as .debug_info */ const char *sec_standard_name, /* Section number from object format */ unsigned obj_sec_num, /* The name associated with this secdata in libdwarf */ const char *targname, /* DW_GROUPNUMBER_ANY or BASE or DWO or some other group num */ unsigned groupnum_of_sec, struct Dwarf_Section_s *secdata, int duperr,int emptyerr,int have_dwarf, int *err) { /* Here accomodate the .debug or .zdebug version, (and of course non- .debug too, but those never zlib) . SECNAMEMAX should be a little bigger than any section name we care about as possibly compressed, which is to say bigger than any standard section name. */ #define SECNAMEMAX 30 int secnamelen = strlen(secname); /* static const char *dprefix = ".debug_"; */ #define DPREFIXLEN 7 static const char *zprefix = ".zdebug_"; #define ZPREFIXLEN 8 int havezdebug = FALSE; int namesmatch = FALSE; /* For example, if the secname is .zdebug_info we update the finaltargname to .debug_info to match with the particular (known, predefined) object section name. We add one character, so check to see if it will, in the end, fit. See the SET_UP_SECTION macro. */ if (secnamelen >= SECNAMEMAX) { /* This is not the target section. our caller will keep looking. */ return DW_DLV_NO_ENTRY; } if ((secnamelen+1) < SECNAMEMAX && !strncmp(secname,zprefix,ZPREFIXLEN) && !strcmp(secname+ZPREFIXLEN,targname+DPREFIXLEN)) { /* zprefix version matches the object section name so the section is compressed and is the section this targname applies to. */ havezdebug = TRUE; namesmatch = TRUE; } else if (!strcmp(secname,targname)) { namesmatch = TRUE; } #undef ZPREFIXLEN #undef DPREFIXLEN #undef SECNAMEMAX if (!namesmatch) { /* This is not the target section. our caller will keep looking. */ return DW_DLV_NO_ENTRY; } /* SETUP_SECTION. See also BUILDING_SECTIONS, BUILDING_MAP */ { /* The section name is a match with targname, or the .zdebug version of targname. */ int sectionerr = 0; sectionerr = add_debug_section_info(dbg,secname, sec_standard_name, obj_sec_num, secdata, groupnum_of_sec, duperr,emptyerr, have_dwarf, havezdebug,err); if (sectionerr != DW_DLV_OK) { /* *err is set already */ return sectionerr; } } return DW_DLV_OK; } #define SET_UP_SECTION(mdbg,mname,mtarg,mgrp,minfo,me1,me2,mdw,mer) \ { \ int lerr = 0; \ lerr = set_up_section(mdbg, \ mname, /* actual section name */ \ mtarg, /* std section name */ \ /* scn_number from macro use context */ \ scn_number,mtarg,mgrp, \ minfo, \ me1,me2,mdw,mer); \ if (lerr != DW_DLV_NO_ENTRY) { \ return lerr; \ } /* else fall through. */ \ } /* If running this long set of tests is slow enough to matter one could set up a local tsearch tree with all this content and search it instead of this set of sequential tests. Or use a switch(){} here with a search tree to to turn name into index for the switch(). */ static int enter_section_in_de_debug_sections_array(Dwarf_Debug dbg, const char *scn_name, /* This is the number of the section in the object file. */ unsigned scn_number, unsigned group_number, int *err) { /* Setup the table that contains the basic information about the sections that are DWARF related. The entries are very unlikely to change very often. */ SET_UP_SECTION(dbg,scn_name,".debug_info", group_number, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_info.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_types", group_number, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); /* types.dwo is non-standard. DWARF4 GNU maybe. */ SET_UP_SECTION(dbg,scn_name,".debug_types.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev", group_number, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_aranges", group_number, &dbg->de_debug_aranges, DW_DLE_DEBUG_ARANGES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line", group_number, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, TRUE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_line_str", group_number, &dbg->de_debug_line_str, DW_DLE_DEBUG_LINE_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_frame", group_number, &dbg->de_debug_frame, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); /* gnu egcs-1.1.2 data */ SET_UP_SECTION(dbg,scn_name,".eh_frame", group_number, &dbg->de_debug_frame_eh_gnu, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_loc", group_number, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); /* .debug_loc.dwo would be non-standard. */ SET_UP_SECTION(dbg,scn_name,".debug_loc.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_pubnames", group_number, &dbg->de_debug_pubnames, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str", group_number, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); /* Section new in DWARF3. */ SET_UP_SECTION(dbg,scn_name,".debug_pubtypes", group_number, &dbg->de_debug_pubtypes, /*13*/ DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_loclists", group_number, &dbg->de_debug_loclists, /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_loclists.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_loclists, /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_rnglists", group_number, &dbg->de_debug_rnglists, /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_rnglists.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_rnglists, /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_str_offsets", group_number, &dbg->de_debug_str_offsets, DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_str_offsets.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_str_offsets, DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_funcnames", group_number, &dbg->de_debug_funcnames, /*11*/ DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only, created years before DWARF3. Content essentially identical to .debug_pubtypes. */ SET_UP_SECTION(dbg,scn_name,".debug_typenames", group_number, &dbg->de_debug_typenames, /*12*/ DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_varnames", group_number, &dbg->de_debug_varnames, DW_DLE_DEBUG_VARNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_weaknames", group_number, &dbg->de_debug_weaknames, DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_macinfo", group_number, &dbg->de_debug_macinfo, DW_DLE_DEBUG_MACINFO_DUPLICATE,0, TRUE,err); /* ".debug_macinfo.dwo" is not allowed. */ /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro", group_number, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_ranges", group_number, &dbg->de_debug_ranges, DW_DLE_DEBUG_RANGES_DUPLICATE,0, TRUE,err); /* No .debug_ranges.dwo allowed. */ /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_sup", group_number, &dbg->de_debug_sup, DW_DLE_DEBUG_SUP_DUPLICATE,0, TRUE,err); /* No .debug_sup.dwo allowed. */ /* .symtab and .strtab have to be in any group. */ SET_UP_SECTION(dbg,scn_name,".symtab", group_number, &dbg->de_elf_symtab, DW_DLE_DEBUG_SYMTAB_ERR,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".strtab", group_number, &dbg->de_elf_strtab, DW_DLE_DEBUG_STRTAB_ERR,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_addr", group_number, &dbg->de_debug_addr, DW_DLE_DEBUG_ADDR_DUPLICATE,0, TRUE,err); /* No .debug_addr.dwo allowed. */ /* gdb added this. */ SET_UP_SECTION(dbg,scn_name,".gdb_index", group_number, &dbg->de_debug_gdbindex, DW_DLE_DUPLICATE_GDB_INDEX,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_names", group_number, &dbg->de_debug_names, /*13*/ DW_DLE_DEBUG_NAMES_DUPLICATE,0, FALSE,err); /* No .debug_names.dwo allowed. */ /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_cu_index", DW_GROUPNUMBER_DWO, &dbg->de_debug_cu_index, DW_DLE_DUPLICATE_CU_INDEX,0, FALSE,err); /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_tu_index", DW_GROUPNUMBER_DWO, &dbg->de_debug_tu_index, DW_DLE_DUPLICATE_TU_INDEX,0, FALSE,err); /* GNU added this. It is not part of DWARF */ SET_UP_SECTION(dbg,scn_name,".gnu_debuglink", DW_GROUPNUMBER_DWO, &dbg->de_gnu_debuglink, DW_DLE_DUPLICATE_GNU_DEBUGLINK,0, FALSE,err); /* GNU added this. It is not part of DWARF */ SET_UP_SECTION(dbg,scn_name,".note.gnu.build-id", DW_GROUPNUMBER_DWO, &dbg->de_note_gnu_buildid, DW_DLE_DUPLICATE_GNU_DEBUGLINK,0, FALSE,err); /* GNU added this. It is not part of DWARF */ SET_UP_SECTION(dbg,scn_name,".debug_gnu_pubtypes.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_gnu_pubtypes, DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_gnu_pubtypes", group_number, &dbg->de_debug_gnu_pubtypes, DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_gnu_pubnames.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_gnu_pubnames, DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_gnu_pubnames", group_number, &dbg->de_debug_gnu_pubnames, DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES,0, FALSE,err); return DW_DLV_NO_ENTRY; } static int is_section_name_known_already(Dwarf_Debug dbg, const char *scn_name) { unsigned i = 0; for ( ; i < dbg->de_debug_sections_total_entries; ++i) { struct Dwarf_dbg_sect_s *section = &dbg->de_debug_sections[i]; if (!strcmp(scn_name, section->ds_name)) { /* The caller will declare this a duplicate, an error. */ return DW_DLV_OK; } } /* This is normal, we expect we've not accepted scn_name already. */ return DW_DLV_NO_ENTRY; } /* Given an Elf ptr, set up dbg with pointers to all the Dwarf data sections. Return NULL on error. This function is also responsible for determining whether the given object contains Dwarf information or not. The test currently used is that it contains either a .debug_info or a .debug_frame section. If not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to return DW_DLV_NO_ENTRY. Earlier, we had thought of using only the presence/absence of .debug_info to test, but we added .debug_frame since there could be stripped objects that have only a .debug_frame section for exception processing. DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR This does not allow for section-groups in object files, for which many .debug_info (and other DWARF) sections may exist. We process. .rela (SHT_RELA) and .rel (SHT_REL) sections because with .rela the referencing section offset value is zero whereas with .rel the referencing section value is already correct for the object itself. In other words, we do it because of the definition of .rela relocations in Elf. However! In some cases clang emits a .rel section (at least for .rel.debug_info) where symtab entries have an st_value that must be treated like an addend: the compiler did not bother to backpatch the DWARF information for these. */ /* These help us ignore some sections that are irrelevant to libdwarf. Maybe should use a hash table instead of sequential search? */ int _dwarf_ignorethissection(const char *scn_name) { if (!strcmp(scn_name,".bss")) { return TRUE; } if (!strcmp(scn_name,".comment")) { return TRUE; } if (!strcmp(scn_name,".sbss")) { return TRUE; } if (!strcmp(scn_name,".jcr")) { return TRUE; } if (!strcmp(scn_name,".init")) { return TRUE; } if (!strcmp(scn_name,".fini_array")) { return TRUE; } if (!strcmp(scn_name,".fini")) { return TRUE; } if (!strcmp(scn_name,".fini_array")) { return TRUE; } if (!strcmp(scn_name,".interp")) { return TRUE; } if (!strcmp(scn_name,".text")) { return TRUE; } if (!strcmp(scn_name,".rela.text")) { return TRUE; } if (!strcmp(scn_name,".rel.text")) { return TRUE; } if (!strcmp(scn_name,".plt")) { return TRUE; } if (!strcmp(scn_name,".rela.plt")) { return TRUE; } if (!strcmp(scn_name,".rel.plt")) { return TRUE; } if (!strcmp(scn_name,".data")) { return TRUE; } if (!strcmp(scn_name,".rel.data")) { return TRUE; } if (!strcmp(scn_name,".rela.data")) { return TRUE; } if (!strcmp(scn_name,".got")) { return TRUE; } if (!strcmp(scn_name,".rela.got")) { return TRUE; } if (!strcmp(scn_name,".rel.got")) { return TRUE; } return FALSE; } /* For an object file with an incorrect rela section name, readelf prints correct debug information, as the tool takes the section type instead of the section name. So check the section name but test section type. */ static int is_a_relx_section(const char *scn_name,int type,int *is_rela) { if (startswith(scn_name,".rela.")) { *is_rela = TRUE; return TRUE; } if (startswith(scn_name,".rel.")) { *is_rela = FALSE; return TRUE; } if (type == SHT_RELA) { *is_rela = TRUE; return TRUE; } if (type == SHT_REL) { *is_rela = FALSE; return TRUE; } *is_rela = FALSE; return FALSE; } /* ASSERT: names like .debug_ or .zdebug_ never passed in here! */ static int is_a_special_section_semi_dwarf(const char *scn_name) { if (!strcmp(scn_name,".strtab") || !strcmp(scn_name,".symtab")) { return TRUE; } /* It's not one of these special sections referenced in the test. */ return FALSE; } static int this_section_dwarf_relevant(const char *scn_name, int type, int *is_rela) { /* A small helper function for _dwarf_setup(). */ if (startswith(scn_name, ".zdebug_") || startswith(scn_name, ".debug_")) { /* standard debug */ return TRUE; } if (_dwarf_ignorethissection(scn_name)) { return FALSE; } /* Now check if a special section could be in a section_group, but though seems unlikely. */ if (!strcmp(scn_name, ".eh_frame")) { /* This is not really a group related file, but it is harmless to consider it such. */ return TRUE; } if (!strcmp(scn_name, ".gnu_debuglink")) { /* This is not a group or DWARF related file, but it is useful for split dwarf. */ return TRUE; } if (!strcmp(scn_name, ".note.gnu.build-id")) { /* This is not a group or DWARF related file, but it is useful for split dwarf. */ return TRUE; } if (!strcmp(scn_name, ".gdb_index")) { return TRUE; } if (is_a_special_section_semi_dwarf(scn_name)) { return TRUE; } if (is_a_relx_section(scn_name,type,is_rela)) { return TRUE; } /* All sorts of sections are of no interest: .text .rel. and many others. */ return FALSE; } /* This assumes any non-Elf object files have no SHT_GROUP sections. So this code will not be invoked on non-Elf objects. One supposes this is unlikely to match any non-Elf version of COMDAT. */ static int insert_sht_list_in_group_map(Dwarf_Debug dbg, struct Dwarf_Obj_Access_Section_s *doas, unsigned comdat_group_number, unsigned section_number, Dwarf_Unsigned section_count, struct Dwarf_Obj_Access_Interface_s * obj, unsigned *did_add_map, Dwarf_Error *error) { struct Dwarf_Section_s secdata; Dwarf_Small * data = 0; int res = 0; Dwarf_Small* secend = 0; memset(&secdata,0,sizeof(secdata)); secdata.dss_size = doas->size; secdata.dss_entrysize = doas->entrysize; secdata.dss_group_number = 1; /* arbitrary. */ secdata.dss_index = section_number; secdata.dss_name = ".group"; secdata.dss_standard_name = ".group"; secdata.dss_number = section_number; secdata.dss_ignore_reloc_group_sec = TRUE; res = _dwarf_load_section(dbg,&secdata,error); if (res != DW_DLV_OK) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } return res; } if (!secdata.dss_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } if (doas->entrysize != 4) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } /* So now pick up the data in dss_data. It is an array of 32 bit fields. Entry zero is just a constant 1. Each additional is a section number. */ data = secdata.dss_data; secend = data + secdata.dss_size; { unsigned i = 1; unsigned count = doas->size/doas->entrysize; Dwarf_Unsigned fval = 0; /* The fields treatments with regard to endianness is unclear. In any case a single bit should be on, as 0x01000000 without any endiannes swapping. Or so it seems given limited evidence. We read with length checking and allow the reader to byte swap and then fix things. At least one test case has big-endian data but little-endian SHT_GROUP data. */ if ((data+DWARF_32BIT_SIZE) > secend) { /* Duplicates the check in READ_UNALIGNED_CK so we can free allocated memory bere. */ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,fval,Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error, secend); if (fval != 1 && fval != 0x1000000) { /* Could be corrupted elf object. */ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } data = data + doas->entrysize; for (i = 1 ; i < count ; ++i) { Dwarf_Unsigned val = 0; if ((data+DWARF_32BIT_SIZE) > secend) { /* Duplicates the check in READ_UNALIGNED_CK so we can free allocated memory bere. */ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,val,Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error, secend); if (val > section_count) { /* Might be confused endianness by the compiler generating the SHT_GROUP. This is pretty horrible. */ Dwarf_Unsigned valr = 0; _dwarf_memcpy_swap_bytes(&valr,&val, DWARF_32BIT_SIZE); if (valr > section_count) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error, DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } /* Ok. Yes, ugly. */ val = valr; } { /* Ensure this group entry DWARF relevant before adding to group map */ struct Dwarf_Obj_Access_Section_s doasx; int resx = DW_DLV_ERROR; int err = 0; int is_rela = FALSE; memset(&doasx,0,sizeof(doasx)); resx = obj->methods->get_section_info(obj->object, val, &doasx, &err); if (resx == DW_DLV_NO_ENTRY){ /* Should we really ignore this? */ continue; } else if (resx == DW_DLV_ERROR){ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } _dwarf_error(dbg,error,err); return resx; } if (!this_section_dwarf_relevant(doasx.name, doasx.type,&is_rela) ) { continue; } data += DWARF_32BIT_SIZE; *did_add_map = TRUE; res = _dwarf_insert_in_group_map(dbg, comdat_group_number,val, doasx.name, error); if (res != DW_DLV_OK) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } return res; } } } } if (secdata.dss_data_was_malloc) { free(secdata.dss_data); secdata.dss_data = 0; } return DW_DLV_OK; } /* Split dwarf CUs can be in an object with non-split or split may be in a separate object. If all in one object the default is to deal with group_number and ignore DW_GROUPNUMBER_DWO. If only .dwo the default is DW_GROUPNUMBER_DWO(2). Otherwise use DW_GROUP_NUMBER_BASE(1). If there are COMDAT SHT_GROUP sections, these are assigned group numbers 3-N as needed. At present this makes the assumption that COMDAT group (ie, SHT_GROUP) sections have lower section numbers than the sections COMDAT refers to. It is not clear whether this is guaranteed, COMDAT is not an official Elf thing and documentation is scarce. In the 1990's SGI folks and others formed a committee and attempted to get COMDAT and a feature allowing section numbers greater than 16 bits into Elf, but there was no group that was able to approve such things. This is called once at dbg init time. */ static int determine_target_group(Dwarf_Unsigned section_count, struct Dwarf_Obj_Access_Interface_s * obj, unsigned *group_number_out, Dwarf_Debug dbg, Dwarf_Error *error) { unsigned obj_section_index = 0; int found_group_one = 0; int found_group_two = 0; struct Dwarf_Group_Data_s *grp = 0; unsigned comdat_group_next = 3; unsigned lowest_comdat_groupnum = 0; grp = &dbg->de_groupnumbers; grp->gd_number_of_groups = 0; grp->gd_number_of_sections = section_count; if (grp->gd_map) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_OK; } for (obj_section_index = 0; obj_section_index < section_count; ++obj_section_index) { struct Dwarf_Obj_Access_Section_s doas; int res = DW_DLV_ERROR; int err = 0; const char *scn_name = 0; unsigned groupnumber = 0; unsigned mapgroupnumber = 0; int is_rela = FALSE; memset(&doas,0,sizeof(doas)); res = obj->methods->get_section_info(obj->object, obj_section_index, &doas, &err); if (res == DW_DLV_NO_ENTRY){ return res; } else if (res == DW_DLV_ERROR){ _dwarf_error(dbg, error,err); return res; } if (doas.type == SHT_GROUP) { /* See assumptions in function comment above. */ unsigned did_add_map = 0; /* Add to our map. Here we are assuming SHT_GROUP records come first. Till proven wrong. */ res = insert_sht_list_in_group_map(dbg,&doas, comdat_group_next, obj_section_index, section_count, obj, &did_add_map,error); if (res != DW_DLV_OK) { return res; } if (!lowest_comdat_groupnum) { lowest_comdat_groupnum = comdat_group_next; } if (did_add_map) { ++grp->gd_number_of_groups; ++comdat_group_next; } continue; } scn_name = doas.name; if (!this_section_dwarf_relevant(scn_name,doas.type, &is_rela) ) { continue; } /* Now at a 'normal' section, though we do not quite know what group it is. */ res = _dwarf_section_get_target_group_from_map(dbg, obj_section_index,&groupnumber,error); if (res == DW_DLV_OK ) { /* groupnumber is set. Fall through. All COMDAT group should get here. */ mapgroupnumber = groupnumber; } else if (res == DW_DLV_ERROR) { return res; } else { /* DW_DLV_NO_ENTRY */ /* Normal non-COMDAT. groupnumber is zero. */ } /* BUILDING_MAP. See also BUILDING_SECTIONS, SETUP_SECTION */ if (!groupnumber) { res =_dwarf_dwo_groupnumber_given_name(scn_name, &groupnumber); /* DW_DLV_ERROR impossible here. */ if (res == DW_DLV_OK) { /* groupnumber set 2 */ } else { /* This is what it has to be. .rela in here too. */ groupnumber = DW_GROUPNUMBER_BASE; } } if (is_a_relx_section(scn_name,doas.type,&is_rela)) { continue; } /* ASSERT: groupnumber non-zero now */ if (!is_a_special_section_semi_dwarf(scn_name)) { if (mapgroupnumber) { /* Already in group map */ continue; } /* !mapgroupnumber */ res = _dwarf_insert_in_group_map(dbg, groupnumber,obj_section_index, scn_name, error); if (res != DW_DLV_OK) { return res; } if (groupnumber == 1) { found_group_one++; } else if (groupnumber == 2) { found_group_two++; } continue; } } if (found_group_two) { ++grp->gd_number_of_groups; } if (found_group_one) { *group_number_out = DW_GROUPNUMBER_BASE; ++grp->gd_number_of_groups; } else { if (found_group_two) { *group_number_out = DW_GROUPNUMBER_DWO; } else { if (lowest_comdat_groupnum) { *group_number_out = lowest_comdat_groupnum; } else { *group_number_out = DW_GROUPNUMBER_BASE; } } } return DW_DLV_OK; } static int _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) { const char *scn_name = 0; struct Dwarf_Obj_Access_Interface_s * obj = 0; int resn = 0; struct Dwarf_Section_s **sections = 0; Dwarf_Endianness endianness; Dwarf_Unsigned section_count = 0; unsigned default_group_number = 0; unsigned foundDwarf = FALSE; unsigned obj_section_index = 0; dbg->de_assume_string_in_bounds = _dwarf_assume_string_in_bounds; /* First make an arbitrary assumption. */ dbg->de_same_endian = 1; dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; obj = dbg->de_obj_file; endianness = obj->methods->get_byte_order(obj->object); /* Then adjust any changes we need. */ #ifdef WORDS_BIGENDIAN dbg->de_big_endian_object = 1; if (endianness == DW_OBJECT_LSB ) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #else /* little endian */ dbg->de_big_endian_object = 0; if (endianness == DW_OBJECT_MSB ) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 1; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ /* The following de_length_size is Not Too Significant. Only used one calculation, and an approximate one at that. */ dbg->de_length_size = obj->methods->get_length_size(obj->object); dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object); section_count = obj->methods->get_section_count(obj->object); resn = determine_target_group(section_count,obj, &default_group_number,dbg,error); if (resn == DW_DLV_ERROR) { return DW_DLV_ERROR; } if (dbg->de_groupnumber == DW_GROUPNUMBER_ANY) { dbg->de_groupnumber = default_group_number; } /* Allocate space to record references to debug sections that can be referenced by RELA sections in the 'sh_info' field. */ sections = (struct Dwarf_Section_s **)calloc(section_count + 1, sizeof(struct Dwarf_Section_s *)); if (!sections) { /* Impossible case, we hope. Give up. */ _dwarf_error(dbg, error, DW_DLE_SECTION_ERROR); return DW_DLV_ERROR; } /* We can skip index 0 when considering ELF files, but not other object types. Indeed regardless of the object type we should skip section 0 here. This is a convention. We depend on it. Non-elf object access code should (in itself) understand we will index beginning at 1 and adjust itself to deal with this Elf convention. Without this convention various parts of the code in this file won't work correctly. A dss_index of 0 must not be used, even though we start at 0 here. So the get_section_info() must adapt to the situation (the elf version does automatically as a result of Elf having a section zero with zero length and an empty name). */ /* ASSERT: all group map entries set up. */ for (obj_section_index = 0; obj_section_index < section_count; ++obj_section_index) { struct Dwarf_Obj_Access_Section_s doas; int res = DW_DLV_ERROR; int err = 0; unsigned groupnumber = 0; unsigned mapgroupnumber = 0; int is_rela = FALSE; res = _dwarf_section_get_target_group_from_map(dbg, obj_section_index, &groupnumber,error); if (res == DW_DLV_OK ) { /* groupnumber is set. Fall through */ mapgroupnumber = groupnumber; } else if (res == DW_DLV_ERROR) { free(sections); return res; } else { /* DW_DLV_NO_ENTRY */ /* fall through, a BASE or DWO group, possibly */ } memset(&doas,0,sizeof(doas)); res = obj->methods->get_section_info(obj->object, obj_section_index, &doas, &err); if (res == DW_DLV_NO_ENTRY){ free(sections); return res; } else if (res == DW_DLV_ERROR){ free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } scn_name = doas.name; if (!groupnumber) { /* This finds dwo sections, group 2 */ res = _dwarf_dwo_groupnumber_given_name(scn_name, &groupnumber); if (res == DW_DLV_NO_ENTRY) { /* No, must be group 1 */ groupnumber = DW_GROUPNUMBER_BASE; } } if (!this_section_dwarf_relevant(scn_name,doas.type, &is_rela) ) { continue; } if (!is_a_relx_section(scn_name,doas.type,&is_rela) && !is_a_special_section_semi_dwarf(scn_name)) { /* We do these actions only for group-related sections. Do for .debug_info etc, never for .strtab or .rela.* We already tested for relevance, so that part is not news. */ if (mapgroupnumber == dbg->de_groupnumber) { /* OK. Mapped. Part of the group.. This will catch the cases where there are versions of a section in multiple COMDATs and in BASE an DWO to get the right one */ } else { /* This section not mapped into this group. */ if (groupnumber == 1 && dbg->de_groupnumber > 2 && !_dwarf_section_in_group_by_name(dbg,scn_name, dbg->de_groupnumber)) { /* Load the section (but as group 1) */ } else { continue; } } } /* BUILDING_SECTIONS. See also BUILDING_MAP, SETUP_SECTION */ { /* Build up the sections table and the de_debug* etc pointers in Dwarf_Debug. */ struct Dwarf_dbg_sect_s *section; int found_match = FALSE; res = is_section_name_known_already(dbg,scn_name); if (res == DW_DLV_OK) { /* DUPLICATE */ free(sections); DWARF_DBG_ERROR(dbg, DW_DLE_SECTION_DUPLICATION, DW_DLV_ERROR); } else if (res == DW_DLV_ERROR) { free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } /* No entry: new-to-us section, the normal case. */ res = enter_section_in_de_debug_sections_array(dbg, scn_name, obj_section_index, groupnumber,&err); if (res == DW_DLV_OK) { section = &dbg->de_debug_sections[ dbg->de_debug_sections_total_entries-1]; res = get_basic_section_data(dbg, section->ds_secdata, &doas, obj_section_index, groupnumber, error, section->ds_duperr, section->ds_emptyerr); if (res != DW_DLV_OK) { free(sections); return res; } sections[obj_section_index] = section->ds_secdata; foundDwarf += section->ds_have_dwarf; found_match = TRUE; /* Normal section set up. Fall through. */ } else if (res == DW_DLV_NO_ENTRY) { /* We get here for relocation sections. Fall through. */ } else { free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } if (!found_match) { /* For an object file with incorrect rel[a] section name, the 'readelf' tool, prints correct debug information, as the tool takes the section type instead of the section name. If the current section is a RELA one and the 'sh_info' refers to a debug section, add the relocation data. */ if (is_a_relx_section(scn_name,doas.type,&is_rela)) { if ( doas.info < section_count) { if (sections[doas.info]) { add_relx_data_to_secdata( sections[doas.info], &doas, obj_section_index,is_rela); } } else { /* Something is wrong with the ELF file. */ free(sections); DWARF_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } } } /* Fetch next section */ } } /* Free table with section information. */ free(sections); if (foundDwarf) { return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* There is one table per CU and one per TU, and each table refers to the associated other DWARF data for that CU or TU. See DW_SECT_* In DWARF4 the type units are in .debug_types In DWARF5 the type units are in .debug_info. */ static int load_debugfission_tables(Dwarf_Debug dbg,Dwarf_Error *error) { int i = 0; if (dbg->de_debug_cu_index.dss_size ==0 && dbg->de_debug_tu_index.dss_size ==0) { /* This is the normal case. No debug fission. Not a .dwp object. */ return DW_DLV_NO_ENTRY; } for (i = 0; i < 2; ++i) { Dwarf_Xu_Index_Header xuptr = 0; struct Dwarf_Section_s* dwsect = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned number_of_cols /* L */ = 0; Dwarf_Unsigned number_of_CUs /* N */ = 0; Dwarf_Unsigned number_of_slots /* M */ = 0; const char *secname = 0; int res = 0; const char *type = 0; if (i == 0) { dwsect = &dbg->de_debug_cu_index; type = "cu"; } else { dwsect = &dbg->de_debug_tu_index; type = "tu"; } if ( !dwsect->dss_size ) { continue; } res = dwarf_get_xu_index_header(dbg,type, &xuptr,&version,&number_of_cols, &number_of_CUs,&number_of_slots, &secname,error); if (res == DW_DLV_NO_ENTRY) { continue; } if (res != DW_DLV_OK) { return res; } if (i == 0) { dbg->de_cu_hashindex_data = xuptr; } else { dbg->de_tu_hashindex_data = xuptr; } } return DW_DLV_OK; } /* 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) { return dwarf_object_init_b(obj,errhand,errarg, DW_GROUPNUMBER_ANY,ret_dbg,error); } /* New March 2017. Enables dealing with DWARF5 split dwarf more fully. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, unsigned groupnumber, 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; dbg->de_groupnumber = groupnumber; 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; int myerr = 0; dwarfstring msg; dwarfstring_constructor(&msg); /* 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. */ 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); dwarfstring_append(&msg,dwarf_errmsg(*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_string(dbg,error,DW_DLE_DBG_ALLOC, dwarfstring_string(&msg)); dwarfstring_destructor(&msg); 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_string(dbg,error,myerr, dwarfstring_string(&msg)); } dwarfstring_destructor(&msg); return setup_result; } dwarf_harmless_init(&dbg->de_harmless_errors, DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE); *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. NEVER returns DW_DLV_ERROR; Aside from certain categories. */ int dwarf_object_finish(Dwarf_Debug dbg, UNUSEDARG Dwarf_Error * error) { int res = 0; res = _dwarf_free_all_of_one_debug(dbg); return res; } #ifdef HAVE_ZLIB /* case 1: The input stream is assumed to contain the four letters ZLIB Followed by 8 bytes of the size of the uncompressed stream. Presented as a big-endian binary number. Following that is the stream to decompress. case 2: The section flag bit SHF_COMPRESSED (1 << 11) must be set. we then do the equivalent of reading a Elf32_External_Chdr or Elf64_External_Chdr to get the type (which must be 1) and the decompressed_length. Then what follows the implicit Chdr is decompressed. */ /* ALLOWED_ZLIB_INFLATION is a heuristic, not necessarily right. The test case klingler2/compresseddebug.amd64 actually inflates about 8 times. */ #define ALLOWED_ZLIB_INFLATION 16 static int do_decompress_zlib(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { Bytef *basesrc = (Bytef *)section->dss_data; Bytef *src = (Bytef *)basesrc; uLong srclen = section->dss_size; Dwarf_Unsigned flags = section->dss_flags; Dwarf_Small *endsection = 0; int res = 0; Bytef *dest = 0; uLongf destlen = 0; Dwarf_Unsigned uncompressed_len = 0; endsection = basesrc + srclen; if ((src + 12) >endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); } section->dss_compressed_length = section->dss_size; if (!strncmp("ZLIB",(const char *)src,4)) { unsigned i = 0; unsigned l = 8; unsigned char *c = src+4; for ( ; i < l; ++i,c++) { uncompressed_len <<= 8; uncompressed_len += *c; } src = src + 12; srclen -= 12; section->dss_uncompressed_length = uncompressed_len; section->dss_ZLIB_compressed = TRUE; } else if (flags & SHF_COMPRESSED) { /* The prefix is a struct: unsigned int type; followed by pad if following are 64bit! size-of-target-address size size-of-target-address If we read using libelf libelf knows about SHF_COMPRESSED and if the object and the running libelf do not match endianness libelf already transformed the two fields we care about to host endianness so the READ_UNALIGNED is just wrong. Just noticed this issue November 2020. */ Dwarf_Small *ptr = (Dwarf_Small *)src; Dwarf_Unsigned type = 0; Dwarf_Unsigned size = 0; /* Dwarf_Unsigned addralign = 0; */ unsigned fldsize = dbg->de_pointer_size; unsigned structsize = 3* fldsize; if (dbg->de_using_libelf) { unsigned offset = 0; unsigned offsetb = 0; #ifdef WORDS_BIGENDIAN offset = sizeof(type) - DWARF_32BIT_SIZE; offsetb = sizeof(type) - fldsize; #else /* LITTLE_ENDIAN */ offset = 0; offsetb = 0; #endif /* !BIG_ENDIAM */ memcpy(((char*)&type)+offset,ptr,(size_t) DWARF_32BIT_SIZE); ptr += fldsize; memcpy(((char*)&size)+offsetb,ptr,(size_t)fldsize); } else { READ_UNALIGNED_CK(dbg,type,Dwarf_Unsigned,ptr, DWARF_32BIT_SIZE, error,endsection); ptr += fldsize; READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,ptr,fldsize, error,endsection); } if (type != ELFCOMPRESS_ZLIB) { DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); } uncompressed_len = size; section->dss_uncompressed_length = uncompressed_len; src += structsize; srclen -= structsize; section->dss_shf_compressed = TRUE; } else { DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); } { /* According to zlib.net zlib essentially never expands the data when compressing. There is no statement about any effective limit in the compression factor though we, here, assume such a limit to check for sanity in the object file. These tests are heuristics. */ Dwarf_Unsigned max_inflated_len = srclen*ALLOWED_ZLIB_INFLATION; if (srclen > 50) { /* If srclen not super tiny lets check the following. */ if (uncompressed_len < (srclen/2)) { /* Violates the approximate invariant about compression not actually inflating. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } } if (max_inflated_len < srclen) { /* The calculation overflowed. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } if (uncompressed_len > max_inflated_len) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } } if ((src +srclen) > endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); } destlen = uncompressed_len; dest = malloc(destlen); if (!dest) { DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } res = uncompress(dest,&destlen,src,srclen); if (res == Z_BUF_ERROR) { free(dest); DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_BUF_ERROR, DW_DLV_ERROR); } else if (res == Z_MEM_ERROR) { free(dest); DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } else if (res != Z_OK) { free(dest); /* Probably Z_DATA_ERROR. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_DATA_ERROR, DW_DLV_ERROR); } /* Z_OK */ section->dss_data = dest; section->dss_size = destlen; section->dss_data_was_malloc = TRUE; section->dss_did_decompress = TRUE; return DW_DLV_OK; } #endif /* HAVE_ZLIB */ /* Load the ELF section with the specified index and set its dss_data pointer to the memory where it was loaded. */ int _dwarf_load_section(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { int res = DW_DLV_ERROR; int err = 0; struct Dwarf_Obj_Access_Interface_s *o = 0; /* check to see if the section is already loaded */ if (section->dss_data != NULL) { return DW_DLV_OK; } o = dbg->de_obj_file; /* There is an elf convention that section index 0 is reserved, and that section is always empty. Non-elf object formats must honor that by ensuring that (when they assign numbers to 'sections' or 'section-like-things') they never assign a real section section-number 0 to dss_index. There is also a convention for 'bss' that that section and its like sections have no data but do have a size. That is never true of DWARF sections */ res = o->methods->load_section( o->object, section->dss_index, §ion->dss_data, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } /* For PE and mach-o all section data was always malloc'd. We do not need to set dss_data_was_malloc though as the o->object data will eventually free the original section data. The first character of any o->object struct gives the type. */ if (res == DW_DLV_NO_ENTRY) { /* Gets this for section->dss_index 0. Which by ELF definition is a section index which is not used (reserved by Elf to mean no-section-index). Otherwise NULL dss_data gets error. BSS would legitimately have no data, but no DWARF related section could possibly be bss. We also get it if the section is present but zero-size. */ return res; } if (section->dss_ignore_reloc_group_sec) { /* Neither zdebug nor reloc apply to .group sections. */ return res; } if ((section->dss_zdebug_requires_decompress || section->dss_shf_compressed || section->dss_ZLIB_compressed) && !section->dss_did_decompress) { if (!section->dss_data) { /* Impossible. This makes no sense. Corrupt object. */ DWARF_DBG_ERROR(dbg, DW_DLE_COMPRESSED_EMPTY_SECTION, DW_DLV_ERROR); } #ifdef HAVE_ZLIB res = do_decompress_zlib(dbg,section,error); if (res != DW_DLV_OK) { return res; } section->dss_did_decompress = TRUE; #else DWARF_DBG_ERROR(dbg,DW_DLE_ZDEBUG_REQUIRES_ZLIB, DW_DLV_ERROR); #endif } if (_dwarf_apply_relocs == 0) { return res; } if (section->dss_reloc_size == 0) { return res; } if (!o->methods->relocate_a_section) { return res; } /*apply relocations */ res = o->methods->relocate_a_section( o->object, section->dss_index, dbg, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, res); } return res; } /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX -64 executable larger than 2GB using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames offsets were wrong.). */ int dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; return DW_DLV_OK; } /* This adds the new types size (new section) to the output data. Oct 27, 2011. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; return DW_DLV_OK; } /* Now with sections new to DWARF5 (unofficial list,preliminary) */ int dwarf_get_section_max_offsets_c(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size, Dwarf_Unsigned * debug_macro_size, Dwarf_Unsigned * debug_str_offsets_size, Dwarf_Unsigned * debug_sup_size, Dwarf_Unsigned * debug_cu_index_size, Dwarf_Unsigned * debug_tu_index_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; *debug_macro_size = dbg->de_debug_macro.dss_size; *debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size; *debug_sup_size = dbg->de_debug_sup.dss_size; *debug_cu_index_size = dbg->de_debug_cu_index.dss_size; *debug_tu_index_size = dbg->de_debug_tu_index.dss_size; return DW_DLV_OK; } /* Now with final sections new to DWARF5 (final) */ int dwarf_get_section_max_offsets_d(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size, Dwarf_Unsigned * debug_macro_size, Dwarf_Unsigned * debug_str_offsets_size, Dwarf_Unsigned * debug_sup_size, Dwarf_Unsigned * debug_cu_index_size, Dwarf_Unsigned * debug_tu_index_size, Dwarf_Unsigned * debug_names_size, Dwarf_Unsigned * debug_loclists_size, Dwarf_Unsigned * debug_rnglists_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; *debug_macro_size = dbg->de_debug_macro.dss_size; *debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size; *debug_sup_size = dbg->de_debug_sup.dss_size; *debug_cu_index_size = dbg->de_debug_cu_index.dss_size; *debug_tu_index_size = dbg->de_debug_tu_index.dss_size; *debug_names_size = dbg->de_debug_names.dss_size; *debug_loclists_size = dbg->de_debug_loclists.dss_size; *debug_rnglists_size = dbg->de_debug_rnglists.dss_size; return DW_DLV_OK; } /* Given a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug dbg, const char *section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error * error) { struct Dwarf_Obj_Access_Section_s doas; struct Dwarf_Obj_Access_Interface_s * obj = 0; Dwarf_Unsigned section_count = 0; Dwarf_Half section_index = 0; *section_addr = 0; *section_size = 0; obj = dbg->de_obj_file; if (NULL == obj) { return DW_DLV_NO_ENTRY; } section_count = obj->methods->get_section_count(obj->object); /* We can skip index 0 when considering ELF files, but not other object types. */ for (section_index = 0; section_index < section_count; ++section_index) { int err = 0; int res = obj->methods->get_section_info(obj->object, section_index, &doas, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } if (!strcmp(section_name,doas.name)) { *section_addr = doas.addr; *section_size = doas.size; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* Given a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug dbg, int section_index, const char **section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error * error) { *section_addr = 0; *section_size = 0; *section_name = NULL; /* Check if we have a valid section index */ if (section_index >= 0 && section_index < dwarf_get_section_count(dbg)) { int res = 0; int err = 0; struct Dwarf_Obj_Access_Section_s doas; struct Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file; if (NULL == obj) { return DW_DLV_NO_ENTRY; } res = obj->methods->get_section_info(obj->object, section_index, &doas, &err); if (res == DW_DLV_ERROR){ DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } *section_addr = doas.addr; *section_size = doas.size; *section_name = doas.name; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* Get section count */ int dwarf_get_section_count(Dwarf_Debug dbg) { struct Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file; if (NULL == obj) { /* -1 */ return DW_DLV_NO_ENTRY; } return obj->methods->get_section_count(obj->object); } Dwarf_Cmdline_Options dwarf_cmdline_options = { FALSE /* Use quiet mode by default. */ }; /* Lets libdwarf reflect a command line option, so we can get details of some errors printed using libdwarf-internal information. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options options) { dwarf_cmdline_options = options; } libdwarf-20210528/libdwarf/ChangeLog20090000664000175000017500000004513713644370703014374 000000000000002009-12-30 DavidAnderson * configure: Regenerated with autoconf 2.64. * config.guess, config.sub: Delete these. * configure.in, README: The --enable-nonshared option was coded incorrectly. The configure options are --enable-shared and --disable-nonshared work correctly. Options --disable-shared and --enable-nonshared work correctly as well (these are the default values). 2009-12-29 DavidAnderson * gennames.c: Add cast to int in printf so that the printf with * as the field width sees an int, not size_t. * Makefile.in: Add depenencies for libdwarf.so to match libdwarf.a 2009-12-26 DavidAnderson * libdwarf.h, pro_section.c, pro_reloc_symbolic.c: Reformatted a few lines that were badly formatted. Initialized local variables where a few were not initialized (this did not affect correctness, just readability). 2009-11-27 DavidAnderson * dwarf_form.c: Was an incorrect implemenation of the reading of DW_FORM_sec_offset. * libdwarf2.1.mm: Improved the documentation on reading DW_FORM_sec_offset. See dwarf_global_formref() documentation. * libdwarf2.1.pdf: Regenerate. 2009-11-27 DavidAnderson * libdwarf.h, dwarf_form.c, dwarf_query.c: Adding new form-class for the old DW_AT_MIPS_fde SGI/IRIX extension (offset into .debug_frame). 2009-11-27 DavidAnderson * libdwarf.h: Added dwarf_formexprloc() and a new error code for it. * dwarf_query.c: The new dwarf_get_form_class() function had a typo for the address class. * dwarf_form.c: dwarf_formexprloc() added so one can read DW_FORM_exprloc location expressions. * dwarf_error.c: New error added for dwarf_formexprloc(). * libdwarf2.1.mm: Document dwarf_formexprloc(). * libdwarf2.1.pdf: Regenerate. 2009-11-27 DavidAnderson * libdwarf.h: Defines typedef Dwarf_Sig8 and the new function dwarf_formsig8(). * dwarf_error.c: Now deals with the latest error codes, including a new one for dwarf_formsig8(). * libdwarf2.1.mm: Document dwarf_formsig8(). * libdwarf2.1.pdf: Regenerate. 2009-11-24 DavidAnderson * libdwarf.h: Added enum dwarf_form_class_e and dwarf_get_form_class() so clients have a simple way to get the form-class mentioned in the DWARF specification. * dwarf_query.c: Implemented dwarf_get_form_class(). * dwarf_die_deliv.c: Added dwarf_next_cu_header_b() function as more useful than dwarf_next_cu_header(). * dwarf_opaque.h: Added commentary about CU record. * dwarf_elf_access.c: Added commentary about the CU header data. * libdwarf2.1.mm: Document dwarf_next_cu_header_b() and suggest users convert to it. Document dwarf_get_form_class(). Rev 1.84 * libdwarf2.1.pdf: Regenerate. 2009-11-23 DavidAnderson * dwarf_line.c: file_name_is_full_path() did not allow for lower case in Windows root path detection (with --enable-windowspath at configure time). Now it does. 2009-11-17 DavidAnderson * gennames.c: Check the return value from fgets(). * dwarf_form.c, dwarf_util.c: Handle DW_FORM_sec_offset, new in DWARF4. * libdwarf2.1.mm: Add comment to macro example to clarify its limitation (it cannot always work). * libdwarf2.1.pdf: Regenerate. 2009-09-30 DavidAnderson * libdwarf.h: Added dwarf_insert_fde_inst_bytes() to simplify copying an fde. Added dwarf_get_cie_index() to provide a direct specific way to get a cie index for an fde. * libdwarf2.1.mm: Minor reformatting to make things easier to read. This is revision 1.82. Documented the new function dwarf_get_cie_index(). * libdwarf2.1.pdf: Regenerated. * dwarf.h: Corrected typo, DW_CFA_cfa_offset_extended_sf is really spelled DW_CFA_offset_extended_sf. Added final new attributes, tag, language. * pro_alloc.c: Reformatting a comment so the line is not so long. * libdwarf2p.1.mm: Clarified that some arguments in fde creation are MIPS/IRIX only (other targets should just pass 0). This is revision 1.27. Document the new function dwarf_insert_fde_inst_bytes(). * libdwarf2p.1.pdf: Regenerated. * config.h.in: Added HAVE_WINDOWS_PATH. * configure.in: Added --enable-windowspath to set HAVE_WINDOWS_PATH. * configure: Regenerated. * pro_section.c: Now allows use of a block of fde instructions from dwarf_insert_fde_inst_bytes(). Some indentation fixed too. * dwarf_line.c: Added detection of Windows full path if HAVE_WINDOWS_PATH defined at library build time. * pro_frame.c: Now handles dwarf3 CFA operations (but not the expression operands yet). Removed some duplicated code in a switch statement. Fixed commentary typos. Created new function dwarf_insert_fde_inst_bytes(). * pro_frame.h: Added fields to support dwarf_insert_fde_inst_bytes(). * dwarf_arange.c: dwarf_get_arange_cu_header_offset() was failing to load .debug_info, so a legitimate use of the function might crash a client. * dwarf_frame2.c: If there are CIE records but no FDEs this is not considered a 'NO ENTRY' case. It is strange but not a formal error and we might want to access the orphan CIE records (to print them when debugging a compiler, for example). * README: Documented --enable-windowspath. * dwarf_frame.c: Adding dwarf_get_cie_index() convenience function. 2009-09-09 DavidAnderson * libdwarf2p.1.mm: Improved the discussion of dwarf_transform_to_disk_form. * libdwarf2p.1.pdf: Regenerated. 2009-08-12 DavidAnderson * pro_section.c: The Dwarf_Die argument to fde creation functions is really optional (NULL is ok) and only used for an IRIX/MIPS extension. So the code now allows a NULL Dwarf_Die argument for these functions. * libdwarf2p.1.mm: Rev 1.24, 11 Aug 2009 now documents the argument as NULL for most users. * libdwarf2p.1.pdf: Regenerated Rev 1.24, 11 Aug 2009. 2009-08-07 DavidAnderson * libdwarf.h: Added to Dwarf_Regtable_Entry_s and Dwarf_Regtable_Entry_s comments. * libdwarf2.1.mm: Revised dwarf_set_frame_rule_table_size() description, making it a bit more complete. * libdwarf2.1.pdf: Regenerated, rev 1.81, 07 August 2009. 2009-08-05 DavidAnderson * libdwarf.h: Interface to dwarf_expand_frame_instructions() changed, the original could not really work right. * libdwarf2.1.mm: Documented revised dwarf_expand_frame_instructions(). * libdwarf2.1.pdf: Regenerated, rev 1.80, 05 August 2009. * dwarf_frame.c: Fixed dwarf_expand_frame_instructions(); 2009-08-05 DavidAnderson * gennames.c: Change include from getopt.h to unistd.h so the code is more universally compilable. 2009-07-24 DavidAnderson * dwarf_frame.c: Change debug printf to use libdwarf.h DW_PR macros instead of %d. 2009-07-20 DavidAnderson * libdwarf.h: Added DW_DLE_NO_ELF64_SUPPORT. * dwarf_elf_access.c: If one has no Elf64 libelf support at build time and runtime one finds an Elf64 object then we return an error (DW_DLE_NO_ELF64_SUPPORT). Pretending we could handle the elf64 was a bug. * dwarf_error.c: Adding strings for new error codes. * dwarf_elf_access.c: Add error code argument. * dwarf_elf_access.h: Add error code argument. * dwarf_original_elf_init.c: Report the correct error code instead of a generic code. 2009-07-16 DavidAnderson * libdwarf.h: Add an error message define relating to rela relocations. * dwarf_alloc.c: Add code to free malloc space (related to rela relocations). * config.h.in: Add ifdef for Sun host machines so rela processing does not segv. * dwarf_opaque.h: Add a flag to the section data to note that we malloced space when rela relocations are involved. * dwarf_elf_access.c: Refine is_32bit_abs_reloc() and is_64bit_abs_reloc() for easier debugging. Add malloc call when doing rela processing as some host libelf libraries make some libelf data areas read-only (Solaris and Irix for example). The malloc space avoids getting a segv. 2009-07-13 DavidAnderson * dwarf_elf_access.c: some cases had = where == was needed in the reloc switch code. 2009-07-05 DavidAnderson * dwarf_opaque.h: New data for .rela and unify section data information. The changes will require consumers supporting non-elf-objects to make small (hopefully simple) changes. * dwarf_init_finish.c: Note existence of .rela sections. * pro_forms.c: Explicitly allow DW_AT_const_value, DW_AT_entry_pc, DW_AT_call_file, DW_AT_call_line. * dwarf_ranges.c: Use simplified _dwarf_load_section() interface. Change an accidental C++ style // comment to oldstyle C comment. * dwarf_print_lines.c, dwarf_form.c, dwarf_query.c, dwarf_vars.c, dwarf_pubtypes.c, dwarf_frame3.c, dwarf_funcs.c, dwarf_arange.c, dwarf_global.c, dwarf_init_finish.c, dwarf_line.c, dwarf_opaque.h, dwarf_string.c, dwarf_weaks.c dwarf_util.c, dwarf_loc.c, dwarf_frame.c, dwarf_macro.c, dwarf_types.c: Use simplified _dwarf_load_section() interface. 2009-07-05 DavidAnderson * dwarf_init_finish.c: Unified some common code into a new local function , reducing file by 60 lines. * dwarf_init_finish.c: Has long checked the wrong field for duplicate debug_info and debug_abbrev. Fixed. Also noted SGI IRIX only sections by adding comments. 2009-07-04 DavidAnderson * libdwarf.h: Adding new function dwarf_CU_dieoffset_given_die(), and comments on dwarf_get_cu_die_offset_given_cu_header_offset(); * libdwarf2.1.mm: documenting dwarf_CU_dieoffset_given_die(). * libdwarf2.1.pdf: Regenerated. * dwarf_opaque.h: New structure Dwarf_Section_s consolidates section information into one struct per section with index and size so we remove many Dwarf_Debug_s fields. * dwarf_print_lines.c, dwarf_form.c, dwarf_query.c, dwarf_vars.c, dwarf_pubtypes.c, dwarf_frame3.c, dwarf_funcs.c, dwarf_alloc.c, dwarf_arange.c, dwarf_init_finish.c , dwarf_ranges.c, dwarf_line.c, dwarf_abbrev.c, dwarf_string.c, dwarf_weaks.c, dwarf_frame2.c, dwarf_util.c, dwarf_loc.c, dwarf_die_deliv.c, dwarf_frame.c, dwarf_macro.c, dwarf_types.c, Reflect Dwarf_Section_s addition using its fields. Simplify years list of SGI copyright using y-y replacing comma list. Minor reformatting for consistency with 4-space indentation. Initialize uninitialized local variables at declaration. * dwarf_addr_finder.c, dwarf_print_lines.c: Initialize 'res' local variables at declaration to DW_DLV_ERROR. * dwarf_global.c: Add dwarf_CU_dieoffset_given_die(). Reflect Dwarf_Section_s addition using its fields. Simplify years list of SGI copyright using y-y replacing comma list. Minor reformatting for consistency with 4-space indentation. Initialize uninitialized local variables at declaration. 2009-06-06 DavidAnderson * configure.in: The new option --enable_namestable switches build time to generate a runtime binary search in the dwarf_get_TAG_name() etc functions instead of the default switch statement (for the rare case one knows a compiler generates poor switch code). * configure: regenerated. * libdwarf.h: Correct format mistakes and omissions in the Dwarf_Regtable_Entry3_s comments. Add prototypes for dwarf_get_TAG_name() and the related new functions. * dwarf_frame.c: Add {} to clarify some 'if' ranges. Remove code updating the DW_FRAME_CFA_COL row when finishing up establishing the current frame table. The code should never have been there. Fixed some indentation of function formal parameters. Removed use of DW_FRAME_CFA_COL and use de_frame_cfa_col_number instead. In dwarf_get_fde_info_for_reg (the older interface) correctly return the cfa table column in the 'old style'. * gennames.c: Copied from dwarfdump.c (with changes). This generates dwarf_names.c so that libdwarf has functions like dwarf_get_TAG_name() which returns functions like dwarf_get_TAG_name() which returns the tag as a string (through a pointer argument). * dwarf.h: The first word of a comment is now capitalized (1 place). * common.c: New, used by gennames.c. * common.h: New, used by gennames.c * Makefile.in: Now contains changes which build and run gennames and create dwarf_names.o (which is part of libdwarf). * libdwarf2.1.mm: Document the new libdwarf functions. * libdwarf2.1.pdf: Regenerated as rev 1.76, 6 June 2009. 2009-06-05 DavidAnderson * dwarf.h: added new DWARF4 attribute (etc) defines. 2009-05-10 DavidAnderson * dwarf_frame.c: Remove use of DW_FRAME_UNDEFINED_VAL in favor of the value in the dbg structure. Adding comments about the meaning of an error case. 2009-05-07 DavidAnderson * Makefile.in: Ensure temp files all get deleted. 2009-05-04 DavidAnderson * dwarf_die_deliv.c: Update _dwarf_get_size_of_val() call (with its new address_size argument). * dwarf_frame.c: Use the new ci_address_size instead of de_pointer_size. * dwarf_frame.h: Added ci_address_size to cie in preparation for this value in DWARF4. * dwarf_util.h: Adding address_size functions and arguments declarations so address_size can vary by CU. * dwarf_util.c: Adding address_size functions and arguments so address_size can vary by CU. * dwarf_loc.c: Adding function dwarf_loclist_from_expr_a() as a version with an address size argument. * dwarf_frame2.c: Now initializes new ci_address_size field. * dwarf_line.c: Now uses address size for CU instead of default de_pointer_size. * dwarf_ranges.c: File left out of svn before. Implements dwarf_get_ranges() and dwarf_get_ranges_a(), the latter is new with address size passed in via a DIE pointer. * dwarf_arange.c: Added commentary. Removed erroneous insistence that every aranges group have the same address_size as the main elf object. * dwarf_query.c: Adding address size to internal calls. * dwarf_print_lines.c: Added '(file number is %d)' to -l -v -v -v output as the file number and traditional C zero-origin index index of a line table header are not the same value (see DWARF3 documentation, the end of section 6.2.5.3). * libdwarf2.1.mm: Documented dwarf_loclist_from_expr_a() and dwarf_get_ranges_a(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h: Add commentary. Add dwarf_loclist_from_expr_a() and dwarf_get_ranges_a() interfaces so address_size passed in. 2009-04-04 DavidAnderson * libdwarf.h, dwarf_frame.c: Added dwarf_set_frame_cfa_value(). Added dwarf_set_frame_rule_initial_value() as proper spelling of dwarf_set_frame_rule_inital_value(), keeping the old spelling for compatibility. * libdwarf2.1.mm: Documented Added dwarf_set_frame_cfa_value(), corrected spelling to dwarf_set_frame_rule_initial_value(). * libdwarf2.1.pdf: Regenerated. * dwarf_opaque.h: Added field de_frame_cfa_col_number so that we do not need to use magic macros at execution time. * dwarf_init_finish.c: Now sets de_frame_cfa_col_number, de_frame_same_value_number, and de_frame_undefined_value_number. 2009-02-02 DavidAnderson * dwarf.h: Added dwarf extensions reported by John Bishop. 2009-03-30 DavidAnderson * dwarf.h: Added dwarf extensions reported on the dwarf-workgroup mailing list by John DelSignore. 2009-03-19 DavidAnderson * libdwarf.h: Expanded comments. * dwarf_die_deliv.c: Expanded comments. 2009-03-16 DavidAnderson * libdwarf.h: Fixed several instances of inconsistent indentation. Documented arguments to dwarf_uncompress_integer_block(). 2009-02-17 DavidAnderson * dwarf_print_lines.c,dwarf_line.c,dwarf_frame.c: C99-isms of // comments and declarations-in-code do not belong in libdwarf. 2009-02-14 DavidAnderson * libdwarf.h: Add support for compile-time definition of the format for Dwarf_Unsigned types. Using macros for DW_PR_DUx etc. * dwarf_print_lines.c: Use the DW_PR_DUx macros. * configure.in: Define --enable-nonstandardprintf * config.h.in: new #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT * configure: Regenerated. * config.guess, config.sub: Latest version from GNU. * dwarf_line.c: Use the DW_PR_DUx macros. * dwarf_frame2.c: Use the DW_PR_DUx macros. * README: document --enable-nonstandardprintf 2009-02-13 DavidAnderson * libdwarf.h: Added argument to dwarf_print_lines() for better error reporting. Added dwarf_check_lineheader() which allows some error reporting when not calling dwarf_print_lines(). * dwarf_print_lines.c: Implements dwarf_check_lineheader() now. * dwarf_sort_line.c: Match up with new arguments to dwarf_read_line_table_prefix(). * dwarf_line.c: Implement new arguments to dwarf_read_line_table_prefix() for better error reporting. Allow erroneous ARM-compiler line table header to be used. * dwarf_line.h: Adding new argument to dwarf_read_line_table_prefix so we can report back on minor errors in the line table prefix. 2009-01-31 DavidAnderson * libdwarf.h: Corrected DW_DLE_LAST. * dwarf_frame.c: Remove accidental use of C99 mid-block variable definition. libdwarf-20210528/libdwarf/pro_log_extra_flag_strings.c0000664000175000017500000002313114004646706020047 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "dwarfstring.h" /* in the producer_init extras string. Handles hex and decimal. Not octal. Used a very small number of times, so performance not an issue. */ /* err will be used...shortly */ static int translatetosigned(char *s,Dwarf_Signed *v, UNUSEDARG int *err) { unsigned char *cp = (unsigned char *)s; unsigned char *digits = (unsigned char *)s; int signmult = 1; Dwarf_Signed l = 0; if (*cp == '0' && (*(cp+1) == 'x'|| (*(cp+1) == 'X'))) { digits += 2; cp = digits; for ( ; *cp; cp++) { l = l << 4; switch (*cp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': l += (*cp - '0'); break; case 'a': case 'A': l += 10; break; case 'b': case 'B': l += 11; break; case 'c': case 'C': l += 12; break; case 'd': case 'D': l += 13; break; case 'e': case 'E': l += 14; break; case 'f': case 'F': l += 15; break; default: #ifdef TESTING printf("ERROR in hex string \"%s\" " "bad character 0x%x, line %d %s\n", s,*cp,__LINE__,__FILE__); #endif *err = DW_DLE_HEX_STRING_ERROR; return DW_DLV_ERROR; } } *v = l; return DW_DLV_OK; } else if (*cp == '-') { signmult = -1; digits ++; } cp = digits; for ( ; *cp; cp++) { l = l * 10; switch (*cp) { case '9': case '8': case '7': case '6': case '5': case '4': case '3': case '2': case '1': case '0': l += (*cp - '0'); break; default: #ifdef TESTING printf("ERROR in decimal string \"%s\", " "bad character 0x%x, line %d %s\n", s,*cp,__LINE__,__FILE__); #endif *err = DW_DLE_DECIMAL_STRING_ERROR; return DW_DLV_ERROR; } } *v = signmult * l; return DW_DLV_OK; } static int update_named_field(Dwarf_P_Debug dbg, dwarfstring *cmsname, dwarfstring *cmsvalue, int *err) { char *name = dwarfstring_string(cmsname); char *value = dwarfstring_string(cmsvalue); Dwarf_Signed v = 0; int res; res = translatetosigned(value,&v,err); if (res != DW_DLV_OK) { return res; } if ( dwarfstring_strlen(cmsvalue) == 0) { return DW_DLV_NO_ENTRY; } /* The value in the string is a number, but always quite a small number. */ if (!strcmp(name,"default_is_stmt")) { dbg->de_line_inits.pi_default_is_stmt = (unsigned)v; } else if (!strcmp(name,"minimum_instruction_length")) { dbg->de_line_inits.pi_minimum_instruction_length = (unsigned)v; } else if (!strcmp(name,"maximum_operations_per_instruction")) { dbg->de_line_inits.pi_maximum_operations_per_instruction = (unsigned)v; } else if (!strcmp(name,"opcode_base")) { dbg->de_line_inits.pi_opcode_base = (unsigned)v; } else if (!strcmp(name,"line_base")) { dbg->de_line_inits.pi_line_base = (int)v; } else if (!strcmp(name,"line_range")) { dbg->de_line_inits.pi_line_range = (int)v; } else if (!strcmp(name,"linetable_version")) { dbg->de_line_inits.pi_linetable_version = (unsigned)v; dbg->de_output_version = (unsigned)v; } else if (!strcmp(name,"segment_selector_size")) { dbg->de_line_inits.pi_segment_selector_size = (unsigned)v; } else if (!strcmp(name,"segment_size")) { dbg->de_line_inits.pi_segment_size = (unsigned)v; } else if (!strcmp(name,"address_size")) { dbg->de_line_inits.pi_address_size = (unsigned)v; dbg->de_pointer_size = (unsigned)v; } else { #ifdef TESTING printf("ERROR due to unknown string \"%s\", line %d %s\n", name,__LINE__,__FILE__); #endif *err = DW_DLE_PRO_INIT_EXTRAS_UNKNOWN; return DW_DLV_ERROR; } return DW_DLV_OK; } static int update_named_value(Dwarf_P_Debug dbg, dwarfstring*cms, int *err) { char * str = dwarfstring_string(cms); char *cp = str; char * value_start = 0; dwarfstring cmsname; dwarfstring cmsvalue; unsigned slen = 0; int res = 0; dwarfstring_constructor(&cmsname); dwarfstring_constructor(&cmsvalue); for ( ; *cp && *cp != '=' && *cp != ' '; cp++) { } if (! *cp) { /* Ignore this, it's empty or has no =value clause */ dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); /* FIXME *err */ return DW_DLV_NO_ENTRY; } if (*cp == ' ') { /* Trailing spaces, no = is an input bug. */ dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); #ifdef TESTING printf("ERROR due to trailing spaces before = " "in \"%s\", line %d %s\n", cp,__LINE__,__FILE__); #endif *err = DW_DLE_PRO_INIT_EXTRAS_ERR; return DW_DLV_ERROR; } slen = cp - str; dwarfstring_append_length(&cmsname,str,slen); cp++; value_start = cp; for ( ; *cp && *cp != ' '; cp++) { } slen = cp - value_start; if (slen) { dwarfstring_append_length(&cmsvalue,value_start,slen); } else { dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); return DW_DLV_NO_ENTRY; } res = update_named_field(dbg,&cmsname,&cmsvalue,err); dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); return res; } static int find_next_comma(const char *base,const char **nextcomma) { const char *cp = base; for ( ; *cp ; ++cp) { if (*cp == ',') { *nextcomma = cp; return DW_DLV_OK; } } /* Encountered end of string, should not happen as we ensured a last string. */ *nextcomma = cp; return DW_DLV_OK; } /* Publicly visible in in libdwarf to enable easy testing of the code here. */ int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err) { int res = 0; const char *nextcharloc = 0; const char *nextcomma = 0; dwarfstring cms; dwarfstring input; if (!extra || !*extra) { /* Nothing to do. */ return DW_DLV_NO_ENTRY; } dwarfstring_constructor(&cms); dwarfstring_constructor(&input); dwarfstring_append(&input,(char *)extra); /* Adding a final , simplifies logic here. */ dwarfstring_append(&input,(char *)","); nextcharloc = dwarfstring_string(&input); while (1) { dwarfstring_reset(&cms); find_next_comma(nextcharloc,&nextcomma); { unsigned len = nextcomma - nextcharloc; if (len > 0) { dwarfstring_append_length(&cms,(char *)nextcharloc, len); res = update_named_value(dbg,&cms,err); if (res == DW_DLV_ERROR) { dwarfstring_destructor(&cms); dwarfstring_destructor(&input); return res; } } else {/* else empty, */ } if (!(nextcomma[1])) { dwarfstring_destructor(&cms); dwarfstring_destructor(&input); return DW_DLV_OK; } nextcharloc = nextcomma+1; } } dwarfstring_destructor(&input); dwarfstring_destructor(&cms); return DW_DLV_OK; } /* ===== end Initialization using string=value,string2=valu2 (etc) */ libdwarf-20210528/libdwarf/dwarf_leb_test.c0000664000175000017500000003615714053207041015426 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "libdwarf.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "pro_encode_nm.h" static void printinteresting(void) { return; } static Dwarf_Signed stest[] = { 0,0xff, 0x800000000000002f, 0x800000000000003f, 0x800000000000004f, 0x8000000000000070, 0x800000000000007f, 0x8000000000000080, 0x8000000000000000, 0x800000ffffffffff, 0x80000000ffffffff, 0x800000ffffffffff, 0x8000ffffffffffff, 0xffffffffffffffff, -1703944 /*18446744073707847672 as signed*/, 562949951588368, -1, -127, -100000, -2000000000, -4000000000, -8000000000, -800000000000, }; static Dwarf_Unsigned utest[] = { 0,0xff,0x7f,0x80, 0x800000000000002f, 0x800000000000003f, 0x800000000000004f, 0x8000000000000070, 0x800000000000007f, 0x8000000000000080, 0x800000ffffffffff, 0x80000000ffffffff, 0x800000ffffffffff, 0x8000ffffffffffff, 9223372036854775808ULL, -1703944 /*18446744073707847672 as signed*/, 562949951588368, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0xffffffffffffffff }; #if 0 /* FOR DEBUGGING */ static void dump_encoded(char *space,int len) { int t; printf("encode len %d: ",len); for ( t = 0; t < len; ++t) { printf("%02x",space[t] & 0xff); } printf("\n"); } #endif #define BUFFERLEN 100 static unsigned signedtest(unsigned len) { unsigned errcnt = 0; unsigned t = 0; char bufferspace[BUFFERLEN]; for ( ; t < len; ++t) { int res = 0; int encodelen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Signed decodeval = 0; res = _dwarf_pro_encode_signed_leb128_nm( stest[t],&encodelen,bufferspace,BUFFERLEN); if (res != DW_DLV_OK) { printf("FAIL signed encode " "DW_DLV_ERROR, index %u expected 0x%llx" " line:%d\n", t,stest[t],__LINE__); ++errcnt; } res = dwarf_decode_signed_leb128( (char *)bufferspace, &decodelen, &decodeval, (char *)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL public DW_DLV_ERROR " "signed decode index %u " "val 0x%llx line:%d\n", t,stest[t],__LINE__); ++errcnt; } if (stest[t] != decodeval) { printf("FAIL public signed decode val index %u " "expected 0x%llx vs got 0x%llx line:%d\n", t,stest[t],decodeval,__LINE__); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL public signed decodelen val " "index %u val 0x%llx " " encodelen %u decodelen %u line:%d\n", t,stest[t],(unsigned)encodelen, (unsigned)decodelen,__LINE__); ++errcnt; } res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)bufferspace, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL got DW_DLV_ERRROR signed decode" " index %u " "expected val 0x%llx line:%d\n", t,stest[t],__LINE__); ++errcnt; } if (stest[t] != decodeval) { printf("FAIL signed decode val index %u " "val 0x%llx vs 0x%llx line:%d\n", t,stest[t],decodeval,__LINE__); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL signed decodelen val index %u val 0x%llx " " encodelen %u decodelen %u line:%d\n", t,stest[t],(unsigned)encodelen, (unsigned)decodelen,__LINE__); ++errcnt; } } return errcnt; } static unsigned unsignedtest(unsigned len) { unsigned errcnt = 0; unsigned t = 0; char bufferspace[BUFFERLEN]; for ( ; t < len; ++t) { int res = 0; int encodelen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Unsigned decodeval = 0; res = _dwarf_pro_encode_leb128_nm( utest[t],&encodelen,bufferspace,BUFFERLEN); if (res != DW_DLV_OK) { printf("FAIL signed encode index %u val 0x%llx line:%d\n", t,utest[t],__LINE__); ++errcnt; } res = dwarf_decode_leb128( (char *)bufferspace, &decodelen, &decodeval, (char *)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL public unsigned decode index %u " "val 0x%llx line:%d\n", t,utest[t],__LINE__); ++errcnt; } if (utest[t] != decodeval) { printf("FAIL public unsigned decode val index %u " "expected 0x%llx vs received 0x%llx line:%d\n", t,utest[t],decodeval,__LINE__); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL public unsigned decodelen val index %u " "val 0x%llx line:%d\n", t,utest[t],__LINE__); ++errcnt; } res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)bufferspace, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL unsigned decode index %u " "val 0x%llx line:%d\n", t,utest[t],__LINE__); ++errcnt; } if (utest[t] != decodeval) { printf("FAIL unsigned decode val index %u " "val 0x%llx vs 0x%llx line:%d\n", t,utest[t],decodeval,__LINE__); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL unsigned decodelen val index %u " "val 0x%llx line:%d\n", t,utest[t],__LINE__); ++errcnt; } } return errcnt; } static unsigned char v1[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; static unsigned char v2[] = { 0xf4,0xff, 0xff, 0xff, 0x0f, 0x4c, 0x00, 0x00, 0x00}; /* 9223372036854775808 == -9223372036854775808 */ static unsigned char v3[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41 }; /* This warning with --enable-sanitize is fixed as of November 11, 2016 when decoding test v4. dwarf_leb.c: runtime error: negation of -9223372036854775808 cannot be represented in type 'Dwarf_Signed' (aka 'long long'); cast to an unsigned type to negate this value to itself. The actual value here is -4611686018427387904 0xc000000000000000, for a 64bit signed int target */ static unsigned char v4[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40 }; /* the 0x40 on bit plays the role of incorporating the bit and also requesting a sign bit. */ /* sort of v4 with zero padding on end. Here with target signed 64bit twos complement */ static unsigned char v5[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* the 0xc0 plays the role of incorporating a bit and continuing input. */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40 /* The 0x40 cannot be or-d in as it is shifted off the end of the target 64bit int area, but it plays the role of requesting sign bit. */ }; /* If we had a target of 32bit signed int we would, to to get 0xc0000000 with trailing padding: 0x80, 0x80, 0x80, 0x80, 0x84, The 4 gets into the int., 8 continues the input any higher bits in the bottom 7 bits get shifted off and vanish, so 0xf6 would get the same value. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40 The 0x40 gets the sign set Simlarly, but without any padding bytes: 0x80, 0x80, 0x80, 0x80, 0x44, The second 4 (and 2 zero bits) gets into the int, first 4 gets the sign bit set */ /* Error, too long due to the non-zero past any valid Dwarf_Signed*/ static unsigned char v6[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41, /* The 0x40 cannot be or-d in as we are off the end of shiftable area, but it plays the role of requesting sign bit. */ }; /* unsigned decode with padding */ static unsigned char v7[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; /* padding exceeds our chosen max */ static unsigned char v8[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; static unsigned specialtests(void) { unsigned errcnt = 0; unsigned vlen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Signed decodeval = 0; Dwarf_Unsigned udecodeval = 0; int res; vlen = sizeof(v1)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v1, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v1[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL unsigned decode special v1 line:%d\n",__LINE__); ++errcnt; } res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v1, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v1[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL unsigned decode special v1 line:%d\n",__LINE__); ++errcnt; } vlen = sizeof(v2)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v2, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v2[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v2 line:%d\n",__LINE__); ++errcnt; } /* If you just do (byte & 0x7f) << shift and byte is (or is promoted to) a signed type on the following decode you get the wrong value. Undefined effect in C leads to error. */ res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v2, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v2[vlen])); if (res != DW_DLV_OK) { printf("FAIL unsigned decode special v2 line:%d\n",__LINE__); ++errcnt; } vlen = sizeof(v3)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v3, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v3[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v3 line:%d\n",__LINE__); ++errcnt; } if ((Dwarf_Unsigned)decodeval != (Dwarf_Unsigned)0x8000000000000000) { printf("FAIL signed decode special v3 value check %lld " "vs %lld line:%d\n", decodeval,(Dwarf_Signed)0x8000000000000000,__LINE__); ++errcnt; } vlen = sizeof(v4)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v4, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v4[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v4 line:%d\n",__LINE__); ++errcnt; } if (decodeval != -4611686018427387904) { printf("FAIL signed decode special v4 value check %lld " "vs %lld line:%d\n", decodeval,-4611686018427387904LL,__LINE__); printf("FAIL signed decode special v4 value check 0x%llx " "vs 0x%llx line:%d\n", decodeval,-4611686018427387904LL,__LINE__); ++errcnt; } vlen = sizeof(v5)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v5, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v5[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v5 line:%d\n",__LINE__); ++errcnt; } if (decodeval != -4611686018427387904) { printf("FAIL signed decode special v5 value check got %lld " "vs expected %lld line:%d\n", decodeval,-4611686018427387904LL,__LINE__); printf("FAIL signed decode special v5 value check got %llx " "vs expected %llx line:%d\n", decodeval,-4611686018427387904LL,__LINE__); ++errcnt; } if (decodelen != vlen) { printf("FAIL signed decode special v5 decode len ck" "Expected decode len %u" "got decode len %u line %d\n", (unsigned)vlen,(unsigned)decodelen,__LINE__); } vlen = sizeof(v6)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v6, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v6[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL signed decode special v6 " "did not get expected error output %d\n", __LINE__); } vlen = sizeof(v7)/sizeof(char); res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v7, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v7[vlen])); if (res == DW_DLV_ERROR) { printf("FAIL unsigned decode special v7 " "unexpected error output %d\n", __LINE__); } if (udecodeval != 1) { printf("FAIL usigned decode special v7 value check got %llu " "vs expected %u line:%d\n", udecodeval,1,__LINE__); } if (vlen != decodelen) { printf("FAIL usigned decode special v7 decode len got %u " "vs expected %u line:%d\n", (unsigned)decodelen,vlen,__LINE__); } vlen = sizeof(v8)/sizeof(char); res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v8, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v8[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL unsigned decode special v8 " "unexpected pass expected DW_DLV_ERROR line:%d\n", __LINE__); } return errcnt; } int main(void) { unsigned slen = sizeof(stest)/sizeof(Dwarf_Signed); unsigned ulen = sizeof(utest)/sizeof(Dwarf_Unsigned); int errs = 0; printinteresting(); errs += signedtest(slen); errs += unsignedtest(ulen); errs += specialtests(); if (errs) { printf("FAIL. leb encode/decode errors\n"); return 1; } printf("PASS leb tests\n"); return 0; } libdwarf-20210528/libdwarf/dwarf_object_detector.h0000644000175000017500000000670413743575426017006 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_OBJECT_DETECTOR_H #define DWARF_OBJECT_DETECTOR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Declares the interface function. outpath is a place you provide, of a length outpath_len you consider reasonable, where the final path used is recorded. outpath_len must be larger than strlen(path); This matters as for mach-o if the path is a directory name the function will look in the standard macho-place for the object file (useful for dSYM) and return the constructed path in oupath. returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY */ #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 #define DW_FTYPE_MACH_O 2 #define DW_FTYPE_PE 3 #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ /* offsetsize refers to the object-file-format. Elf 32 or macho-32 or PE 32, for example. Not to DWARF offset sizes. */ /* Path means look(first) for an dynsym object of the same name per MacOS standards, making the outpath space needed is more than that in path. Copies the actual path into outpath, (an error if the length in outpath_len is less than needed for the object found). If DW_DLV_NO_ENTRY or DW_DLV_ERROR returned the argument values other than path must be considered to be in an unknown state. */ /* The errcode is a small integer distinct from libdwarf and simply printing the integer (returned through *errcode when the function returns DW_DLV_ERROR) will hopefully suffice for most purposes. */ int dwarf_object_detector_path(const char *path, char *outpath, unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_OBJECT_DETECTOR_H */ libdwarf-20210528/libdwarf/dwarf_elf_reloc_ppc.h0000664000175000017500000002431513644370703016432 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_ppc(unsigned long); #ifndef R_PPC_NONE #define R_PPC_NONE 0 #endif /* R_PPC_NONE */ #ifndef R_PPC_ADDR32 #define R_PPC_ADDR32 1 #endif /* R_PPC_ADDR32 */ #ifndef R_PPC_ADDR24 #define R_PPC_ADDR24 2 #endif /* R_PPC_ADDR24 */ #ifndef R_PPC_ADDR16 #define R_PPC_ADDR16 3 #endif /* R_PPC_ADDR16 */ #ifndef R_PPC_ADDR16_LO #define R_PPC_ADDR16_LO 4 #endif /* R_PPC_ADDR16_LO */ #ifndef R_PPC_ADDR16_HI #define R_PPC_ADDR16_HI 5 #endif /* R_PPC_ADDR16_HI */ #ifndef R_PPC_ADDR16_HA #define R_PPC_ADDR16_HA 6 #endif /* R_PPC_ADDR16_HA */ #ifndef R_PPC_ADDR14 #define R_PPC_ADDR14 7 #endif /* R_PPC_ADDR14 */ #ifndef R_PPC_ADDR14_BRTAKEN #define R_PPC_ADDR14_BRTAKEN 8 #endif /* R_PPC_ADDR14_BRTAKEN */ #ifndef R_PPC_ADDR14_BRNTAKEN #define R_PPC_ADDR14_BRNTAKEN 9 #endif /* R_PPC_ADDR14_BRNTAKEN */ #ifndef R_PPC_REL24 #define R_PPC_REL24 10 #endif /* R_PPC_REL24 */ #ifndef R_PPC_REL14 #define R_PPC_REL14 11 #endif /* R_PPC_REL14 */ #ifndef R_PPC_REL14_BRTAKEN #define R_PPC_REL14_BRTAKEN 12 #endif /* R_PPC_REL14_BRTAKEN */ #ifndef R_PPC_REL14_BRNTAKEN #define R_PPC_REL14_BRNTAKEN 13 #endif /* R_PPC_REL14_BRNTAKEN */ #ifndef R_PPC_GOT16 #define R_PPC_GOT16 14 #endif /* R_PPC_GOT16 */ #ifndef R_PPC_GOT16_LO #define R_PPC_GOT16_LO 15 #endif /* R_PPC_GOT16_LO */ #ifndef R_PPC_GOT16_HI #define R_PPC_GOT16_HI 16 #endif /* R_PPC_GOT16_HI */ #ifndef R_PPC_GOT16_HA #define R_PPC_GOT16_HA 17 #endif /* R_PPC_GOT16_HA */ #ifndef R_PPC_PLTREL24 #define R_PPC_PLTREL24 18 #endif /* R_PPC_PLTREL24 */ #ifndef R_PPC_COPY #define R_PPC_COPY 19 #endif /* R_PPC_COPY */ #ifndef R_PPC_GLOB_DAT #define R_PPC_GLOB_DAT 20 #endif /* R_PPC_GLOB_DAT */ #ifndef R_PPC_JMP_SLOT #define R_PPC_JMP_SLOT 21 #endif /* R_PPC_JMP_SLOT */ #ifndef R_PPC_RELATIVE #define R_PPC_RELATIVE 22 #endif /* R_PPC_RELATIVE */ #ifndef R_PPC_LOCAL24PC #define R_PPC_LOCAL24PC 23 #endif /* R_PPC_LOCAL24PC */ #ifndef R_PPC_UADDR32 #define R_PPC_UADDR32 24 #endif /* R_PPC_UADDR32 */ #ifndef R_PPC_UADDR16 #define R_PPC_UADDR16 25 #endif /* R_PPC_UADDR16 */ #ifndef R_PPC_REL32 #define R_PPC_REL32 26 #endif /* R_PPC_REL32 */ #ifndef R_PPC_PLT32 #define R_PPC_PLT32 27 #endif /* R_PPC_PLT32 */ #ifndef R_PPC_PLTREL32 #define R_PPC_PLTREL32 28 #endif /* R_PPC_PLTREL32 */ #ifndef R_PPC_PLT16_LO #define R_PPC_PLT16_LO 29 #endif /* R_PPC_PLT16_LO */ #ifndef R_PPC_PLT16_HI #define R_PPC_PLT16_HI 30 #endif /* R_PPC_PLT16_HI */ #ifndef R_PPC_PLT16_HA #define R_PPC_PLT16_HA 31 #endif /* R_PPC_PLT16_HA */ #ifndef R_PPC_SDAREL16 #define R_PPC_SDAREL16 32 #endif /* R_PPC_SDAREL16 */ #ifndef R_PPC_SECTOFF #define R_PPC_SECTOFF 33 #endif /* R_PPC_SECTOFF */ #ifndef R_PPC_SECTOFF_LO #define R_PPC_SECTOFF_LO 34 #endif /* R_PPC_SECTOFF_LO */ #ifndef R_PPC_SECTOFF_HI #define R_PPC_SECTOFF_HI 35 #endif /* R_PPC_SECTOFF_HI */ #ifndef R_PPC_SECTOFF_HA #define R_PPC_SECTOFF_HA 36 #endif /* R_PPC_SECTOFF_HA */ #ifndef R_PPC_37 #define R_PPC_37 37 #endif /* R_PPC_37 */ #ifndef R_PPC_38 #define R_PPC_38 38 #endif /* R_PPC_38 */ #ifndef R_PPC_39 #define R_PPC_39 39 #endif /* R_PPC_39 */ #ifndef R_PPC_40 #define R_PPC_40 40 #endif /* R_PPC_40 */ #ifndef R_PPC_41 #define R_PPC_41 41 #endif /* R_PPC_41 */ #ifndef R_PPC_42 #define R_PPC_42 42 #endif /* R_PPC_42 */ #ifndef R_PPC_43 #define R_PPC_43 43 #endif /* R_PPC_43 */ #ifndef R_PPC_44 #define R_PPC_44 44 #endif /* R_PPC_44 */ #ifndef R_PPC_45 #define R_PPC_45 45 #endif /* R_PPC_45 */ #ifndef R_PPC_46 #define R_PPC_46 46 #endif /* R_PPC_46 */ #ifndef R_PPC_47 #define R_PPC_47 47 #endif /* R_PPC_47 */ #ifndef R_PPC_48 #define R_PPC_48 48 #endif /* R_PPC_48 */ #ifndef R_PPC_49 #define R_PPC_49 49 #endif /* R_PPC_49 */ #ifndef R_PPC_50 #define R_PPC_50 50 #endif /* R_PPC_50 */ #ifndef R_PPC_51 #define R_PPC_51 51 #endif /* R_PPC_51 */ #ifndef R_PPC_52 #define R_PPC_52 52 #endif /* R_PPC_52 */ #ifndef R_PPC_53 #define R_PPC_53 53 #endif /* R_PPC_53 */ #ifndef R_PPC_54 #define R_PPC_54 54 #endif /* R_PPC_54 */ #ifndef R_PPC_55 #define R_PPC_55 55 #endif /* R_PPC_55 */ #ifndef R_PPC_56 #define R_PPC_56 56 #endif /* R_PPC_56 */ #ifndef R_PPC_57 #define R_PPC_57 57 #endif /* R_PPC_57 */ #ifndef R_PPC_58 #define R_PPC_58 58 #endif /* R_PPC_58 */ #ifndef R_PPC_59 #define R_PPC_59 59 #endif /* R_PPC_59 */ #ifndef R_PPC_60 #define R_PPC_60 60 #endif /* R_PPC_60 */ #ifndef R_PPC_61 #define R_PPC_61 61 #endif /* R_PPC_61 */ #ifndef R_PPC_62 #define R_PPC_62 62 #endif /* R_PPC_62 */ #ifndef R_PPC_63 #define R_PPC_63 63 #endif /* R_PPC_63 */ #ifndef R_PPC_64 #define R_PPC_64 64 #endif /* R_PPC_64 */ #ifndef R_PPC_65 #define R_PPC_65 65 #endif /* R_PPC_65 */ #ifndef R_PPC_66 #define R_PPC_66 66 #endif /* R_PPC_66 */ #ifndef R_PPC_TLS #define R_PPC_TLS 67 #endif /* R_PPC_TLS */ #ifndef R_PPC_DTPMOD32 #define R_PPC_DTPMOD32 68 #endif /* R_PPC_DTPMOD32 */ #ifndef R_PPC_TPREL16 #define R_PPC_TPREL16 69 #endif /* R_PPC_TPREL16 */ #ifndef R_PPC_TPREL16_LO #define R_PPC_TPREL16_LO 70 #endif /* R_PPC_TPREL16_LO */ #ifndef R_PPC_TPREL16_HI #define R_PPC_TPREL16_HI 71 #endif /* R_PPC_TPREL16_HI */ #ifndef R_PPC_TPREL16_HA #define R_PPC_TPREL16_HA 72 #endif /* R_PPC_TPREL16_HA */ #ifndef R_PPC_TPREL32 #define R_PPC_TPREL32 73 #endif /* R_PPC_TPREL32 */ #ifndef R_PPC_DTPREL16 #define R_PPC_DTPREL16 74 #endif /* R_PPC_DTPREL16 */ #ifndef R_PPC_DTPREL16_LO #define R_PPC_DTPREL16_LO 75 #endif /* R_PPC_DTPREL16_LO */ #ifndef R_PPC_DTPREL16_HI #define R_PPC_DTPREL16_HI 76 #endif /* R_PPC_DTPREL16_HI */ #ifndef R_PPC_DTPREL16_HA #define R_PPC_DTPREL16_HA 77 #endif /* R_PPC_DTPREL16_HA */ #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* R_PPC_DTPREL32 */ #ifndef R_PPC_GOT_TLSGD16 #define R_PPC_GOT_TLSGD16 79 #endif /* R_PPC_GOT_TLSGD16 */ #ifndef R_PPC_GOT_TLSGD16_LO #define R_PPC_GOT_TLSGD16_LO 80 #endif /* R_PPC_GOT_TLSGD16_LO */ #ifndef R_PPC_GOT_TLSGD16_HI #define R_PPC_GOT_TLSGD16_HI 81 #endif /* R_PPC_GOT_TLSGD16_HI */ #ifndef R_PPC_GOT_TLSGD16_HA #define R_PPC_GOT_TLSGD16_HA 82 #endif /* R_PPC_GOT_TLSGD16_HA */ #ifndef R_PPC_GOT_TLSLD16 #define R_PPC_GOT_TLSLD16 83 #endif /* R_PPC_GOT_TLSLD16 */ #ifndef R_PPC_GOT_TLSLD16_LO #define R_PPC_GOT_TLSLD16_LO 84 #endif /* R_PPC_GOT_TLSLD16_LO */ #ifndef R_PPC_GOT_TLSLD16_HI #define R_PPC_GOT_TLSLD16_HI 85 #endif /* R_PPC_GOT_TLSLD16_HI */ #ifndef R_PPC_GOT_TLSLD16_HA #define R_PPC_GOT_TLSLD16_HA 86 #endif /* R_PPC_GOT_TLSLD16_HA */ #ifndef R_PPC_GOT_TPREL16 #define R_PPC_GOT_TPREL16 87 #endif /* R_PPC_GOT_TPREL16 */ #ifndef R_PPC_GOT_TPREL16_LO #define R_PPC_GOT_TPREL16_LO 88 #endif /* R_PPC_GOT_TPREL16_LO */ #ifndef R_PPC_GOT_TPREL16_HI #define R_PPC_GOT_TPREL16_HI 89 #endif /* R_PPC_GOT_TPREL16_HI */ #ifndef R_PPC_GOT_TPREL16_HA #define R_PPC_GOT_TPREL16_HA 90 #endif /* R_PPC_GOT_TPREL16_HA */ #ifndef R_PPC_GOT_DTPREL16 #define R_PPC_GOT_DTPREL16 91 #endif /* R_PPC_GOT_DTPREL16 */ #ifndef R_PPC_GOT_DTPREL16_LO #define R_PPC_GOT_DTPREL16_LO 92 #endif /* R_PPC_GOT_DTPREL16_LO */ #ifndef R_PPC_GOT_DTPREL16_HI #define R_PPC_GOT_DTPREL16_HI 93 #endif /* R_PPC_GOT_DTPREL16_HI */ #ifndef R_PPC_GOT_DTPREL16_HA #define R_PPC_GOT_DTPREL16_HA 94 #endif /* R_PPC_GOT_DTPREL16_HA */ #ifndef R_PPC_TLSGD #define R_PPC_TLSGD 95 #endif /* R_PPC_TLSGD */ #ifndef R_PPC_TLSLD #define R_PPC_TLSLD 96 #endif /* R_PPC_TLSLD */ #ifndef R_PPC_EMB_NADDR32 #define R_PPC_EMB_NADDR32 101 #endif /* R_PPC_EMB_NADDR32 */ #ifndef R_PPC_EMB_NADDR16 #define R_PPC_EMB_NADDR16 102 #endif /* R_PPC_EMB_NADDR16 */ #ifndef R_PPC_EMB_NADDR16_LO #define R_PPC_EMB_NADDR16_LO 103 #endif /* R_PPC_EMB_NADDR16_LO */ #ifndef R_PPC_EMB_NADDR16_HI #define R_PPC_EMB_NADDR16_HI 104 #endif /* R_PPC_EMB_NADDR16_HI */ #ifndef R_PPC_EMB_NADDR16_HA #define R_PPC_EMB_NADDR16_HA 105 #endif /* R_PPC_EMB_NADDR16_HA */ #ifndef R_PPC_EMB_SDAI16 #define R_PPC_EMB_SDAI16 106 #endif /* R_PPC_EMB_SDAI16 */ #ifndef R_PPC_EMB_SDA2I16 #define R_PPC_EMB_SDA2I16 107 #endif /* R_PPC_EMB_SDA2I16 */ #ifndef R_PPC_EMB_SDA2REL #define R_PPC_EMB_SDA2REL 108 #endif /* R_PPC_EMB_SDA2REL */ #ifndef R_PPC_EMB_SDA21 #define R_PPC_EMB_SDA21 109 #endif /* R_PPC_EMB_SDA21 */ #ifndef R_PPC_EMB_MRKREF #define R_PPC_EMB_MRKREF 110 #endif /* R_PPC_EMB_MRKREF */ #ifndef R_PPC_EMB_RELSEC16 #define R_PPC_EMB_RELSEC16 111 #endif /* R_PPC_EMB_RELSEC16 */ #ifndef R_PPC_EMB_RELST_LO #define R_PPC_EMB_RELST_LO 112 #endif /* R_PPC_EMB_RELST_LO */ #ifndef R_PPC_EMB_RELST_HI #define R_PPC_EMB_RELST_HI 113 #endif /* R_PPC_EMB_RELST_HI */ #ifndef R_PPC_EMB_RELST_HA #define R_PPC_EMB_RELST_HA 114 #endif /* R_PPC_EMB_RELST_HA */ #ifndef R_PPC_EMB_BIT_FLD #define R_PPC_EMB_BIT_FLD 115 #endif /* R_PPC_EMB_BIT_FLD */ #ifndef R_PPC_EMB_RELSDA #define R_PPC_EMB_RELSDA 116 #endif /* R_PPC_EMB_RELSDA */ #ifndef R_PPC_DIAB_SDA21_LO #define R_PPC_DIAB_SDA21_LO 180 #endif /* R_PPC_DIAB_SDA21_LO */ #ifndef R_PPC_DIAB_SDA21_HI #define R_PPC_DIAB_SDA21_HI 181 #endif /* R_PPC_DIAB_SDA21_HI */ #ifndef R_PPC_DIAB_SDA21_HA #define R_PPC_DIAB_SDA21_HA 182 #endif /* R_PPC_DIAB_SDA21_HA */ #ifndef R_PPC_DIAB_RELSDA_LO #define R_PPC_DIAB_RELSDA_LO 183 #endif /* R_PPC_DIAB_RELSDA_LO */ #ifndef R_PPC_DIAB_RELSDA_HI #define R_PPC_DIAB_RELSDA_HI 184 #endif /* R_PPC_DIAB_RELSDA_HI */ #ifndef R_PPC_DIAB_RELSDA_HA #define R_PPC_DIAB_RELSDA_HA 185 #endif /* R_PPC_DIAB_RELSDA_HA */ #ifndef R_PPC_IRELATIVE #define R_PPC_IRELATIVE 248 #endif /* R_PPC_IRELATIVE */ #ifndef R_PPC_REL16 #define R_PPC_REL16 249 #endif /* R_PPC_REL16 */ #ifndef R_PPC_REL16_LO #define R_PPC_REL16_LO 250 #endif /* R_PPC_REL16_LO */ #ifndef R_PPC_REL16_HI #define R_PPC_REL16_HI 251 #endif /* R_PPC_REL16_HI */ #ifndef R_PPC_REL16_HA #define R_PPC_REL16_HA 252 #endif /* R_PPC_REL16_HA */ libdwarf-20210528/libdwarf/ChangeLog20140000664000175000017500000005005413644370703014362 000000000000002014-12-31: David Anderson * dwarf_error.c: Add DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION. * libdwarf.h.in: Add DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION. * dwarf_form.c(dwarf_formexprloc): Call the new function _dwarf_reference_outside_section() as a check for an exprloc with data that is outside the section it belongs in. Ie, a bug somewhere. Return error DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION if applicable. * dwarf_frame2.c(read_encoded_ptr): Pass error down so we set a complete Dwarf_Error record at the point of error. Just three functions that could use this were changed. * dwarf_leb.c(_dwarf_decode_u_leb128): Presented with bogus leb values we stop scanning the leb number before overrunning our value-output buffer (and dumping core). The change is reasonably adequate but will not catch all cases. * dwarf_query.c(dwarf_attrlist): Call _dwarf_reference_outside_section to check the pointer is valid. * dwarf_util.c,dwarf_util.h: Implement _dwarf_reference_outside_section(). 2014-12-28: David Anderson * dwarf_alloc.c: Added global _dwarf_failsafe_error to enable better error reporting when malloc arena has no space left. On dwarf_dealloc() avoids attempting a free() of the static struct. * dwarf_error.c,libdwarf.h.in: New error code DW_DLE_FAILSAFE_ERRVAL for the malloc-arena-exhausted case. Now use that static instead of aborting. * dwarf_error.h: New field and library-private extern declaration for the malloc-arena-exhausted case. * libdwarf2.1.mm: Documented the handling of Dwarf_Error when malloc space exhausted. * libdwarf2.1.pdf: Regenerated. Rev 2.23. 2014-09-10: David Anderson * dwarf_tsearchhash.c(calculate_allowed_fill): Moved a declaration to avoid using a C99 feature. * dwarf_query.c(dwarf_highpc_b): Moved a declaration to avoid using aC99 feature. * dwarf_util.c(dwarf_print): Moved a declaration to avoid using aC99 feature. 2014-08-11 David Anderson, avoiding some compiler warnings. *dwarf_xu_index.c,dwarf_macro.c: Failed to cast the pointer returned by _dwarf_get_macro (one place in each file). 2014-08-04 David Anderson, avoiding some compiler warnings. * dwarf_alloc.c, dwarf_alloc.h: Change some uses of Dwarf_Ptr to be char * so we avoid adding (etc) to Dwarf_Ptr. * dwarf_gdbindex.c: Cast _dwarf_get_alloc() return properly. * dwarf_loc.c: Cast Dwarf_Ptr to char * in a couple places. * dwarf_query.c,dwarf_sort_line.c,pro_arange.c: Change names of local variables to avoid compiler warning about shadowing other locals. * dwarf_tsearchhash.c: Changed to avoid compiler warnings about const casts whereever possible. * libdwarf.h.in: Added prototypes for DWARF5 dwarf_get_SECT_name() and dwarf_get_MACRO_name(). * pro_alloc.c: Add include of pro_alloc.h. * pro_forms.c: Made _dwarf_add_AT_reference_internal() static to avoid warning. * pro_types.c: Add include of pro_types.h. 2014-08-02 David Anderson * dwarf_gdbindex.c: Fix an argument list by adding section name. * libdwarf.h.in: Fix an argument list by adding section name. Clarify some commentary on dwarf_get_xu* function declarations. * libdwarf2.1.mm: Documented the new gdbindex and dwarf_get_xu* functions. * libdwarf2.1.pdf: Regenerate. Version 2.22. 2014-07-12 David Anderson * dwarf_die_deliv.c: Remove trailing whitespace. Implement dwarf_get_die_section_name() allow clients to get the Elf section name actually used for the section. * dwarf_xu_index.c: Remmove traling whitespace and fix indents. 2014-07-11 David Anderson * dwarf_opaque.h: Various CU context fields were not clarified by comments, so comments added. 2014-07-11 David Anderson * dwarf_opaque.h: Clarified a couple comments. 2014-07-11 David Anderson * dwarf_xu_index.c: Now extracts the offset and size table data correctly. 2014-07-10 David Anderson * dwarf_die_deliv.c: Clarify a comment a little bit. No change in the code. 2014-07-10 David Anderson * dwarf_error.c,libdwarf.h.in: Added new error codes. * dwarf_xu_index.c: Now extracts the hash table values from .debug_tu_index and .debug_cu_index sections. 2014-07-09 David Anderson * dwarf_alloc.c,dwarf_xu_index.c,dwarf_xu_index.h: Removed trailing whitespace characters. 2014-07-09 David Anderson * Makefile.in: Added dwarf_xu_index.o. Moved dwarf_macro.o to get closer to alphabetical order in the list. * dwarf.h: Added DW_SECT codes so the .debug_[tc]u.index sections can be interpreted properly. DWARF5. * dwarf_alloc.c: Added dwarf_xu_index.h #include. Added struct Dwarf_Xu_Index_Header_s to alloced structs. Added a couple lines of commentary about .gdb_index section access type. * dwarf_alloc.h: Increased ALLOC_AREA_INDEX_TABLE_MAX to 57 for the new alloc type. * dwarf_die_deliv.c: Removed trailing whitespace. * dwarf_elf_access.c: Added commentary. * dwarf_error.c: Added new error codes for .debug_tu_index and .debug_cu_index sections code. * dwarf_init_finish.c: Add handling of .debug_tu_index and .debug_cu_index sections. * dwarf_opaque.h: Add de_debug_cu_index and de_debug_tu_index to Dwarf_Debug_s struct. * dwarf_xu_index.c: New code for the newly handled DWARF5 sections .debug_tu_index and .debug_cu_index . * dwarf_xu_index.h: Defines struct Dwarf_Xu_Index_Header_s. * libdwarf.h.in: Declares new functions implementing some of the new section interfaces. 2014-07-05 David Anderson * dwarf_arange.c(dwarf_get_aranges_list): Remove the length variable as its calculated value is unused. rename length to area_length for clarity. Calculate arange_ptr_past_end early and correctly. Ensure that the test for version 4 is a >= to reflect normal standards upgrades. * dwarf_die_deliv.c(dwarf_find_offdie_CU_Context): Add commentary about offsets and lengths for clarity. Rename fields for clarity about local vs global offset. Use the newly named fields for precise tests of section overflow of a type unit. * dwarf_frame.h: Add commentary about pointers in the cie_fde_prefix_s structure. * dwarf_global.c(_dwarf_internal_get_pubnames_like_data): Add commentary about the of fields. * dwarf_opaque.h: Improve commentary about offsets. 2014-07-03 David Anderson * dwarf_die_deliv.c: Fixed CU type offset check. Created local variable so we do not repeat a calculation so the error does not recur and simplifying nearby code. * gdb_index.c: Remove unused local variable. * dwarf_opaque.h: Change offset entries from Dwarf_Word to Dwarf_Unsigned to ensure we do not remove bits from values. * dwarf_query.c: Remove unused local variable and a comment referencing that unused variable. * pro_reloc_stream.c: Remove unused local variable. 2014-07-01 David Anderson * dwarf_alloc.c, dwarf_gdbindex.c, dwarf_init_finish.c, dwarf_opaque.h, libdwarf.h.in: Fixed indent errors and removed trailing whitespace. 2014-07-01 David Anderson * libdwarf.h.in: Matched up gdbindex symboltable interfaces with the C source. * dwarf_gdbindex.c: Implement Symbol table access. 2014-06-30 David Anderson * libdwarf.h.in: Remove useless interface to gdbindex. * dwarf_gdbindex.c: Implement TU list access code. Implement access to the address area. 2014-06-29 David Anderson * dwarf_error.c: Added error codes for gdbindex access. * libdwarf.h.in: Revised gdbindex function interface: simpler. * dwarf_gdbindex.c, dwarf_gdbindex.h: Implement gdbindex functions. 2014-06-28 David Anderson * Makefile.in: Add dwarf_gdbindex.o to objects. * dwarf_alloc.c: Add new type Dwarf_Gdbindex_s to allocatable types. * dwarf_elf_access.c: Add a comment reflecting lack of need to relocate a .gdb_index section. * dwarf_error.c: Add new error strings for gdb_index related errors. * dwarf_init_finish.c: Add .gdb_index section to the sections we read. Refactor a test into a function this_section_dwarf_relevant() to make code more readable. * dwarf_opaque.h: Add de_debug_gdbindex to Dwarf_Debug_s. * libdwarf.h.in: Add opaque types for .gdb_index section interfaces. Add DW_DLA_GDBINDEX for allocatability of the new type. Add new GDB_INDEX error codes in DW_DLA list. Declare new gdb_index interfaces. 2014-05-19 David Anderson * dwarf_init_finish.c: Removed unused local variable. * dwarf_opaque.h: Added _dwarf_extract_string_offset_via_str_offsets() to communicate the argument list to other libdwarf source files. * dwarf_query.c: Fixed botch in call argument list, the dwarf_opaque.h change exposed it. Deleted an unused local variable. * pro_reloc_symbolic.c: Deleted an unused local variable. 2014-05-18 David Anderson * libdwarf2.1.mm: Fixed a typo in the H3 line for dwarf_get_debug_add_index(). * libdwarf2.1.pdf: Regenerated. Rev 2.20, May 18 2014. 2014-05-18 David Anderson * dwarf_loc.: Fixed offset update for DW_OP_constx/addrx. 2014-05-18 David Anderson * dwarf_form.c: Removed trailing whitespace, added commentary. * dwarf_loc.c: Added commentary. 2014-05-18 David Anderson * libdwarf.h.in, dwarf_form.c: Restored the function dwarf_get_debug_addr_index(). It is useful as a convenience for apps like dwarfdump. 2014-05-18 David Anderson * dwarf_die_deliv.c,dwarf_error.c,dwarf_form.c,dwarf_init_finish.c, dwarf_opaque.h,dwarf_query.c,dwarf_util.c,libdwarf.h.in: Fixed numerous indent errors and removed trailing whitespace. 2014-05-17 David Anderson * dwarf.h: Minor comment enhancement. * dwarf_loc.c: Fixed code for DW_OP_constx, DW_OP_addrx, DW_OP_GNU_addr_index, DW_OP_GNU_const_index. * dwarf_form.c: DW_FORM_addr_index, DW_FORM_addrx, DW_FORM_strx, DW_FORM_GNU_str_index * dwarf_opaque.h: added new field dss_name to help debugging. * dwarf_query.c: Returns DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION when debug_addr is missing so address cannot be literally extracted. New functions: dwarf_get_debug_addr_index() and dwarf_get_debug_str_index(). * libdwarf.h.in: New error codes for FORM errors. New function declarations: dwarf_get_debug_addr_index() and dwarf_get_debug_str_index(). 2014-05-14 David Anderson * dwarf_die_deliv.c: Refactored several interfaces and used DW_DLV_OK (etc) returned values internally much more than before to get the desired behavior easily. * dwarf_error.c: Error strings for 8 new error numbers. * dwarf_form.c: DW_FORM_addr_index, DW_FORM_addrx support added. * dwarf_init_finish.c: Sections .debug_addr and .debug_addr.dwo now handled if present. * dwarf_opaque.h: New Dwarf_CU_Context fields added so we can get CU DIE attributes for DW_FORM_addrx DW_FORM_strx etc. New de_debug* fields added for the new DebugFission sections. * dwarf_query.c: Using the revised _dwarf_get_size_of_val() internal function. Handling DW_FORM_GNU_str_index, DW_FORM_strx. New functions (internal) for DW_FORM_strx, DW_FORM_addrx and the GNU version of these to avoid duplicating code. * dwarf_util.c: Implement revised _dwarf_get_size_of_val(). Handling DW_FORM_GNU_str_index, DW_FORM_strx. * dwarf_util.h: Updated _dwarf_get_size_of_val() declaration. * libdwarf2.1.mm: Revision 2.8. May 15 2014. Documented a restriction to a sensible view to strings that dwarf_errmsg() returns. However without actually changing anything to take advantage of that restriction. * libdwarf2.1.pdf: Regenerated. 2014-05-11 David Anderson * dwarf_error.c: Added 3 new error strings. * dwarf_form.c: Added DW_FORM_GNU_str_index and partial DW_FORM_GNU_addr_index handling. * dwarf_init_finish.c: Refactored initial section setup so we can handle dwo (DebugFission) or regular sections. * dwarf_query.c: Add support for DW_FORM_GNU_str_index. Partial support for DW_FORM_GNU_addr_index. * dwarf_util.c: Add support for DW_FORM_GNU_str_index, DW_FORM_GNU_addr_index. * libdwarf.h.in: 4 new error codes in DW_DLE_ list. Last now 248. 2014-05-09 David Anderson * Makefile.in: Write ar std-out to ar-output-temp so the text is not needlessly filling a terminal window. 2014-05-08 David Anderson * dwarf.h: Adds DW_AT_GNU_dwo_id, DW_AT_GNU_dwo_name and other GNU extensions. * libdwarf.h.in: Producer code changes: The dwarf_producer_init_d() is new and has new arguments. The older dwarf_producer_init() and _b _c versions are removed. Only one producer callback declaration exists now: Dwarf_Callback_Func. * pro_init.c: Implements the new dwarf_producer_init_d() function and initializes fields at runtime to select what DWARF to emit. Messy and confusing initialization code rewritten to depend on the runtime arguments to dwarf_producer_init_d, not library compile-time. * pro_opaque.h: New runtime fields set by initialization code. * pro_reloc.c: Fix a couple comment indentations. * pro_forms.c: Add curly braces in an if to avoid a hard-to-find bug (there was none yet, but it was a trap...). * pro_reloc_symbolic.c,pro_reloc_stream.c: Remove use of obsolete callback functions. * pro_section.c: Ensure only IRIX isa/abi target generates an exception CIE entry. Remove use of obsolete callbacks. * pro_util.h: Remove confusing and unreadable relocation number ifdefs that depended on settings at library compile-time. Most of the content of the file is deleted now. See isa_relocs[] in pro_init.c * dwarf_error.c: Added error code (used by producer code). * libdwarf2p.1.mm: Now version 1.36. Updated dwarf_producer_init() documentation. * libdwarf2p.1.pdf: Regenerated. 2014-04-14 David Anderson * pro_forms.c: Modified a comment about DW_FORM_ref_addr. No logic change. * bldDWindex.sh: Deleted. This shell script was intended for DWARF2 postscript post-processing and was never useful. 2014-04-12 David Anderson * dwarf_die_deliv.c,dwarf_query.c: Gets the version stamp passed to _dwarf_get_size_of_val() so DW_FORM_ref_addr handled correctly. * dwarf_form.c: Handle DW_FORM_ref_addr as the V2 specification says (V3 and later continue to be handled unchanged.). * dwarf_util.c: Handle DW_FORM_ref_addr as the V2 specification says (V3 and later continue to be handled unchanged.). * dwarf_addr_finder.c: Removed a mistaken handling of DW_FORM_ref_addr. No one should be using this function's features though... * pro_forms.c: Made a comment clearer about DW_FORM_ref_addr. * pro_section.c: Made a comment clearer, removed #if 0 code. 2014-04-02 David Anderson * libdwarf2.1.mm: Examples using dwarf_offdie_b() were miscoded (is_info argument not provided). Now fixed. Now at version 2.17. * libdwarf2.1.pdf: Regenerated 2014-03-17 David Anderson * dwarf.v2.mm,dwarf.v2.pdf,index.v2.mm,index.v2.pdf: Removed these files, they are now on dwarfstd.org. * Makefile.in: Removed mention of the deleted files. * README, COPYING: Removed mention of the deleted files. 2014-02-08 David Anderson * libdwarf2p.1.mm: Now version 1.35. Added a few words about the sect_name_index field in the callback from libdwarf to your code for each new Elf section to be generated. * libdwarf2p.1.pdf: Regenerated. 2014-02-02 David Anderson * dwarf_alloc.c: Added commentary. * dwarf_loc.c: Fixed two indents. * gennames.c: Removed trailing newlines from the printf output (dwarf_names_new.h is the file generated). * libdwarf.h.in: Removed trailing whitespace. 2014-02-01 David Anderson * dwarf_alloc.c: Instead of doing a long list of address compares, use the hash 'tree' and tfind() to determine if we malloced the space or simply took an address from .debug_info ( or other in-memory section) when we returned a _dwarf_get_alloc() pointer to the user. 2014-01-31 David Anderson * configure.in: The test to generate HAVE___UINT32_T_IN_SYS_TYPES_H was in a strange place. Moved it up a few lines. * configure: Regenerated. * dwarf_alloc.c: Added comment hinting at how dwarf_dealloc can be further simplified. 2014-01-30 David Anderson * dwarf_loc.c: Add support for DW_FORM_exprloc to dwarf_loclist_n(). * libdwarf2.1.mm: Document support for DW_FORM_exprloc.Version 2.16 * libdwarf2.1.pdf: Regenerate. * dwarf.h, dwarf_form.c, dwarf_line.c, dwarf_query.c, dwarf_util.c: Add limited support for DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. 2014-01-30 David Anderson * dwarf_alloc.c: Refactored and added relevant commentary. Added a check for debug_types in dwarf_dealloc(). * dwarf_init_finish.c: Corrected a comment and made one line declation-is-initialization. * dwarf_opaque.h: Added commentary. 2014-01-29 David Anderson * common.h,dwarf.h,dwarf_abbrev.c,dwarf_abbrev.h,dwarf_addr_finder.c, dwarf_alloc.c,dwarf_alloc.h,dwarf_arange.c,dwarf_arange.h, dwarf_base_types.h,dwarf_die_deliv.c,dwarf_die_deliv.h, dwarf_elf_access.c,dwarf_elf_access.h,dwarf_error.c,dwarf_error.h, dwarf_form.c,dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c, dwarf_frame3.c,dwarf_funcs.c,dwarf_funcs.h,dwarf_global.c, dwarf_global.h,dwarf_harmless.c,dwarf_harmless.h,dwarf_incl.h, dwarf_init_finish.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_loc.h,dwarf_macro.h,dwarf_opaque.h,dwarf_reloc_arm.h, dwarf_reloc_mips.h,dwarf_reloc_ppc.h,dwarf_reloc_ppc64.h, dwarf_reloc_x86_64.h,dwarf_tsearch.h,dwarf_types.h,dwarf_util.h, dwarf_vars.h,dwarf_weaks.h,libdwarfdefs.h,malloc_check.h, pro_alloc.h,pro_arange.h,pro_die.h,pro_encode_nm.h,pro_error.h, pro_frame.h,pro_incl.h,pro_line.h,pro_opaque.h,dwarf_tsearch.h: Remove trailing whitespace. 2014-01-29 David Anderson * dwarf_tsearch.h, dwarf_tsearchhash.c: New files implementing a hashed tree with tsearch() interfaces. * Makefile.in: Add dwarf_tsearchhash.c to the build. * dwarf_init_finish.c: Remove references to malloc_check and _dwarf_setup_debug() and include of "malloc_check.h" as those are no longer needed. * dwarf_line.c: Removed a superfluous _dwarf_get_alloc(). The result of the call was never used. * dwarf_opaque.h: Removed Dwarf_Alloc_Hdr_s references and simple malloc references. added de_alloc_tree as base of a hash database replacing most of dwarf_alloc.c. * dwarf_query.c: Removed an unused local variable. * dwarf_alloc.h,dwarf_alloc.c: Removed simple malloc support and all the complicated code handling allocation record-keeping in favor of much simpler code calling functions using a tsearch-like interface. 2014-01-10 David Anderson * dwarf_print_lines.c,dwarf_macro.c: Remove trailing whitespace. * dwarf_ranges.c, dwarf_sort_lines.c: Remove trailing whitespace. * dwarf_query.c, dwarf_pubtypes.c: Remove trailing whitespace. * dwarf_original_elf_init.c,dwarf_loc.c: Remove trailing whitespace. * gennames.c: Fix a printf so the generated dwarf_names.c does not have a trailing space. 2014-01-10 David Anderson * gennames.c: Added comment clarifying why error is set before the call to fgets, and fixing the declaration order to avoid c99-ism. * dwarf_frame2.c: Use /* not // for comments in C. libdwarf-20210528/libdwarf/CMakeLists.txt0000664000175000017500000001232014051001566015022 00000000000000set_source_group(SOURCES "Source Files" dwarf_abbrev.c dwarf_alloc.c dwarf_crc32.c dwarf_arange.c dwarf_debug_sup.c dwarf_debuglink.c dwarf_die_deliv.c dwarf_debug_names.c dwarf_dsc.c dwarf_elf_access.c dwarf_elf_load_headers.c dwarf_elfread.c dwarf_elf_rel_detector.c dwarf_error.c dwarf_find_sigref.c dwarf_fission_to_cu.c dwarf_form.c dwarf_form_class_names.c dwarf_frame.c dwarf_frame2.c dwarf_funcs.c dwarf_gdbindex.c dwarf_global.c dwarf_gnu_index.c dwarf_groups.c dwarf_harmless.c dwarf_generic_init.c dwarf_init_finish.c dwarf_leb.c dwarf_line.c dwarf_loc.c dwarf_loclists.c dwarf_locationop_read.c dwarf_machoread.c dwarf_macro.c dwarf_macro5.c dwarf_names.c dwarf_object_read_common.c dwarf_object_detector.c dwarf_original_elf_init.c dwarf_peread.c dwarf_pubtypes.c dwarf_query.c dwarf_ranges.c dwarf_rnglists.c dwarfstring.h dwarfstring.c dwarf_stringsection.c dwarf_tied.c dwarf_str_offsets.c dwarf_tsearchhash.c dwarf_types.c dwarf_util.c dwarf_vars.c dwarf_weaks.c dwarf_xu_index.c dwarf_print_lines.c malloc_check.c pro_alloc.c pro_arange.c crc32.c pro_debug_sup.c pro_die.c pro_dnames.c pro_encode_nm.c pro_error.c pro_expr.c pro_finish.c pro_forms.c pro_funcs.c pro_frame.c pro_init.c pro_line.c pro_reloc.c pro_reloc_stream.c pro_reloc_symbolic.c pro_pubnames.c pro_section.c pro_types.c pro_vars.c pro_macinfo.c pro_weaks.c) set_source_group(HEADERS "Header Files" dwarf.h dwarf_abbrev.h dwarf_alloc.h dwarf_arange.h dwarf_base_types.h dwarf_debuglink.h dwarf_die_deliv.h dwarf_debug_names.h dwarf_dsc.h dwarf_elf_access.h dwarf_elf_defines.h dwarf_elfread.h dwarf_elf_rel_detector.h dwarf_elf_reloc_386.h dwarf_elf_reloc_aarch64.h dwarf_elf_reloc_arm.h dwarf_elf_reloc_mips.h dwarf_elf_reloc_ppc64.h dwarf_elf_reloc_ppc.h dwarf_elf_reloc_sparc.h dwarf_elf_reloc_x86_64.h dwarf_elfstructs.h dwarf_error.h dwarf_frame.h dwarf_funcs.h dwarf_gdbindex.h dwarf_global.h dwarf_harmless.h dwarf_gnu_index.h dwarf_incl.h dwarf_line.h dwarf_loc.h dwarf_machoread.h dwarf_macro.h dwarf_macro5.h dwarf_names.h dwarf_object_detector.h dwarf_opaque.h dwarf_pe_descr.h dwarf_peread.h dwarf_reading.h dwarf_reloc_arm.h dwarf_reloc_mips.h dwarf_reloc_ppc.h dwarf_reloc_ppc64.h dwarf_reloc_x86_64.h dwarf_rnglists.h dwarf_tied_decls.h dwarf_tsearch.h dwarf_str_offsets.h dwarf_types.h dwarf_util.h dwarf_vars.h dwarf_weaks.h dwarf_xu_index.h libdwarfdefs.h dwarf_macho_loader.h malloc_check.h memcpy_swap.h pro_alloc.h pro_arange.h pro_die.h pro_encode_nm.h pro_error.h pro_expr.h pro_frame.h pro_incl.h pro_line.h pro_log_extra_flag_strings.c pro_macinfo.h pro_opaque.h pro_reloc.h pro_reloc_stream.h pro_reloc_symbolic.h pro_section.h pro_types.h pro_util.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) list(LENGTH DWARF_TARGETS targetCount) math(EXPR targetCount "${targetCount} - 1") list(APPEND DWARF_LIBS ${LIBELF_LIBRARIES}) if(UNIX) list(APPEND DWARF_LIBS z) endif() foreach(i RANGE ${targetCount}) list(GET DWARF_TARGETS ${i} target) list(GET DWARF_TYPES ${i} type) add_library(${target} ${type} ${SOURCES} ${HEADERS} ${GENNAMES_OUTPUT} ${CONFIGURATION_FILES}) set_folder(${target} libdwarf) target_include_directories(${target} PUBLIC ${LIBELF_INCLUDE_DIRS}) target_compile_options(${target} PRIVATE ${DW_FWALL}) msvc_posix(${target}) target_link_libraries(${target} PUBLIC ${LIBELF_LIBRARIES}) set_target_properties(${target} PROPERTIES OUTPUT_NAME dwarf) set(SUFFIX $<$:64>) set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS ${target} RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) endforeach() if (DO_TESTING) set_source_group(TESTLEB "Source Files" dwarf_leb_test.c dwarf_leb.c pro_encode_nm.c ) add_executable(selfleb ${TESTLEB}) target_compile_options(selfleb PRIVATE ${DW_FWALL}) add_test(NAME selfleb COMMAND selfleb) endif() if (DO_TESTING) set_source_group(TESTTIED "Source Files" dwarf_tied_test.c dwarf_tied.c dwarf_tsearchhash.c ) add_executable(selftied ${TESTTIED}) target_compile_options(selftied PRIVATE ${DW_FWALL}) add_test(NAME selftied COMMAND selftied) set_source_group(TESTSTRING "Source Files" test_dwarfstring.c dwarfstring.c dwarfstring.h) add_executable(teststring ${TESTSTRING}) target_compile_options(selftied PRIVATE ${DW_FWALL}) add_test(NAME teststring COMMAND teststring) endif() # The install has to be here, not in # ../CMakeLists.txt to make install work properly # for cmake before cmake 3.13. This also works # for newer cmake. add_custom_target(dd DEPENDS ${DWARF_TARGETS} dwarfdump) install(TARGETS ${DWARF_TARGETS} EXPORT libdwarfTargets ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) install(EXPORT libdwarfTargets FILE libdwarf-targets.cmake NAMESPACE libdwarf:: DESTINATION lib/cmake/libdwarf ) install( FILES cmake/libdwarf-config.cmake DESTINATION lib/cmake/libdwarf ) install(DIRECTORY libdwarf DESTINATION include/ FILES_MATCHING PATTERN "*.h") install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libdwarf/libdwarf.h DESTINATION include/libdwarf) libdwarf-20210528/libdwarf/dwarf_gdbindex.c0000664000175000017500000004562313764007262015422 00000000000000/* Copyright (C) 2014-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "memcpy_swap.h" #include "dwarf_gdbindex.h" #define TRUE 1 #define FALSE 0 /* The dwarf_util macro READ_UNALIGNED cannot be directly used because gdb defines the section contents of .gdb_index as little-endian always. */ #if WORDS_BIGENDIAN /* meaning on this host */ #define READ_GDBINDEX(dest,desttype, source, length) \ do { \ BIGGEST_UINT _ltmp = 0; \ _dwarf_memcpy_swap_bytes((((char *)(&_ltmp)) \ + sizeof(_ltmp) - length), \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) #else /* little-endian on this host */ #define READ_GDBINDEX(dest,desttype, source, length) \ do { \ BIGGEST_UINT _ltmp = 0; \ memcpy(((char *)(&_ltmp)) , \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) #endif struct gi_fileheader_s { char gfs [4][6]; }; struct dwarf_64bitpair { gdbindex_64 offset; gdbindex_64 length; }; static int set_base(Dwarf_Debug dbg, struct Dwarf_Gdbindex_array_instance_s * hdr, Dwarf_Small *start, Dwarf_Small *end, /* entrylen is the length of a single struct as seen in the object. */ Dwarf_Unsigned entrylen, /* The size of each field in the struct in the object. */ Dwarf_Unsigned fieldlen, enum gdbindex_type_e type, Dwarf_Error * err) { if (type == git_std || type == git_cuvec) { /* cuvec is sort of a fake as a simple section, but a useful one. */ Dwarf_Unsigned count = 0; if ( end < start) { _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ERROR); return DW_DLV_ERROR; } count = end - start; count = count / entrylen; hdr->dg_type = type; hdr->dg_base = start; hdr->dg_count = count; hdr->dg_entry_length = entrylen; hdr->dg_fieldlen = fieldlen; } else { /* address area. */ /* 64bit, 64bit, offset. Then 32bit pad. */ Dwarf_Unsigned count = 0; hdr->dg_base = start; if ( end < start) { _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR); return DW_DLV_ERROR; } /* entry length includes pad. */ hdr->dg_entry_length = 2*sizeof(gdbindex_64) + DWARF_32BIT_SIZE; count = end - start; count = count / hdr->dg_entry_length; hdr->dg_count = count; /* The dg_fieldlen is a fake, the fields are not all the same length. */ hdr->dg_fieldlen = DWARF_32BIT_SIZE; hdr->dg_type = type; } return DW_DLV_OK; } int dwarf_gdbindex_header(Dwarf_Debug dbg, Dwarf_Gdbindex * gdbindexptr, Dwarf_Unsigned * version, Dwarf_Unsigned * cu_list_offset, Dwarf_Unsigned * types_cu_list_offset, Dwarf_Unsigned * address_area_offset, Dwarf_Unsigned * symbol_table_offset, Dwarf_Unsigned * constant_pool_offset, Dwarf_Unsigned * section_size, Dwarf_Unsigned * unused_reserved, const char ** section_name, Dwarf_Error * error) { struct gi_fileheader_s header; Dwarf_Gdbindex indexptr = 0; int res = DW_DLV_ERROR; if (!dbg->de_debug_gdbindex.dss_size) { return DW_DLV_NO_ENTRY; } if (!dbg->de_debug_gdbindex.dss_data) { res = _dwarf_load_section(dbg, &dbg->de_debug_gdbindex,error); if (res != DW_DLV_OK) { return res; } } if (dbg->de_debug_gdbindex.dss_size < sizeof(struct gi_fileheader_s) ) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_GDB_INDEX_SECTION); return DW_DLV_ERROR; } memcpy(&header,dbg->de_debug_gdbindex.dss_data, sizeof(struct gi_fileheader_s)); indexptr = (Dwarf_Gdbindex)_dwarf_get_alloc(dbg, DW_DLA_GDBINDEX,1); if (indexptr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } indexptr->gi_dbg = dbg; indexptr->gi_section_data = dbg->de_debug_gdbindex.dss_data; indexptr->gi_section_length = dbg->de_debug_gdbindex.dss_size; READ_GDBINDEX(indexptr->gi_version ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_cu_list_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_types_cu_list_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 2*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_address_area_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 3*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_symbol_table_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 4*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_constant_pool_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 5*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); res = set_base(dbg,&indexptr->gi_culisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_cu_list_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset, 2*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_typesculisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_addressareahdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_address,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_symboltablehdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, 2*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE, git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_cuvectorhdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, /* There is no real single vector size. but we'll use the entire rest as if there was. */ dbg->de_debug_gdbindex.dss_data + indexptr->gi_section_length, DWARF_32BIT_SIZE, DWARF_32BIT_SIZE, git_cuvec,error); if (res == DW_DLV_ERROR) { return res; } /* Really just pointing to constant pool area. */ indexptr->gi_string_pool = dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset; *gdbindexptr = indexptr; *version = indexptr->gi_version; *cu_list_offset = indexptr->gi_cu_list_offset; *types_cu_list_offset = indexptr->gi_types_cu_list_offset; *address_area_offset = indexptr->gi_address_area_offset; *symbol_table_offset = indexptr->gi_symbol_table_offset; *constant_pool_offset = indexptr->gi_constant_pool_offset; *section_size = indexptr->gi_section_length; *unused_reserved = 0; *section_name = dbg->de_debug_gdbindex.dss_name; return DW_DLV_OK; } int dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_culisthdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * cu_length, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_culisthdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; unsigned fieldlen = gdbindexptr->gi_culisthdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_culisthdr.dg_base; base += entryindex*gdbindexptr->gi_culisthdr.dg_entry_length; READ_GDBINDEX(offset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(length ,Dwarf_Unsigned, base+ fieldlen, fieldlen); *cu_offset = offset; *cu_length = length; return DW_DLV_OK; } int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_typesculisthdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_types_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * t_offset, Dwarf_Unsigned * t_length, Dwarf_Unsigned * t_signature, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_typesculisthdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned signature = 0; unsigned fieldlen = gdbindexptr->gi_typesculisthdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_typesculisthdr.dg_base; base += entryindex*gdbindexptr->gi_typesculisthdr.dg_entry_length; READ_GDBINDEX(offset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(length ,Dwarf_Unsigned, base+ (1*fieldlen), fieldlen); READ_GDBINDEX(signature ,Dwarf_Unsigned, base+ (2*fieldlen), fieldlen); *t_offset = offset; *t_length = length; *t_signature = signature; return DW_DLV_OK; } int dwarf_gdbindex_addressarea(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_addressareahdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * low_address, Dwarf_Unsigned * high_address, Dwarf_Unsigned * cu_index, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_addressareahdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned lowaddr = 0; Dwarf_Unsigned highaddr = 0; Dwarf_Unsigned cuindex = 0; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_addressareahdr.dg_base; base += entryindex*gdbindexptr->gi_addressareahdr.dg_entry_length; READ_GDBINDEX(lowaddr ,Dwarf_Unsigned, base, sizeof(gdbindex_64)); READ_GDBINDEX(highaddr ,Dwarf_Unsigned, base+ (1*sizeof(gdbindex_64)), sizeof(gdbindex_64)); READ_GDBINDEX(cuindex ,Dwarf_Unsigned, base+ (2*sizeof(gdbindex_64)), DWARF_32BIT_SIZE); *low_address = lowaddr; *high_address = highaddr; *cu_index = cuindex; return DW_DLV_OK; } int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_symboltablehdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * string_offset, Dwarf_Unsigned * cu_vector_offset, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_symboltablehdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned symoffset = 0; Dwarf_Unsigned cuoffset = 0; unsigned fieldlen = gdbindexptr->gi_symboltablehdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_symboltablehdr.dg_base; base += entryindex*gdbindexptr->gi_symboltablehdr.dg_entry_length; READ_GDBINDEX(symoffset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(cuoffset ,Dwarf_Unsigned, base + fieldlen, fieldlen); *string_offset = symoffset; *cu_vector_offset = cuoffset; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned * innercount, Dwarf_Error * error) { Dwarf_Small *base = gdbindex->gi_cuvectorhdr.dg_base; Dwarf_Small *end = gdbindex->gi_section_data + gdbindex->gi_section_length; Dwarf_Unsigned val = 0; unsigned fieldlen = gdbindex->gi_cuvectorhdr.dg_entry_length; base += cuvector_offset; if ((base + fieldlen) >= end) { _dwarf_error(gdbindex->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } READ_GDBINDEX(val,Dwarf_Unsigned, base, fieldlen); *innercount = val; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned innerindex, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_instance_expand_value() */ Dwarf_Unsigned * attributes, Dwarf_Error * error) { Dwarf_Small *base = gdbindexptr->gi_cuvectorhdr.dg_base; Dwarf_Small *end = gdbindexptr->gi_section_data + gdbindexptr->gi_section_length; Dwarf_Unsigned val = 0; unsigned fieldlen = gdbindexptr->gi_cuvectorhdr.dg_entry_length; base += cuvector_offset; if ((base+fieldlen) >= end) { _dwarf_error(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base += fieldlen; base += innerindex*fieldlen; READ_GDBINDEX(val ,Dwarf_Unsigned, base, fieldlen); *attributes = val; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_instance_expand_value( UNUSEDARG Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned value, Dwarf_Unsigned * cu_index, Dwarf_Unsigned * reserved1, Dwarf_Unsigned * symbol_kind, Dwarf_Unsigned * is_static, UNUSEDARG Dwarf_Error * error) { *cu_index = value & 0xffffff; *reserved1 = (value >> 24) & 0xf; *symbol_kind = (value >> 28) & 0x7; *is_static = (value >> 31) & 1; return DW_DLV_OK; } /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned stringoffsetinpool, const char ** string_ptr, Dwarf_Error * error) { Dwarf_Small *pooldata = 0; Dwarf_Small *section_end = 0; Dwarf_Small *stringitself = 0; Dwarf_Debug dbg = 0; int res = 0; if (!gdbindexptr) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m,"DW_DLE_GDB_INDEX_INDEX_ERROR: " "The gdbindex pointer to " "dwarf_gdbindex_string_by_offset()" " is NULL"); _dwarf_error_string(gdbindexptr->gi_dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } dbg = gdbindexptr->gi_dbg; if (!dbg) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m,"DW_DLE_GDB_INDEX_INDEX_ERROR: " "The gdbindex Dwarf_Debug in" "dwarf_gdbindex_string_by_offset()" " is NULL"); _dwarf_error_string(dbg, error, DW_DLE_GDB_INDEX_INDEX_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } pooldata = gdbindexptr->gi_section_data + gdbindexptr->gi_constant_pool_offset; section_end = gdbindexptr->gi_section_data + gdbindexptr->gi_section_length; stringitself = pooldata + stringoffsetinpool; if (stringitself > section_end) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_GDBINDEX_STRING_ERROR: " "The dwarf_gdbindex_string_by_offset() " "string starts past the end of the " "section at section_offset 0x%" DW_PR_XZEROS DW_PR_DUx ".", (Dwarf_Unsigned)(uintptr_t) (stringitself -gdbindexptr->gi_section_data)); _dwarf_error_string(dbg, error, DW_DLE_GDBINDEX_STRING_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } res = _dwarf_check_string_valid(dbg,pooldata, stringitself, section_end, DW_DLE_GDBINDEX_STRING_ERROR, error); if (res != DW_DLV_OK) { return res; } *string_ptr = (const char *)stringitself; return DW_DLV_OK; } void dwarf_gdbindex_free(Dwarf_Gdbindex indexptr) { if (indexptr) { Dwarf_Debug dbg = indexptr->gi_dbg; dwarf_dealloc(dbg,indexptr,DW_DLA_GDBINDEX); } } libdwarf-20210528/libdwarf/malloc_check.c0000664000175000017500000002257613764007262015061 00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* malloc_check.c For checking dealloc completeness. This code is as simple as possible and works ok for reasonable size allocation counts. It treats allocation as global, and so will not work very well if an application opens more than one Dwarf_Debug. */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "config.h" #include "dwarf_incl.h" #include "malloc_check.h" #ifdef WANT_LIBBDWARF_MALLOC_CHECK /* To turn off printing every entry, just change the define to set PRINT_MALLOC_DETAILS 0. */ #define PRINT_MALLOC_DETAILS 0 #define MC_TYPE_UNKNOWN 0 #define MC_TYPE_ALLOC 1 #define MC_TYPE_DEALLOC 2 struct mc_data_s { struct mc_data_s *mc_prev; unsigned long mc_address; /* Assumes this is large enough to hold a pointer! */ long mc_alloc_number; /* Assigned in order by when record created. */ unsigned char mc_alloc_code; /* Allocation code, libdwarf. */ unsigned char mc_type; unsigned char mc_dealloc_noted; /* Used on an ALLOC node. */ unsigned char mc_dealloc_noted_count; /* Used on an ALLOC node. */ }; /* */ #define HASH_TABLE_SIZE 10501 static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE]; static long mc_data_list_size = 0; static char *alloc_type_name[MAX_DW_DLA + 1] = { "", "DW_DLA_STRING", "DW_DLA_LOC", "DW_DLA_LOCDESC", "DW_DLA_ELLIST", "DW_DLA_BOUNDS", "DW_DLA_BLOCK", "DW_DLA_DEBUG", "DW_DLA_DIE", "DW_DLA_LINE", "DW_DLA_ATTR", "DW_DLA_TYPE", "DW_DLA_SUBSCR", "DW_DLA_GLOBAL", "DW_DLA_ERROR", "DW_DLA_LIST", "DW_DLA_LINEBUF", "DW_DLA_ARANGE", "DW_DLA_ABBREV", "DW_DLA_FRAME_OP", "DW_DLA_CIE", "DW_DLA_FDE", "DW_DLA_LOC_BLOCK", "DW_DLA_FRAME_BLOCK", "DW_DLA_FUNC", "DW_DLA_TYPENAME", "DW_DLA_VAR", "DW_DLA_WEAK", "DW_DLA_ADDR", "DW_DLA_ABBREV_LIST", "DW_DLA_CHAIN", "DW_DLA_CU_CONTEXT", "DW_DLA_FRAME", "DW_DLA_GLOBAL_CONTEXT", "DW_DLA_FILE_ENTRY", "DW_DLA_LINE_CONTEXT", "DW_DLA_LOC_CHAIN", "DW_DLA_HASH_TABLE", "DW_DLA_FUNC_CONTEXT", "DW_DLA_TYPENAME_CONTEXT", "DW_DLA_VAR_CONTEXT", "DW_DLA_WEAK_CONTEXT", "DW_DLA_PUBTYPES_CONTEXT" /* Don't forget to expand this list if the list of codes expands. */ }; static unsigned hash_address(unsigned long addr) { unsigned long a = addr >> 2; return a % HASH_TABLE_SIZE; } #if PRINT_MALLOC_DETAILS static void print_alloc_dealloc_detail(unsigned long addr, int code, char *whichisit) { fprintf(stderr, "%s addr 0x%lx code %d (%s) entry %ld\n", whichisit, addr, code, alloc_type_name[code], mc_data_list_size); } #else #define print_alloc_dealloc_detail(a,b,c) /* nothing */ #endif /* Create a zeroed struct or die. */ static void * newone(void) { struct mc_data_s *newd = malloc(sizeof(struct mc_data_s)); if (newd == 0) { fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size); exit(1); } memset(newd, 0, sizeof(struct mc_data_s)); return newd; } /* Notify checker that get_alloc has allocated user data. */ void dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code) { struct mc_data_s *newd = newone(); unsigned long addr = (unsigned long) addr_in; struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; print_alloc_dealloc_detail(addr, code, "alloc "); newd->mc_address = addr; newd->mc_alloc_code = code; newd->mc_type = MC_TYPE_ALLOC; newd->mc_alloc_number = mc_data_list_size; newd->mc_prev = *base; *base = newd; newd->mc_alloc_number = mc_data_list_size; mc_data_list_size += 1; } static void print_entry(char *msg, struct mc_data_s *data) { fprintf(stderr, "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n", msg, (long) data->mc_address, data->mc_alloc_code, alloc_type_name[data->mc_alloc_code], (data->mc_type == MC_TYPE_ALLOC) ? "alloc " : (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown", (unsigned) data->mc_dealloc_noted, (unsigned) data->mc_dealloc_noted_count); } /* newd is a 'dealloc'. */ static long balanced_by_alloc_p(struct mc_data_s *newd, long *addr_match_num, struct mc_data_s **addr_match, struct mc_data_s *base) { struct mc_data_s *cur = base; for (; cur; cur = cur->mc_prev) { if (cur->mc_address == newd->mc_address) { if (cur->mc_type == MC_TYPE_ALLOC) { if (cur->mc_alloc_code == newd->mc_alloc_code) { *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return cur->mc_alloc_number; } else { /* code mismatch */ *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return -1; } } else { /* Unbalanced new/del */ *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return -1; } } } return -1; } /* A dealloc is to take place. Ensure it balances an alloc. */ void dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code) { struct mc_data_s *newd = newone(); long prev; long addr_match_num = -1; struct mc_data_s *addr_match = 0; unsigned long addr = (unsigned long) addr_in; struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; print_alloc_dealloc_detail(addr, code, "dealloc "); newd->mc_address = (unsigned long) addr; newd->mc_alloc_code = code; newd->mc_type = MC_TYPE_DEALLOC; newd->mc_prev = *base; prev = balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base); if (prev < 0) { fprintf(stderr, "Unbalanced dealloc at index %ld\n", mc_data_list_size); print_entry("new", newd); fprintf(stderr, "addr-match_num? %ld\n", addr_match_num); if (addr_match) { print_entry("prev entry", addr_match); if (addr_match->mc_dealloc_noted > 1) { fprintf(stderr, "Above is Duplicate dealloc!\n"); } } abort(); exit(3); } addr_match->mc_dealloc_noted = 1; addr_match->mc_dealloc_noted_count += 1; if (addr_match->mc_dealloc_noted_count > 1) { fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num); print_entry("new dealloc entry", newd); print_entry("bad alloc entry", addr_match); } *base = newd; mc_data_list_size += 1; } /* Final check for leaks. */ void dwarf_malloc_check_complete(char *msg) { long i = 0; long total = mc_data_list_size; long hash_slots_used = 0; long max_chain_length = 0; fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total); for (; i < HASH_TABLE_SIZE; ++i) { struct mc_data_s *cur = mc_data_hash[i]; long cur_chain_length = 0; if (cur == 0) continue; ++hash_slots_used; for (; cur; cur = cur->mc_prev) { ++cur_chain_length; if (cur->mc_type == MC_TYPE_ALLOC) { if (cur->mc_dealloc_noted) { if (cur->mc_dealloc_noted > 1) { fprintf(stderr, " Duplicate dealloc! entry %ld\n", cur->mc_alloc_number); print_entry("duplicate dealloc", cur); } continue; } else { fprintf(stderr, "malloc no dealloc, entry %ld\n", cur->mc_alloc_number); print_entry("dangle", cur); } } else { /* mc_type is MC_TYPE_DEALLOC, already checked */ } } if (cur_chain_length > max_chain_length) { max_chain_length = cur_chain_length; } } fprintf(stderr, "mc hash table slots=%ld, " "used=%ld, maxchain=%ld\n", (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length); return; } #else extern void *libdwarf_an_unused_function_so_not_empty_c_file(void); #endif /* WANT_LIBBDWARF_MALLOC_CHECK */ libdwarf-20210528/libdwarf/dwarf_machoread.h0000664000175000017500000001056613763277633015576 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_MACHOREAD_H #define DWARF_MACHOREAD_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct generic_macho_header { Dwarf_Unsigned magic; Dwarf_Unsigned cputype; Dwarf_Unsigned cpusubtype; Dwarf_Unsigned filetype; Dwarf_Unsigned ncmds; /* number of load commands */ /* the size of all the load commands */ Dwarf_Unsigned sizeofcmds; Dwarf_Unsigned flags; Dwarf_Unsigned reserved; }; struct generic_macho_command { Dwarf_Unsigned cmd; Dwarf_Unsigned cmdsize; Dwarf_Unsigned offset_this_command; }; struct generic_macho_segment_command { Dwarf_Unsigned cmd; Dwarf_Unsigned cmdsize; char segname[24]; Dwarf_Unsigned vmaddr; Dwarf_Unsigned vmsize; Dwarf_Unsigned fileoff; Dwarf_Unsigned filesize; Dwarf_Unsigned maxprot; Dwarf_Unsigned initprot; Dwarf_Unsigned nsects; Dwarf_Unsigned flags; /* our index into mo_commands */ Dwarf_Unsigned macho_command_index; Dwarf_Unsigned sectionsoffset; }; struct generic_macho_section { /* Larger than in file, room for NUL guaranteed */ char sectname[24]; char segname[24]; const char * dwarfsectname; Dwarf_Unsigned addr; Dwarf_Unsigned size; Dwarf_Unsigned offset; Dwarf_Unsigned align; Dwarf_Unsigned reloff; Dwarf_Unsigned nreloc; Dwarf_Unsigned flags; Dwarf_Unsigned reserved1; Dwarf_Unsigned reserved2; Dwarf_Unsigned reserved3; Dwarf_Unsigned generic_segment_num; Dwarf_Unsigned offset_of_sec_rec; Dwarf_Small* loaded_data; }; /* ident[0] == 'M' means this is a macho header. ident[1] will be 1 indicating version 1. Other bytes in ident not defined, should be zero. */ typedef struct dwarf_macho_filedata_s { char mo_ident[8]; const char * mo_path; /* libdwarf must free.*/ int mo_fd; int mo_destruct_close_fd; /*aka: lib owns fd */ int mo_is_64bit; Dwarf_Unsigned mo_filesize; Dwarf_Small mo_offsetsize; /* 32 or 64 section data */ Dwarf_Small mo_pointersize; int mo_ftype; Dwarf_Endianness mo_endian; /*Dwarf_Small mo_machine; */ void (*mo_copy_word) (void *, const void *, unsigned long); /* Used to hold 32 and 64 header data */ struct generic_macho_header mo_header; unsigned mo_command_count; Dwarf_Unsigned mo_command_start_offset; struct generic_macho_command *mo_commands; Dwarf_Unsigned mo_offset_after_commands; Dwarf_Unsigned mo_segment_count; struct generic_macho_segment_command *mo_segment_commands; Dwarf_Unsigned mo_dwarf_sectioncount; struct generic_macho_section *mo_dwarf_sections; } dwarf_macho_object_access_internals_t; int dwarf_load_macho_header( dwarf_macho_object_access_internals_t * mfp, int *errcode); int dwarf_load_macho_commands( dwarf_macho_object_access_internals_t * mfp, int *errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_MACHOREAD_H */ libdwarf-20210528/libdwarf/dwarf_util.c0000664000175000017500000013641414007376551014613 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. Portions Copyright 2020 Google All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include /* For free() and emergency abort() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* for open() */ #endif /* HAVE_SYS_STAT_H */ #include /* for open() */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_abbrev.h" #include "memcpy_swap.h" #include "dwarf_die_deliv.h" #include "dwarfstring.h" #include "pro_encode_nm.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #define MINBUFLEN 1000 #define TRUE 1 #define FALSE 0 #if _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ /* The function returned allows dwarfdump and other callers to do an endian-sensitive copy-word with a chosen source-length. */ typedef void (*endian_funcp_type)(void *, const void *,unsigned long); const char * dwarf_package_version(void) { return PACKAGE_VERSION; } #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif endian_funcp_type dwarf_get_endian_copy_function(Dwarf_Debug dbg) { if (dbg) { return dbg->de_copy_word; } return 0; } Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg) { if (!dbg) { return FALSE; } if (dbg->de_cu_hashindex_data) { return TRUE; } return FALSE; } Dwarf_Bool _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg) { if (!dbg) { return FALSE; } if (dbg->de_tu_hashindex_data ) { return TRUE; } return FALSE; } Dwarf_Bool _dwarf_file_has_debug_fission_index(Dwarf_Debug dbg) { if (!dbg) { return FALSE; } if (dbg->de_cu_hashindex_data || dbg->de_tu_hashindex_data) { return 1; } return FALSE; } void _dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned targ, Dwarf_Unsigned sectionlen) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE: " " The header length of 0x%x is larger", targ); dwarfstring_append_printf_u(&m," than the " "section length of 0x%x.",sectionlen); _dwarf_error_string(dbg, error,DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE, dwarfstring_string(&m)); dwarfstring_destructor(&m); } int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, const char **compname_out, Dwarf_Error *error) { Dwarf_Attribute comp_dir_attr = 0; Dwarf_Attribute comp_name_attr = 0; int resattr = 0; Dwarf_Debug dbg = 0; dbg = die->di_cu_context->cc_dbg; resattr = dwarf_attr(die, DW_AT_name, &comp_name_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *name = 0; cres = dwarf_formstring(comp_name_attr, &name, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compname_out = (const char *)name; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); } resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *cdir = 0; cres = dwarf_formstring(comp_dir_attr, &cdir, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compdir_out = (const char *) cdir; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); } return resattr; } /* Given a form, and a pointer to the bytes encoding a value of that form, val_ptr, this function returns the length, in bytes, of a value of that form. When using this function, check for a return of 0 a recursive DW_FORM_INDIRECT value. */ int _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Half cu_version, Dwarf_Half address_size, Dwarf_Small * val_ptr, int v_length_size, Dwarf_Unsigned *size_out, Dwarf_Small *section_end_ptr, Dwarf_Error*error) { Dwarf_Unsigned length = 0; Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned form_indirect = 0; Dwarf_Unsigned ret_value = 0; switch (form) { /* When we encounter a FORM here that we know about but forgot to enter here, we had better not just continue. Usually means we forgot to update this function when implementing form handling of a new FORM. Disaster results from using a bogus value, so generate error. */ default: _dwarf_error(dbg,error,DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE); return DW_DLV_ERROR; case 0: return DW_DLV_OK; case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_addr: if (address_size) { *size_out = address_size; } else { /* This should never happen, address_size should be set. */ *size_out = dbg->de_pointer_size; } return DW_DLV_OK; case DW_FORM_ref_sig8: *size_out = 8; /* sizeof Dwarf_Sig8 */ return DW_DLV_OK; /* DWARF2 was wrong on the size of the attribute for DW_FORM_ref_addr. We assume compilers are using the corrected DWARF3 text (for 32bit pointer target objects pointer and offsets are the same size anyway). It is clear (as of 2014) that for 64bit folks used the V2 spec in the way V2 was written, so the ref_addr has to account for that.*/ case DW_FORM_ref_addr: if (cu_version == DW_CU_VERSION2) { *size_out = address_size; } else { *size_out = v_length_size; } return DW_DLV_OK; case DW_FORM_block1: { Dwarf_Unsigned space_left = 0; if (val_ptr >= section_end_ptr) { _dwarf_error_string(dbg,error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: DW_FORM_block1" " itself is off the end of the section." " Corrupt Dwarf."); return DW_DLV_ERROR; } ret_value = *(Dwarf_Small *) val_ptr; /* ptrdiff_t is generated but not named */ space_left = (section_end_ptr >= val_ptr)? (section_end_ptr - val_ptr):0; if (ret_value > space_left) { _dwarf_error_string(dbg,error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: DW_FORM_block1" " runs off the end of the section." " Corrupt Dwarf."); return DW_DLV_ERROR; } *size_out = ret_value +1; } return DW_DLV_OK; case DW_FORM_block2: { Dwarf_Unsigned space_left = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, val_ptr, DWARF_HALF_SIZE,error,section_end_ptr); /* ptrdiff_t is generated but not named */ space_left = (section_end_ptr >= val_ptr)? (section_end_ptr - val_ptr):0; if (ret_value > space_left) { _dwarf_error_string(dbg,error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: DW_FORM_block2" " runs off the end of the section." " Corrupt Dwarf."); return DW_DLV_ERROR; } *size_out = ret_value + DWARF_HALF_SIZE; } return DW_DLV_OK; case DW_FORM_block4: { Dwarf_Unsigned space_left = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, val_ptr, DWARF_32BIT_SIZE, error,section_end_ptr); /* ptrdiff_t is generated but not named */ space_left = (section_end_ptr >= val_ptr)? (section_end_ptr - val_ptr):0; if (ret_value > space_left) { _dwarf_error_string(dbg,error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: DW_FORM_block4" " runs off the end of the section." " Corrupt Dwarf."); return DW_DLV_ERROR; } *size_out = ret_value + DWARF_32BIT_SIZE; } return DW_DLV_OK; case DW_FORM_data1: *size_out = 1; return DW_DLV_OK; case DW_FORM_data2: *size_out = 2; return DW_DLV_OK; case DW_FORM_data4: *size_out = 4; return DW_DLV_OK; case DW_FORM_data8: *size_out = 8; return DW_DLV_OK; case DW_FORM_data16: *size_out = 16; return DW_DLV_OK; case DW_FORM_string: { int res = 0; res = _dwarf_check_string_valid(dbg,val_ptr, val_ptr, section_end_ptr, DW_DLE_FORM_STRING_BAD_STRING, error); if ( res != DW_DLV_OK) { return res; } } *size_out = strlen((char *) val_ptr) + 1; return DW_DLV_OK; case DW_FORM_block: case DW_FORM_exprloc: { DECODE_LEB128_UWORD_LEN_CK(val_ptr,length,leb128_length, dbg,error,section_end_ptr); *size_out = length + leb128_length; return DW_DLV_OK;; } case DW_FORM_flag_present: *size_out = 0; return DW_DLV_OK; case DW_FORM_flag: *size_out = 1; return DW_DLV_OK; case DW_FORM_sec_offset: /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */ *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_ref_udata: { UNUSEDARG Dwarf_Unsigned v = 0; /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK;; } case DW_FORM_indirect: { Dwarf_Unsigned indir_len = 0; int res = 0; Dwarf_Unsigned info_data_len = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,form_indirect, indir_len, dbg,error,section_end_ptr); if (form_indirect == DW_FORM_indirect) { /* We are in big trouble: The true form of DW_FORM_indirect is DW_FORM_indirect? Nonsense. Should never happen. */ _dwarf_error(dbg,error, DW_DLE_NESTED_FORM_INDIRECT_ERROR); return DW_DLV_ERROR; } /* If form_indirect is DW_FORM_implicit_const then the following call will set info_data_len 0 */ res = _dwarf_get_size_of_val(dbg, form_indirect, cu_version, address_size, val_ptr + indir_len, v_length_size, &info_data_len, section_end_ptr, error); if (res != DW_DLV_OK) { return res; } *size_out = indir_len + info_data_len; return DW_DLV_OK; } case DW_FORM_ref1: *size_out = 1; return DW_DLV_OK; case DW_FORM_ref2: *size_out = 2; return DW_DLV_OK; case DW_FORM_ref4: *size_out = 4; return DW_DLV_OK; case DW_FORM_ref8: *size_out = 8; return DW_DLV_OK; /* DW_FORM_implicit_const is a value in the abbreviations, not in the DIEs and this functions measures DIE size. */ case DW_FORM_implicit_const: *size_out = 0; return DW_DLV_OK; case DW_FORM_sdata: { /* Discard the decoded value, we just want the length of the value. */ UNUSEDARG Dwarf_Signed v = 0; /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_SWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } case DW_FORM_ref_sup4: *size_out = 4; return DW_DLV_OK; case DW_FORM_ref_sup8: *size_out = 8; return DW_DLV_OK; case DW_FORM_addrx1: *size_out = 1; return DW_DLV_OK; case DW_FORM_addrx2: *size_out = 2; return DW_DLV_OK; case DW_FORM_addrx3: *size_out = 4; return DW_DLV_OK; case DW_FORM_addrx4: *size_out = 4; return DW_DLV_OK; case DW_FORM_strx1: *size_out = 1; return DW_DLV_OK; case DW_FORM_strx2: *size_out = 2; return DW_DLV_OK; case DW_FORM_strx3: *size_out = 4; return DW_DLV_OK; case DW_FORM_strx4: *size_out = 4; return DW_DLV_OK; case DW_FORM_loclistx: case DW_FORM_rnglistx: case DW_FORM_addrx: case DW_FORM_GNU_addr_index: case DW_FORM_strx: case DW_FORM_GNU_str_index: { UNUSEDARG Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } case DW_FORM_line_strp: case DW_FORM_strp: *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_udata: { /* Discard the decoded value, we just want the length of the value. */ UNUSEDARG Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } } } /* We allow an arbitrary number of HT_MULTIPLE entries before resizing. It seems up to 20 or 30 would work nearly as well. We could have a different resize multiple than 'resize now' test multiple, but for now we don't do that. */ #define HT_MULTIPLE 8 /* Copy the old entries, updating each to be in a new list. Don't delete anything. Leave the htin with stale data. */ static void copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin, Dwarf_Hash_Table htout) { Dwarf_Hash_Table_Entry entry_in = htin->tb_entries; unsigned entry_in_count = htin->tb_table_entry_count; Dwarf_Hash_Table_Entry entry_out = htout->tb_entries; unsigned entry_out_count = htout->tb_table_entry_count; unsigned k = 0; for (; k < entry_in_count; ++k,++entry_in) { Dwarf_Abbrev_List listent = entry_in->at_head; Dwarf_Abbrev_List nextlistent = 0; for (; listent ; listent = nextlistent) { unsigned newtmp = listent->abl_code; unsigned newhash = newtmp%entry_out_count; Dwarf_Hash_Table_Entry e; nextlistent = listent->abl_next; e = entry_out+newhash; /* Move_entry_to_new_hash. This reverses the order of the entries, effectively, but that does not seem significant. */ listent->abl_next = e->at_head; e->at_head = listent; htout->tb_total_abbrev_count++; } } } /* We allow zero form here, end of list. */ int _dwarf_valid_form_we_know(Dwarf_Unsigned at_form, Dwarf_Unsigned at_name) { if (at_form == 0 && at_name == 0) { return TRUE; } if (at_name == 0) { return FALSE; } if (at_form <= DW_FORM_addrx4 ) { return TRUE; } if (at_form == DW_FORM_GNU_addr_index || at_form == DW_FORM_GNU_str_index || at_form == DW_FORM_GNU_ref_alt || at_form == DW_FORM_GNU_strp_alt) { return TRUE; } return FALSE; } int _dwarf_format_TAG_err_msg(Dwarf_Debug dbg, Dwarf_Unsigned tag, const char *m, Dwarf_Error *errp) { dwarfstring v; dwarfstring_constructor(&v); dwarfstring_append(&v,(char *)m); dwarfstring_append(&v," The value "); dwarfstring_append_printf_u(&v,"0x%" DW_PR_DUx " is outside the valid TAG range.",tag); dwarfstring_append(&v," Corrupt DWARF."); _dwarf_error_string(dbg, errp,DW_DLE_TAG_CORRUPT, dwarfstring_string(&v)); dwarfstring_destructor(&v); return DW_DLV_ERROR; } /* This function returns a pointer to a Dwarf_Abbrev_List_s struct for the abbrev with the given code. It puts the struct on the appropriate hash table. It also adds all the abbrev between the last abbrev added and this one to the hash table. In other words, the .debug_abbrev section is scanned sequentially from the top for an abbrev with the given code. All intervening abbrevs are also put into the hash table. This function hashes the given code, and checks the chain at that hash table entry to see if a Dwarf_Abbrev_List_s with the given code exists. If yes, it returns a pointer to that struct. Otherwise, it scans the .debug_abbrev section from the last byte scanned for that CU till either an abbrev with the given code is found, or an abbrev code of 0 is read. It puts Dwarf_Abbrev_List_s entries for all abbrev's read till that point into the hash table. The hash table contains both a head pointer and a tail pointer for each entry. While the lists can move and entries can be moved between lists on reallocation, any given Dwarf_Abbrev_list entry never moves once allocated, so the pointer is safe to return. See also dwarf_get_abbrev() in dwarf_abbrev.c. On returning DW_DLV_NO_ENTRY (as well as DW_DLV_OK) it sets *highest_known_code as a side effect for better error messages by callers. Returns DW_DLV_ERROR on error. */ int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Abbrev_List *list_out, Dwarf_Unsigned *highest_known_code, Dwarf_Error *error) { Dwarf_Debug dbg = cu_context->cc_dbg; Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table; Dwarf_Hash_Table_Entry entry_base = 0; Dwarf_Hash_Table_Entry entry_cur = 0; Dwarf_Unsigned hash_num = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned abbrev_tag = 0; Dwarf_Abbrev_List hash_abbrev_entry = 0; Dwarf_Abbrev_List inner_list_entry = 0; Dwarf_Hash_Table_Entry inner_hash_entry = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr end_abbrev_ptr = 0; unsigned hashable_val = 0; if (!hash_table_base->tb_entries) { hash_table_base->tb_table_entry_count = HT_MULTIPLE; hash_table_base->tb_total_abbrev_count= 0; hash_table_base->tb_entries = (struct Dwarf_Hash_Table_Entry_s *)_dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE_ENTRY, hash_table_base->tb_table_entry_count); if (!hash_table_base->tb_entries) { *highest_known_code = cu_context->cc_highest_known_code; return DW_DLV_NO_ENTRY; } } else if (hash_table_base->tb_total_abbrev_count > (hash_table_base->tb_table_entry_count * HT_MULTIPLE)) { struct Dwarf_Hash_Table_s newht; memset(&newht,0,sizeof(newht)); /* Effectively multiplies by >= HT_MULTIPLE */ newht.tb_table_entry_count = hash_table_base->tb_total_abbrev_count; newht.tb_total_abbrev_count = 0; newht.tb_entries = (struct Dwarf_Hash_Table_Entry_s *) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE_ENTRY, newht.tb_table_entry_count); if (!newht.tb_entries) { *highest_known_code = cu_context->cc_highest_known_code; return DW_DLV_NO_ENTRY; } /* Copy the existing entries to the new table, rehashing each. */ copy_abbrev_table_to_new_table(hash_table_base, &newht); /* Dealloc only the entries hash table array, not the lists of things pointed to by a hash table entry array. */ dwarf_dealloc(dbg, hash_table_base->tb_entries, DW_DLA_HASH_TABLE_ENTRY); hash_table_base->tb_entries = 0; /* Now overwrite the existing table descriptor with the new, newly valid, contents. */ *hash_table_base = newht; } /* Else is ok as is, add entry */ if (code > cu_context->cc_highest_known_code) { cu_context->cc_highest_known_code = code; } hashable_val = code; hash_num = hashable_val % hash_table_base->tb_table_entry_count; entry_base = hash_table_base->tb_entries; entry_cur = entry_base + hash_num; /* Determine if the 'code' is the list of synonyms already. */ for (hash_abbrev_entry = entry_cur->at_head; hash_abbrev_entry != NULL && hash_abbrev_entry->abl_code != code; hash_abbrev_entry = hash_abbrev_entry->abl_next); if (hash_abbrev_entry) { /* This returns a pointer to an abbrev list entry, not the list itself. */ *highest_known_code = cu_context->cc_highest_known_code; *list_out = hash_abbrev_entry; return DW_DLV_OK; } if (cu_context->cc_last_abbrev_ptr) { abbrev_ptr = cu_context->cc_last_abbrev_ptr; end_abbrev_ptr = cu_context->cc_last_abbrev_endptr; } else { /* This is ok because cc_abbrev_offset includes DWP offset if appropriate. */ abbrev_ptr = dbg->de_debug_abbrev.dss_data + cu_context->cc_abbrev_offset; if (cu_context->cc_dwp_offsets.pcu_type) { /* In a DWP the abbrevs for this context are known quite precisely. */ Dwarf_Unsigned size = 0; /* Ignore the offset returned. Already in cc_abbrev_offset. */ _dwarf_get_dwp_extra_offset( &cu_context->cc_dwp_offsets, DW_SECT_ABBREV,&size); /* ASSERT: size != 0 */ end_abbrev_ptr = abbrev_ptr + size; } else { end_abbrev_ptr = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; } } /* End of abbrev's as we are past the end entirely. This can happen,though it seems wrong. Or we are at the end of the data block, which we also take as meaning done with abbrevs for this CU. An abbreviations table is supposed to end with a zero byte. Not ended by end of data block. But we are allowing what is possibly a bit more flexible end policy here. */ if (abbrev_ptr >= end_abbrev_ptr) { return DW_DLV_NO_ENTRY; } /* End of abbrev's for this cu, since abbrev code is 0. */ if (*abbrev_ptr == 0) { *highest_known_code = cu_context->cc_highest_known_code; return DW_DLV_NO_ENTRY; } do { unsigned new_hashable_val = 0; Dwarf_Off abb_goff = 0; Dwarf_Unsigned atcount = 0; Dwarf_Byte_Ptr abbrev_ptr2 = 0; int res = 0; abb_goff = abbrev_ptr - dbg->de_debug_abbrev.dss_data; DECODE_LEB128_UWORD_CK(abbrev_ptr, abbrev_code, dbg,error,end_abbrev_ptr); DECODE_LEB128_UWORD_CK(abbrev_ptr, abbrev_tag, dbg,error,end_abbrev_ptr); if (abbrev_tag > DW_TAG_hi_user) { return _dwarf_format_TAG_err_msg(dbg, abbrev_tag,"DW_DLE_TAG_CORRUPT", error); } if (abbrev_ptr >= end_abbrev_ptr) { _dwarf_error(dbg, error, DW_DLE_ABBREV_OFF_END); return DW_DLV_ERROR; } inner_list_entry = (Dwarf_Abbrev_List) _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1); if (inner_list_entry == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_hashable_val = abbrev_code; if (abbrev_code > cu_context->cc_highest_known_code) { cu_context->cc_highest_known_code = abbrev_code; } hash_num = new_hashable_val % hash_table_base->tb_table_entry_count; inner_hash_entry = entry_base + hash_num; /* Move_entry_to_new_hash */ inner_list_entry->abl_next = inner_hash_entry->at_head; inner_hash_entry->at_head = inner_list_entry; hash_table_base->tb_total_abbrev_count++; inner_list_entry->abl_code = abbrev_code; inner_list_entry->abl_tag = abbrev_tag; inner_list_entry->abl_has_child = *(abbrev_ptr++); inner_list_entry->abl_abbrev_ptr = abbrev_ptr; inner_list_entry->abl_goffset = abb_goff; hash_table_base->tb_total_abbrev_count++; /* Cycle thru the abbrev content, ignoring the content except to find the end of the content. */ res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr, end_abbrev_ptr,&atcount,&abbrev_ptr2,error); if (res != DW_DLV_OK) { *highest_known_code = cu_context->cc_highest_known_code; return res; } abbrev_ptr = abbrev_ptr2; inner_list_entry->abl_count = atcount; } while ((abbrev_ptr < end_abbrev_ptr) && *abbrev_ptr != 0 && abbrev_code != code); *highest_known_code = cu_context->cc_highest_known_code; cu_context->cc_last_abbrev_ptr = abbrev_ptr; cu_context->cc_last_abbrev_endptr = end_abbrev_ptr; if (abbrev_code == code) { *list_out = inner_list_entry; return DW_DLV_OK; } /* We cannot find an abbrev_code matching code. ERROR will be declared eventually. Might be better to declare specific errors here? */ return DW_DLV_NO_ENTRY; } /* We check that: areaptr <= strptr. a NUL byte (*p) exists at p < end. and return DW_DLV_ERROR if a check fails. de_assume_string_in_bounds */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *strptr, void *areaendptr, int suggested_error, Dwarf_Error*error) { Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; if (p < start) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (p >= end) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (dbg->de_assume_string_in_bounds) { /* This NOT the default. But folks can choose to live dangerously and just assume strings ok. */ return DW_DLV_OK; } while (p < end) { if (*p == 0) { return DW_DLV_OK; } ++p; } _dwarf_error(dbg,error,DW_DLE_STRING_NOT_TERMINATED); return DW_DLV_ERROR; } /* Return non-zero if the start/end are not valid for the die's section. If pastend matches the dss_data+dss_size then pastend is a pointer that cannot be dereferenced. But we allow it as valid here, it is normal for a pointer to point one-past-end in various circumstances (one must avoid dereferencing it, of course). Return 0 if valid. Return 1 if invalid. */ int _dwarf_reference_outside_section(Dwarf_Die die, Dwarf_Small * startaddr, Dwarf_Small * pastend) { Dwarf_Debug dbg = 0; Dwarf_CU_Context contxt = 0; struct Dwarf_Section_s *sec = 0; contxt = die->di_cu_context; dbg = contxt->cc_dbg; if (die->di_is_info) { sec = &dbg->de_debug_info; } else { sec = &dbg->de_debug_types; } if (startaddr < sec->dss_data) { return 1; } if (pastend > (sec->dss_data + sec->dss_size)) { return 1; } return 0; } /* A byte-swapping version of memcpy for cross-endian use. Only 2,4,8 should be lengths passed in. */ void _dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len) { memcpy(s1,s2,(size_t)len); return; } void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len) { unsigned char *targ = (unsigned char *) s1; const unsigned char *src = (const unsigned char *) s2; if (len == 4) { targ[3] = src[0]; targ[2] = src[1]; targ[1] = src[2]; targ[0] = src[3]; } else if (len == 8) { targ[7] = src[0]; targ[6] = src[1]; targ[5] = src[2]; targ[4] = src[3]; targ[3] = src[4]; targ[2] = src[5]; targ[1] = src[6]; targ[0] = src[7]; } else if (len == 2) { targ[1] = src[0]; targ[0] = src[1]; } /* should NOT get below here: is not the intended use */ else if (len == 1) { targ[0] = src[0]; } else { memcpy(s1, s2, (size_t)len); } return; } /* This calculation used to be sprinkled all over. Now brought to one place. We try to accurately compute the size of a cu header given a known cu header location ( an offset in .debug_info or debug_types). */ /* ARGSUSED */ int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Bool is_info, Dwarf_Unsigned *area_length_out, Dwarf_Error *error) { int local_length_size = 0; int local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned final_size = 0; Dwarf_Small *section_start = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; Dwarf_Small *cuptr = section_start + offset; Dwarf_Unsigned section_length = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; Dwarf_Small * section_end_ptr = section_start + section_length; READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, cuptr, local_length_size, local_extension_size, error,section_length,section_end_ptr); READ_UNALIGNED_CK(dbg, version, Dwarf_Half, cuptr, DWARF_HALF_SIZE,error,section_end_ptr); cuptr += DWARF_HALF_SIZE; if (version == 5) { Dwarf_Ubyte unit_type = 0; READ_UNALIGNED_CK(dbg, unit_type, Dwarf_Ubyte, cuptr, sizeof(Dwarf_Ubyte),error,section_end_ptr); switch (unit_type) { case DW_UT_compile: case DW_UT_partial: final_size = local_extension_size + local_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ sizeof(Dwarf_Small)+ /* Size of unit type field. */ sizeof(Dwarf_Small)+ /* Size of address size field. */ local_length_size ; /* Size of abbrev offset field. */ break; case DW_UT_type: case DW_UT_split_type: final_size = local_extension_size + local_length_size +/*Size of type unit length field.*/ DWARF_HALF_SIZE + /* Size of version stamp field. */ sizeof(Dwarf_Small)+ /*Size of unit type field. */ sizeof(Dwarf_Small)+ /*Size of address size field. */ local_length_size + /*Size of abbrev offset field. */ sizeof(Dwarf_Sig8) + /*Size of type signature field.*/ local_length_size; /* Size of type offset field. */ break; case DW_UT_skeleton: case DW_UT_split_compile: final_size = local_extension_size + local_length_size + /* Size of unit length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ sizeof(Dwarf_Small) + /* Size of unit type field. */ sizeof(Dwarf_Small)+ /* Size of address size field. */ local_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Sig8); /* Size of dwo id field. */ break; default: _dwarf_error(dbg,error,DW_DLE_UNIT_TYPE_NOT_HANDLED); return DW_DLV_ERROR; } } else if (version == 4) { final_size = local_extension_size + local_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ local_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Small); /* Size of address size field. */ if (!is_info) { final_size += /* type signature size */ sizeof (Dwarf_Sig8) + /* type offset size */ local_length_size; } } else if (version < 4) { final_size = local_extension_size + local_length_size + DWARF_HALF_SIZE + local_length_size + sizeof(Dwarf_Small); /* Size of address size field. */ } *area_length_out = final_size; return DW_DLV_OK; } /* Pretend we know nothing about the CU and just roughly compute the result. */ Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg, Dwarf_Bool dinfo) { Dwarf_Unsigned finalsize = 0; finalsize = dbg->de_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ dbg->de_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Small); /* Size of address size field. */ if (!dinfo) { finalsize += /* type signature size */ sizeof (Dwarf_Sig8) + /* type offset size */ dbg->de_length_size; } return finalsize; } /* Now that we delay loading .debug_info, we need to do the load in more places. So putting the load code in one place now instead of replicating it in multiple places. */ int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_ERROR; if (dbg->de_debug_info.dss_data) { return DW_DLV_OK; } res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_load_section(dbg, &dbg->de_debug_info, error); if (res != DW_DLV_OK) { return res; } /* debug_info won't be meaningful without .debug_rnglists and .debug_rnglists if there is one or both such sections. */ res = dwarf_load_rnglists(dbg,0,error); if (res == DW_DLV_ERROR) { return res; } res = dwarf_load_loclists(dbg,0,error); if (res == DW_DLV_ERROR) { return res; } return DW_DLV_OK; } int _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_ERROR; if (dbg->de_debug_types.dss_data) { return DW_DLV_OK; } res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_load_section(dbg, &dbg->de_debug_types, error); return res; } void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg, Dwarf_Hash_Table hash_table) { /* A Hash Table is an array with tb_table_entry_count struct Dwarf_Hash_Table_s entries in the array. */ unsigned hashnum = 0; if (!hash_table) { /* Not fully set up yet. There is nothing to do. */ return; } if (!hash_table->tb_entries) { /* Not fully set up yet. There is nothing to do. */ return; } for (; hashnum < hash_table->tb_table_entry_count; ++hashnum) { struct Dwarf_Abbrev_List_s *abbrev = 0; struct Dwarf_Abbrev_List_s *nextabbrev = 0; struct Dwarf_Hash_Table_Entry_s *tb = &hash_table->tb_entries[hashnum]; abbrev = tb->at_head; for (; abbrev; abbrev = nextabbrev) { nextabbrev = abbrev->abl_next; abbrev->abl_next = 0; dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST); } tb->at_head = 0; } /* Frees all the entries at once: an array. */ dwarf_dealloc(dbg,hash_table->tb_entries,DW_DLA_HASH_TABLE_ENTRY); hash_table->tb_entries = 0; } /* If no die provided the size value returned might be wrong. If different compilation units have different address sizes this may not give the correct value in all contexts if the die pointer is NULL. If the Elf offset size != address_size (for example if address_size = 4 but recorded in elf64 object) this may not give the correct value in all contexts if the die pointer is NULL. If the die pointer is non-NULL (in which case it must point to a valid DIE) this will return the correct size. */ int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_CU_Context context = 0; Dwarf_Half addrsize = 0; if (!die) { return dbg->de_pointer_size; } context = die->di_cu_context; addrsize = context->cc_address_size; return addrsize; } /* Encode val as an unsigned LEB128. */ int dwarf_encode_leb128(Dwarf_Unsigned val, int *nbytes, char *space, int splen) { /* Encode val as an unsigned LEB128. */ return _dwarf_pro_encode_leb128_nm(val,nbytes,space,splen); } /* Encode val as a signed LEB128. */ int dwarf_encode_signed_leb128(Dwarf_Signed val, int *nbytes, char *space, int splen) { /* Encode val as a signed LEB128. */ return _dwarf_pro_encode_signed_leb128_nm(val,nbytes,space,splen); } struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback( Dwarf_Debug dbg, struct Dwarf_Printf_Callback_Info_s * newvalues) { struct Dwarf_Printf_Callback_Info_s oldval = dbg->de_printf_callback; if (!newvalues) { return oldval; } if ( newvalues->dp_buffer_user_provided) { if ( oldval.dp_buffer_user_provided) { /* User continues to control the buffer. */ dbg->de_printf_callback = *newvalues; }else { /* Switch from our control of buffer to user control. */ free(oldval.dp_buffer); oldval.dp_buffer = 0; dbg->de_printf_callback = *newvalues; } } else if (oldval.dp_buffer_user_provided){ /* Switch from user control to our control */ dbg->de_printf_callback = *newvalues; dbg->de_printf_callback.dp_buffer_len = 0; dbg->de_printf_callback.dp_buffer= 0; } else { /* User does not control the buffer. */ dbg->de_printf_callback = *newvalues; dbg->de_printf_callback.dp_buffer_len = oldval.dp_buffer_len; dbg->de_printf_callback.dp_buffer = oldval.dp_buffer; } return oldval; } /* No varargs required */ int _dwarf_printf(Dwarf_Debug dbg, const char * data) { int nlen = 0; struct Dwarf_Printf_Callback_Info_s *bufdata = &dbg->de_printf_callback; dwarf_printf_callback_function_type func = bufdata->dp_fptr; if (!func) { return 0; } nlen = strlen(data); func(bufdata->dp_user_pointer,data); return nlen; } /* Often errs and errt point to the same Dwarf_Error, So exercise care. All the arguments MUST be non-null.*/ void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt) { if (!errt || !errs) { return; } if (!dbgs || !dbgt) { return; } if (dbgs == dbgt) { if (errs != errt) { Dwarf_Error ers = *errs; *errs = 0; *errt = ers; } } else { /* Do not stomp on the system errno variable if there is one! */ int mydw_errno = dwarf_errno(*errs); dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR); *errs = 0; _dwarf_error(dbgt,errt, mydw_errno); } } static int inthissection(struct Dwarf_Section_s *sec,Dwarf_Small *ptr) { if (!sec->dss_data) { return FALSE; } if (ptr < sec->dss_data ) { return FALSE; } if (ptr >= (sec->dss_data + sec->dss_size) ) { return FALSE; } return TRUE; } #define FINDSEC(m_s,m_p,n,st,l,e) \ do { \ if (inthissection((m_s),(m_p))) { \ *(n) = (m_s)->dss_name; \ *(st)= (m_s)->dss_data; \ *(l) = (m_s)->dss_size; \ *(e) = (m_s)->dss_data + (m_s)->dss_size; \ return DW_DLV_OK; \ } \ } while (0) /* So we can know a section end even when we do not have the section info apriori It's only needed for a subset of sections. */ int _dwarf_what_section_are_we(Dwarf_Debug dbg, Dwarf_Small * our_pointer, const char ** section_name_out, Dwarf_Small ** sec_start_ptr_out, Dwarf_Unsigned * sec_len_out, Dwarf_Small ** sec_end_ptr_out, UNUSEDARG Dwarf_Error * error) { FINDSEC(&dbg->de_debug_info, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_loc, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_loclists, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_rnglists, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_addr, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_line, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_aranges, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_macro, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_ranges, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_str_offsets, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_addr, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_pubtypes, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_gdbindex, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_abbrev, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_cu_index, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_tu_index, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_line_str, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_types, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_sup, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_frame, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_frame_eh_gnu, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); return DW_DLV_NO_ENTRY; } /* New September 2019. */ int dwarf_add_file_path( Dwarf_Debug dbg, const char * file_name, Dwarf_Error* error) { if (!dbg || !file_name) { /* Pretty much a disaster. Caller error. */ _dwarf_error(dbg,error,DW_DLE_NULL_ARGS_DWARF_ADD_PATH); return DW_DLV_ERROR; } if (!dbg->de_path) { dbg->de_path = strdup(file_name); } return DW_DLV_OK; } /* New late April 2020. All the crucial macros will surely need to use wrapper code to ensure we do not leak memory at certain points. */ int _dwarf_read_unaligned_ck_wrapper(Dwarf_Debug dbg, Dwarf_Unsigned *out_value, Dwarf_Small *readfrom, int readlength, Dwarf_Small *end_arange, Dwarf_Error *err) { Dwarf_Unsigned val = 0; READ_UNALIGNED_CK(dbg,val,Dwarf_Unsigned, readfrom,readlength,err,end_arange); *out_value = val; return DW_DLV_OK; } int _dwarf_read_area_length_ck_wrapper(Dwarf_Debug dbg, Dwarf_Unsigned *out_value, Dwarf_Small **readfrom, int * length_size_out, int * exten_size_out, Dwarf_Unsigned sectionlength, Dwarf_Small *endsection, Dwarf_Error *err) { Dwarf_Small *ptr = *readfrom; Dwarf_Unsigned val = 0; int length_size = 0; int exten_size = 0; READ_AREA_LENGTH_CK(dbg,val,Dwarf_Unsigned, ptr,length_size,exten_size, err, sectionlength,endsection); *readfrom = ptr; *out_value = val; *length_size_out = length_size; *exten_size_out = exten_size; return DW_DLV_OK; } /* New March 2020 */ /* We need to increment startptr for the caller in these wrappers so the caller passes in wrappers return either DW_DLV_OK or DW_DLV_ERROR. Never DW_DLV_NO_ENTRY. */ int _dwarf_leb128_uword_wrapper(Dwarf_Debug dbg, Dwarf_Small ** startptr, Dwarf_Small * endptr, Dwarf_Unsigned *out_value, Dwarf_Error * error) { Dwarf_Unsigned utmp2 = 0; Dwarf_Small * start = *startptr; DECODE_LEB128_UWORD_CK(start, utmp2, dbg,error,endptr); *out_value = utmp2; *startptr = start; return DW_DLV_OK; } int _dwarf_leb128_sword_wrapper(Dwarf_Debug dbg, Dwarf_Small ** startptr, Dwarf_Small * endptr, Dwarf_Signed *out_value, Dwarf_Error * error) { Dwarf_Small * start = *startptr; Dwarf_Signed stmp2 = 0; DECODE_LEB128_SWORD_CK(start, stmp2, dbg,error,endptr); *out_value = stmp2; *startptr = start; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_errmsg_list.h0000664000175000017500000006744514053207613016175 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_ERRMSG_LIST_H #define DWARF_ERRMSG_LIST_H /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be added to this Array Errors in the list (missing a comma, for example) happen too often. Making this a separate little file simplifies testing for missing-commas/extra-strings. String count should match DW_DLE_LAST+1 */ const char *_dwarf_errmsgs[] = { "No error (0)\n", "DW_DLE_VMM (1) dwarf format/library version mismatch", "DW_DLE_MAP (2) memory map failure", "DW_DLE_LEE (3) libelf error", "DW_DLE_NDS (4) no debug section", "DW_DLE_NLS (5) no line section ", "DW_DLE_ID (6) invalid descriptor for query ", "DW_DLE_IOF (7) I/O failure ", "DW_DLE_MAF (8) memory allocation failure ", "DW_DLE_IA (9) invalid argument ", "DW_DLE_MDE (10) mangled debugging entry:libelf detected error", "DW_DLE_MLE (11) mangled line number entry ", "DW_DLE_FNO (12) file not open ", "DW_DLE_FNR (13) file not a regular file ", "DW_DLE_FWA (14) file open with wrong access ", "DW_DLE_NOB (15) not an object file ", "DW_DLE_MOF (16) mangled object file header ", "DW_DLE_EOLL (17) end of location list entries ", "DW_DLE_NOLL (18) no location list section ", "DW_DLE_BADOFF (19) Invalid offset ", "DW_DLE_EOS (20) end of section ", "DW_DLE_ATRUNC (21) abbreviations section appears truncated", "DW_DLE_BADBITC (22) Address size passed to dwarf bad", "DW_DLE_DBG_ALLOC (23) Unable to malloc a Dwarf_Debug structure", "DW_DLE_FSTAT_ERROR (24) The file fd passed to dwarf_init " "cannot be fstat()ed", "DW_DLE_FSTAT_MODE_ERROR (25) The file mode bits do not " "indicate that the file being opened via " "dwarf_init() is a normal file", "DW_DLE_INIT_ACCESS_WRONG (26) A call to dwarf_init had an " "access of other than DW_DLC_READ", "DW_DLE_ELF_BEGIN_ERROR (27) a call to " "elf_begin(... ELF_C_READ_MMAP... ) failed", "DW_DLE_ELF_GETEHDR_ERROR (28) a call to " "elf32_getehdr() or elf64_getehdr() failed", "DW_DLE_ELF_GETSHDR_ERROR (29) a call to " "elf32_getshdr() or elf64_getshdr() failed", "DW_DLE_ELF_STRPTR_ERROR (30) a call to " "elf_strptr() failed trying to get a section name", "DW_DLE_DEBUG_INFO_DUPLICATE (31) Only one .debug_info " "section is allowed", "DW_DLE_DEBUG_INFO_NULL (32) .debug_info section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_ABBREV_DUPLICATE (33) Only one .debug_abbrev " "section is allowed", "DW_DLE_DEBUG_ABBREV_NULL (34) .debug_abbrev section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_ARANGES_DUPLICATE (35) Only one .debug_aranges " "section is allowed", "DW_DLE_DEBUG_ARANGES_NULL (36) .debug_aranges section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_LINE_DUPLICATE (37) Only one .debug_line " "section is allowed", "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc " "section is allowed", "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo " "section is allowed", "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames " "section is allowed", "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_STR_DUPLICATE (45) Only one .debug_str " "section is allowed", "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_CU_LENGTH_ERROR (47) Corrupted DWARF or corrupted object", "DW_DLE_VERSION_STAMP_ERROR (48) Corrupted DWARF or corrupted object", "DW_DLE_ABBREV_OFFSET_ERROR (49) Corrupted DWARF or corrupted object", "DW_DLE_ADDRESS_SIZE_ERROR (50) size too large", "DW_DLE_DEBUG_INFO_PTR_NULL (51)", "DW_DLE_DIE_NULL (52)", "DW_DLE_STRING_OFFSET_BAD (53) Corrupted DWARF or corrupted object", "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)", "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)", "DW_DLE_LINE_NUM_OPERANDS_BAD (56)", "DW_DLE_LINE_SET_ADDR_ERROR (57)", "DW_DLE_LINE_EXT_OPCODE_BAD (58)", "DW_DLE_DWARF_LINE_NULL (59)", "DW_DLE_INCL_DIR_NUM_BAD (60)", "DW_DLE_LINE_FILE_NUM_BAD (61)", "DW_DLE_ALLOC_FAIL (62) Out of memory or corrupted object", "DW_DLE_NO_CALLBACK_FUNC (63)", "DW_DLE_SECT_ALLOC (64)", "DW_DLE_FILE_ENTRY_ALLOC (65)", "DW_DLE_LINE_ALLOC (66)", "DW_DLE_FPGM_ALLOC (67)", "DW_DLE_INCDIR_ALLOC (68)", "DW_DLE_STRING_ALLOC (69)", "DW_DLE_CHUNK_ALLOC (70)", "DW_DLE_BYTEOFF_ERR (71)", "DW_DLE_CIE_ALLOC (72)", "DW_DLE_FDE_ALLOC (73)", "DW_DLE_REGNO_OVFL (74)", "DW_DLE_CIE_OFFS_ALLOC (75)", "DW_DLE_WRONG_ADDRESS (76)", "DW_DLE_EXTRA_NEIGHBORS (77)", "DW_DLE_WRONG_TAG (78)", "DW_DLE_DIE_ALLOC (79)", "DW_DLE_PARENT_EXISTS (80)", "DW_DLE_DBG_NULL (81)", "DW_DLE_DEBUGLINE_ERROR (82)", "DW_DLE_DEBUGFRAME_ERROR (83)", "DW_DLE_DEBUGINFO_ERROR (84)", "DW_DLE_ATTR_ALLOC (85)", "DW_DLE_ABBREV_ALLOC (86)", "DW_DLE_OFFSET_UFLW (87)", "DW_DLE_ELF_SECT_ERR (88)", "DW_DLE_DEBUG_FRAME_LENGTH_BAD (89)", "DW_DLE_FRAME_VERSION_BAD (90)", "DW_DLE_CIE_RET_ADDR_REG_ERROR (91)", "DW_DLE_FDE_NULL (92)", "DW_DLE_FDE_DBG_NULL (93)", "DW_DLE_CIE_NULL (94)", "DW_DLE_CIE_DBG_NULL (95)", "DW_DLE_FRAME_TABLE_COL_BAD (96)", "DW_DLE_PC_NOT_IN_FDE_RANGE (97)", "DW_DLE_CIE_INSTR_EXEC_ERROR (98)", "DW_DLE_FRAME_INSTR_EXEC_ERROR (99)", "DW_DLE_FDE_PTR_NULL (100)", "DW_DLE_RET_OP_LIST_NULL (101)", "DW_DLE_LINE_CONTEXT_NULL (102)", "DW_DLE_DBG_NO_CU_CONTEXT (103)", "DW_DLE_DIE_NO_CU_CONTEXT (104)", "DW_DLE_FIRST_DIE_NOT_CU (105)", "DW_DLE_NEXT_DIE_PTR_NULL (106)", "DW_DLE_DEBUG_FRAME_DUPLICATE (107) Only one .debug_frame " "section is allowed", "DW_DLE_DEBUG_FRAME_NULL (108) .debug_frame section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_ABBREV_DECODE_ERROR (109)", "DW_DLE_DWARF_ABBREV_NULL (110)", "DW_DLE_ATTR_NULL (111)", "DW_DLE_DIE_BAD (112)", "DW_DLE_DIE_ABBREV_BAD (113)", "DW_DLE_ATTR_FORM_BAD (114)", "DW_DLE_ATTR_NO_CU_CONTEXT (115)", "DW_DLE_ATTR_FORM_SIZE_BAD (116)", "DW_DLE_ATTR_DBG_NULL (117)", "DW_DLE_BAD_REF_FORM (118)", "DW_DLE_ATTR_FORM_OFFSET_BAD (119)", "DW_DLE_LINE_OFFSET_BAD (120)", "DW_DLE_DEBUG_STR_OFFSET_BAD (121)", "DW_DLE_STRING_PTR_NULL (122)", "DW_DLE_PUBNAMES_VERSION_ERROR (123)", "DW_DLE_PUBNAMES_LENGTH_BAD (124)", "DW_DLE_GLOBAL_NULL (125)", "DW_DLE_GLOBAL_CONTEXT_NULL (126)", "DW_DLE_DIR_INDEX_BAD (127)", "DW_DLE_LOC_EXPR_BAD (128)", "DW_DLE_DIE_LOC_EXPR_BAD (129)", "DW_DLE_ADDR_ALLOC (130)", "DW_DLE_OFFSET_BAD (131)", "DW_DLE_MAKE_CU_CONTEXT_FAIL (132)", "DW_DLE_REL_ALLOC (133)", "DW_DLE_ARANGE_OFFSET_BAD (134)", "DW_DLE_SEGMENT_SIZE_BAD (135) Size of a segment selector " "should usually be less than 8 (bytes).", "DW_DLE_ARANGE_LENGTH_BAD (136)", "DW_DLE_ARANGE_DECODE_ERROR (137)", "DW_DLE_ARANGES_NULL (138)", "DW_DLE_ARANGE_NULL (139)", "DW_DLE_NO_FILE_NAME (140)", "DW_DLE_NO_COMP_DIR (141)", "DW_DLE_CU_ADDRESS_SIZE_BAD (142)", "DW_DLE_INPUT_ATTR_BAD (143)", "DW_DLE_EXPR_NULL (144)", "DW_DLE_BAD_EXPR_OPCODE (145)", "DW_DLE_EXPR_LENGTH_BAD (146)", "DW_DLE_MULTIPLE_RELOC_IN_EXPR (147)", "DW_DLE_ELF_GETIDENT_ERROR (148)", "DW_DLE_NO_AT_MIPS_FDE (149)", "DW_DLE_NO_CIE_FOR_FDE (150)", "DW_DLE_DIE_ABBREV_LIST_NULL (151) No abbrev exists for " "the requested abbrev code" , "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE (152)", "DW_DLE_DEBUG_FUNCNAMES_NULL (153) .debug_funcnames section " "present but elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR (154)", "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD (155)", "DW_DLE_FUNC_NULL (156)", "DW_DLE_FUNC_CONTEXT_NULL (157)", "DW_DLE_DEBUG_TYPENAMES_DUPLICATE (158)", "DW_DLE_DEBUG_TYPENAMES_NULL (159) .debug_typenames section " "present but elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR (160)", "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD (161)", "DW_DLE_TYPE_NULL (162)", "DW_DLE_TYPE_CONTEXT_NULL (163)", "DW_DLE_DEBUG_VARNAMES_DUPLICATE (164)", "DW_DLE_DEBUG_VARNAMES_NULL (165) .debug_varnames section present " "but elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR (166)", "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD (167)", "DW_DLE_VAR_NULL (168)", "DW_DLE_VAR_CONTEXT_NULL (169)", "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE (170)", "DW_DLE_DEBUG_WEAKNAMES_NULL (171) .debug_weaknames section " "present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR (172)", "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD (173)", "DW_DLE_WEAK_NULL (174)", "DW_DLE_WEAK_CONTEXT_NULL (175)", "DW_DLE_LOCDESC_COUNT_WRONG (176)", "DW_DLE_MACINFO_STRING_NULL (177)", "DW_DLE_MACINFO_STRING_EMPTY (178)", "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", "DW_DLE_MACINFO_MALLOC_FAIL (180)", "DW_DLE_DEBUGMACINFO_ERROR (181)", "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_MAX_BAD (183) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_INCONSISTENT (186) in .debug_macinfo", "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)", "DW_DLE_DF_POP_EMPTY_STACK(191)", "DW_DLE_DF_ALLOC_FAIL(192)", "DW_DLE_DF_FRAME_DECODING_ERROR(193)", "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)", "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)", "DW_DLE_PUBTYPE_CONTEXT(196)", "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)", "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)", "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)", "DW_DLE_FRAME_CIE_DECODE_ERROR(200)", "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)", "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)", "DW_DLE_LINK_LOOP(203)", "DW_DLE_STRP_OFFSET_BAD(204)", "DW_DLE_DEBUG_RANGES_DUPLICATE(205)", "DW_DLE_DEBUG_RANGES_OFFSET_BAD(206)", "DW_DLE_DEBUG_RANGES_MISSING_END(207)", "DW_DLE_DEBUG_RANGES_OUT_OF_MEM(208)", "DW_DLE_DEBUG_SYMTAB_ERR(209)", "DW_DLE_DEBUG_STRTAB_ERR(210)", "DW_DLE_RELOC_MISMATCH_INDEX(211)", "DW_DLE_RELOC_MISMATCH_RELOC_INDEX(212)", "DW_DLE_RELOC_MISMATCH_STRTAB_INDEX(213)", "DW_DLE_RELOC_SECTION_MISMATCH(214)", "DW_DLE_RELOC_SECTION_MISSING_INDEX(215)", "DW_DLE_RELOC_SECTION_LENGTH_ODD(216)", "DW_DLE_RELOC_SECTION_PTR_NULL(217)", "DW_DLE_RELOC_SECTION_MALLOC_FAIL(218)", "DW_DLE_NO_ELF64_SUPPORT(219)", "DW_DLE_MISSING_ELF64_SUPPORT(220)", "DW_DLE_ORPHAN_FDE(221)", "DW_DLE_DUPLICATE_INST_BLOCK(222)", "DW_DLE_BAD_REF_SIG8_FORM(223)", "DW_DLE_ATTR_EXPRLOC_FORM_BAD(224)", "DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD(225)", "DW_DLE_NOT_REF_FORM(226)", "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE(227)", "DW_DLE_REF_SIG8_NOT_HANDLED (228)", "DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH (229)", "DW_DLE_LOC_BAD_TERMINATION (230) the last location operator " "in an expression is missing some associated data, " "an operator ended too soon", "DW_DLE_SYMTAB_SECTION_LENGTH_ODD (231) so doing " "relocations seems unsafe", "DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD (232) so doing a " "relocation seems unsafe", "DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN (233) so " "doing a relocation is unsafe", "DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO(234)", "DW_DLE_LINE_NUMBER_HEADER_ERROR (235), a line number program " "header seems incomplete (perhaps the header_length is wrong?).", "DW_DLE_DEBUG_TYPES_NULL (236)", "DW_DLE_DEBUG_TYPES_DUPLICATE (237)", "DW_DLE_DEBUG_TYPES_ONLY_DWARF4 (238) DW4 and DW5 have types CUs", "DW_DLE_DEBUG_TYPEOFFSET_BAD (239)", "DW_DLE_GNU_OPCODE_ERROR (240)", "DW_DLE_DEBUGPUBTYPES_ERROR (241), could not create pubtypes section", "DW_DLE_AT_FIXUP_NULL (242)", "DW_DLE_AT_FIXUP_DUP (243)", "DW_DLE_BAD_ABINAME (244)", "DW_DLE_TOO_MANY_DEBUG(245), too many .debug_* sections " "present somehow", "DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE(246)", "DW_DLE_SECTION_DUPLICATION(247)", "DW_DLE_SECTION_ERROR(248)", "DW_DLE_DEBUG_ADDR_DUPLICATE(249)", "DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM(250)", "DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE(251)", "DW_DLE_NEXT_DIE_PAST_END(252)", "DW_DLE_NEXT_DIE_WRONG_FORM(253)", "DW_DLE_NEXT_DIE_NO_ABBREV_LIST(254)", "DW_DLE_NESTED_FORM_INDIRECT_ERROR(255)", "DW_DLE_CU_DIE_NO_ABBREV_LIST(256)", "DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION(257)", "DW_DLE_ATTR_FORM_NOT_ADDR_INDEX(258)", "DW_DLE_ATTR_FORM_NOT_STR_INDEX(259)", "DW_DLE_DUPLICATE_GDB_INDEX(260)", "DW_DLE_ERRONEOUS_GDB_INDEX_SECTION(261) The section is too small", "DW_DLE_GDB_INDEX_COUNT_ERROR(262)", "DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR(263)", "DW_DLE_GDB_INDEX_CUVEC_ERROR(264)", "DW_DLE_GDB_INDEX_INDEX_ERROR(265)", "DW_DLE_DUPLICATE_CU_INDEX(266)", "DW_DLE_DUPLICATE_TU_INDEX(267)", "DW_DLE_XU_TYPE_ARG_ERROR(268) XU means dwarf_cu_ or " "tu_ index section", "DW_DLE_XU_IMPOSSIBLE_ERROR(269) XU means dwarf_cu_ or " "tu_ index section", "DW_DLE_XU_NAME_COL_ERROR(270) XU means dwarf_cu_ or " "tu_ index section", "DW_DLE_XU_HASH_ROW_ERROR(271) XU means dwarf_cu_ or " "tu_ index section", "DW_DLE_XU_HASH_INDEX_ERROR(272) XU means dwarf_cu_ or " "tu_ index section", "DW_DLE_FAILSAFE_ERRVAL(273)", "DW_DLE_ARANGE_ERROR(274) producer problem in object generation", "DW_DLE_PUBNAMES_ERROR(275) producer problem in object generation", "DW_DLE_FUNCNAMES_ERROR(276) producer problem in object generation", "DW_DLE_TYPENAMES_ERROR(277) producer problem in object generation", "DW_DLE_VARNAMES_ERROR(278) producer problem in object generation", "DW_DLE_WEAKNAMES_ERROR(279) producer problem in object generation", "DW_DLE_RELOCS_ERROR(280) producer problem in object generation", "DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)", "DW_DLE_FISSION_INDEX_WRONG(282)", "DW_DLE_FISSION_VERSION_ERROR(283)", "DW_DLE_NEXT_DIE_LOW_ERROR(284) corrupted DIE tree", "DW_DLE_CU_UT_TYPE_ERROR(285) bad DW_UT_* value, corrupt DWARF5", "DW_DLE_NO_SUCH_SIGNATURE_FOUND(286) CU signature not in the index", "DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG(287) libdwarf software error", "DW_DLE_ATTR_FORM_NOT_DATA8(288) wanted an 8 byte signature", "DW_DLE_SIG_TYPE_WRONG_STRING (289) expected tu or cu", "DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH(290) is a " "broken dwp package file", "DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH(291) is a " "broken dwp package file", "DW_DLE_DWP_MISSING_DWO_ID(292)", "DW_DLE_DWP_SIBLING_ERROR(293)", "DW_DLE_DEBUG_FISSION_INCOMPLETE(294)", "DW_DLE_FISSION_SECNUM_ERR(295) internal libdwarf error", "DW_DLE_DEBUG_MACRO_DUPLICATE(296)", "DW_DLE_DEBUG_NAMES_DUPLICATE(297)", "DW_DLE_DEBUG_LINE_STR_DUPLICATE(298)", "DW_DLE_DEBUG_SUP_DUPLICATE(299)", "DW_DLE_NO_SIGNATURE_TO_LOOKUP(300)", "DW_DLE_NO_TIED_ADDR_AVAILABLE(301)", "DW_DLE_NO_TIED_SIG_AVAILABLE(302)", "DW_DLE_STRING_NOT_TERMINATED(303) section data may be corrupted", "DW_DLE_BAD_LINE_TABLE_OPERATION(304) two-level line table botch", "DW_DLE_LINE_CONTEXT_BOTCH(305) call is wrong or memory corruption", "DW_DLE_LINE_CONTEXT_INDEX_WRONG(306)", "DW_DLE_NO_TIED_STRING_AVAILABLE(307) tied file does not " "have the string", "DW_DLE_NO_TIED_FILE_AVAILABLE(308) see dwarf_set_tied_dbg()", "DW_DLE_CU_TYPE_MISSING(309) libdwarf bug or data corruption", "DW_DLE_LLE_CODE_UNKNOWN (310) libdwarf bug or data corruption", "DW_DLE_LOCLIST_INTERFACE_ERROR (311) interface cannot do " "location or DW_OP*", "DW_DLE_LOCLIST_INDEX_ERROR (312)", "DW_DLE_INTERFACE_NOT_SUPPORTED (313)", "DW_DLE_ZDEBUG_REQUIRES_ZLIB (314) Unable to decompress .zdebug " "as zlib missing", "DW_DLE_ZDEBUG_INPUT_FORMAT_ODD(315)", "DW_DLE_ZLIB_BUF_ERROR (316) Z_BUF_ERROR buffer size small", "DW_DLE_ZLIB_DATA_ERROR (317) Z_DATA_ERROR compressed data corrupted", "DW_DLE_MACRO_OFFSET_BAD (318)", "DW_DLE_MACRO_OPCODE_BAD (319)", "DW_DLE_MACRO_OPCODE_FORM_BAD (320)", "DW_DLE_UNKNOWN_FORM (321) Possibly corrupt DWARF data", "DW_DLE_BAD_MACRO_HEADER_POINTER(322)", "DW_DLE_BAD_MACRO_INDEX(323)", "DW_DLE_MACRO_OP_UNHANDLED(324) Possibly an implementation extension", "DW_DLE_MACRO_PAST_END(325)", "DW_DLE_LINE_STRP_OFFSET_BAD(326)", "DW_DLE_STRING_FORM_IMPROPER(327) An internal libdwarf logic error", "DW_DLE_ELF_FLAGS_NOT_AVAILABLE(328) elf/non-elf object confusion?", "DW_DLE_LEB_IMPROPER (329) Runs off end of section or CU", "DW_DLE_DEBUG_LINE_RANGE_ZERO (330) Corrupted line section", "DW_DLE_READ_LITTLEENDIAN_ERROR (331) Corrupted dwarfdata " "littleendian host", "DW_DLE_READ_BIGENDIAN_ERROR (332) Corrupted dwarf data " "bigendian host", "DW_DLE_RELOC_INVALID (333) relocation corruption", "DW_DLE_INFO_HEADER_ERROR(334) Corrupt dwarf", "DW_DLE_ARANGES_HEADER_ERROR(335) Corrupt dwarf", "DW_DLE_LINE_OFFSET_WRONG_FORM(336) Corrupt dwarf", "DW_DLE_FORM_BLOCK_LENGTH_ERROR(337) Corrupt dwarf", "DW_DLE_ZLIB_SECTION_SHORT (338) Corrupt dwarf", "DW_DLE_CIE_INSTR_PTR_ERROR (339)", "DW_DLE_FDE_INSTR_PTR_ERROR (340)", "DW_DLE_FISSION_ADDITION_ERROR (341) Corrupt dwarf", "DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE (342) Corrupt dwarf", "DW_DLE_LOCEXPR_OFF_SECTION_END (343) Corrupt dwarf", "DW_DLE_POINTER_SECTION_UNKNOWN (344)", "DW_DLE_ERRONEOUS_XU_INDEX_SECTION(345) XU means cu_ or tu_ index", "DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH(346) " "Inconsistent line table, corrupted.", "DW_DLE_COMPRESSED_EMPTY_SECTION(347) corrupt section data", "DW_DLE_SIZE_WRAPAROUND(348) Impossible string length", "DW_DLE_ILLOGICAL_TSEARCH(349) Impossible situation. " "Corrupted data?", "DW_DLE_BAD_STRING_FORM(350) Not a currently allowed form", "DW_DLE_DEBUGSTR_ERROR(351) problem generating .debug_str section", "DW_DLE_DEBUGSTR_UNEXPECTED_REL(352) string relocation " "will be wrong.", "DW_DLE_DISCR_ARRAY_ERROR(353) Internal error in dwarf_discr_list()", "DW_DLE_LEB_OUT_ERROR(354) Insufficient buffer to turn " "integer to leb", "DW_DLE_SIBLING_LIST_IMPROPER(355) Runs off end of section. " "Corrupt dwarf", "DW_DLE_LOCLIST_OFFSET_BAD(356) Corrupt dwarf", "DW_DLE_LINE_TABLE_BAD(357) Corrupt line table", "DW_DLE_DEBUG_LOClISTS_DUPLICATE(358)", "DW_DLE_DEBUG_RNGLISTS_DUPLICATE(359)", "DW_DLE_ABBREV_OFF_END(360)", "DW_DLE_FORM_STRING_BAD_STRING(361) string runs off end of data", "DW_DLE_AUGMENTATION_STRING_OFF_END(362) augmentation runs off " "of its section", "DW_DLE_STRING_OFF_END_PUBNAMES_LIKE(363) one of the global " "sections, string bad", "DW_DLE_LINE_STRING_BAD(364) runs off end of line data", "DW_DLE_DEFINE_FILE_STRING_BAD(365) runs off end of section", "DW_DLE_MACRO_STRING_BAD(366) DWARF5 macro def/undef string " "runs off section data", "DW_DLE_MACINFO_STRING_BAD(367) DWARF2..4 macro def/undef " "string runs off section data", "DW_DLE_ZLIB_UNCOMPRESS_ERROR(368) Surely an invalid " "uncompress length", "DW_DLE_IMPROPER_DWO_ID(369)", "DW_DLE_GROUPNUMBER_ERROR(370) An error determining default " "target group number", "DW_DLE_ADDRESS_SIZE_ZERO(371)", "DW_DLE_DEBUG_NAMES_HEADER_ERROR(372)", "DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR(373) corrupt dwarf", "DW_DLE_DEBUG_NAMES_PAD_NON_ZERO(374) corrupt dwarf", "DW_DLE_DEBUG_NAMES_OFF_END(375) corrupt dwarf", "DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW(376) Surprising " "overrun of fixed size array", "DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION(377)", "DW_DLE_DEBUG_NAMES_NULL_POINTER(378) null argument", "DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG(379) index outside valid range", "DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET(380) offset outside entrypool", "DW_DLE_DEBUG_NAMES_UNHANDLED_FORM(381) Might be corrupt " "dwarf or incomplete DWARF support", "DW_DLE_LNCT_CODE_UNKNOWN(382)", "DW_DLE_LNCT_FORM_CODE_NOT_HANDLED(383) Might be bad form " "or just not implemented", "DW_DLE_LINE_HEADER_LENGTH_BOTCH(384) Internal libdwarf error", "DW_DLE_STRING_HASHTAB_IDENTITY_ERROR(385) Internal libdwarf error", "DW_DLE_UNIT_TYPE_NOT_HANDLED(386) Possibly incomplete " "dwarf5 support", "DW_DLE_GROUP_MAP_ALLOC(387) Out of malloc space", "DW_DLE_GROUP_MAP_DUPLICATE(388) Each section # should appear once", "DW_DLE_GROUP_COUNT_ERROR(389) An inconsistency in map entry count", "DW_DLE_GROUP_INTERNAL_ERROR(390) libdwarf data corruption", "DW_DLE_GROUP_LOAD_ERROR(391) corrupt data?", "DW_DLE_GROUP_LOAD_READ_ERROR(392)", "DW_DLE_AUG_DATA_LENGTH_BAD(393) Data does not fit in section", "DW_DLE_ABBREV_MISSING(394) Unable to find abbrev for DIE", "DW_DLE_NO_TAG_FOR_DIE(395)", "DW_DLE_LOWPC_WRONG_CLASS(396) found in dwarf_lowpc()", "DW_DLE_HIGHPC_WRONG_FORM(397) found in dwarf_highpc()", "DW_DLE_STR_OFFSETS_BASE_WRONG_FORM(398)", "DW_DLE_DATA16_OUTSIDE_SECTION(399)", "DW_DLE_LNCT_MD5_WRONG_FORM(400)", "DW_DLE_LINE_HEADER_CORRUPT(401) possible data corruption", "DW_DLE_STR_OFFSETS_NULLARGUMENT(402) improper call", "DW_DLE_STR_OFFSETS_NULL_DBG(403) improper call", "DW_DLE_STR_OFFSETS_NO_MAGIC(404) improper call", "DLE_STR_OFFSETS_ARRAY_SIZE(405) Not a multiple of entry size", "DW_DLE_STR_OFFSETS_VERSION_WRONG(406) Must be 5 ", "DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG(407) Requested outside bound", "DW_DLE_STR_OFFSETS_EXTRA_BYTES(408) .debug_str_offsets " "section problem", "DW_DLE_DUP_ATTR_ON_DIE(409) Compiler error, object improper DWARF", "DW_DLE_SECTION_NAME_BIG(410) Caller provided insufficient " "room for section name", "DW_DLE_FILE_UNAVAILABLE(411). Unable find/read object file", "DW_DLE_FILE_WRONG_TYPE(412). Not an object type we recognize.", "DW_DLE_SIBLING_OFFSET_WRONG(413). Corrupt dwarf.", "DW_DLE_OPEN_FAIL(414) Unable to open, possibly a bad filename", "DW_DLE_OFFSET_SIZE(415) Offset size is neither 32 nor 64", "DW_DLE_MACH_O_SEGOFFSET_BAD(416) corrupt object", "DW_DLE_FILE_OFFSET_BAD(417) corrupt object", "DW_DLE_SEEK_ERROR(418). Seek failed, corrupt object", "DW_DLE_READ_ERROR(419). Read failed, corrupt object", "DW_DLE_ELF_CLASS_BAD(420) Corrupt object.", "DW_DLE_ELF_ENDIAN_BAD(421) Corrupt object.", "DW_DLE_ELF_VERSION_BAD(422) Corrupt object.", "DW_DLE_FILE_TOO_SMALL(423) File is too small to be an object file.", "DW_DLE_PATH_SIZE_TOO_SMALL(424) buffer passed to " "dwarf_object_detector_path is too small.", "DW_DLE_BAD_TYPE_SIZE(425) At compile time the build " "configured itself improperly.", "DW_DLE_PE_SIZE_SMALL(426) File too small to be valid PE object.", "DW_DLE_PE_OFFSET_BAD(427) Calculated offset too large. " "Corrupt object.", "DW_DLE_PE_STRING_TOO_LONG(428) Increase size for call.", "DW_DLE_IMAGE_FILE_UNKNOWN_TYPE(429) a PE object has an " "unknown machine type, not 0x14c, 0x200 or 0x8664", "DLE_LINE_TABLE_LINENO_ERROR(430) Negative line number " "impossible. Corrupted line table.", "DW_DLE_PRODUCER_CODE_NOT_AVAILABLE(431) Without elf.h " "the producer code is not available.", "DW_DLE_NO_ELF_SUPPORT(432) libdwarf was compiled without " "Elf object support.", "DW_DLE_NO_STREAM_RELOC_SUPPORT(433) no elf.h so cannot " "generate STREAM relocations", "DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR(434) Flag value passed " "in not allowed.", "DW_DLE_SECTION_SIZE_ERROR(435) Corrupt Elf. Section size: " "greater than file size or not a multiple of section entry size", "DW_DLE_INTERNAL_NULL_POINTER(436) Internal libdwarf " "call:null pointer", "DW_DLE_SECTION_STRING_OFFSET_BAD(437) Corrupt Elf, an " "offset to section name is invalid", "DW_DLE_SECTION_INDEX_BAD(438) Corrupt Elf, a section " "index is incorrect", "DW_DLE_INTEGER_TOO_SMALL(439) Build does not allow reading Elf64", "DW_DLE_ELF_SECTION_LINK_ERROR(440) Corrupt Elf, section " "links in error", "DW_DLE_ELF_SECTION_GROUP_ERROR(441) Corrupt Elf, section " "group information problem", "DW_DLE_ELF_SECTION_COUNT_MISMATCH(442) Corrupt Elf or libdwarf bug.", "DW_DLE_ELF_STRING_SECTION_MISSING(443) Corrupt Elf, " "string section wrong type", "DW_DLE_SEEK_OFF_END(444) Corrupt Elf. Seek past the end not allowed", "DW_DLE_READ_OFF_END(445) Corrupt Elf. A read would read past " "end of object", "DW_DLE_ELF_SECTION_ERROR(446) Section offset or size is too large. " "Corrupt elf object.", "DW_DLE_ELF_STRING_SECTION_ERROR(447) String section missing. " "Corrupt Elf", "DW_DLE_MIXING_SPLIT_DWARF_VERSIONS(448) DWARF5 header " "signature and DWARF4 DW_AT_[GNU]_dwo_id " "present in one CU header/die. Corrupt Dwarf.", "DW_DLE_TAG_CORRUPT(449) DW_TAG outside allowed range. " "Corrupt DWARF.", "DW_DLE_FORM_CORRUPT(450) DW_FORM unknown, too large a value. " "Corrupt DWARF?", "DW_DLE_ATTR_CORRUPT(451) DW_AT outside allowed range. " "Corrupt DWARF.", "DW_DLE_ABBREV_ATTR_DUPLICATION(452) Abbreviation list corruption.", "DW_DLE_DWP_SIGNATURE_MISMATCH(453) Impossible signature " "mismatch. Corrupted Dwarf?", "DW_DLE_CU_UT_TYPE_VALUE(454) Internal libdwarf data corruption", "DW_DLE_DUPLICATE_GNU_DEBUGLINK(455) Duplicated section " ".gnu_debuglink", "DW_DLE_CORRUPT_GNU_DEBUGLINK(456) Section length wrong", "DW_DLE_CORRUPT_NOTE_GNU_DEBUGID(457) Data corruption in " ".note.gnu.debugid section", "DW_DLE_CORRUPT_GNU_DEBUGID_SIZE(458) Section .note.gnu.debugid " "size incorrect", "DW_DLE_CORRUPT_GNU_DEBUGID_STRING(459) Section .note.gnu.debugid " "owner string not terminated properly", "DW_DLE_HEX_STRING_ERROR(460). dwarf_producer_init() " "extras string has a bad hex string", "DW_DLE_DECIMAL_STRING_ERROR(461) dwarf_producer_init() extras " "string has a bad decimal string", "DW_DLE_PRO_INIT_EXTRAS_UNKNOWN(462) dwarf_producer_init() extras " "string has an unknown string", "DW_DLE_PRO_INIT_EXTRAS_ERR(463) dwarf_producer_init() extras " "string has an unexpected space character", "DW_DLE_NULL_ARGS_DWARF_ADD_PATH(464) either Dwarf_Debug or " "file_path argument to dwarf_add_file_path is NULL.", "DW_DLE_DWARF_INIT_DBG_NULL(465) a dwarf_init*() call " "the return-dbg argument is null", "DW_DLE_ELF_RELOC_SECTION_ERROR(466) A relocation section header " "link field is incorrect.", "DW_DLE_USER_DECLARED_ERROR(467) library user created this.", "DW_DLE_RNGLISTS_ERROR(468) Corrupt dwarf. Bad .debug_rnglists data.", "DW_DLE_LOCLISTS_ERROR(469) Corrupt dwarf. Bad .debug_loclists data.", "DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE(470) corrupt section header.", "DW_DLE_GDBINDEX_STRING_ERROR(471) .gdb_index section string error", "DW_DLE_GNU_PUBNAMES_ERROR(472) A problem with .debug_gnu_pubnames", "DW_DLE_GNU_PUBTYPES_ERROR(473) A problem with .debug_gnu_pubtypes", "DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES(474) Duplicated section " ".debug_gnu_pubnames", "DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES(475) Duplicated section " ".debug_gnu_pubtypes", "DW_DLE_DEBUG_SUP_STRING_ERROR(476) The string in .debug_sup head " "runs off the end of the section. Corrupt data", "DW_DLE_DEBUG_SUP_ERROR(477). .debug_sup data corruption", "DW_DLE_LOCATION_ERROR(478). A location processing libdwarf error", "DW_DLE_DEBUGLINK_PATH_SHORT(479) Buffer provided for GNU " "debuglink is too small", "DW_DLE_SIGNATURE_MISMATCH(480) DWARF4 extension dwo_id and " "dwarf5signature present but they do not match!", "DW_DLE_MACRO_VERSION_ERROR(481) Unknown DWARF5 macro version." " Corrupt data.", "DW_DLE_NEGATIVE_SIZE(482) A size < 0 " "(from DW_FORM_implicit_const) is not appropriate", }; #endif /* DWARF_ERRMSG_LIST_H */ libdwarf-20210528/libdwarf/dwarf_names_enum.h0000664000175000017500000016614114054205616015765 00000000000000/* Automatically generated, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #ifndef __DWARF_NAMES_ENUM_H__ #define __DWARF_NAMES_ENUM_H__ enum Dwarf_TAG_e { DW_TAG_array_type = 0x0001, DW_TAG_class_type = 0x0002, DW_TAG_entry_point = 0x0003, DW_TAG_enumeration_type = 0x0004, DW_TAG_formal_parameter = 0x0005, DW_TAG_imported_declaration = 0x0008, DW_TAG_label = 0x000a, DW_TAG_lexical_block = 0x000b, DW_TAG_member = 0x000d, DW_TAG_pointer_type = 0x000f, DW_TAG_reference_type = 0x0010, DW_TAG_compile_unit = 0x0011, DW_TAG_string_type = 0x0012, DW_TAG_structure_type = 0x0013, DW_TAG_subroutine_type = 0x0015, DW_TAG_typedef = 0x0016, DW_TAG_union_type = 0x0017, DW_TAG_unspecified_parameters = 0x0018, DW_TAG_variant = 0x0019, DW_TAG_common_block = 0x001a, DW_TAG_common_inclusion = 0x001b, DW_TAG_inheritance = 0x001c, DW_TAG_inlined_subroutine = 0x001d, DW_TAG_module = 0x001e, DW_TAG_ptr_to_member_type = 0x001f, DW_TAG_set_type = 0x0020, DW_TAG_subrange_type = 0x0021, DW_TAG_with_stmt = 0x0022, DW_TAG_access_declaration = 0x0023, DW_TAG_base_type = 0x0024, DW_TAG_catch_block = 0x0025, DW_TAG_const_type = 0x0026, DW_TAG_constant = 0x0027, DW_TAG_enumerator = 0x0028, DW_TAG_file_type = 0x0029, DW_TAG_friend = 0x002a, DW_TAG_namelist = 0x002b, DW_TAG_namelist_item = 0x002c, DW_TAG_packed_type = 0x002d, DW_TAG_subprogram = 0x002e, DW_TAG_template_type_parameter = 0x002f, DW_TAG_template_value_parameter = 0x0030, DW_TAG_thrown_type = 0x0031, DW_TAG_try_block = 0x0032, DW_TAG_variant_part = 0x0033, DW_TAG_variable = 0x0034, DW_TAG_volatile_type = 0x0035, DW_TAG_dwarf_procedure = 0x0036, DW_TAG_restrict_type = 0x0037, DW_TAG_interface_type = 0x0038, DW_TAG_namespace = 0x0039, DW_TAG_imported_module = 0x003a, DW_TAG_unspecified_type = 0x003b, DW_TAG_partial_unit = 0x003c, DW_TAG_imported_unit = 0x003d, DW_TAG_mutable_type = 0x003e, DW_TAG_condition = 0x003f, DW_TAG_shared_type = 0x0040, DW_TAG_type_unit = 0x0041, DW_TAG_rvalue_reference_type = 0x0042, DW_TAG_template_alias = 0x0043, DW_TAG_coarray_type = 0x0044, DW_TAG_generic_subrange = 0x0045, DW_TAG_dynamic_type = 0x0046, DW_TAG_atomic_type = 0x0047, DW_TAG_call_site = 0x0048, DW_TAG_call_site_parameter = 0x0049, DW_TAG_skeleton_unit = 0x004a, DW_TAG_immutable_type = 0x004b, DW_TAG_lo_user = 0x4080, DW_TAG_MIPS_loop = 0x4081, DW_TAG_HP_array_descriptor = 0x4090, DW_TAG_format_label = 0x4101, DW_TAG_function_template = 0x4102, DW_TAG_class_template = 0x4103, DW_TAG_GNU_BINCL = 0x4104, DW_TAG_GNU_EINCL = 0x4105, DW_TAG_GNU_template_template_parameter = 0x4106, DW_TAG_GNU_template_parameter_pack = 0x4107, DW_TAG_GNU_formal_parameter_pack = 0x4108, DW_TAG_GNU_call_site = 0x4109, DW_TAG_GNU_call_site_parameter = 0x410a, DW_TAG_SUN_function_template = 0x4201, DW_TAG_SUN_class_template = 0x4202, DW_TAG_SUN_struct_template = 0x4203, DW_TAG_SUN_union_template = 0x4204, DW_TAG_SUN_indirect_inheritance = 0x4205, DW_TAG_SUN_codeflags = 0x4206, DW_TAG_SUN_memop_info = 0x4207, DW_TAG_SUN_omp_child_func = 0x4208, DW_TAG_SUN_rtti_descriptor = 0x4209, DW_TAG_SUN_dtor_info = 0x420a, DW_TAG_SUN_dtor = 0x420b, DW_TAG_SUN_f90_interface = 0x420c, DW_TAG_SUN_fortran_vax_structure = 0x420d, DW_TAG_SUN_hi = 0x42ff, DW_TAG_ALTIUM_circ_type = 0x5101, DW_TAG_ALTIUM_mwa_circ_type = 0x5102, DW_TAG_ALTIUM_rev_carry_type = 0x5103, DW_TAG_ALTIUM_rom = 0x5111, DW_TAG_ghs_namespace = 0x8004, DW_TAG_ghs_using_namespace = 0x8005, DW_TAG_ghs_using_declaration = 0x8006, DW_TAG_ghs_template_templ_param = 0x8007, DW_TAG_upc_shared_type = 0x8765, DW_TAG_upc_strict_type = 0x8766, DW_TAG_upc_relaxed_type = 0x8767, DW_TAG_PGI_kanji_type = 0xa000, DW_TAG_PGI_interface_block = 0xa020, DW_TAG_BORLAND_property = 0xb000, DW_TAG_BORLAND_Delphi_string = 0xb001, DW_TAG_BORLAND_Delphi_dynamic_array = 0xb002, DW_TAG_BORLAND_Delphi_set = 0xb003, DW_TAG_BORLAND_Delphi_variant = 0xb004, DW_TAG_hi_user = 0xffff }; enum Dwarf_children_e { DW_children_no = 0x0000, DW_children_yes = 0x0001 }; enum Dwarf_FORM_e { DW_FORM_addr = 0x0001, DW_FORM_block2 = 0x0003, DW_FORM_block4 = 0x0004, DW_FORM_data2 = 0x0005, DW_FORM_data4 = 0x0006, DW_FORM_data8 = 0x0007, DW_FORM_string = 0x0008, DW_FORM_block = 0x0009, DW_FORM_block1 = 0x000a, DW_FORM_data1 = 0x000b, DW_FORM_flag = 0x000c, DW_FORM_sdata = 0x000d, DW_FORM_strp = 0x000e, DW_FORM_udata = 0x000f, DW_FORM_ref_addr = 0x0010, DW_FORM_ref1 = 0x0011, DW_FORM_ref2 = 0x0012, DW_FORM_ref4 = 0x0013, DW_FORM_ref8 = 0x0014, DW_FORM_ref_udata = 0x0015, DW_FORM_indirect = 0x0016, DW_FORM_sec_offset = 0x0017, DW_FORM_exprloc = 0x0018, DW_FORM_flag_present = 0x0019, DW_FORM_strx = 0x001a, DW_FORM_addrx = 0x001b, DW_FORM_ref_sup4 = 0x001c, DW_FORM_strp_sup = 0x001d, DW_FORM_data16 = 0x001e, DW_FORM_line_strp = 0x001f, DW_FORM_ref_sig8 = 0x0020, DW_FORM_implicit_const = 0x0021, DW_FORM_loclistx = 0x0022, DW_FORM_rnglistx = 0x0023, DW_FORM_ref_sup8 = 0x0024, DW_FORM_strx1 = 0x0025, DW_FORM_strx2 = 0x0026, DW_FORM_strx3 = 0x0027, DW_FORM_strx4 = 0x0028, DW_FORM_addrx1 = 0x0029, DW_FORM_addrx2 = 0x002a, DW_FORM_addrx3 = 0x002b, DW_FORM_addrx4 = 0x002c, DW_FORM_GNU_addr_index = 0x1f01, DW_FORM_GNU_str_index = 0x1f02, DW_FORM_GNU_ref_alt = 0x1f20, DW_FORM_GNU_strp_alt = 0x1f21 }; enum Dwarf_AT_e { DW_AT_sibling = 0x0001, DW_AT_location = 0x0002, DW_AT_name = 0x0003, DW_AT_ordering = 0x0009, DW_AT_subscr_data = 0x000a, DW_AT_byte_size = 0x000b, DW_AT_bit_offset = 0x000c, DW_AT_bit_size = 0x000d, DW_AT_element_list = 0x000f, DW_AT_stmt_list = 0x0010, DW_AT_low_pc = 0x0011, DW_AT_high_pc = 0x0012, DW_AT_language = 0x0013, DW_AT_member = 0x0014, DW_AT_discr = 0x0015, DW_AT_discr_value = 0x0016, DW_AT_visibility = 0x0017, DW_AT_import = 0x0018, DW_AT_string_length = 0x0019, DW_AT_common_reference = 0x001a, DW_AT_comp_dir = 0x001b, DW_AT_const_value = 0x001c, DW_AT_containing_type = 0x001d, DW_AT_default_value = 0x001e, DW_AT_inline = 0x0020, DW_AT_is_optional = 0x0021, DW_AT_lower_bound = 0x0022, DW_AT_producer = 0x0025, DW_AT_prototyped = 0x0027, DW_AT_return_addr = 0x002a, DW_AT_start_scope = 0x002c, DW_AT_bit_stride = 0x002e, DW_AT_upper_bound = 0x002f, DW_AT_abstract_origin = 0x0031, DW_AT_accessibility = 0x0032, DW_AT_address_class = 0x0033, DW_AT_artificial = 0x0034, DW_AT_base_types = 0x0035, DW_AT_calling_convention = 0x0036, DW_AT_count = 0x0037, DW_AT_data_member_location = 0x0038, DW_AT_decl_column = 0x0039, DW_AT_decl_file = 0x003a, DW_AT_decl_line = 0x003b, DW_AT_declaration = 0x003c, DW_AT_discr_list = 0x003d, DW_AT_encoding = 0x003e, DW_AT_external = 0x003f, DW_AT_frame_base = 0x0040, DW_AT_friend = 0x0041, DW_AT_identifier_case = 0x0042, DW_AT_macro_info = 0x0043, DW_AT_namelist_item = 0x0044, DW_AT_priority = 0x0045, DW_AT_segment = 0x0046, DW_AT_specification = 0x0047, DW_AT_static_link = 0x0048, DW_AT_type = 0x0049, DW_AT_use_location = 0x004a, DW_AT_variable_parameter = 0x004b, DW_AT_virtuality = 0x004c, DW_AT_vtable_elem_location = 0x004d, DW_AT_allocated = 0x004e, DW_AT_associated = 0x004f, DW_AT_data_location = 0x0050, DW_AT_byte_stride = 0x0051, DW_AT_entry_pc = 0x0052, DW_AT_use_UTF8 = 0x0053, DW_AT_extension = 0x0054, DW_AT_ranges = 0x0055, DW_AT_trampoline = 0x0056, DW_AT_call_column = 0x0057, DW_AT_call_file = 0x0058, DW_AT_call_line = 0x0059, DW_AT_description = 0x005a, DW_AT_binary_scale = 0x005b, DW_AT_decimal_scale = 0x005c, DW_AT_small = 0x005d, DW_AT_decimal_sign = 0x005e, DW_AT_digit_count = 0x005f, DW_AT_picture_string = 0x0060, DW_AT_mutable = 0x0061, DW_AT_threads_scaled = 0x0062, DW_AT_explicit = 0x0063, DW_AT_object_pointer = 0x0064, DW_AT_endianity = 0x0065, DW_AT_elemental = 0x0066, DW_AT_pure = 0x0067, DW_AT_recursive = 0x0068, DW_AT_signature = 0x0069, DW_AT_main_subprogram = 0x006a, DW_AT_data_bit_offset = 0x006b, DW_AT_const_expr = 0x006c, DW_AT_enum_class = 0x006d, DW_AT_linkage_name = 0x006e, DW_AT_string_length_bit_size = 0x006f, DW_AT_string_length_byte_size = 0x0070, DW_AT_rank = 0x0071, DW_AT_str_offsets_base = 0x0072, DW_AT_addr_base = 0x0073, DW_AT_rnglists_base = 0x0074, DW_AT_dwo_id = 0x0075, DW_AT_dwo_name = 0x0076, DW_AT_reference = 0x0077, DW_AT_rvalue_reference = 0x0078, DW_AT_macros = 0x0079, DW_AT_call_all_calls = 0x007a, DW_AT_call_all_source_calls = 0x007b, DW_AT_call_all_tail_calls = 0x007c, DW_AT_call_return_pc = 0x007d, DW_AT_call_value = 0x007e, DW_AT_call_origin = 0x007f, DW_AT_call_parameter = 0x0080, DW_AT_call_pc = 0x0081, DW_AT_call_tail_call = 0x0082, DW_AT_call_target = 0x0083, DW_AT_call_target_clobbered = 0x0084, DW_AT_call_data_location = 0x0085, DW_AT_call_data_value = 0x0086, DW_AT_noreturn = 0x0087, DW_AT_alignment = 0x0088, DW_AT_export_symbols = 0x0089, DW_AT_deleted = 0x008a, DW_AT_defaulted = 0x008b, DW_AT_loclists_base = 0x008c, DW_AT_ghs_namespace_alias = 0x0806, DW_AT_ghs_using_namespace = 0x0807, DW_AT_ghs_using_declaration = 0x0808, DW_AT_HP_block_index = 0x2000, DW_AT_MIPS_fde = 0x2001, DW_AT_MIPS_loop_begin = 0x2002, DW_AT_MIPS_tail_loop_begin = 0x2003, DW_AT_MIPS_epilog_begin = 0x2004, DW_AT_MIPS_loop_unroll_factor = 0x2005, DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, DW_AT_MIPS_stride = 0x2008, DW_AT_MIPS_abstract_name = 0x2009, DW_AT_MIPS_clone_origin = 0x200a, DW_AT_MIPS_has_inlines = 0x200b, DW_AT_MIPS_stride_byte = 0x200c, DW_AT_MIPS_stride_elem = 0x200d, DW_AT_MIPS_ptr_dopetype = 0x200e, DW_AT_MIPS_allocatable_dopetype = 0x200f, DW_AT_MIPS_assumed_shape_dopetype = 0x2010, DW_AT_MIPS_assumed_size = 0x2011, DW_AT_HP_raw_data_ptr = 0x2012, DW_AT_HP_pass_by_reference = 0x2013, DW_AT_HP_opt_level = 0x2014, DW_AT_HP_prof_version_id = 0x2015, DW_AT_HP_opt_flags = 0x2016, DW_AT_HP_cold_region_low_pc = 0x2017, DW_AT_HP_cold_region_high_pc = 0x2018, DW_AT_HP_all_variables_modifiable = 0x2019, DW_AT_HP_linkage_name = 0x201a, DW_AT_HP_prof_flags = 0x201b, DW_AT_HP_unit_name = 0x201f, DW_AT_HP_unit_size = 0x2020, DW_AT_HP_widened_byte_size = 0x2021, DW_AT_HP_definition_points = 0x2022, DW_AT_HP_default_location = 0x2023, DW_AT_INTEL_other_endian = 0x2026, DW_AT_HP_is_result_param = 0x2029, DW_AT_ghs_rsm = 0x2083, DW_AT_ghs_frsm = 0x2085, DW_AT_ghs_frames = 0x2086, DW_AT_ghs_rso = 0x2087, DW_AT_ghs_subcpu = 0x2092, DW_AT_ghs_lbrace_line = 0x2093, DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, DW_AT_GNU_guarded_by = 0x2108, DW_AT_GNU_pt_guarded_by = 0x2109, DW_AT_GNU_guarded = 0x210a, DW_AT_GNU_pt_guarded = 0x210b, DW_AT_GNU_locks_excluded = 0x210c, DW_AT_GNU_exclusive_locks_required = 0x210d, DW_AT_GNU_shared_locks_required = 0x210e, DW_AT_GNU_odr_signature = 0x210f, DW_AT_GNU_template_name = 0x2110, DW_AT_GNU_call_site_value = 0x2111, DW_AT_GNU_call_site_data_value = 0x2112, DW_AT_GNU_call_site_target = 0x2113, DW_AT_GNU_call_site_target_clobbered = 0x2114, DW_AT_GNU_tail_call = 0x2115, DW_AT_GNU_all_tail_call_sites = 0x2116, DW_AT_GNU_all_call_sites = 0x2117, DW_AT_GNU_all_source_call_sites = 0x2118, DW_AT_GNU_macros = 0x2119, DW_AT_GNU_deleted = 0x211a, DW_AT_GNU_dwo_name = 0x2130, DW_AT_GNU_dwo_id = 0x2131, DW_AT_GNU_ranges_base = 0x2132, DW_AT_GNU_addr_base = 0x2133, DW_AT_GNU_pubnames = 0x2134, DW_AT_GNU_pubtypes = 0x2135, DW_AT_GNU_discriminator = 0x2136, DW_AT_GNU_locviews = 0x2137, DW_AT_GNU_entry_view = 0x2138, DW_AT_SUN_template = 0x2201, DW_AT_SUN_alignment = 0x2202, DW_AT_SUN_vtable = 0x2203, DW_AT_SUN_count_guarantee = 0x2204, DW_AT_SUN_command_line = 0x2205, DW_AT_SUN_vbase = 0x2206, DW_AT_SUN_compile_options = 0x2207, DW_AT_SUN_language = 0x2208, DW_AT_SUN_browser_file = 0x2209, DW_AT_SUN_vtable_abi = 0x2210, DW_AT_SUN_func_offsets = 0x2211, DW_AT_SUN_cf_kind = 0x2212, DW_AT_SUN_vtable_index = 0x2213, DW_AT_SUN_omp_tpriv_addr = 0x2214, DW_AT_SUN_omp_child_func = 0x2215, DW_AT_SUN_func_offset = 0x2216, DW_AT_SUN_memop_type_ref = 0x2217, DW_AT_SUN_profile_id = 0x2218, DW_AT_SUN_memop_signature = 0x2219, DW_AT_SUN_obj_dir = 0x2220, DW_AT_SUN_obj_file = 0x2221, DW_AT_SUN_original_name = 0x2222, DW_AT_SUN_hwcprof_signature = 0x2223, DW_AT_SUN_amd64_parmdump = 0x2224, DW_AT_SUN_part_link_name = 0x2225, DW_AT_SUN_link_name = 0x2226, DW_AT_SUN_pass_with_const = 0x2227, DW_AT_SUN_return_with_const = 0x2228, DW_AT_SUN_import_by_name = 0x2229, DW_AT_SUN_f90_pointer = 0x222a, DW_AT_SUN_pass_by_ref = 0x222b, DW_AT_SUN_f90_allocatable = 0x222c, DW_AT_SUN_f90_assumed_shape_array = 0x222d, DW_AT_SUN_c_vla = 0x222e, DW_AT_SUN_return_value_ptr = 0x2230, DW_AT_SUN_dtor_start = 0x2231, DW_AT_SUN_dtor_length = 0x2232, DW_AT_SUN_dtor_state_initial = 0x2233, DW_AT_SUN_dtor_state_final = 0x2234, DW_AT_SUN_dtor_state_deltas = 0x2235, DW_AT_SUN_import_by_lname = 0x2236, DW_AT_SUN_f90_use_only = 0x2237, DW_AT_SUN_namelist_spec = 0x2238, DW_AT_SUN_is_omp_child_func = 0x2239, DW_AT_SUN_fortran_main_alias = 0x223a, DW_AT_SUN_fortran_based = 0x223b, DW_AT_ALTIUM_loclist = 0x2300, DW_AT_use_GNAT_descriptive_type = 0x2301, DW_AT_GNAT_descriptive_type = 0x2302, DW_AT_GNU_numerator = 0x2303, DW_AT_GNU_denominator = 0x2304, DW_AT_GNU_bias = 0x2305, DW_AT_go_kind = 0x2900, DW_AT_go_key = 0x2901, DW_AT_go_elem = 0x2902, DW_AT_go_embedded_field = 0x2903, DW_AT_go_runtime_type = 0x2904, DW_AT_upc_threads_scaled = 0x3210, DW_AT_IBM_wsa_addr = 0x393e, DW_AT_IBM_home_location = 0x393f, DW_AT_IBM_alt_srcview = 0x3940, DW_AT_PGI_lbase = 0x3a00, DW_AT_PGI_soffset = 0x3a01, DW_AT_PGI_lstride = 0x3a02, DW_AT_BORLAND_property_read = 0x3b11, DW_AT_BORLAND_property_write = 0x3b12, DW_AT_BORLAND_property_implements = 0x3b13, DW_AT_BORLAND_property_index = 0x3b14, DW_AT_BORLAND_property_default = 0x3b15, DW_AT_BORLAND_Delphi_unit = 0x3b20, DW_AT_BORLAND_Delphi_class = 0x3b21, DW_AT_BORLAND_Delphi_record = 0x3b22, DW_AT_BORLAND_Delphi_metaclass = 0x3b23, DW_AT_BORLAND_Delphi_constructor = 0x3b24, DW_AT_BORLAND_Delphi_destructor = 0x3b25, DW_AT_BORLAND_Delphi_anonymous_method = 0x3b26, DW_AT_BORLAND_Delphi_interface = 0x3b27, DW_AT_BORLAND_Delphi_ABI = 0x3b28, DW_AT_BORLAND_Delphi_frameptr = 0x3b30, DW_AT_BORLAND_closure = 0x3b31, DW_AT_LLVM_include_path = 0x3e00, DW_AT_LLVM_config_macros = 0x3e01, DW_AT_LLVM_sysroot = 0x3e02, DW_AT_LLVM_tag_offset = 0x3e03, DW_AT_APPLE_optimized = 0x3fe1, DW_AT_APPLE_flags = 0x3fe2, DW_AT_APPLE_isa = 0x3fe3, DW_AT_APPLE_block = 0x3fe4, DW_AT_APPLE_major_runtime_vers = 0x3fe5, DW_AT_APPLE_runtime_class = 0x3fe6, DW_AT_APPLE_omit_frame_ptr = 0x3fe7, DW_AT_APPLE_property_name = 0x3fe8, DW_AT_APPLE_property_getter = 0x3fe9, DW_AT_APPLE_property_setter = 0x3fea, DW_AT_APPLE_property_attribute = 0x3feb, DW_AT_APPLE_objc_complete_type = 0x3fec, DW_AT_APPLE_property = 0x3fed, DW_AT_APPLE_objc_direct = 0x3fee, DW_AT_APPLE_sdk = 0x3fef, DW_AT_hi_user = 0x3fff }; enum Dwarf_OP_e { DW_OP_addr = 0x0003, DW_OP_deref = 0x0006, DW_OP_const1u = 0x0008, DW_OP_const1s = 0x0009, DW_OP_const2u = 0x000a, DW_OP_const2s = 0x000b, DW_OP_const4u = 0x000c, DW_OP_const4s = 0x000d, DW_OP_const8u = 0x000e, DW_OP_const8s = 0x000f, DW_OP_constu = 0x0010, DW_OP_consts = 0x0011, DW_OP_dup = 0x0012, DW_OP_drop = 0x0013, DW_OP_over = 0x0014, DW_OP_pick = 0x0015, DW_OP_swap = 0x0016, DW_OP_rot = 0x0017, DW_OP_xderef = 0x0018, DW_OP_abs = 0x0019, DW_OP_and = 0x001a, DW_OP_div = 0x001b, DW_OP_minus = 0x001c, DW_OP_mod = 0x001d, DW_OP_mul = 0x001e, DW_OP_neg = 0x001f, DW_OP_not = 0x0020, DW_OP_or = 0x0021, DW_OP_plus = 0x0022, DW_OP_plus_uconst = 0x0023, DW_OP_shl = 0x0024, DW_OP_shr = 0x0025, DW_OP_shra = 0x0026, DW_OP_xor = 0x0027, DW_OP_bra = 0x0028, DW_OP_eq = 0x0029, DW_OP_ge = 0x002a, DW_OP_gt = 0x002b, DW_OP_le = 0x002c, DW_OP_lt = 0x002d, DW_OP_ne = 0x002e, DW_OP_skip = 0x002f, DW_OP_lit0 = 0x0030, DW_OP_lit1 = 0x0031, DW_OP_lit2 = 0x0032, DW_OP_lit3 = 0x0033, DW_OP_lit4 = 0x0034, DW_OP_lit5 = 0x0035, DW_OP_lit6 = 0x0036, DW_OP_lit7 = 0x0037, DW_OP_lit8 = 0x0038, DW_OP_lit9 = 0x0039, DW_OP_lit10 = 0x003a, DW_OP_lit11 = 0x003b, DW_OP_lit12 = 0x003c, DW_OP_lit13 = 0x003d, DW_OP_lit14 = 0x003e, DW_OP_lit15 = 0x003f, DW_OP_lit16 = 0x0040, DW_OP_lit17 = 0x0041, DW_OP_lit18 = 0x0042, DW_OP_lit19 = 0x0043, DW_OP_lit20 = 0x0044, DW_OP_lit21 = 0x0045, DW_OP_lit22 = 0x0046, DW_OP_lit23 = 0x0047, DW_OP_lit24 = 0x0048, DW_OP_lit25 = 0x0049, DW_OP_lit26 = 0x004a, DW_OP_lit27 = 0x004b, DW_OP_lit28 = 0x004c, DW_OP_lit29 = 0x004d, DW_OP_lit30 = 0x004e, DW_OP_lit31 = 0x004f, DW_OP_reg0 = 0x0050, DW_OP_reg1 = 0x0051, DW_OP_reg2 = 0x0052, DW_OP_reg3 = 0x0053, DW_OP_reg4 = 0x0054, DW_OP_reg5 = 0x0055, DW_OP_reg6 = 0x0056, DW_OP_reg7 = 0x0057, DW_OP_reg8 = 0x0058, DW_OP_reg9 = 0x0059, DW_OP_reg10 = 0x005a, DW_OP_reg11 = 0x005b, DW_OP_reg12 = 0x005c, DW_OP_reg13 = 0x005d, DW_OP_reg14 = 0x005e, DW_OP_reg15 = 0x005f, DW_OP_reg16 = 0x0060, DW_OP_reg17 = 0x0061, DW_OP_reg18 = 0x0062, DW_OP_reg19 = 0x0063, DW_OP_reg20 = 0x0064, DW_OP_reg21 = 0x0065, DW_OP_reg22 = 0x0066, DW_OP_reg23 = 0x0067, DW_OP_reg24 = 0x0068, DW_OP_reg25 = 0x0069, DW_OP_reg26 = 0x006a, DW_OP_reg27 = 0x006b, DW_OP_reg28 = 0x006c, DW_OP_reg29 = 0x006d, DW_OP_reg30 = 0x006e, DW_OP_reg31 = 0x006f, DW_OP_breg0 = 0x0070, DW_OP_breg1 = 0x0071, DW_OP_breg2 = 0x0072, DW_OP_breg3 = 0x0073, DW_OP_breg4 = 0x0074, DW_OP_breg5 = 0x0075, DW_OP_breg6 = 0x0076, DW_OP_breg7 = 0x0077, DW_OP_breg8 = 0x0078, DW_OP_breg9 = 0x0079, DW_OP_breg10 = 0x007a, DW_OP_breg11 = 0x007b, DW_OP_breg12 = 0x007c, DW_OP_breg13 = 0x007d, DW_OP_breg14 = 0x007e, DW_OP_breg15 = 0x007f, DW_OP_breg16 = 0x0080, DW_OP_breg17 = 0x0081, DW_OP_breg18 = 0x0082, DW_OP_breg19 = 0x0083, DW_OP_breg20 = 0x0084, DW_OP_breg21 = 0x0085, DW_OP_breg22 = 0x0086, DW_OP_breg23 = 0x0087, DW_OP_breg24 = 0x0088, DW_OP_breg25 = 0x0089, DW_OP_breg26 = 0x008a, DW_OP_breg27 = 0x008b, DW_OP_breg28 = 0x008c, DW_OP_breg29 = 0x008d, DW_OP_breg30 = 0x008e, DW_OP_breg31 = 0x008f, DW_OP_regx = 0x0090, DW_OP_fbreg = 0x0091, DW_OP_bregx = 0x0092, DW_OP_piece = 0x0093, DW_OP_deref_size = 0x0094, DW_OP_xderef_size = 0x0095, DW_OP_nop = 0x0096, DW_OP_push_object_address = 0x0097, DW_OP_call2 = 0x0098, DW_OP_call4 = 0x0099, DW_OP_call_ref = 0x009a, DW_OP_form_tls_address = 0x009b, DW_OP_call_frame_cfa = 0x009c, DW_OP_bit_piece = 0x009d, DW_OP_implicit_value = 0x009e, DW_OP_stack_value = 0x009f, DW_OP_implicit_pointer = 0x00a0, DW_OP_addrx = 0x00a1, DW_OP_constx = 0x00a2, DW_OP_entry_value = 0x00a3, DW_OP_const_type = 0x00a4, DW_OP_regval_type = 0x00a5, DW_OP_deref_type = 0x00a6, DW_OP_xderef_type = 0x00a7, DW_OP_convert = 0x00a8, DW_OP_reinterpret = 0x00a9, DW_OP_GNU_push_tls_address = 0x00e0, DW_OP_HP_is_value = 0x00e1, DW_OP_HP_fltconst4 = 0x00e2, DW_OP_HP_fltconst8 = 0x00e3, DW_OP_HP_mod_range = 0x00e4, DW_OP_HP_unmod_range = 0x00e5, DW_OP_HP_tls = 0x00e6, DW_OP_INTEL_bit_piece = 0x00e8, DW_OP_WASM_location = 0x00ed, DW_OP_WASM_location_int = 0x00ee, DW_OP_GNU_uninit = 0x00f0, DW_OP_GNU_encoded_addr = 0x00f1, DW_OP_GNU_implicit_pointer = 0x00f2, DW_OP_GNU_entry_value = 0x00f3, DW_OP_GNU_const_type = 0x00f4, DW_OP_GNU_regval_type = 0x00f5, DW_OP_GNU_deref_type = 0x00f6, DW_OP_GNU_convert = 0x00f7, DW_OP_PGI_omp_thread_num = 0x00f8, DW_OP_GNU_reinterpret = 0x00f9, DW_OP_GNU_parameter_ref = 0x00fa, DW_OP_GNU_addr_index = 0x00fb, DW_OP_GNU_const_index = 0x00fc, DW_OP_GNU_variable_value = 0x00fd, DW_OP_hi_user = 0x00ff }; enum Dwarf_ATE_e { DW_ATE_address = 0x0001, DW_ATE_boolean = 0x0002, DW_ATE_complex_float = 0x0003, DW_ATE_float = 0x0004, DW_ATE_signed = 0x0005, DW_ATE_signed_char = 0x0006, DW_ATE_unsigned = 0x0007, DW_ATE_unsigned_char = 0x0008, DW_ATE_imaginary_float = 0x0009, DW_ATE_packed_decimal = 0x000a, DW_ATE_numeric_string = 0x000b, DW_ATE_edited = 0x000c, DW_ATE_signed_fixed = 0x000d, DW_ATE_unsigned_fixed = 0x000e, DW_ATE_decimal_float = 0x000f, DW_ATE_UTF = 0x0010, DW_ATE_UCS = 0x0011, DW_ATE_ASCII = 0x0012, DW_ATE_ALTIUM_fract = 0x0080, DW_ATE_ALTIUM_accum = 0x0081, DW_ATE_HP_float128 = 0x0082, DW_ATE_HP_complex_float128 = 0x0083, DW_ATE_HP_floathpintel = 0x0084, DW_ATE_HP_imaginary_float80 = 0x0085, DW_ATE_HP_imaginary_float128 = 0x0086, DW_ATE_SUN_interval_float = 0x0091, DW_ATE_SUN_imaginary_float = 0x0092, DW_ATE_hi_user = 0x00ff }; enum Dwarf_DEFAULTED_e { DW_DEFAULTED_no = 0x0000, DW_DEFAULTED_in_class = 0x0001, DW_DEFAULTED_out_of_class = 0x0002 }; enum Dwarf_IDX_e { DW_IDX_compile_unit = 0x0001, DW_IDX_type_unit = 0x0002, DW_IDX_die_offset = 0x0003, DW_IDX_parent = 0x0004, DW_IDX_type_hash = 0x0005, DW_IDX_hi_user = 0x0fff, DW_IDX_lo_user = 0x2000 }; enum Dwarf_LLEX_e { DW_LLEX_end_of_list_entry = 0x0000, DW_LLEX_base_address_selection_entry = 0x0001, DW_LLEX_start_end_entry = 0x0002, DW_LLEX_start_length_entry = 0x0003, DW_LLEX_offset_pair_entry = 0x0004 }; enum Dwarf_LLE_e { DW_LLE_end_of_list = 0x0000, DW_LLE_base_addressx = 0x0001, DW_LLE_startx_endx = 0x0002, DW_LLE_startx_length = 0x0003, DW_LLE_offset_pair = 0x0004, DW_LLE_default_location = 0x0005, DW_LLE_base_address = 0x0006, DW_LLE_start_end = 0x0007, DW_LLE_start_length = 0x0008 }; enum Dwarf_RLE_e { DW_RLE_end_of_list = 0x0000, DW_RLE_base_addressx = 0x0001, DW_RLE_startx_endx = 0x0002, DW_RLE_startx_length = 0x0003, DW_RLE_offset_pair = 0x0004, DW_RLE_base_address = 0x0005, DW_RLE_start_end = 0x0006, DW_RLE_start_length = 0x0007 }; enum Dwarf_GNUIVIS_e { DW_GNUIVIS_global = 0x0000, DW_GNUIVIS_static = 0x0001 }; enum Dwarf_GNUIKIND_e { DW_GNUIKIND_none = 0x0000, DW_GNUIKIND_type = 0x0001, DW_GNUIKIND_variable = 0x0002, DW_GNUIKIND_function = 0x0003, DW_GNUIKIND_other = 0x0004 }; enum Dwarf_UT_e { DW_UT_compile = 0x0001, DW_UT_type = 0x0002, DW_UT_partial = 0x0003, DW_UT_skeleton = 0x0004, DW_UT_split_compile = 0x0005, DW_UT_split_type = 0x0006, DW_UT_lo_user = 0x0080, DW_UT_hi_user = 0x00ff }; enum Dwarf_SECT_e { DW_SECT_INFO = 0x0001, DW_SECT_TYPES = 0x0002, DW_SECT_ABBREV = 0x0003, DW_SECT_LINE = 0x0004, DW_SECT_LOCLISTS = 0x0005, DW_SECT_STR_OFFSETS = 0x0006, DW_SECT_MACRO = 0x0007, DW_SECT_RNGLISTS = 0x0008 }; enum Dwarf_DS_e { DW_DS_unsigned = 0x0001, DW_DS_leading_overpunch = 0x0002, DW_DS_trailing_overpunch = 0x0003, DW_DS_leading_separate = 0x0004, DW_DS_trailing_separate = 0x0005 }; enum Dwarf_END_e { DW_END_default = 0x0000, DW_END_big = 0x0001, DW_END_little = 0x0002, DW_END_lo_user = 0x0040, DW_END_hi_user = 0x00ff }; enum Dwarf_ATCF_e { DW_ATCF_lo_user = 0x0040, DW_ATCF_SUN_mop_bitfield = 0x0041, DW_ATCF_SUN_mop_spill = 0x0042, DW_ATCF_SUN_mop_scopy = 0x0043, DW_ATCF_SUN_func_start = 0x0044, DW_ATCF_SUN_end_ctors = 0x0045, DW_ATCF_SUN_branch_target = 0x0046, DW_ATCF_SUN_mop_stack_probe = 0x0047, DW_ATCF_SUN_func_epilog = 0x0048, DW_ATCF_hi_user = 0x00ff }; enum Dwarf_ACCESS_e { DW_ACCESS_public = 0x0001, DW_ACCESS_protected = 0x0002, DW_ACCESS_private = 0x0003 }; enum Dwarf_VIS_e { DW_VIS_local = 0x0001, DW_VIS_exported = 0x0002, DW_VIS_qualified = 0x0003 }; enum Dwarf_VIRTUALITY_e { DW_VIRTUALITY_none = 0x0000, DW_VIRTUALITY_virtual = 0x0001, DW_VIRTUALITY_pure_virtual = 0x0002 }; enum Dwarf_LANG_e { DW_LANG_C89 = 0x0001, DW_LANG_C = 0x0002, DW_LANG_Ada83 = 0x0003, DW_LANG_C_plus_plus = 0x0004, DW_LANG_Cobol74 = 0x0005, DW_LANG_Cobol85 = 0x0006, DW_LANG_Fortran77 = 0x0007, DW_LANG_Fortran90 = 0x0008, DW_LANG_Pascal83 = 0x0009, DW_LANG_Modula2 = 0x000a, DW_LANG_Java = 0x000b, DW_LANG_C99 = 0x000c, DW_LANG_Ada95 = 0x000d, DW_LANG_Fortran95 = 0x000e, DW_LANG_PLI = 0x000f, DW_LANG_ObjC = 0x0010, DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, DW_LANG_Python = 0x0014, DW_LANG_OpenCL = 0x0015, DW_LANG_Go = 0x0016, DW_LANG_Modula3 = 0x0017, DW_LANG_Haskel = 0x0018, DW_LANG_C_plus_plus_03 = 0x0019, DW_LANG_C_plus_plus_11 = 0x001a, DW_LANG_OCaml = 0x001b, DW_LANG_Rust = 0x001c, DW_LANG_C11 = 0x001d, DW_LANG_Swift = 0x001e, DW_LANG_Julia = 0x001f, DW_LANG_Dylan = 0x0020, DW_LANG_C_plus_plus_14 = 0x0021, DW_LANG_Fortran03 = 0x0022, DW_LANG_Fortran08 = 0x0023, DW_LANG_RenderScript = 0x0024, DW_LANG_BLISS = 0x0025, DW_LANG_lo_user = 0x8000, DW_LANG_Mips_Assembler = 0x8001, DW_LANG_Upc = 0x8765, DW_LANG_SUN_Assembler = 0x9001, DW_LANG_ALTIUM_Assembler = 0x9101, DW_LANG_hi_user = 0xffff }; enum Dwarf_ID_e { DW_ID_case_sensitive = 0x0000, DW_ID_up_case = 0x0001, DW_ID_down_case = 0x0002, DW_ID_case_insensitive = 0x0003 }; enum Dwarf_CC_e { DW_CC_normal = 0x0001, DW_CC_program = 0x0002, DW_CC_nocall = 0x0003, DW_CC_pass_by_reference = 0x0004, DW_CC_pass_by_value = 0x0005, DW_CC_lo_user = 0x0040, DW_CC_GNU_borland_fastcall_i386 = 0x0041, DW_CC_ALTIUM_interrupt = 0x0065, DW_CC_ALTIUM_near_system_stack = 0x0066, DW_CC_ALTIUM_near_user_stack = 0x0067, DW_CC_ALTIUM_huge_user_stack = 0x0068, DW_CC_GNU_BORLAND_safecall = 0x00b0, DW_CC_GNU_BORLAND_stdcall = 0x00b1, DW_CC_GNU_BORLAND_pascal = 0x00b2, DW_CC_GNU_BORLAND_msfastcall = 0x00b3, DW_CC_GNU_BORLAND_msreturn = 0x00b4, DW_CC_GNU_BORLAND_thiscall = 0x00b5, DW_CC_GNU_BORLAND_fastcall = 0x00b6, DW_CC_LLVM_vectorcall = 0x00c0, DW_CC_LLVM_Win64 = 0x00c1, DW_CC_LLVM_X86_64SysV = 0x00c2, DW_CC_LLVM_AAPCS = 0x00c3, DW_CC_LLVM_AAPCS_VFP = 0x00c4, DW_CC_LLVM_IntelOclBicc = 0x00c5, DW_CC_LLVM_SpirFunction = 0x00c6, DW_CC_LLVM_OpenCLKernel = 0x00c7, DW_CC_LLVM_Swift = 0x00c8, DW_CC_LLVM_PreserveMost = 0x00c9, DW_CC_LLVM_PreserveAll = 0x00ca, DW_CC_LLVM_X86RegCall = 0x00cb, DW_CC_GDB_IBM_OpenCL = 0x00ff, }; enum Dwarf_INL_e { DW_INL_not_inlined = 0x0000, DW_INL_inlined = 0x0001, DW_INL_declared_not_inlined = 0x0002, DW_INL_declared_inlined = 0x0003 }; enum Dwarf_ORD_e { DW_ORD_row_major = 0x0000, DW_ORD_col_major = 0x0001 }; enum Dwarf_DSC_e { DW_DSC_label = 0x0000, DW_DSC_range = 0x0001 }; enum Dwarf_LNCT_e { DW_LNCT_path = 0x0001, DW_LNCT_directory_index = 0x0002, DW_LNCT_timestamp = 0x0003, DW_LNCT_size = 0x0004, DW_LNCT_MD5 = 0x0005, DW_LNCT_GNU_subprogram_name = 0x0006, DW_LNCT_GNU_decl_file = 0x0007, DW_LNCT_GNU_decl_line = 0x0008, DW_LNCT_lo_user = 0x2000, DW_LNCT_LLVM_source = 0x2001, DW_LNCT_hi_user = 0x3fff }; enum Dwarf_LNS_e { DW_LNS_copy = 0x0001, DW_LNS_advance_pc = 0x0002, DW_LNS_advance_line = 0x0003, DW_LNS_set_file = 0x0004, DW_LNS_set_column = 0x0005, DW_LNS_negate_stmt = 0x0006, DW_LNS_set_basic_block = 0x0007, DW_LNS_const_add_pc = 0x0008, DW_LNS_fixed_advance_pc = 0x0009, DW_LNS_set_prologue_end = 0x000a, DW_LNS_set_epilogue_begin = 0x000b, DW_LNS_set_isa = 0x000c, DW_LNS_set_address_from_logical = 0x000d, DW_LNS_inlined_call = 0x000e, DW_LNS_pop_context = 0x000f }; enum Dwarf_LNE_e { DW_LNE_end_sequence = 0x0001, DW_LNE_set_address = 0x0002, DW_LNE_define_file = 0x0003, DW_LNE_set_discriminator = 0x0004, DW_LNE_HP_negate_is_UV_update = 0x0011, DW_LNE_HP_push_context = 0x0012, DW_LNE_HP_pop_context = 0x0013, DW_LNE_HP_set_file_line_column = 0x0014, DW_LNE_HP_set_routine_name = 0x0015, DW_LNE_HP_set_sequence = 0x0016, DW_LNE_HP_negate_post_semantics = 0x0017, DW_LNE_HP_negate_function_exit = 0x0018, DW_LNE_HP_negate_front_end_logical = 0x0019, DW_LNE_HP_define_proc = 0x0020, DW_LNE_HP_source_file_correlation = 0x0080, DW_LNE_hi_user = 0x00ff }; enum Dwarf_ISA_e { DW_ISA_UNKNOWN = 0x0000, DW_ISA_ARM_thumb = 0x0001, DW_ISA_ARM_arm = 0x0002 }; enum Dwarf_MACRO_e { DW_MACRO_define = 0x0001, DW_MACRO_undef = 0x0002, DW_MACRO_start_file = 0x0003, DW_MACRO_end_file = 0x0004, DW_MACRO_define_strp = 0x0005, DW_MACRO_undef_strp = 0x0006, DW_MACRO_import = 0x0007, DW_MACRO_define_sup = 0x0008, DW_MACRO_undef_sup = 0x0009, DW_MACRO_import_sup = 0x000a, DW_MACRO_define_strx = 0x000b, DW_MACRO_undef_strx = 0x000c, DW_MACRO_lo_user = 0x00e0, DW_MACRO_hi_user = 0x00ff }; enum Dwarf_MACINFO_e { DW_MACINFO_define = 0x0001, DW_MACINFO_undef = 0x0002, DW_MACINFO_start_file = 0x0003, DW_MACINFO_end_file = 0x0004, DW_MACINFO_vendor_ext = 0x00ff }; enum Dwarf_CFA_e { DW_CFA_extended = 0x0000, DW_CFA_set_loc = 0x0001, DW_CFA_advance_loc1 = 0x0002, DW_CFA_advance_loc2 = 0x0003, DW_CFA_advance_loc4 = 0x0004, DW_CFA_offset_extended = 0x0005, DW_CFA_restore_extended = 0x0006, DW_CFA_undefined = 0x0007, DW_CFA_same_value = 0x0008, DW_CFA_register = 0x0009, DW_CFA_remember_state = 0x000a, DW_CFA_restore_state = 0x000b, DW_CFA_def_cfa = 0x000c, DW_CFA_def_cfa_register = 0x000d, DW_CFA_def_cfa_offset = 0x000e, DW_CFA_def_cfa_expression = 0x000f, DW_CFA_expression = 0x0010, DW_CFA_offset_extended_sf = 0x0011, DW_CFA_def_cfa_sf = 0x0012, DW_CFA_def_cfa_offset_sf = 0x0013, DW_CFA_val_offset = 0x0014, DW_CFA_val_offset_sf = 0x0015, DW_CFA_val_expression = 0x0016, DW_CFA_lo_user = 0x001c, DW_CFA_MIPS_advance_loc8 = 0x001d, DW_CFA_GNU_window_save = 0x002d, DW_CFA_GNU_args_size = 0x002e, DW_CFA_GNU_negative_offset_extended = 0x002f, DW_CFA_METAWARE_info = 0x0034, DW_CFA_high_user = 0x003f, DW_CFA_advance_loc = 0x0040, DW_CFA_offset = 0x0080, DW_CFA_restore = 0x00c0 }; enum Dwarf_EH_e { DW_EH_PE_absptr = 0x0000, DW_EH_PE_uleb128 = 0x0001, DW_EH_PE_udata2 = 0x0002, DW_EH_PE_udata4 = 0x0003, DW_EH_PE_udata8 = 0x0004, DW_EH_PE_sleb128 = 0x0009, DW_EH_PE_sdata2 = 0x000a, DW_EH_PE_sdata4 = 0x000b, DW_EH_PE_sdata8 = 0x000c, DW_EH_PE_pcrel = 0x0010, DW_EH_PE_textrel = 0x0020, DW_EH_PE_datarel = 0x0030, DW_EH_PE_funcrel = 0x0040, DW_EH_PE_aligned = 0x0050, DW_EH_PE_omit = 0x00ff }; enum Dwarf_FRAME_e { DW_FRAME_CFA_COL = 0x0000, DW_FRAME_REG1 = 0x0001, DW_FRAME_REG2 = 0x0002, DW_FRAME_REG3 = 0x0003, DW_FRAME_REG4 = 0x0004, DW_FRAME_REG5 = 0x0005, DW_FRAME_REG6 = 0x0006, DW_FRAME_REG7 = 0x0007, DW_FRAME_REG8 = 0x0008, DW_FRAME_REG9 = 0x0009, DW_FRAME_REG10 = 0x0010, DW_FRAME_REG11 = 0x0011, DW_FRAME_REG12 = 0x0012, DW_FRAME_REG13 = 0x0013, DW_FRAME_REG14 = 0x0014, DW_FRAME_REG15 = 0x0015, DW_FRAME_REG16 = 0x0016, DW_FRAME_REG17 = 0x0017, DW_FRAME_REG18 = 0x0018, DW_FRAME_REG19 = 0x0019, DW_FRAME_REG20 = 0x0020, DW_FRAME_REG21 = 0x0021, DW_FRAME_REG22 = 0x0022, DW_FRAME_REG23 = 0x0023, DW_FRAME_REG24 = 0x0024, DW_FRAME_REG25 = 0x0025, DW_FRAME_REG26 = 0x0026, DW_FRAME_REG27 = 0x0027, DW_FRAME_REG28 = 0x0028, DW_FRAME_REG29 = 0x0029, DW_FRAME_REG30 = 0x0030, DW_FRAME_REG31 = 0x0031, DW_FRAME_FREG0 = 0x0032, DW_FRAME_FREG1 = 0x0033, DW_FRAME_FREG2 = 0x0034, DW_FRAME_FREG3 = 0x0035, DW_FRAME_FREG4 = 0x0036, DW_FRAME_FREG5 = 0x0037, DW_FRAME_FREG6 = 0x0038, DW_FRAME_FREG7 = 0x0039, DW_FRAME_FREG8 = 0x0040, DW_FRAME_FREG9 = 0x0041, DW_FRAME_FREG10 = 0x0042, DW_FRAME_FREG11 = 0x0043, DW_FRAME_FREG12 = 0x0044, DW_FRAME_FREG13 = 0x0045, DW_FRAME_FREG14 = 0x0046, DW_FRAME_FREG15 = 0x0047, DW_FRAME_FREG16 = 0x0048, DW_FRAME_FREG17 = 0x0049, DW_FRAME_FREG18 = 0x0050, DW_FRAME_FREG19 = 0x0051, DW_FRAME_FREG20 = 0x0052, DW_FRAME_FREG21 = 0x0053, DW_FRAME_FREG22 = 0x0054, DW_FRAME_FREG23 = 0x0055, DW_FRAME_FREG24 = 0x0056, DW_FRAME_FREG25 = 0x0057, DW_FRAME_FREG26 = 0x0058, DW_FRAME_FREG27 = 0x0059, DW_FRAME_FREG28 = 0x0060, DW_FRAME_FREG29 = 0x0061, DW_FRAME_FREG30 = 0x0062, DW_FRAME_FREG31 = 0x0063, DW_FRAME_FREG32 = 0x0064, DW_FRAME_FREG33 = 0x0065, DW_FRAME_FREG34 = 0x0066, DW_FRAME_FREG35 = 0x0067, DW_FRAME_FREG36 = 0x0068, DW_FRAME_FREG37 = 0x0069, DW_FRAME_FREG38 = 0x0070, DW_FRAME_FREG39 = 0x0071, DW_FRAME_FREG40 = 0x0072, DW_FRAME_FREG41 = 0x0073, DW_FRAME_FREG42 = 0x0074, DW_FRAME_FREG43 = 0x0075, DW_FRAME_FREG44 = 0x0076, DW_FRAME_FREG45 = 0x0077, DW_FRAME_FREG46 = 0x0078, DW_FRAME_FREG47 = 0x0079, DW_FRAME_FREG48 = 0x0080, DW_FRAME_FREG49 = 0x0081, DW_FRAME_FREG50 = 0x0082, DW_FRAME_FREG51 = 0x0083, DW_FRAME_FREG52 = 0x0084, DW_FRAME_FREG53 = 0x0085, DW_FRAME_FREG54 = 0x0086, DW_FRAME_FREG55 = 0x0087, DW_FRAME_FREG56 = 0x0088, DW_FRAME_FREG57 = 0x0089, DW_FRAME_FREG58 = 0x0090, DW_FRAME_FREG59 = 0x0091, DW_FRAME_FREG60 = 0x0092, DW_FRAME_FREG61 = 0x0093, DW_FRAME_FREG62 = 0x0094, DW_FRAME_FREG63 = 0x0095, DW_FRAME_FREG64 = 0x0096, DW_FRAME_FREG65 = 0x0097, DW_FRAME_FREG66 = 0x0098, DW_FRAME_FREG67 = 0x0099, DW_FRAME_FREG68 = 0x0100, DW_FRAME_FREG69 = 0x0101, DW_FRAME_FREG70 = 0x0102, DW_FRAME_FREG71 = 0x0103, DW_FRAME_FREG72 = 0x0104, DW_FRAME_FREG73 = 0x0105, DW_FRAME_FREG74 = 0x0106, DW_FRAME_FREG75 = 0x0107, DW_FRAME_FREG76 = 0x0108, DW_FRAME_HIGHEST_NORMAL_REGISTER = 0x0188 }; enum Dwarf_CHILDREN_e { DW_CHILDREN_no = 0x0000, DW_CHILDREN_yes = 0x0001 }; enum Dwarf_ADDR_e { DW_ADDR_none = 0x0000 }; #endif /* __DWARF_NAMES_ENUM_H__ */ /* END FILE */ libdwarf-20210528/libdwarf/cmake/0000775000175000017500000000000014054271043013426 500000000000000libdwarf-20210528/libdwarf/cmake/libdwarf-config.cmake0000664000175000017500000000015113753322212017402 00000000000000if (NOT TARGET libdwarf::libdwarf) include(${CMAKE_CURRENT_LIST_DIR}/libdwarf-targets.cmake) endif() libdwarf-20210528/libdwarf/ChangeLog20180000664000175000017500000012143113644370703014364 000000000000002018-12-21 David Anderson * pdfbld.sh: Now more flexible for creating one or both pdfs. * libdwarf2.1.pdf: Regenerated rev 2.70 per yesterday's .mm changes. 2018-12-20 David Anderson * dwarf_elf_access.c,memcpy_swap.h,pro_alloc.h,pro_dnames.h: Removing trailing whitespace, trailing blank lines. 2018-12-20 David Anderson * dwarf_dnames.c,pro_dnames.h,pro_die.h: Remove some uses of Dwarf_ufixed. * pro_section.c: Remove some uses of Dwarf_ufixed and instead of 2,4,8 use DWARF_HALF_SIZE, DWARF_23BIT_SIZE or DWARF_64BIT_SIZE as appropriate. 2018-12-20 David Anderson * Makefile.am: Adding new header memcpy_swap.h to the headers list. * dwarf_gdbindex.c,dwarf_init_finish.c,dwarf_machoread.c, dwarf_object_detector.c, dwarf_peread.c: Include memcpy_swap.h. Use the new _dwarf_memcpy_noswap_bytes instead of memcpy directly. * pro_init.c: Include memcpy_swap.h. Use the new _dwarf_memcpy_noswap_bytes instead of memcpy directly. Delete local declaration now memcpy_swap.h used here. * dwarf_machoread.h,dwarf_peread.h: mo_copy_word declaration adjustment to match the new _dwarf_memcpy_noswap_bytes * dwarf_incl.h: Put before "dwarf.h" and "libdwarf.h" includes (and don't use <> on dwarf.h or libdwarf.h as they may only be locally defined) * dwarf_opaque.h: void return on de_copy_word now. Delete ugly redeclaration of _dwarf_memcpy_swap_bytes. * dwarf_util.c: Implement dwarf_get_endian_copy_function so dwarfdump can swap bytes where it needs to (as in printing frame instruction bytes). And implement _dwarf_memcpy_noswap_bytes with a void return. _dwarf_memcpy_swap_bytes now also with void return. * libdwarf.h.in: Declare the new function dwarf_get_endian_copy_function(). * pro_alloc.h: Add idempotency and ifdef __cplusplus. * pro_incl.h: Delete pointless blank lines in the macro definition area. * pro_opaque.h: delete include. No longer needed as de_copy_word no longer uses size_t. 2018-12-19 David Anderson * dwarf_elf_access.c(dwarf_get_elf): Now uses the new format per-object-type to quickly figure out if there is an Elf * open. 2018-12-19 David Anderson * dwarf_errmsg_list.h: Added DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. * dwarf_error.c: Added dwarf_errmsg_by_number() so one can get more complete messages when all we have is an error number. * dwarf_object_detector.c: For PE objects the correct machine id for 64bit is 0x8664, not 0x8886. * libdwarf.h.in: Added dwarf_errmsg_by_number() and DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. Fixed a couple trailing white-space instances. * pro_section.c: Removed the blank last line of the file. 2018-12-07 David Anderson * pro_die.c pro_finish.c pro_forms.c pro_line.c: Some lines were too long and one test for error (from the last set of changes) was written in a usable but non-standard way so that's now done in the standard way. 2018-12-05 David Anderson * dwarf_query.c: Removed useless blank lines. * libdwarf.h.in: Many new producer functions so the better return values of DW_DLV_OK/DW_DLV_ERROR are available for every producer call. The older functions are present and continue to work. * libdwarf2p.1.mm: Document the old (a couple got left out earlier) and new producer functions. * libdwarf2p.1.pdf: Regenerated. Version 1.48. * pro_arange.c, pro_die.c, pro_expr.c, pro_forms.c, pro_frame.c,pro_funcs.c,pro_line.c,pro_opaque.h, pro_pubnames.c,pro_reloc.c,pro_section.c,pro_types.c, pro_vars.c,pro_weaks.c: New functions provided so caller code is easier to read. The new interfaces are more type-safe than before. 2018-11-29 David Anderson * dwarf_abbrev.c: Now deals with DW_FORM_implicit_const properly. * dwarf_arange.c: Remove trailing whitespace. * dwarf_die_deliv.c: Now deals with DW_FORM_implicit_const properly. * dwarf_machoread.c,dwarf_object_detector.c, dwarf_peread.c: Remove trailing whitespace and fix indentation. * dwarf_opaque.h: Add ar_implicit_const to Dwarf_Attribute_s to deal with the implicit const FORM. * dwarf_query.c: Now deals with DW_FORM_implicit_const properly. * dwarf_util.c: Remove trailing whitespace and fix indentation. Now deals with DW_FORM_implicit_const properly. * libdwarf.h.in: Declare new function dwarf_add_AT_implicit_const(). * libdwarf_version.h: Updated version string. * pro_die.h: Add abb_implicits to Dwarf_P_Abbrev_s deal with the implicit const FORM. * pro_forms.c: Implement dwarf_add_AT_implicit_const(). * pro_opaque.h: Add Dwarf_Signed dsa_implicitvalue to Dwarf_Sort_Abbrev_s for implicit value(s). * pro_section.c: Now deals with DW_FORM_implicit_const properly. * pro_section.h: Now SECTION_TYPE defaults to 1 as the suggested section type, which is SHT_PROGBITS in Elf. See the comments there. Used to depend on a #ifdef and sometimes was defined SHT_MIPS_DWARF. * libdwarf2p.1.mm: Document the new implicit const function. * libdwarf2p.1.pdf: Regenerate. Version 1.47. 2018-11-28 David Anderson * CMakeLists.txt: The previous change failed to deal with the new pe .h files properly. Fixed. And, the SOURCES and HEADERS lists are now on shorter lines so they fit in 70 characters. 2018-11-26 David Anderson * Makefile.am: Added new files * dwarf_pe_descr.h,dwarf_peread.c,dwarf_peread.h: New files implementing reading DWARF from PE object files. * dwarf_arange.c: Notice some zero length things in .debug_aranges and ignore them. Only ever seen in a PE dll with DWARF . Odd. Needs further checking. * dwarf_die_deliv.c: Here too, check for zero length CU and just move along. Same dll. Odd. Needs further checking. * dwarf_generic_init.c: Call the pe setup code. * dwarf_init_finish.c: Delete useless blank line. * dwarf_machoread.c: Add checks to catch corrupted object files. * dwarf_opaque.h: Add _dwarf_pe_setup(). * dwarf_util.h: Some macro lines were too long. Shortened so they are easier to read/verify. * libdwarf_version.h: Updated version string. * CMakeLists.txt: Added new pe files. 2018-11-24 David Anderson * dwarf_object_detector.c: The same ASNAR bug fixed here now. * libdwarf_version.h: Updated date string. 2018-11-22 David Anderson * dwarf_machoread.c: A bug in the ASNAR macro for big-endian hosts lead to coredump reading mach-o objects (of any endianness) on such hosts. 2018-11-20 David Anderson * Makefile.am: The setup for cross-builds was incomplete for errmsg_check. Fixed. * dwarf_base_types.h: Removed a nested include of libdwarfdefs.h. * dwarf_incl.h: Moved the include of libdwarfdefs.h to here. * dwarf_errmsg_list.h: Added new (as yet unused) error messages. * dwarf_machoread.c: Added overview commentary. * dwarf_test_errmsg_list.c: Improved error messages in a few cases so errors detected are more self-explanatory. * libdwarf.h.in: Added new (as yet unused) error message defines. 2018-11-06 David Anderson * dwarf_machoread.c(_dwarf_macho_object_access_init): Following a malloc the null check referenced the wrong variable! 2018-11-05 David Anderson * dwarf_machoread.c: Added a sanity check on mo_command_count before adding it to anything. Now malloc a Dwarf_Obj_Access_Interface_s so we use a local function consistently. We were freeing on an address of a local variable... But only if a mach-o object was seriously corrupted. * dwarf_object_detector.c: We now know we misinterpreted a comment in the macho-loader header. DW_ENDIAN_SAME (and _OPPOSITE) were inappropriate. Endianness detection for PE and mach-o objects are fixed. * libdwarf.h.in,dwarf_object_detector.h: Dropping DW_ENDIAN_SAME and DW_ENDIAN_OPPOSITE as we no longer use them. * dwarf_macho_loader.h: Added commentary about the MH_MAGIC etc values. * libdwarf_version.h: Updated date string. 2018-11-01 David Anderson * libdwarf_version.h: Updated date string. * dwarf_machoread.c(dwarf_macho_load_dwarf_section_details64): Had an off-by-one error (which was already corrected in the *details32 function). If the last section was DWARF related this bug caused a DWARF section to appear unavailable. 2018-10-30 David Anderson * libdwarf_version.h: Updated date string. 2018-10-24 David Anderson * libdwarf2.1.mm: Added documentation on new functions dwarf_object_detector_fd(), dwarf_object_detector_path(), and dwarf_init_path(). Fixed indentation many places (many still to fix). * libdwarf2.1.pdf: Regenerated Reg 2.68. * dwarf_macho_loader.h: Renamed from macho-loader.h * Makefile.am: reflects name change. * dwarf_machoread.c: Uses renamed macho structs. * dwarf_machoread.h: Renames a couple macho structs. Aligns fieldnames with the similar item in libdwarf.h. * dwarf_object_detector.c: A build on 32bit machine noticed a function-prototype inconsistency in declaring dwarf_object_detector_path(). Fixed. Now allows outpath, outlen of the dwarf_object_detector_path() call to be zero, suppressing macho dSYM subdirectory checks. 2018-10-23 David Anderson * dw_elfstructs.h: Adding this for use with object readers. * dwarf_init_finish.c: Fixed placement of blank line to match standard source formatting. * macho-loader.h: Now avoids direct use of integral types. Uses macro to setup each member. * dwarf_machoread.c: New macro ASNAR handles endianness and uses the new struct member format in macho-loader.h * dwarf_object_detector.c * dwarf_reading.h: Simplified as a result of the new ASNAR macro and the structs it helps with. * libdwarf_version.h: New version string. 2018-10-20 David Anderson * dwarf_machoread.c,dwarf_machoread.h: Moved macros from the .h to the .c. * dwarf_object_detector: Removed the need to know the correct type of fields in object-defined headers. We know the lengths and layouts and that suffices because we copy everything anyway to deal with endianness. No more need to define t16 or t32 as the 'right' type. 2018-10-19 David Anderson * dwarf_version.h: Updated date string. * dwarf_errmsg_list.h: New errors DW_DLE_ELF_CLASS_BAD(420), DW_DLE_ELF_ENDIAN_BAD(421), DW_DLE_ELF_VERSION_BAD(422), DW_DLE_FILE_TOO_SMALL(423),DW_DLE_PATH_SIZE_TOO_SMALL(424), DW_DLE_BAD_TYPE_SIZE(425) for new checks for object correctness. Of more than one object type. * dwarf_generic_init.c: The new function dwarf_init_path has a new type for the call to dwarf_object_detector. * dwarf_object_detector.c: Now works in the libdwarf context. Contains checks for Elf, Mach-o and PE object files as well as recognizing archives ( such as .a). * dwarf_object_detector.h: Tweaked into final form. * dwarf_opaque.h: Added de_filesize field as we usually now know the file size for checking offsets. * libdwarf.h.in: Added the DW_DLE named above. declared dwarf_object_detector_path() and dwarf_object_detector_fd() as public functions. * pro_alloc.c: #ifdefd the include of malloc.h. 2018-10-17 David Anderson * macho-loader.h: A header for reading mach-o dsym objects. * dwarf_generic_init.c,dwarf_init_finish.c: Now modified to support reading mach-o. * dwarf_machoread.c,dwarf_machoread.h: Contains the mach-o specific details. * dwarf_object_read_common.c: New, has a * dwarf_opaque.h * dwarf_original_elf_init.c: now allows elf or mach-o objects and calls the appropriate setup code. * dwarf_reading.h: new common header for reading without libelf. * pro_section.c: Fix trailing whitespace. 2018-10-15 David Anderson * dwarf_version.h: Updated date string. * dwarf_die_deliv.c: Now a sibling-offset error returns an error of DW_DLE_SIBLING_OFFSET_WRONG. Now the code avoids adding a corrupt value to a pointer (thus properly detecting DW_DLE_SIBLING_OFFSET_WRONG). * libdwarf.h.in: Added DW_DLE_SIBLING_OFFSET_WRONG. * dwarf_errmsg_list.h: Added DW_DLE_SIBLING_OFFSET_WRONG to the errmsg strings list. 2018-10-14 David Anderson * dwarf_version.h: Updated date string. * pro_section.c: An extra 0-byte was being added in generated DWARF at the end of section as if the top level was a sibling chain, and GNU readelf noticed the wasted byte. No longer added. 2018-10-02 David Anderson * dwarf_generic_init.c,dwarf_original_elf_init.c: Fixed remaining indent issues. 2018-10-02 David Anderson * Makefile.am: Tweaks for the object detector files. * dwarf_errmsg_list.h,libdwarf.h.in: New error codes. * dwarf_generic_init.c,dwarf_original_elf_init.c: * Removed a function that just caused confusion, it was doing two jobs. Now each job called where needed. * dwarf_object_detector.c,dwarf_object_detector.h: tweeks for better error codes and trailing spaces and indent issues. * dwarf_opaque.h: Removed deleted function. 2018-10-02 David Anderson * dwarf_object_detector.h,dwarf_object_detector.c: To be used soon. 2018-09-29 David Anderson * gennames.c: Fixed an indent issue in a comment. 2018-09-28 Carlos Alberto Enciso * dwgetopt: Use size_t to remove conversion warning on Windows platform. * getnames.c: Generate '#ifdef __cplusplus/#endif' include guards to allow the inclusion of header files by C++ code. 2018-09-21 David Anderson * CMakeLists.txt: Add dwarf_generic_init.c into sources list. * Makefile.am: Ensure all cmake files get into releases. 2018-09-18 David Anderson * dwarf_generic_init.c: Moved dwarf_finish() here from dwarf_original_elf_init.c. * dwarf_original_elf.c: Moved dwarf_finish() out of this file. * dwarf_init_finish.c: Corrected a comment. frmo->from 2018-09-18 David Anderson * dwarf_generic_init.c: Moved dwarf_init() and dwarf_init_b() to this new file. From dwarf_original_elf_init.c. These functions will allow handling non-elf object DWARF in the future. * dwarf_original_elf_init.c: Functions moved to dwarf_generic_init.c and _dwarf_elf_init_file_ownership no longer static so it can be called from dwarf_generic_init.c. * Makefile.am: Add the new source file to the sources list. 2018-09-12 David Anderson * dwarf_version.h: Updated date string. * libdwarf.h.in: Corrected the use of HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson * libdwarf.h.in: Restored use of HAVE_NONSTANDARD_PRINTF_64_FORMAT for those needing that feature. 2018-09-02 David Anderson * Makefile.am: Changed the way to build gennames executable to the automake way, eliminating make warnings when building. * Makefile.in: regenerated. 2018-08-23 David Anderson * CMakeLists.txt: Adjusted to fit new/changed file names. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall. * dwarf_die_deliv.c,pro_section.c: Removed unused local variables. 2018-08-14 David Anderson * libdwarf.h.in: DW_HARMLESS_ERROR_MSG_STRING_SIZE now 300, c compiler noted 200 was too small for a harmless-error sprintf string in dwarf_frame2.c (line 192). * Makefile.am. Added CPPFLAGS_FOR_BUILD where it was accidentally omitted. * libdwarf_version.h: Updated the version date string. 2018-08-09 David Anderson * Makefile.am: Added AM_TESTS_ENVIRONMENT enabling make check from any build directory. Also,add dwarf_test_errmsg_list.c to the files in a release so make check can work * runtests.sh: Handle the environment variable AM_TESTS_ENVIRONMENT sets: DWTOPSRCDIR 2018-08-07 David Anderson * libdwarf2.1.mm: Revised the argument list of dwarf_get_real_section_name() to add compression size information. * libdwarf2.1.pdf: Regenerated version 2.67. * dwarf_die_deliv.c: Added compression-size arguments to call to dwarf_get_real_section_name() and updated the string additions to match. * dwarf_init_finish.c: Update compression before/after sizes in new fields dss_compressed_length dss_uncompressed_length.. * dwarf_opaque.h: Add the new dss_ fields. * libdwarf.h.in: Revised prototype of dwarf_get_real_section_name() 2018-08-06 David Anderson * libdwarf2.1.mm: Revised the argument list of dwarf_get_real_section_name() so it works properly. * libdwarf2.1.pdf: Regenerated version 2.66. * dwarf_die_deliv.c: Added third argument to call to dwarf_get_real_section_name() and updated the string * dwarf_opaque.h: Added flag dss_ZLIB_compressed so we can report compression more accurately. 2018-08-05 David Anderson * dwarf_die_deliv.c: Was failing to report SHF_COMPRESSED in dwarfdump do to mistake here (statement with no side effect!). 2018-08-05 David Anderson * libdwarf_version.h: Updated version string. * dwarf_errmsg_list.h: Support the new error code. * dwarf_opaque.h: Fields to support dwarf_get_real_section_name(). * dwarf_die_deliv.c: Implements dwarf_get_real_section_name(). * dwarf_init_finish.c: Changes to support dwarf_get_real_section_name(). * libdwarf.h.in: Declare dwarf_get_real_section_name(). Add a new error code. * libdwarf2.1.mm: Document dwarf_get_real_section_name(). * libdwarf2.1.pdf: Regenerate. Version 2.65. 2018-08-04 David Anderson * dwarf_util.h: Remove trailing whitespace. * pro_dnames.h: Preliminary structs for writing .debug_names * pro_section.c: Corrected a comment. Removed some debug code. Fixed indent mistakes. * pro_opaque.h: Fixed indent error. * pro_init.c: Extracted Bernstein hash into its own function. Fixed indent errors. 2018-08-02 David Anderson * libdwarf_version.h: Updated version date. * pro_section.c: #if 0 or comment out some debug code. * dwarf_util.c:Replaced accidental loss of 'do'. * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Move all but libdwarf*pdf out of the /usr/local/share install set, keep them all in the distribution set. 2018-07-31 David Anderson * Makefile.am: add pro_dnames.h pro_dnames.c for .debug_names support.. * dwarf_errmsg_list.h: Add DW_DLE_DUP_ATTR_ON_DIE error code. * dwarf_frame2.c: Move qsort_compare up to top of file to avoid a forward declaration. * dwarf_init_finish.c: Additional comments. * dwarf_util.c: Corrected comment. Moved local variable declarations down to where needed. * libdwarf.h.in: Declare new function dwarf_force_debug_names() used for testing. * pro_die.h: Add comment. * pro_dnames.c: Remove junk whitespace. * pro_forms.c(_dwarf_pro_add_at_to_die): Add DW_AT_data_member_location, DW_AT_trampoline to the allowed set. * pro_opaque.h: Add de_dnames_sect to Dwarf_P_Debug_s. * pro_section.c: Now sorts abbreviations by attribute number. Refactors header generation to make it easier to read the code. Refactors _dwarf_pro_getabbrev() for clarity (using newly-sorted abbreviation list). 2018-07-30 David Anderson * pro_dnames.c, pro_dnames.h: New, these just placeholders for the moment. To write out .debug_names. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. 2018-07-24 David Anderson * libdwarf_version.h: Updated version string. * dwarf_line_table_reader_common.h:Removed trailing whitespace and fixed indentations. * pro_line.c: Removed trailing whitespace. * pro_reloc.c,pro_reloc.h: Defines _dwarf_pro_pre_alloc_specific_reloc_slots(). Deletes _dwarf_pro_pre_alloc_n_reloc_slots() * pro_reloc_symbolic.c: Now uses _dwarf_pro_pre_alloc_specific_reloc_slots() so static analysis can understand what the code does. Fixes Coverity CID 186978. * pro_arange.c: Now uses _dwarf_pro_pre_alloc_specific_reloc_slots instead of _dwarf_pro_pre_alloc_n_reloc_slots. 2018-07-24 David Anderson * dwarf_init_finish.c(set_up_section): A simple revision eliminates any copying and simplifies the logic. And eliminates the use of safe_strcpy(). * dwarf_util.h, dwarf_util.c: Remove safe_strcpy(). 2018-07-23 David Anderson * Makefile.am: Make it impossible for Make to build the libdwarf pdf files. We do not want users to be required to have the pdf tools. * pdfbld.sh: A script to build the libdwarf pdf files when required (the .mm files rarely change). 2018-07-23 David Anderson * libdwarf_version.h: Updated version string. * pro_line.c: Added comments on the oddness of some return values (signed vs unsigned and error returns). * dwarf_die_deliv.c: Removed a statement that had no effect (A leftover of recent changes). * gennames.c: Signed vs unsigned compare was accidental in the code this generates. Changed the local var to unsigned. 2018-07-22 David Anderson * dwarf_init_finish.c: Now calls _dwarf_safe_strcpy() so we are sure there is no string overrun. * dwarf_util.c: Implements _dwarf_safe_strcpy(). * dwarf_util.h: Declares _dwarf_safe_strcpy(). 2018-07-22 David Anderson * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): Coverity CID 186884. A much cleaner and more readable fix. 2018-07-21 David Anderson * libdwarf_version.h: Updated version string. * dwarf_init_finish.c: Coverity CID 186884. Revised the logic for clarity and added comments too. * libdwarf_version.h: Update version string. * dwarf_dnames.c: Coverity CID 186887. Encapsulating DECODE_LEB128_UWORD_CK in a function so we can catch an error and free appropriate resources. Fixed cases of error where DW_DLV_OK returned. * dwarf_abbrev.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_ranges.c,dwarf_tsearchhash.c: Removed trailing whitespace. * dwarf_xu_index.c: Coverity CID 186894. We know the string length (2) so we just assign the bytes directly avoiding any possibility of overrun. * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): Coverity CID 186978. Was dereferencing a pointer after zeroing the pointer, now fixed and the obfuscating single-call function code moved to where used, deleted function. * dwarf_macro.c: Coverity CID 186980. Removed code testing for zero count as it is impossible to get to that spot with count==0. * pro_forms.c: The new return of error is now return ((Dwarf_P_Attribute) DW_DLV_BADADDR); to at least avoid a warning about this necessary uglyness of pointer/integer confusion. The dwarf reader (consumer) interfaces have none of this. 2018-07-20 David Anderson * dwarf_line_table_reader_common.h: Encapsulating DECODE_LEB128_UWORD_CK in a function so we can catch an error and free appropriate resources. 2018-07-20 David Anderson * dwarf_frame.c: Coverity CID 186901. Removed duplicate check for dbg null. * dwarf_macro5.c: Coverity CID 186890. Was testing wrong status value. resattr -> lres 2018-07-20 David Anderson * dwarf_arange.c(dwarf_get_aranges_list): Coverity CID 186976. This function has a serious problem, it reads agranges without knowing the CU version number so anything with segment_selector != 0 could be read wrong. Unless the compiler authors did in early versions what DWARF4 called for in aranges: a segment selector value. * dwarf_elf_access.c(update_entry): Coverity CID 187700. If we do not have ELF64 symbol type available avoid letting us fall through to dereference a null pointer. * dwarf_print_lines.c(dwarf_print_lines): Coverity CID 186985. Coverity CID 186973 Remove if(){} as it is not needed. * dwarf_macro.c(dwarf_get_macro_details): Coverity CID 186980. Removed dead code for count==0 as count will be at least 1. * pro_arange.c: Coverity CID 186974. Delete redundant check for null. * pro_section.c(dwarf_pro_getabbrev): Coverity CID 186983. Avoid dereferencing forms/attrs if they are null. * pro_forms.c(dwarf_add_AT_location_expr): Coverity CID 186984. Was potentially reading more from input than could possibly exist in the fixed-maximum-length input. Coverity CID 186975. Make block_size Dwarf_Unsigned to (possibly) avoid this warning. * pro_expr.c(dwarf_add_expr_gen): Coverity CID 186987. Add break; to the last case in the switch. * pro_macinfo.c(dwarf_vendor_ext): Coverity CID 186988. Coverity CIE 186981 Deleting dead code. * pro_types.c(_dwarf_transform_simplename_to_disk)): Coverity CID 186977. Delete dead code. * pro_init.c(common_init): Coverity CID 187001. Now we avoid dereferencing a potentially NULL pointer abiname. * pro_frame.c(dwarf_add_fde_inst): Coverity CID 186979. Added missing check of 'res' variable. 2018-07-20 David Anderson * libdwarf_version.h: Updated version string. * pro_frame.c: Coverity CID 186989. Dereferenced tmpaug before NULL check. Fixed. * pro_section.c: Coverity CID 186990. copy-paste error changed val_len to val_len2. * dwarf_abbrev.c: Coverity CID 186982. dwarf_get_abbrev_count() could leak Dwarf_Error. No longer can. * dwarf_print_lines.c: Coverity CID 186973. Remove useless code. * dwarf_ranges.c: Coverity CID 186909. Ensure null not dereferenced. * dwarf_dnames.c: Coverity CID 186899. If needed !firstdab, not firstdab. Also, free local allocations on error. * dwarf_dsc.c: Coverity CID 186898. Null check on wrong variable. * dwarf_tsearchhash.c: Coverity CID 186893. Leak on error fixed. * dwarf_query.c: Coverity CID 186892. Testing res, now res3. * dwarf_macro5.c: Coverity CID 186891. Dead code moved to correct place. Coverity CID 186906. Only increment curopsonly if non-null. * dwarf_dnames.c: Coverity CID 186889. Fixed leak on error. * dwarf_die_deliv.c: Coverity CID 186888. Fixed: Removed assignment overridden later. Coverity CID 186904: deref before: null check, dataptr,dis. * dwarf_frame2.c: Coverity CID 186885. Fixed: loop inappropriate. Coverity CID 186908. Fixed test res->resf. * dwarf_line_table_reader_common.h: Coverity CID 186886. Fixed leak. 2018-07-16 David Anderson * dwarf_incl.h: Refine ifdef of HAVE_STDAFX_H. * dwarf_tsearch.h: Correcting web references in comments. * pro_incl.h: Refine ifdef of HAVE_STDAFX_H. 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-07-09 David Anderson * dwarf_dnames.c: free(tmp) -> free(dab) 2018-06-19 David Anderson * configure.ac, config.h.in: Removed HAVE_NONSTANDARD_PRINTF_64_FORMAT. * configure: Regenerated. 2018-06-19 David Anderson * pro_util.h: Deleted unused sizeof_sbyte macro, simplified sizeof_ubyte to 1. 2018-06-19 David Anderson * dwarf_base_types.h,dwarf_die_deliv.c,dwarf_dnames.c, dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_init_finish.c, dwarf_loc2.h,dwarf_macro5.c,dwarf_query.c,dwarf_str_offsets.c, dwarf_util.c,pro_opaque.h: Now defining using DWARF_32BIT_SIZE DWARF_64BIT_SIZE DWARF_HALF_SIZE instead of using sizeof(Dwarf_Unsigned) or sizeof(Dwarf_Half). Making it clearer we're reading the size the standard says the items are. 2018-06-14 David Anderson * libdwarf.h.in: Simplified definitions of Dwarf_Unsigned etc and DW_PR*. 2018-06-12 David Anderson * dwarf_arange.c dwarf_base_types.h dwarf_die_deliv.c, dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_global.c, dwarf_line_table_reader_common.h,dwarf_loc.c,dwarf_macro5.c, dwarf_opaque.h,dwarf_str_offsets.c,dwarf_util.c,libdwarfdefs.h, pro_arange.c,pro_section.c,pro_types.c,pro_util.h: Now, if Dwarf_Half is not defined 16 bits it is likely that everything will still work right. We don't use sizeof(Dwarf_Half) now. 2018-06-12 David Anderson * libdwarf.h.in: Removed Dwarf_Frame_Op3 struct declaration. It was never used and was a bad idea. A functional interface is a likely replacement. 2018-05-30 David Anderson * Fix botch in revised Makefile.in. 2018-05-30 David Anderson * Makefile.in: Add gennames dependency on libdwarf_version.h * libdwarf_version.h: Create to hold the DW_VERSION_DATE_STR string. 2018-05-26 David Anderson * gennames.c: Update version string * dwarf_arange.c: Instead of load_section(dbg,.debug_info, and then *_abbrevr, call the combined _info and _abbrev function _dwarf_load_debug_info() as is done everywhere else. 2018-05-24 David Anderson * dwarf_aranges.c: Calling dwarf_get_aranges() without loading .debug_info and .debug_abbrev resulted in an error when checking for the sanity of an offset into .debug_info: DW_DLE_ARANGE_OFFSET_BAD. Now libdwarf ensures the needed sections are loaded because the 'section length' of compressed sections is only correct after such are loaded. 2018-05-17 David Anderson * config.h.in: Added #undef HAVE_VSNPRINTF HAVE_SNPRINTF * configure: regenerated. * configure.ac: Added AC_CHECK_FUNCS(snprintf) AC_CHECK_FUNCS(vsnprintf) * dwarf_alloc.c(_dwarf_free_all_of_one_debug): Added fclose of dbg->de_printf_callback_null_device_handle. * dwarf_opaque.h: Added de_printf_callback_null_device_handle Dwarf_Debug member. * dwarf_arange.c,dwarf_die_deliv.c,dwarf_frame2.c, gennames.c: Use static buffers, not on-stack char array targets for sprintf/snprintf. Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function if present, else c90 * dwarf_util.c: Putting null_device_handle in Dwarf_Debug struct Use static buffers, not on-stack char array targets for sprintf/snprintf. Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function if present, else c90. 2018-05-16 David Anderson * dwarf_leb.c, dwarf_util.c: Removed use of C99 like vsnprintf. Now using C90. 2018-05-15 David Anderson * dwarf_incl.h: Inserted include here. stddef.h defines really basic useful C90 things like NULL. * dwarf_opaque.h: Remove nested include stddef.h. 2018-05-15 David Anderson * dwarf_incl.h: Removed dwarf_alloc.h include * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_dnames.c,dwarf_dsc.c,dwarf_error.c,dwarf_form.c dwarf_frame.c, dwarf_frame2.c,dwarf_gdbindex.c,dwarf_global.c,dwarf_incl.h, dwarf_init_finish.c,dwarf_line.c,dwarf_loc.c,dwarf_macro.c, dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c,dwarf_ranges.c, dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c: Added explicit include dwarf_alloc.h. 2018-05-15 David Anderson * Makefile.in: dwarf_frame3.c now gone from build. It should be removed. Nothing in it is used. * dwarf_incl.h: Removed dwarf_error.h include * dwarf_*: put includes in local normal order and added include dwarf_error.h as needed (in many files). 2018-05-15 David Anderson * dwarf_incl.h: Removed dwarf_util.h include * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_frame2.c, dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, dwarf_loc.c,dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, dwarf_ranges.c,dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c, dwarf_string.c,dwarf_macro.c: Added include dwarf_util.h. 2018-05-15 David Anderson * dwarf_die_deliv.c,dwarf_dsc.c,dwarf_error.c, dwarf_init_finish.c,dwarf_original_elf_init.c, pro_error.c,pro_line.c: Removed the unnecessary inclusion of elf.h. * dwarf_incl.h: Removed the unnecessary inclusion of elf.h, limits.h, and dwarf_xu_index.h. 2018-05-15 David Anderson * dwarf_abbrev.c,dwarf_alloc.c,dwarf_die_deliv.c, dwarf_dsc.c,dwarf_dsc.h,dwarf_elf_access.c,dwarf_error.h, dwarf_gdbindex.h,dwarf_global.h,dwarf_groups.c, dwarf_harmless.c,dwarf_harmless.h,dwarf_leb.c,dwarf_loc.h, dwarf_loc2.h,dwarf_opaque.h,dwarf_print_lines.c, dwarf_ranges.c,dwarf_string.c,dwarf_tsearch.h, dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, dwarf_xu_index.h,pro_alloc.c,pro_die.h,pro_finish.c, pro_util.h: Removed trailing blank lines. Updated copyright year. 2018-05-15 David Anderson * dwarf_loc2.c, dwarf_line_table_reader_common.c, dwarf_errmsg_list.c: Renamed to end in .h, not .c, as these are all targets of #include. * dwarf_test_errmsg_list.c: New file with the test code extracted from dwarf_errmsg_list.c and #including the new dwarf_errmsg_list.h * Makefile.in: Renamings .c to .h and the errmsg checking builds the new dwarf_test_errmsg_list.c The -DTESTING in building dwarf_test_errmsg_list.c is no longer necessary. * dwarf_error.c, dwarf_line.c,dwarf_print_lines.c: Reflect the .c->h renamings 2018-05-14 David Anderson * libdwarf.h.in: Removed trailing whitespace. 2018-05-14 David Anderson * libdwarf2.1.mm: Documented dwarf_get_fde_info_for_reg3_b(). Refined some comments about frame data. * libdwarf2.1.pdf: Regenerated. Version 2.64 2018-05-14 David Anderson * gennames.c: Updated version string. 2018-05-14 David Anderson * dwarf_frame2.c: Do a thorough check of every non-zero augmentation data length in a way that will catch integer overflows. * dwarf_str_offsets.c: Fixed a botch in the original dwarf_dealloc in dwarf_close_str_offsets_table_access(). 2018-05-14 David Anderson * dwarf_frame.c: Implemented dwarf_get_fde_info_for_reg3_b(). * libdwarf.h.in: Fixed arg list for dwarf_get_fde_info_for_reg3_b. 2018-05-14 David Anderson * libdwarf.h.in: Declare new frame function, next commit will have the code in dwarf_frame.c. 2018-05-01 Carlos Alberto Enciso * gennames.c: Reversed the order of calling process_args() vs print_args(). There is no visible difference for linux/unix, and is just to match the convention now used in dwarfdump for the ordering. 2018-04-22 David Anderson * gennames.c: Updated version string. * libdwarf.h.in: Removed trailing comma from enumeration list. 2018-04-19 David Anderson * dwgetopt.c: Changed to match correction in dwarfdump version. 2018-04-17 David Anderson * dwgetopt.c: Changed to match correction in dwarfdump version. 2018-04-16 David Anderson * dwarf_str_offsets.c: Removed debug call to dump_bytes() * gennames.c: Updated version string. 2018-04-14 David Anderson * CMakeLists.txt: Added new source/header files to cmake. 2018-04-14 David Anderson * libdwarf2.1.mm: Complete doc on the new .debug_str_offsets interfaces. * Regenerated. Rev 2.63. 2018-04-13 David Anderson * gennames.c: Updated version string. * Makefile.in: Added dwarf_str_offsets.o to target list. * checkexamples.c: Added example code for the .debug_str_offsets section interfaces. * dwarf_alloc.h: Update ALLOC_AREA_INDEX_TABLE_MAX for new allocatable. * dwarf_alloc.c:Add #include and array entry for DW_DLA_STR_OFFSETS * libdwarf.h.in: * dwarf_errmsg_list.c: Added new .debug_str_offsets section reader error codes. * dwarf_str_offsets.h: New. Hidden struct for .debug_str_offsets interfaces. * dwarf_str_offsets.c: New for .debug_str_offsets. * libdwarf2.1.mm: Incomplete doc on the new interfaces. 2018-03-29 David Anderson * configure.ac: Now uses AC_COMPILE_IFELSE instead of AC_TRY_COMPILE. Substantial changes along those lines. * config.h.in, configure: Regenerated. 2018-03-28 David Anderson * configure.ac: Replaces configure.in and uses AC_COMPILE_IFELSE instead of the deprecated AC_TRY_COMPILE. * configure: Regenerated. * config.h.in: Regenerated 2018-03-27 David Anderson * configure.in: Cross compiling tested, working. * configure: regenerated. 2018-03-25 David Anderson * configure.in: Support for cross compiling * configure: regenerated. * Makefile.in: Support for cross compiling 2018-03-25 David Anderson * Makefile.in: Add comments about what is built for build system (as opposed to host or target). 2018-03-24 David Anderson * checkexamples.c: This is just example code for libdwarf2.1.mm, not part of libdwarf. Now checked by cc for errors and organized in the same order the examples appear in the .mm. * dwarf_errmsg_list.c: Added error code DW_DLE_LINE_HEADER_CORRUPT. * dwarf_line.c(_dwarf_set_line_table_regs_default_values): Add line-table header version number argument so the function works for DWARF5 (and earlier as well). Now uses dwarf_srclines_files_indexes() several places, simplifying the code. * dwarf_line.h: Adds new fields to Dwarf_Line_Context_s so that dwarf_srclines_files_indexes() logic is simple. * dwarf_line_table_reader_common.c: Passes version number to _dwarf_set_line_table_regs_default_values() so it works right for DWARF5 (and for earlier DWARF). * libdwarf.h.in: Added DW_DLE_LINE_HEADER_CORRUPT to error list. Added function dwarf_srclines_files_indexes(). * libdwarf2.1.mm: Rev 2.61. Document the new function dwarf_srclines_files_indexes() and update all examples for formatting and correct C. * libdwarf2.1.pdf: Regenerated, Rev 2.61. 2018-03-22 David Anderson * dwarf_line.c, dwarf_print_lines.c: Index file numbers for all versions of DWARF (DWARF5 indexes starting at 0). 2018-03-21 David Anderson * gennames.c: Updated version string. 2018-03-21 David Anderson * dwarf_elf_access.c: Allow for relocations on .debug_str_offsets. * dwarf_errmsg_list.c: Clarified meaning of DW_DLE_DIE_ABBREV_LIST_NULL, added new errors DW_DLE_STR_OFFSETS_BASE_WRONG_FORM, DW_DLE_DATA16_OUTSIDE_SECTION, DW_DLE_LNCT_MD5_WRONG_FORM * dwarf_form.c: Added support for DWARF5 new FORMs. * dwarf_line.c: Added dwarf_srclines_files_data_b() so clients needing DWARF5 line table support can get the DW_LNCT_MD5 value if it is present. * dwarf_line.h: Added support for the DWARF5 MD5 data. * dwarf_line_table_reader_common.c: Added DW_LNCT_MD5 support. * dwarf_opaque.h: Added _dwarf_extract_data16 so we do not have code duplication reading this data. * dwarf_print_lines.c: If MD5 present, we now print it. * dwarf_query.c: Correct handling of form for DW_AT_str_offsets_base. * dwarf_util.c: Add support for DWARF5 FORMs. * libdwarf.h.in: Define the values of the new DW_DLE codes mentioned above. Declare new function dwarf_srclines_files_data_b() * libdwarf2.1.mm: Document new function. Rev 2.61. * libdwarf2.1.pdf: Generated Rev 2.61 2018-01-05 David Anderson * dwarf_macro5.c(_dwarf_get_macro_ops_count_internal): A test duplicated the preceding loop condition so the body of the test was dead code. Removed the dead code. 2018-01-29 David Anderson * dwarf_arange.c: Improve and comment checks for stepping off the end of arange data. * dwarf_die_deliv.c: Make an error code returned a bit more specific. DW_DLA_DIE_BAD becomes DW_DLE_ABBREV_MISSING. * dwarf_errmsg_list.c: Added new error codes DW_DLE_ABBREV_MISSING DW_DLE_NO_TAG_FOR_DIE DW_DLE_LOWPC_WRONG_CLASS DW_DLE_HIGHPC_WRONG_FORM. * dwarf_form.c: Used DW_DLE_NO_TAG_FOR_DIE instead of DW_DLA_DIE_BAD to make an error return more specific. * dwarf_frame2.c: Add new checks for corrupted dwarf frame data. * dwarf_query.c: Added error check and changed DW_DLE_DIE_BAD to DW_DLE_ABBREV_MISSING in one place. Other DWARF corruption checks and error refinements added. * libdwarf.h.in: Added the defines for the new DW_DLE codes. 2018-01-29 David Anderson * gennames.c: Update version string. libdwarf-20210528/libdwarf/dwarf_elf_rel_detector.c0000664000175000017500000002126313764007262017131 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include "dwarf_elf_defines.h" #include "dwarf_elf_rel_detector.h" unsigned _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine) { unsigned r = 0; switch (machine) { #if defined(EM_MIPS) && defined (R_MIPS_32) case EM_MIPS: r = (0 #if defined (R_MIPS_32) | (type == R_MIPS_32) #endif #if defined (R_MIPS_TLS_DTPREL32) | (type == R_MIPS_TLS_DTPREL32) #endif /* DTPREL32 */ ); break; #endif /* MIPS case */ #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32) case EM_SPARC32PLUS: r = (0 #if defined(R_SPARC_UA32) | (type == R_SPARC_UA32) #endif #if defined(R_SPARC_TLS_DTPOFF32) | (type == R_SPARC_TLS_DTPOFF32) #endif ); break; #endif #if defined(EM_SPARCV9) && defined (R_SPARC_UA32) case EM_SPARCV9: r = (type == R_SPARC_UA32); break; #endif #if defined(EM_SPARC) && defined (R_SPARC_UA32) case EM_SPARC: r = (0 #if defined(R_SPARC_UA32) | (type == R_SPARC_UA32) #endif #if (R_SPARC_TLS_DTPOFF32) | (type == R_SPARC_TLS_DTPOFF32) #endif ); break; #endif /* EM_SPARC */ #if defined(EM_386) && defined (R_386_32) && defined (R_386_PC32) case EM_386: r = (0 #if defined (R_386_32) | (type == R_386_32) #endif #if defined (R_386_GOTPC) | (type == R_386_GOTPC) #endif #if defined (R_386_PC32) | (type == R_386_PC32) #endif #if defined (R_386_TLS_LDO_32) | (type == R_386_TLS_LDO_32) #endif #if defined (R_386_TLS_DTPOFF32) | (type == R_386_TLS_DTPOFF32) #endif ); break; #endif /* EM_386 */ #if defined (EM_SH) && defined (R_SH_DIR32) case EM_SH: r = (0 #if defined (R_SH_DIR32) | (type == R_SH_DIR32) #endif #if defined (R_SH_DTPOFF32) | (type == R_SH_TLS_DTPOFF32) #endif ); break; #endif /* SH */ #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) case EM_IA_64: /* 32bit? ! */ r = (0 #if defined (R_IA64_SECREL32LSB) | (type == R_IA64_SECREL32LSB) #endif #if defined (R_IA64_DIR32LSB) | (type == R_IA64_DIR32LSB) #endif #if defined (R_IA64_DTPREL32LSB) | (type == R_IA64_DTPREL32LSB) #endif ); break; #endif /* EM_IA_64 */ #if defined(EM_ARM) && defined (R_ARM_ABS32) case EM_ARM: case EM_AARCH64: r = (0 #if defined (R_ARM_ABS32) | ( type == R_ARM_ABS32) #endif #if defined (R_AARCH64_ABS32) | ( type == R_AARCH64_ABS32) #endif #if defined (R_ARM_TLS_LDO32) | ( type == R_ARM_TLS_LDO32) #endif ); break; #endif /* EM_ARM */ /* On FreeBSD xR_PPC64_ADDR32 not defined so we use the xR_PPC_ names which have the proper value. Our headers have: xR_PPC64_ADDR64 38 xR_PPC_ADDR32 1 so we use this one xR_PPC64_ADDR32 R_PPC_ADDR32 xR_PPC64_DTPREL32 110 which may be wrong/unavailable xR_PPC64_DTPREL64 78 xR_PPC_DTPREL32 78 */ #if defined(EM_PPC64) && defined (R_PPC_ADDR32) case EM_PPC64: r = (0 #if defined(R_PPC_ADDR32) | (type == R_PPC_ADDR32) #endif #if defined(R_PPC64_DTPREL32) | (type == R_PPC64_DTPREL32) #endif ); break; #endif /* EM_PPC64 */ #if defined(EM_PPC) && defined (R_PPC_ADDR32) case EM_PPC: r = (0 #if defined (R_PPC_ADDR32) | (type == R_PPC_ADDR32) #endif #if defined (R_PPC_DTPREL32) | (type == R_PPC_DTPREL32) #endif ); break; #endif /* EM_PPC */ #if defined(EM_S390) && defined (R_390_32) case EM_S390: r = (0 #if defined (R_390_32) | (type == R_390_32) #endif #if defined (R_390_TLS_LDO32) | (type == R_390_TLS_LDO32) #endif ); break; #endif /* EM_S390 */ #if defined(EM_X86_64) && \ ( defined(R_X86_64_32) || defined(R_X86_64_PC32) ||\ defined(R_X86_64_DTPOFF32) ) #if defined(EM_K10M) case EM_K10M: #endif #if defined(EM_L10M) case EM_L10M: #endif case EM_X86_64: r = (0 #if defined (R_X86_64_PC32) | (type == R_X86_64_PC32) #endif #if defined (R_X86_64_32) | (type == R_X86_64_32) #endif #if defined (R_X86_64_DTPOFF32) | (type == R_X86_64_DTPOFF32) #endif ); break; #endif /* EM_X86_64 */ case EM_QUALCOMM_DSP6: r = (type == R_QUALCOMM_REL32); break; } return r; } unsigned _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine) { unsigned r = 0; switch (machine) { #if defined(EM_MIPS) && defined (R_MIPS_64) case EM_MIPS: r = (0 #if defined (R_MIPS_64) | (type == R_MIPS_64) #endif #if defined (R_MIPS_32) | (type == R_MIPS_32) #endif #if defined(R_MIPS_TLS_DTPREL64) | (type == R_MIPS_TLS_DTPREL64) #endif ); break; #endif /* EM_MIPS */ #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64) case EM_SPARC32PLUS: r = (type == R_SPARC_UA64); break; #endif #if defined(EM_SPARCV9) && defined (R_SPARC_UA64) case EM_SPARCV9: r = (0 #if defined (R_SPARC_UA64) | (type == R_SPARC_UA64) #endif #if defined (R_SPARC_TLS_DTPOFF64) | (type == R_SPARC_TLS_DTPOFF64) #endif ); break; #endif #if defined(EM_SPARC) && defined (R_SPARC_UA64) case EM_SPARC: r = (0 #if defined(R_SPARC_UA64) | (type == R_SPARC_UA64) #endif #if defined (R_SPARC_TLS_DTPOFF64) | (type == R_SPARC_TLS_DTPOFF64) #endif ); break; #endif /* EM_SPARC */ #if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB) case EM_IA_64: /* 64bit */ r = (0 #if defined (R_IA64_SECREL64LSB) | (type == R_IA64_SECREL64LSB) #endif #if defined (R_IA64_SECREL32LSB) | (type == R_IA64_SECREL32LSB) #endif #if defined (R_IA64_DIR64LSB) | (type == R_IA64_DIR64LSB) #endif #if defined (R_IA64_DTPREL64LSB) | (type == R_IA64_DTPREL64LSB) #endif #if defined (R_IA64_REL32LSB) | (type == R_IA64_REL32LSB) #endif ); break; #endif /* EM_IA_64 */ #if defined(EM_PPC64) && defined (R_PPC64_ADDR64) case EM_PPC64: r = (0 #if defined(R_PPC64_ADDR64) | (type == R_PPC64_ADDR64) #endif #if defined(R_PPC64_DTPREL64) | (type == R_PPC64_DTPREL64) #endif ); break; #endif /* EM_PPC64 */ #if defined(EM_S390) && defined (R_390_64) case EM_S390: r = (0 #if defined(R_390_64) | (type == R_390_64) #endif #if defined(R_390_TLS_LDO64) | (type == R_390_TLS_LDO64) #endif ); break; #endif /* EM_390 */ #if defined(EM_X86_64) && defined (R_X86_64_64) #if defined(EM_K10M) case EM_K10M: #endif #if defined(EM_L10M) case EM_L10M: #endif case EM_X86_64: r = (0 #if defined (R_X86_64_64) | (type == R_X86_64_64) #endif #if defined (R_X86_64_PC64) | (type == R_X86_64_PC64) #endif #if defined (R_X86_64_DTPOFF32) | (type == R_X86_64_DTPOFF64) #endif ); break; #endif /* EM_X86_64 */ #if defined(EM_AARCH64) && defined (R_AARCH64_ABS64) case EM_AARCH64: r = (0 #if defined (R_AARCH64_ABS64) | ( type == R_AARCH64_ABS64) #endif ); break; #endif /* EM_AARCH64 */ } return r; } libdwarf-20210528/libdwarf/dwarf_original_elf_init.c0000664000175000017500000001554213764007262017310 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2011-2020 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif #endif #include #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_elf_access.h" #include "dwarf_object_detector.h" #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* New March 2017 */ int dwarf_elf_init_b( #ifndef DWARF_WITH_LIBELF UNUSEDARG dwarf_elf_handle elf_file_pointer, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG unsigned group_number, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug * ret_dbg, #else dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, #endif /* DWARF_WITH_LIBELF */ Dwarf_Error * error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ Dwarf_Obj_Access_Interface *binary_interface = 0; int res = DW_DLV_OK; int localerrnum = 0; int libdwarf_owns_elf = FALSE; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR); } if (access != DW_DLC_READ) { DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); } /* This allocates and fills in *binary_interface. */ res = dwarf_elf_object_access_init( elf_file_pointer, libdwarf_owns_elf, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } /* allocates and initializes Dwarf_Debug */ res = dwarf_object_init_b(binary_interface, errhand, errarg, group_number, ret_dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } (*ret_dbg)->de_using_libelf = TRUE; res = dwarf_add_debuglink_global_path(*ret_dbg, "/usr/lib/debug",error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } /* DBG known */ return res; #endif /* DWARF_WITH_LIBELF */ } int dwarf_elf_init( #ifndef DWARF_WITH_LIBELF UNUSEDARG dwarf_elf_handle elf_file_pointer, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug * ret_dbg, #else dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, #endif Dwarf_Error * error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ int res = 0; res = dwarf_elf_init_b(elf_file_pointer, DW_GROUPNUMBER_ANY, access,errhand,errarg,ret_dbg,error); return res; #endif /* DWARF_WITH_LIBELF */ } int _dwarf_elf_setup( #ifndef DWARF_WITH_LIBELF UNUSEDARG int fd, UNUSEDARG char *path, UNUSEDARG unsigned ftype, UNUSEDARG unsigned endian, UNUSEDARG unsigned offsetsize, UNUSEDARG size_t filesize, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG unsigned groupnumber, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug *dbg, #else int fd, UNUSEDARG char *path, UNUSEDARG unsigned ftype, UNUSEDARG unsigned endian, UNUSEDARG unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg, #endif /* DWARF_WITH_LIBELF */ Dwarf_Error *error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ Elf_Cmd what_kind_of_elf_read = ELF_C_READ; Dwarf_Obj_Access_Interface *binary_interface = 0; int res = DW_DLV_OK; int localerrnum = 0; int libdwarf_owns_elf = TRUE; dwarf_elf_handle elf_file_pointer = 0; elf_version(EV_CURRENT); elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0); if (elf_file_pointer == NULL) { DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); } /* Sets up elf access function pointers. */ res = dwarf_elf_object_access_init( elf_file_pointer, libdwarf_owns_elf, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } /* allocates and initializes Dwarf_Debug */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } (*dbg)->de_filesize = filesize; (*dbg)->de_using_libelf = TRUE; res = dwarf_add_debuglink_global_path(*dbg, "/usr/lib/debug",error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); } return res; #endif /* DWARF_WITH_LIBELF */ } libdwarf-20210528/libdwarf/libdwarf2p.1.mm0000664000175000017500000045456314003660063015033 00000000000000\." $Revision: 1.12 $ \." $Date: 2002/01/14 23:40:11 $ \." \." \." the following line may be removed if the ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." Increment body point size .S +2 \." ============================================== \." Put current date in the following at each rev .ds vE Rev 1.53, 25 January 2021 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 3 .SA 1 .TL A Producer Library Interface to DWARF .AF "" .AU "David Anderson" .PF "'\*(vE '- \\\\nP -''" .AS 1 This document describes an interface to a library of functions to create DWARF debugging information entries and DWARF line number information. It does not make recommendations as to how the functions described in this document should be implemented nor does it suggest possible optimizations. .P The document is oriented to creating DWARF version 2. Support for creating DWARF3 and DWARF4 and DWARF5 is only partial: various features since DWARF2 cannot be created. .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" This document describes an interface to \f(CWlibdwarf\fP, a library of functions to provide creation of DWARF debugging information records, DWARF line number information, DWARF address range and pubnames information, weak names information, and DWARF frame description information. .H 2 "Copyright" Copyright 1993-2006 Silicon Graphics, Inc. Copyright 2007-2021 David Anderson. Permission is hereby granted to copy or republish or use any or all of this document without restriction except that when publishing more than a small amount of the document please acknowledge Silicon Graphics, Inc and David Anderson. This document is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .H 2 "Purpose and Scope" The purpose of this document is to propose a library of functions to create DWARF debugging information. Reading (consuming) of such records is discussed in a separate document. The functions in this document have mostly been implemented at Silicon Graphics and used by the SGI code generator to provide debugging information. Some functions (and support for some extensions) were provided by Sun Microsystems. Example code showing one use of the functionality may be found in the dwarfgen \f(CWdwarfgen\fP and \f(CWsimpleexample\fP application (provided in the source distribution along with libdwarf). .P The focus of this document is the functional interface, and as such, implementation and optimization issues are intentionally ignored. .P Error handling, error codes, and certain \f(CWLibdwarf\fP codes are discussed in the "\fIA Consumer Library Interface to DWARF\fP", which should be read before reading this document. .P Before December 2018 very few functions in the Producer Library follow the error-returns as defined in "\fIA Consumer Library Interface to DWARF\fP". .P As of December 2018 every Producer Library call has a version that supports that Consumer Library Interface and returns DW_DLV_OK or DW_DLV_ERROR (the Producer Library has no use of DW_DLV_NO_ENTRY). The table of contents of this document lists the latest version of each function. However, all the earlier documentation is present here immediately following the documentation of the latest, and preferred, interface. All the earlier interfaces are supported in the library. .P Early interfaces (before December 2018) The general style of functions here in the producer library is rather C-traditional with various types as return values (quite different from the consumer library interfaces). The style generally follows the style of the original DWARF1 reader proposed as an interface to DWARF. When the style of the reader interfaces was changed (1994) in the dwarf reader ( See the "Document History" section of "A Consumer Library Interface to DWARF") the interfaces here were not changed as it seemed like too much of a change for the two applications then using the interface! So this interface remains in the traditional C style of returning various data types with various (somewhat inconsistent) means of indicating failure. .P December 2018 and later function interfaces all return either DW_DLV_OK or DW_DLV_ERROR in a simple int. .P The error handling code in the library may either return a value or abort. The library user can provide a function that the producer code will call on errors (which would allow callers avoid testing for error returns if the user function exits or aborts). See the \f(CWdwarf_producer_init()\fP description below for more details. .H 2 "Document History" This document originally prominently referenced "UNIX International Programming Languages Special Interest Group " (PLSIG). Both UNIX International and the affiliated Programming Languages Special Interest Group are defunct (UNIX is a registered trademark of UNIX System Laboratories, Inc. in the United States and other countries). Nothing except the general interface style is actually related to anything shown to the PLSIG (this document was open sourced with libdwarf in the mid 1990's). .P See "http://www.dwarfstd.org" for information on current DWARF standards and committee activities. .H 2 "Definitions" DWARF debugging information entries (DIEs) are the segments of information placed in the \f(CW.debug_info\fP and related sections by compilers, assemblers, and linkage editors that, in conjunction with line number entries, are necessary for symbolic source-level debugging. Refer to the document "\fIDWARF Debugging Information Format\fP" from UI PLSIG for a more complete description of these entries. .P This document adopts all the terms and definitions in "\fIDWARF Debugging Information Format\fP" version 2. and the "\fIA Consumer Library Interface to DWARF\fP". .P In addition, this document refers to Elf, the ATT/USL System V Release 4 object format. This is because the library was first developed for that object format. Hopefully the functions defined here can easily be applied to other object formats. .H 2 "Overview" The remaining sections of this document describe a proposed producer (compiler or assembler) interface to \fILibdwarf\fP, first by describing the purpose of additional types defined by the interface, followed by descriptions of the available operations. This document assumes you are thoroughly familiar with the information contained in the \fIDWARF Debugging Information Format\fP document, and "\fIA Consumer Library Interface to DWARF\fP". .P The interface necessarily knows a little bit about the object format (which is assumed to be Elf). We make an attempt to make this knowledge as limited as possible. For example, \fILibdwarf\fP does not do the writing of object data to the disk. The producer program does that. .H 2 "Revision History" .VL 15 .LI "March 1993" Work on dwarf2 sgi producer draft begins .LI "March 1999" Adding a function to allow any number of trips through the dwarf_get_section_bytes() call. .LI "April 10 1999" Added support for assembler text output of dwarf (as when the output must pass through an assembler). Revamped internals for better performance and simpler provision for differences in ABI. .LI "Sep 1, 1999" Added support for little- and cross- endian debug info creation. .LI "May 7 2007" This library interface now cleans up, deallocating all memory it uses (the application simply calls dwarf_producer_finish(dbg)). .LI "September 20 2010" Now documents the marker feature of DIE creation. .LI "May 01 2014" The dwarf_producer_init() code has a new interface and DWARF is configured at run time by its arguments. The producer code used to be configured at configure time, but the configure time producer configure options are no longer used. The configuration was unnecessarily complicated: the run-time configuration is simpler to understand. .LI "September 10, 2016" Beginning the process of creating new interfaces so that checking for error is consistent across all calls (as is done in the consumer library). The old interfaces are kept and supported so we have binary and source compatibility with old code. .LI "December 01, 2018" All function interfaces now have a version that returns only DW_DLV_OK or DW_DLV_ERROR and pointer and other values are returned through pointer arguments. For example, dwarf_add_frame_info_c() is the December 2018 version, while dwarf_add_frame_info(), dwarf_add_frame_info_b() are earlier versions (which are still supported). .LI "July 14, 2020" To enable testing of reading the DWARF5 section .debug_sup the new function dwarf_add_debug_sup() is added. dwarfgen can call this function, though dwarfgen presently only fills out a bogus .debug_sup section to enable simple testing. .LI "January 25, 2021" dwarf_add_AT_block_a() now also supports the DWARF5 form DW_FORM_exprloc. .LE .H 1 "Type Definitions" .H 2 "General Description" The \fIlibdwarf.h\fP header file contains typedefs and preprocessor definitions of types and symbolic names used to reference objects of \fI Libdwarf \fP . The types defined by typedefs contained in \fI libdwarf.h\fP all use the convention of adding \fI Dwarf_ \fP as a prefix to indicate that they refer to objects used by Libdwarf. The prefix \fI Dwarf_P_\fP is used for objects referenced by the \fI Libdwarf\fP Producer when there are similar but distinct objects used by the Consumer. .H 2 "Namespace issues" Application programs should avoid creating names beginning with \f(CWDwarf_\fP \f(CWdwarf_\fP or \f(CWDW_\fP as these are reserved to dwarf and libdwarf. .H 1 "libdwarf and Elf and relocations" Much of the description below presumes that Elf is the object format in use. The library is probably usable with other object formats that allow arbitrary sections to be created. The library does not write anything to disk. Instead it provides access so that callers can do that. .H 2 "binary or assembler output" With \f(CWDW_DLC_STREAM_RELOCATIONS\fP (see below) it is assumed that the calling app will simply write the streams and relocations directly into an Elf file, without going through an assembler. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the calling app must either A) generate binary relocation streams and write the generated debug information streams and the relocation streams direct to an elf file or B) generate assembler output text for an assembler to read and produce an object file. With case B) the libdwarf-calling application must use the relocation information to change points of each binary stream into references to symbolic names. It is necessary for the assembler to be willing to accept and generate relocations for references from arbitrary byte boundaries. For example: .sp .nf .in +4 .data 0a0bcc #producing 3 bytes of data. .word mylabel #producing a reference .word endlabel - startlabel #producing absolute length .in -4 .fi .sp .H 2 "libdwarf relationship to Elf" When the documentation below refers to 'an elf section number' it is really only dependent on getting (via the callback function passed by the caller of \f(CWdwarf_producer_init()\fP. a sequence of integers back (with 1 as the lowest). When the documentation below refers to 'an Elf symbol index' it is really dependent on Elf symbol numbers only if \f(CWDW_DLC_STREAM_RELOCATIONS\fP are being generated (see below). With \f(CWDW_DLC_STREAM_RELOCATIONS\fP the library is generating Elf relocations and the section numbers in binary form so the section numbers and symbol indices must really be Elf (or elf-like) numbers. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the values passed as symbol indexes can be any integer set or even pointer set. All that libdwarf assumes is that where values are unique they get unique values. Libdwarf does not generate any kind of symbol table from the numbers and does not check their uniqueness or lack thereof. .H 2 "libdwarf and relocations" With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP libdwarf creates binary streams of debug information and arrays of relocation information describing the necessary relocation. The Elf section numbers and symbol numbers appear nowhere in the binary streams. Such appear only in the relocation information and the passed-back information from calls requesting the relocation information. As a consequence, the 'symbol indices' can be any pointer or integer value as the caller must arrange that the output deal with relocations. With \f(CWDW_DLC_STREAM_RELOCATIONS\fP all the relocations are directly created by libdwarf as binary streams (libdwarf only creates the streams in memory, it does not write them to disk). .H 2 "symbols, addresses, and offsets" The following applies to calls that pass in symbol indices, addresses, and offsets, such as \f(CWdwarf_add_AT_targ_address_c() \fP \f(CWdwarf_add_arange_b()\fP and \f(CWdwarf_add_frame_fde_c()\fP. With \f(CWDW_DLC_STREAM_RELOCATIONS\fP a passed in address is one of: a) a section offset and the (non-global) symbol index of a section symbol. b) A symbol index (global symbol) and a zero offset. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the same approach can be used, or, instead, a passed in address may be c) a symbol handle and an offset. In this case, since it is up to the calling app to generate binary relocations (if appropriate) or to turn the binary stream into a text stream (for input to an assembler, if appropriate) the application has complete control of the interpretation of the symbol handles. .H 1 "Memory Management" Several of the functions that comprise the \fILibdwarf\fP producer interface dynamically allocate values and some return pointers to those spaces. The dynamically allocated spaces can not be reclaimed (and must not be freed) except that all such libdwarf-allocated memory is freed by \f(CWdwarf_producer_finish_a(dbg)\fP or \f(CWdwarf_producer_finish(dbg)\fP. All data for a particular \f(CWDwarf_P_Debug\fP descriptor is separate from the data for any other \f(CWDwarf_P_Debug\fP descriptor in use in the library-calling application. .H 2 "Read Only Properties" The read-only properties specified in the consumer interface document do not generally apply to the functions described here. .H 2 "Storage Deallocation" Calling \f(CWdwarf_producer_finish_a(dbg)\fP frees all the space, and invalidates all pointers returned from \f(CWLibdwarf\fP functions on or descended from \f(CWdbg\fP). .H 2 "Error Handling" In general any error detected by the producer should be considered fatal. That is, it is impossible to produce correct output so producing anything seems questionable. .P The original producer interfaces tended to return a pointer or a large integer as a result and required the caller to cast that value to determine if it was actually a -1 meaning there was an error. .P Beginning in September 2016 additional interfaces are being added to eliminate the necessity for callers to do this ugly casting of results. In December 2018 that process has reached completion. The revised functions return \f(CWDW_DLV_OK\fP, or \f(CWDW_DLV_ERROR\fP. (which are small signed integers) and will have an additional pointer argument that will provide the value that used to be the return value. This will make the interfaces type-safe. .P The function \f(CWdwarf_get_section_bytes_a()\fP can also return \f(CWDW_DLV_NO_ENTRY\fP. .P The original interfaces will remain. Binary and source compatibility for old code using the older interfaces is retained. .H 1 "Functional Interface" This section describes the functions available in the \fILibdwarf\fP library. Each function description includes its definition, followed by a paragraph describing the function's operation. .P The following sections describe these functions. .P The functions may be categorized into groups: \fIinitialization and termination operations\fP, \fIdebugging information entry creation\fP, \fIElf section callback function\fP, \fIattribute creation\fP, \fIexpression creation\fP, \fIline number creation\fP, \fIfast-access (aranges) creation\fP, \fIfast-access (pubnames) creation\fP, \fIfast-access (weak names) creation\fP, \fImacro information creation\fP, \fIlow level (.debug_frame) creation\fP, and \fIlocation list (.debug_loc) creation\fP. .P .H 2 "Initialization and Termination Operations" These functions setup \f(CWLibdwarf\fP to accumulate debugging information for an object, usually a compilation-unit, provided by the producer. The actual addition of information is done by functions in the other sections of this document. Once all the information has been added, functions from this section are used to transform the information to appropriate byte streams, and help to write out the byte streams to disk. Typically then, a producer application would create a \f(CWDwarf_P_Debug\fP descriptor to gather debugging information for a particular compilation-unit using \f(CWdwarf_producer_init()\fP. The producer application would use this \f(CWDwarf_P_Debug\fP descriptor to accumulate debugging information for this object using functions from other sections of this document. Once all the information had been added, it would call \f(CWdwarf_transform_to_disk_form()\fP to convert the accumulated information into byte streams in accordance with the \f(CWDWARF\fP standard. The application would then repeatedly call \f(CWdwarf_get_section_bytes_a()\fP for each of the \f(CW.debug_*\fP created. This gives the producer information about the data bytes to be written to disk. At this point, the producer would release all resource used by \f(CWLibdwarf\fP for this object by calling \f(CWdwarf_producer_finish_a()\fP. It is also possible to create assembler-input character streams from the byte streams created by this library. This feature requires slightly different interfaces than direct binary output. The details are mentioned in the text. .H 3 "dwarf_producer_init()" .DS \f(CWint dwarf_producer_init( Dwarf_Unsigned flags, Dwarf_Callback_Func func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void * user_data const char *isa_name, const char *dwarf_version, const char *extra, Dwarf_P_Debug *dbg_returned, Dwarf_Error *error) \fP .DE .P The function \f(CWdwarf_producer_init() \fP returns a new \f(CWDwarf_P_Debug\fP descriptor that can be used to add \f(CWDwarf\fP information to the object. On success it returns \f(CWDW_DLV_OK\fP. On error it returns \f(CWDW_DLV_ERROR\fP. \f(CWflags\fP determine whether the target object is 64-bit or 32-bit. \f(CWfunc\fP is a pointer to a function called-back from \f(CWLibdwarf\fP whenever \f(CWLibdwarf\fP needs to create a new object section (as it will for each .debug_* section and related relocation section). .P The \f(CWflags\fP values (to be OR'd together in the flags field in the calling code) are as follows: .in +4 \f(CWDW_DLC_WRITE\fP is required. The values \f(CWDW_DLC_READ\fP \f(CWDW_DLC_RDWR\fP are not supported by the producer and must not be passed. The flag bit \f(CWDW_DLC_POINTER64\fP (or \f(CWDW_DLC_SIZE_64\fP) Indicates the target has a 64 bit (8 byte) address size. The flag bit \f(CWDW_DLC_POINTER32\fP (or \f(CWDW_DLC_SIZE_32\fP) Indicates the target has a 32 bit (4 byte) address size. If none of these pointer sizes is passed in \f(CWDW_DLC_POINTER32\fP is assumed. The flag bit \f(CWDW_DLC_OFFSET32\fP indicates that 32bit offsets should be used in the generated DWARF. The flag bit \f(CWDW_DLC_OFFSET64\fP \f(CWDW_DLC_OFFSET_SIZE_64\fP indicates that 64bit offsets should be used in the generated DWARF. The flag bit \f(CWDW_DLC_IRIX_OFFSET64\fP indicates that the generated DWARF should use the early (pre DWARF3) IRIX method of generating 64 bit offsets. In this case \f(CWDW_DLC_POINTER64\fP should also be passed in, and the \f(CWisa_name\fP passed in (see below) should be "irix". If \f(CWDW_DLC_TARGET_BIGENDIAN\fP or \f(CWDW_DLC_TARGET_LITTLEENDIAN\fP is not ORed into \f(CWflags\fP then endianness the same as the host is assumed. If both \f(CWDW_DLC_TARGET_LITTLEENDIAN\fP and \f(CWDW_DLC_TARGET_BIGENDIAN\fP are OR-d in it is an error. Either one of two output forms is specifiable: \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP . The default is \f(CWDW_DLC_STREAM_RELOCATIONS\fP . The \f(CWDW_DLC_STREAM_RELOCATIONS\fP are relocations in a binary stream (as used in a MIPS/IRIX Elf object). The \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP are the same relocations but expressed in an array of structures defined by libdwarf, which the caller of the relevant function (see below) must deal with appropriately. This method of expressing relocations allows the producer-application to easily produce assembler text output of debugging information. When \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP is ORed into \f(CWflags\fP then relocations are returned not as streams but through an array of structures. .in -4 .P The function \f(CWfunc\fP must be provided by the user of this library. Its prototype is: .DS \f(CWtypedef int (*Dwarf_Callback_Func)( char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_index, void * user_data, int* error) \fP .DE For each section in the object file that \f(CWlibdwarf\fP needs to create, it calls this function once (calling it from \f(CWdwarf_transform_to_disk_form()\fP), passing in the section \f(CWname\fP, the section \f(CWtype\fP, the section \f(CWflags\fP, the \f(CWlink\fP field, and the \f(CWinfo\fP field. For an Elf object file these values should be appropriate Elf section header values. For example, for relocation callbacks, the \f(CWlink\fP field is supposed to be set (by the app) to the index of the symtab section (the link field passed through the callback must be ignored by the app). And, for relocation callbacks, the \f(CWinfo\fP field is passed as the elf section number of the section the relocations apply to. .P The \f(CWsect_name_index\fP field is a field you use to pass a symbol index back to libdwarf. In Elf, each section gets an elf symbol table entry so that relocations have an address to refer to (relocations rely on addresses in the Elf symbol table). You will create the Elf symbol table, so you have to tell libdwarf the index to put into relocation records for the section newly defined here. .P On success the user function should return the Elf section number of the newly created Elf section. .P On success, the function should also set the integer pointed to by \f(CWsect_name_index\fP to the Elf symbol number assigned in the Elf symbol table of the new Elf section. This symbol number is needed with relocations dependent on the relocation of this new section. .P Use the \f(CWdwarf_producer_init_c()\fP interface instead of this interface. .P For example, the \f(CW.debug_line\fP section's third data element (in a compilation unit) is the offset from the beginning of the \f(CW.debug_info\fP section of the compilation unit entry for this \f(CW.debug_line\fP set. The relocation entry in \f(CW.rel.debug_line\fP for this offset must have the relocation symbol index of the symbol \f(CW.debug_info\fP returned by the callback of that section-creation through the pointer \f(CWsect_name_index\fP. .P On failure, the function should return -1 and set the \f(CWerror\fP integer to an error code. .P Nothing in libdwarf actually depends on the section index returned being a real Elf section. The Elf section is simply useful for generating relocation records. Similarly, the Elf symbol table index returned through the \f(CWsect_name_index\fP must be an index that can be used in relocations against this section. The application will probably want to note the values passed to this function in some form, even if no Elf file is being produced. .P \f(CWerrhand\fP is a pointer to a function that will be used as a default fall-back function for handling errors detected by \f(CWLibdwarf\fP. .P \f(CWerrarg\fP is the default error argument used by the function pointed to by \f(CWerrhand\fP. .P For historical reasons the error handling is complicated and the following three paragraphs describe the three possible scenarios when a producer function detects an error. In all cases a short error message is printed on stdout if the error number is negative (as all such should be, see libdwarf.h). Then further action is taken as follows. .P First, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is non-null the \f(CWerrhand\fP argument here is ignored in that call and the specific producer function sets the Dwarf_Error and returns some specific value (for dwarf_producer_init it is DW_DLV_OK as mentioned just above) indicating there is an error. .P Second, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is NULL and the \f(CWerrarg\fP to \f(CWdwarf_producer_init()\fP is non-NULL then on an error in the producer code the Dwarf_Handler function is called and if that called function returns the producer code returns a specific value (for dwarf_producer_init it is DW_DLV_OK as mentioned just above) indicating there is an error. .P Third, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is NULL and the \f(CWerrarg\fP to \f(CWdwarf_producer_init()\fP is NULL then on an error \f(CWabort()\fP is called. .P The \f(CWuser_data\fP argument is not examined by libdwarf. It is passed to user code in all calls by libdwarf to the \f(CWDwarf_Callback_Func()\fP function and may be used by consumer code for the consumer's own purposes. Typical uses might be to pass in a pointer to some user data structure or to pass an integer that somehow is useful to the libdwarf-using code. .P The \f(CWisa_name\fP argument must be non-null and contain one of the strings defined in the isa_relocs array in pro_init.c: "irix","mips","x86", "x86_64","arm","arm64","ppc","ppc64", "sparc". The names are not strictly ISA names (nor ABI names) but a hopefully-meaningful mixing of the concepts of ISA and ABI. The intent is mainly to define relocation codes applicable to DW_DLC_STREAM_RELOCATIONS. New \f(CWisa_name\fP values will be provided as users request. In the "irix" case a special relocation is defined so a special CIE reference field can be created (if and only if the augmentation string is "z"). .P The \f(CWdwarf_version\fP argument should be one of "V2", "V3", "V4", "V5" to indicate which DWARF version is the overall format to be emitted. Individual section version numbers will obey the standard for that overall DWARF version. .P The \f(CWextra\fP argument is supports a comma-separated list of options. Passing in a null pointer or an empty string is acceptable if no such options are needed or used. All-lowercase option names are reserved to the libdwarf implementation itself (specific implementations may want to use a leading upper-case letter for additional options). .P The available options are .DS "default_is_stmt", "address_size", "minimum_instruction_length", "maximum_operations_per_instruction", "opcode_base", "line_base", "line_range", "linetable_version", "segment_selector_size", and "segment_size". .DE .P For example, to set the line-table generation default value of is_stmt to 0 pass in .DS "default_is_stmt=0". .DE To also set the minimum_instruction_length used in calculating line table address-advance values to one one would pass in .DS "default_is_stmt=0,minimum_instruction_length=1". .DE It's appropriate to add .DS "opcode_base=13" .DE for DWARF3 through DWARF5. All these default to something, but the something depends on environment what macro names are set by the environment or a just constants which makes it difficult to alter these values. See pro_line.h for the use of line-table related constants (which will vary depending on the target ISA and ABI and compilers). .P The \f(CWerror\fP argument is set through the pointer to return specific error if \f(CWerror\fP is non-null and and there is an error. The error details will be passed back through this pointer argument. .H 3 "dwarf_pro_set_default_string_form()" .DS \f(CWint dwarf_pro_set_default_string_form( Dwarf_P_Debug *dbg, int desired_form, Dwarf_Error *error) \fP .DE .P The function \f(CWdwarf_pro_set_default_string_form()\fP sets the \f(CWDwarf_P_Debug\fP descriptor to favor one of the two allowed values: \f(CWDW_FORM_string\fP (the default) or \f(CWDW_FORM_strp\fP. .P When \f(CWDW_FORM_strp\fP is selected very short names will still use form \f(CWDW_FORM_string\fP . .P The function should be called immediately after a successful call to \f(CWdwarf_producer_init()\fP. .P Strings for \f(CWDW_FORM_strp\fP are not duplicated in the \f(CW.debug_str\fP section: each unique string appears exactly once. .P On success it returns \f(CWDW_DLV_OK\fP. On error it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_transform_to_disk_form_a()" .DS \f(CWint dwarf_transform_to_disk_form_a( Dwarf_P_Debug dbg, Dwarf_Signed *chunk_count_out, Dwarf_Error* error)\fP .DE New September 2016. The function \f(CWdwarf_transform_to_disk_form_a()\fP is new in September 2016. It produces the same result as \f(CWdwarf_transform_to_disk_form()\fP but returns the count through the new pointer argument \f(CWchunk_count_out\fP . .P On success it returns \f(CWDW_DLV_OK\fP and sets \f(CWchunk_count_out\fP to the number of chunks of section data to be accessed by \f(CWdwarf_get_section_bytes_a()\fP . .P It turns the DIE and other information specified for this \f(CWDwarf_P_Debug\fP into a stream of bytes for each section being produced. These byte streams can be retrieved from the \f(CWDwarf_P_Debug\fP by calls to \f(CWdwarf_get_section_bytes_a()\fP (see below). .P In case of error \f(CWdwarf_transform_to_disk_form_a()\fP returns \f(CWDW_DLV_ERROR\fP. .P The number of chunks is used to access data by \f(CWdwarf_get_section_bytes_a()\fP (see below) and the section data provided your code will insert into an object file or the like. Each section of the resulting object is typically many small chunks. Each chunk has a section index and a length as well as a pointer to a block of data (see \f(CWdwarf_get_section_bytes_a()\fP ). .P For each unique section being produced \f(CWdwarf_transform_to_disk_form_a()\fP calls the \f(CWDwarf_Callback_Func\fP exactly once. The callback provides the connection between Elf sections (which we presume is the object format to be emitted) and the \f(CWlibdwarf()\fP internal section numbering. .P For \f(CWDW_DLC_STREAM_RELOCATIONS\fP a call to \f(CWDwarf_Callback_Func\fP is made by libdwarf for each relocation section. Calls to \f(CWdwarf_get_section_bytes_a()\fP (see below). allow the \f(CWdwarf_transform_to_disk_form_a()\fP caller to get byte streams and write them to an object file as desired, just as with the other sections of the object being created. .P For \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the user code should use \f(CWdwarf_get_relocation_info_count()\fP and \f(CWdwarf_get_relocation_info()\fP to retrieve the relocation info generated by \f(CWdwarf_transform_to_disk_form()\fP and do something with it. .P On failure it returns \f(CWDW_DLV_ERROR\fP and returns an error pointer through \f(CW*error\fP . .H 4 "dwarf_transform_to_disk_form()" .DS \f(CWDwarf_Signed dwarf_transform_to_disk_form( Dwarf_P_Debug dbg, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_transform_to_disk_form()\fP is the original call to generate output and a better interface is used by \f(CWdwarf_transform_to_disk_form_a()\fP though both do the same work and have the same meaning. .H 3 "dwarf_get_section_bytes_a()" .DS \f(CWint dwarf_get_section_bytes_a( Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Ptr *section_bytes, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_section_bytes_a() \fP must be called repetitively, with the index \f(CWdwarf_section\fP starting at 0 and continuing for the number of sections returned by \f(CWdwarf_transform_to_disk_form_a() \fP. .P It returns \f(CWDW_DLV_NO_ENTRY\fP to indicate that there are no more sections of \f(CWDwarf\fP information. Normally one would index through using the sectioncount from dwarf_transform_to_disk_form_a() so \f(CWDW_DLV_NO_ENTRY\fP would never be seen. For each successful return (return value \f(CWDW_DLV_OK\fP), \f(CW*section_bytes\fP points to \f(CW*length\fP bytes of data that are normally added to the output object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application. It is illegal to call these in any order other than 0 through N-1 where N is the number of dwarf sections returned by \f(CWdwarf_transform_to_disk_form() \fP. The elf section number is returned through the pointer \f(CWelf_section_index\fP. The \f(CWdwarf_section\fP number is ignored: the data is returned as if the caller passed in the correct dwarf_section numbers in the required sequence. .P In case of an error, \f(CWDW_DLV_ERROR\fP is returned and the \f(CWerror\fP argument is set to indicate the error. .P There is no requirement that the section bytes actually be written to an elf file. For example, consider the .debug_info section and its relocation section (the call back function would resulted in assigning 'section' numbers and the link field to tie these together (.rel.debug_info would have a link to .debug_info). One could examine the relocations, split the .debug_info data at relocation boundaries, emit byte streams (in hex) as assembler output, and at each relocation point, emit an assembler directive with a symbol name for the assembler. Examining the relocations is awkward though. It is much better to use \f(CWdwarf_get_section_relocation_info() \fP .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. Function created 01 December 2018. .H 4 "dwarf_get_section_bytes()" .DS \f(CWDwarf_Ptr dwarf_get_section_bytes( Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error* error)\fP .DE Beginning in September 2016 one should call \f(CWdwarf_get_section_bytes_a()\fP in preference to \f(CWdwarf_get_section_bytes()\fP as the former makes checking for errors easier. .P The function \f(CWdwarf_get_section_bytes()\fP must be called repetitively, with the index \f(CWdwarf_section\fP starting at 0 and continuing for the number of sections returned by \f(CWdwarf_transform_to_disk_form() \fP. .P It returns \f(CWNULL\fP to indicate that there are no more sections of \f(CWDwarf\fP information. Normally one would index through using the sectioncount from dwarf_transform_to_disk_form_a() so \f(CWNULL\fP would never be seen. .P For each non-NULL return, the return value points to \f(CW*length\fP bytes of data that are normally added to the output object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application. The elf section number is returned through the pointer \f(CWelf_section_index\fP. .P In case of an error, \f(CWDW_DLV_BADADDR\fP is returned and the \f(CWerror\fP argument is set to indicate the error. .P It is illegal to call these in any order other than 0 through N-1 where N is the number of dwarf sections returned by \f(CWdwarf_transform_to_disk_form() \fP. The \f(CWdwarf_section\fP number is actually ignored: the data is returned as if the caller passed in the correct dwarf_section numbers in the required sequence. The \f(CWerror\fP argument is not used. .P There is no requirement that the section bytes actually be written to an elf file. For example, consider the .debug_info section and its relocation section (the call back function would resulted in assigning 'section' numbers and the link field to tie these together (.rel.debug_info would have a link to .debug_info). One could examine the relocations, split the .debug_info data at relocation boundaries, emit byte streams (in hex) as assembler output, and at each relocation point, emit an assembler directive with a symbol name for the assembler. Examining the relocations is awkward though. It is much better to use \f(CWdwarf_get_section_relocation_info() \fP .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. .H 3 "dwarf_get_relocation_info_count()" .DS \f(CWint dwarf_get_relocation_info_count( Dwarf_P_Debug dbg, Dwarf_Unsigned *count_of_relocation_sections , int *drd_buffer_version, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_relocation_info() \fP returns, through the pointer \f(CWcount_of_relocation_sections\fP, the number of times that \f(CWdwarf_get_relocation_info() \fP should be called. The function \f(CWdwarf_get_relocation_info() \fP returns DW_DLV_OK if the call was successful (the \f(CWcount_of_relocation_sections\fP is therefore meaningful, though \f(CWcount_of_relocation_sections\fP could be zero). \f(CW*drd_buffer_version\fP is the value 2. If the structure pointed to by the \f(CW*reldata_buffer\fP changes this number will change. The application should verify that the number is the version it understands (that it matches the value of DWARF_DRD_BUFFER_VERSION (from libdwarf.h)). The value 1 version was never used in production MIPS libdwarf (version 1 did exist in source). It returns DW_DLV_NO_ENTRY if \f(CWcount_of_relocation_sections\fP is not meaningful because \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP was not passed to the \f(CWdwarf_producer_init_c()\fP \f(CWdwarf_producer_init_b()\fP or \f(CWdwarf_producer_init()\fP call (whichever one was used). It returns DW_DLV_ERROR if there was an error, in which case \f(CWcount_of_relocation_sections\fP is not meaningful. .H 3 "dwarf_get_relocation_info()" .DS \f(CWint dwarf_get_relocation_info( Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, Dwarf_Signed *elf_section_index_link, Dwarf_Unsigned *relocation_buffer_count, Dwarf_Relocation_Data *reldata_buffer, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_relocation_info() \fP should normally be called repetitively, for the number of relocation sections that \f(CWdwarf_get_relocation_info_count() \fP indicated exist. It returns \f(CWDW_DLV_OK\fP to indicate that valid values are returned through the pointer arguments. The \f(CWerror\fP argument is not set. It returns DW_DLV_NO_ENTRY if there are no entries (the count of relocation arrays is zero.). The \f(CWerror\fP argument is not set. It returns \f(CWDW_DLV_ERROR\fP if there is an error. Calling \f(CWdwarf_get_relocation_info() \fP more than the number of times indicated by \f(CWdwarf_get_relocation_info_count() \fP (without an intervening call to \f(CWdwarf_reset_section_bytes() \fP ) results in a return of \f(CWDW_DLV_ERROR\fP once past the valid count. The \f(CWerror\fP argument is set to indicate the error. Now consider the returned-through-pointer values for \f(CWDW_DLV_OK\fP . \f(CW*elf_section_index\fP is the 'elf section index' of the section implied by this group of relocations. \f(CW*elf_section_index_link\fP is the section index of the section that these relocations apply to. \f(CW*relocation_buffer_count\fP is the number of array entries of relocation information in the array pointed to by \f(CW*reldata_buffer\fP . \f(CW*reldata_buffer\fP points to an array of 'struct Dwarf_Relocation_Data_s' structures. The version 2 array information is as follows: .nf enum Dwarf_Rel_Type {dwarf_drt_none, dwarf_drt_data_reloc, dwarf_drt_segment_rel, dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* contains Dwarf_Rel_Type */ unsigned char drd_length; /* typically 4 or 8 */ Dwarf_Unsigned drd_offset; /* where the data to reloc is */ Dwarf_Unsigned drd_symbol_index; }; .fi The \f(CWDwarf_Rel_Type\fP enum is encoded (via casts if necessary) into the single unsigned char \f(CWdrd_type\fP field to control the space used for this information (keep the space to 1 byte). The unsigned char \f(CWdrd_length\fP field holds the size in bytes of the field to be relocated. So for elf32 object formats with 32 bit apps, \f(CWdrd_length\fP will be 4. For objects with MIPS -64 contents, \f(CWdrd_length\fP will be 8. For some dwarf 64 bit environments, such as ia64, \f(CWdrd_length\fP is 4 for some relocations (file offsets, for example) and 8 for others (run time addresses, for example). If \f(CWdrd_type\fP is \f(CWdwarf_drt_none\fP, this is an unused slot and it should be ignored. If \f(CWdrd_type\fP is \f(CWdwarf_drt_data_reloc\fP this is an ordinary relocation. The relocation type means either (R_MIPS_64) or (R_MIPS_32) (or the like for the particular ABI. \f(CWdrd_length\fP gives the length of the field to be relocated. \f(CWdrd_offset\fP is an offset (of the value to be relocated) in the section this relocation stuff is linked to. \f(CWdrd_symbol_index\fP is the symbol index (if elf symbol indices were provided) or the handle to arbitrary information (if that is what the caller passed in to the relocation-creating dwarf calls) of the symbol that the relocation is relative to. When \f(CWdrd_type\fP is \f(CWdwarf_drt_first_of_length_pair\fP the next data record will be \f(CWdrt_second_of_length_pair\fP and the \f(CWdrd_offset\fP of the two data records will match. The relevant 'offset' in the section this reloc applies to should contain a symbolic pair like .nf .in +4 .word second_symbol - first_symbol .in -4 .fi to generate a length. \f(CWdrd_length\fP gives the length of the field to be relocated. \f(CWdrt_segment_rel\fP means (R_MIPS_SCN_DISP) is the real relocation (R_MIPS_SCN_DISP applies to exception tables and this part may need further work). \f(CWdrd_length\fP gives the length of the field to be relocated. .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. .H 3 "dwarf_reset_section_bytes()" .DS \f(CWvoid dwarf_reset_section_bytes( Dwarf_P_Debug dbg )\fP .DE The function \f(CWdwarf_reset_section_bytes() \fP is used to reset the internal information so that \f(CWdwarf_get_section_bytes() \fP will begin (on the next call) at the initial dwarf section again. It also resets so that calls to \f(CWdwarf_get_relocation_info() \fP will begin again at the initial array of relocation information. Some dwarf producers need to be able to run through the \f(CWdwarf_get_section_bytes()\fP and/or the \f(CWdwarf_get_relocation_info()\fP calls more than once and this call makes additional passes possible. The set of Dwarf_Ptr values returned is identical to the set returned by the first pass. It is acceptable to call this before finishing a pass of \f(CWdwarf_get_section_bytes()\fP or \f(CWdwarf_get_relocation_info()\fP calls. No errors are possible as this just resets some internal pointers. It is unwise to call this before \f(CWdwarf_transform_to_disk_form() \fP has been called. .P .H 3 "dwarf_pro_get_string_stats()" .DS \f(CWint dwarf_pro_get_string_stats( Dwarf_P_Debug dbg, Dwarf_Unsigned * str_count, Dwarf_Unsigned * str_total_length, Dwarf_Unsigned * strp_count_debug_str, Dwarf_Unsigned * strp_len_debug_str, Dwarf_Unsigned * strp_reused_count, Dwarf_Unsigned * strp_reused_len, Dwarf_Error* error) \fP .DE If it returns \f(CWDW_DLV_OK\fP the function \f(CWdwarf_pro_get_string_stats()\fP returns information about how \f(CWDW_AT_name\fP etc strings were stored in the output object. The values suggest how much string duplication was detected in the DWARF being created. .P Call it after calling \f(CWdwarf_transform_to_disk_form()\fP and before calling \f(CWdwarf_producer_finish_a()\fP . It has no effect on the object being output. .P On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP through the pointer. .H 3 "dwarf_producer_finish_a()" .DS \f(CWint dwarf_producer_finish_a( Dwarf_P_Debug dbg, Dwarf_Error* error) \fP .DE This is new in September 2016 and has the newer interface style, but is otherwise identical to \f(CWdwarf_producer_finish() \fP. .P The function \f(CWdwarf_producer_finish_a() \fP should be called after all the bytes of data have been copied somewhere (normally the bytes are written to disk). It frees all dynamic space allocated for \f(CWdbg\fP, include space for the structure pointed to by \f(CWdbg\fP. This should not be called till the data have been copied or written to disk or are no longer of interest. It returns \f(CWDW_DLV_OK\fP if successful. .P On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP through the pointer. .H 4 "dwarf_producer_finish()" .DS \f(CWDwarf_Unsigned dwarf_producer_finish( Dwarf_P_Debug dbg, Dwarf_Error* error) \fP .DE This is the original interface. It works but calling \f(CWdwarf_producer_finish_a() \fP is preferred as it matches the latest libdwarf interface standard. .P The function \f(CWdwarf_producer_finish() \fP should be called after all the bytes of data have been copied somewhere (normally the bytes are written to disk). It frees all dynamic space allocated for \f(CWdbg\fP, include space for the structure pointed to by \f(CWdbg\fP. This should not be called till the data have been copied or written to disk or are no longer of interest. It returns zero if successful. .P On error it returns \f(CWDW_DLV_NOCOUNT\fP and sets \f(CWerror\fP through the pointer. .H 2 "Debugging Information Entry Creation" The functions in this section add new \f(CWDIE\fPs to the object, and also the relationships among the \f(CWDIE\fP to be specified by linking them up as parents, children, left or right siblings of each other. In addition, there is a function that marks the root of the graph thus created. .H 3 "dwarf_add_die_to_debug_a()" .DS \f(CWint dwarf_add_die_to_debug_a( Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_die_to_debug_a() \fP indicates to \f(CWLibdwarf\fP the root \f(CWDIE\fP of the \f(CWDIE\fP graph that has been built so far. It is intended to mark the compilation-unit \f(CWDIE\fP for the object represented by \f(CWdbg\fP. The root \f(CWDIE\fP is specified by \f(CWfirst_die\fP. .P It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_error\fP on error. Function created 2016. .H 4 "dwarf_add_die_to_debug()" .DS \f(CWDwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error *error) \fP .DE This is the original form of the call. Use \f(CWdwarf_add_die_to_debug_a() instead. .P It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_new_die_a()" .DS \f(CWint dwarf_new_die_a( Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf_P_Die *die_out, Dwarf_Error *error) \fP .DE New September 2016. On success \f(CWdwarf_new_die_a() \fP returns DW_DLV_OK and creates a new \f(CWDIE\fP with its parent, child, left sibling, and right sibling \f(CWDIE\fPs specified by \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP, respectively. The new die is passed to the caller via the argument \f(CWdie_out() \fP . There is no requirement that all of these \f(CWDIE\fPs be specified, i.e. any of these descriptors may be \f(CWNULL\fP. If none is specified, this will be an isolated \f(CWDIE\fP. A \f(CWDIE\fP is transformed to disk form by \f(CWdwarf_transform_to_disk_form() \fP only if there is a path from the \f(CWDIE\fP specified by \f(CWdwarf_add_die_to_debug\fP to it. .P The value of \f(CWnew_tag\fP is the tag which is given to the new \f(CWDIE\fP. \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP are pointers to establish links to existing \f(CWDIE\fPs. Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL. If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. .P To add attributes to the new \f(CWDIE\fP, use the \f(CWAttribute Creation\fP functions defined in the next section. .P On failure \f(CWdwarf_new_die_a() \fP returns DW_DLV_ERROR and sets \f(CW*error\fP. Function created 01 December 2018. .H 4 "dwarf_new_die()" .DS \f(CWDwarf_P_Die dwarf_new_die( Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE This is the original form of the function and users should switch to calling \f(CWdwarf_new_die_a()\fP instead to use the newer interface. See \f(CWdwarf_new_die_a()\fP for details (both functions do the same thing). .H 3 "dwarf_die_link_a()" .DS \f(CWint dwarf_die_link_a( Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left-sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE New September 2016. On success the function \f(CWdwarf_die_link_a() \fP returns \f(CWDW_DLV_OK\fP and links an existing \f(CWDIE\fP described by the given \f(CWdie\fP to other existing \f(CWDIE\fPs. The given \f(CWdie\fP can be linked to a parent \f(CWDIE\fP, a child \f(CWDIE\fP, a left sibling \f(CWDIE\fP, or a right sibling \f(CWDIE\fP by specifying non-NULL \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP \f(CWDwarf_P_Die\fP descriptors. Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL. If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. Non-NULL links overwrite the corresponding links the given \f(CWdie\fP may have had before the call to \f(CWdwarf_die_link_a() \fP. If there is an error \f(CWdwarf_die_link_a() \fP returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP with the specific applicable error code. .H 4 "dwarf_die_link()" .DS \f(CWDwarf_P_Die dwarf_die_link( Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left-sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE This is the original function to link \f(CWDIEs\fP together. The function does the same thing as \f(CWdwarf_die_link_a()\fP but. the newer function is simpler to work with. .H 2 "DIE Markers" DIE markers provide a way for a producer to extract DIE offsets from DIE generation. The markers do not influence the generation of DWARF, they simply allow a producer to extract .debug_info offsets for whatever purpose the producer finds useful (for example, a producer might want some unique other section unknown to libdwarf to know a particular DIE offset). One marks one or more DIEs as desired any time before calling \f(CWdwarf_transform_to_disk_form()\fP. After calling \f(CWdwarf_transform_to_disk_form()\fP call \f(CWdwarf_get_die_markers()\fP which has the offsets where the marked DIEs were written in the generated .debug_info data. .H 3 "dwarf_add_die_marker_a()" .DS \f(CWint dwarf_add_die_marker_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error *error) \fP .DE This is preferred over \f(CWdwarf_add_die_marker()\fP. The function \f(CWdwarf_add_die_marker_a()\fP writes the value \f(CWmarker\fP to the \f(CWDIE\fP descriptor given by \f(CWdie\fP. Passing in a marker of 0 means 'there is no marker' (zero is the default in DIEs). It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_die_marker()" .DS \f(CWDwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error *error) \fP .DE This is preferred over \f(CWdwarf_add_die_marker()\fP. The function \f(CWdwarf_add_die_marker_a()\fP writes the value \f(CWmarker\fP to the \f(CWDIE\fP descriptor given by \f(CWdie\fP. Passing in a marker of 0 means 'there is no marker' (zero is the default in DIEs). It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 4 "dwarf_get_die_marker_a()" .DS \f(CWint dwarf_get_die_marker_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned *marker, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker() \fP returns the current marker value for this DIE through the pointer \f(CWmarker\fP. A marker value of 0 means 'no marker was set'. It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_get_die_marker()" .DS \f(CWDwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned *marker, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker() \fP returns the current marker value for this DIE through the pointer \f(CWmarker\fP. A marker value of 0 means 'no marker was set'. It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_get_die_markers_a()" .DS \f(CWint dwarf_get_die_markers_a( Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, Dwarf_Unsigned *marker_count, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_markers_a()\fP returns a pointer to an array of \f(CWDwarf_P_Marker\fP pointers to \f(CWstruct Dwarf_P_Marker_s\fP structures through the pointer \f(CWmarker_list\fP. The array length is returned through the pointer \f(CWmarker_count\fP. The call is only meaningful after a call to \f(CWdwarf_transform_to_disk_form()\fP as the transform call creates the \f(CWstruct Dwarf_P_Marker_s\fP structures, one for each DIE generated for .debug_info (but only for DIEs that had a non-zero marker value). The field \f(CWma_offset\fP in the structure is set during generation of the .debug_info byte stream. The field \f(CWma_marker\fP in the structure is a copy of the DIE marker of the DIE given that offset. It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP (if there are no markers it returns \f(CWDW_DLV_ERROR\fP). .H 4 "dwarf_get_die_markers()" .DS \f(CWDwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, Dwarf_Unsigned *marker_count, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker()\fP returns a pointer to an array of \f(CWDwarf_P_Marker\fP pointers to \f(CWstruct Dwarf_P_Marker_s\fP structures through the pointer \f(CWmarker_list\fP. The array length is returned through the pointer \f(CWmarker_count\fP. The call is only meaningful after a call to \f(CWdwarf_transform_to_disk_form()\fP as the transform call creates the \f(CWstruct Dwarf_P_Marker_s\fP structures, one for each DIE generated for .debug_info (but only for DIEs that had a non-zero marker value). The field \f(CWma_offset\fP in the structure is set during generation of the .debug_info byte stream. The field \f(CWma_marker\fP in the structure is a copy of the DIE marker of the DIE given that offset. It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_BADADDR\fP (if there are no markers it returns \f(CWDW_DLV_BADADDR\fP). .H 2 "Attribute Creation" The functions in this section add attributes to a \f(CWDIE\fP. These functions return a \f(CWDwarf_P_Attribute\fP descriptor that represents the attribute added to the given \f(CWDIE\fP. In most cases the return value is only useful to determine if an error occurred. Some of the attributes have values that are relocatable. They need a symbol with respect to which the linker will perform relocation. This symbol is specified by means of an index into the Elf symbol table for the object (of course, the symbol index can be more general than an index). .H 3 "dwarf_add_AT_location_expr_a()" .DS \f(CWint dwarf_add_AT_location_expr_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_P_Attr *attr_out, Dwarf_Error *error) \fP .DE On success the function \f(CWdwarf_add_AT_location_expr_a()\fP returns \f(CWDW_DLV_OK\fP and adds the attribute specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by \f(CWownerdie\fP. The new attribute is passed back to the caller through the pointer \f(CWattr_out\fP. The attribute should be one that has a location expression as its value. The location expression that is the value is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP. If the expression has a \f(CWDW_OP_addr\fP the code simply assumes that \f(CWDW_OP_addr\fP is the first operation and bases the only relocation that can be created on that assumption. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_location_expr()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_location_expr( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_location_expr()\fP adds the attribute specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by \f(CWownerdie\fP. The attribute should be one that has a location expression as its value. The location expression that is the value is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute given, on success. On error it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_name_a()" .DS \f(CWint dwarf_add_AT_name_a( Dwarf_P_Die ownerdie, char *name, Dwarf_P_Attribute * attr_out, Dwarf_Error *error) \fP .DE New November 2018, a better alternative to \f(CWdwarf_add_AT_name()\fP. The function \f(CWdwarf_add_AT_name_a() \fP adds the string specified by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute for the given \f(CWDIE\fP, \f(CWownerdie\fP. It returns DW_DLV_OK on success and assigns the new attribute descriptor to \f(CW*attr_out\fP. On error it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*attr_out\fP. .H 4 "dwarf_add_AT_name()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_name( Dwarf_P_Die ownerdie, char *name, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_name()\fP adds the string specified by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute for the given \f(CWDIE\fP, \f(CWownerdie\fP. It returns the \f(CWDwarf_P_attribute\fP descriptor for the \f(CWDW_AT_name\fP attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_comp_dir_a()" .DS \f(CWint dwarf_add_AT_comp_dir_a( Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_comp_dir_a\fP adds the string given by \f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the new attribute. .P On error, it returns \f(CWDW_DLV_ERROR\fP and does not touch \f(CWattr_out\fP . .H 4 "dwarf_add_AT_comp_dir()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_comp_dir( Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_Error *error) \fP .DE The function \f(CWint dwarf_add_AT_comp_dir\fP adds the string given by \f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_producer_a()" .DS \f(CWint dwarf_add_AT_producer_a( Dwarf_P_Die ownerdie, char *producer_string, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_producer()\fP adds the string given by \f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP. On success it returns \f(CWDW_DLV_OK\fP and returns the new attribute descriptor representing this attribute through the pointer argument \f(CWattr_out\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_producer()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_producer( Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_producer() \fP adds the string given by \f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor representing this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_any_value_sleb_a()" .DS \f(CWint dwarf_add_AT_any_value_sleb_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *out_attr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_sleb_a()\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_sdata\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_attr\fP to the created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. The function was created 01 December 2018. .H 4 "dwarf_add_AT_any_value_sleb()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_any_value_sleb( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_sleb() \fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_sdata\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. The function was created 13 August 2013. .H 3 "dwarf_add_AT_const_value_signedint_a()" .DS \f(CWint dwarf_add_AT_const_value_signedint_a( Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_signedint_a\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. On success it returns \f(CWDW_DLV_OK\fP and sets *attr_out to the created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_const_value_signedint()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_signedint( Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_signedint\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_implicit_const()" .DS \f(CWint dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *outattr, Dwarf_Error * error); \fP .DE The function \f(CWdwarf_add_AT_implicit_const\fP creates a new attribute and adds the signed value to the abbreviation entry for this new attribute and attaches the new attribute to the DIE passed in. .P The new attribute has \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The \f(CWform\fP in the generated attribute is \f(CWDW_FORM_implicit_const.\fP The \f(CWsigned_value\fP argument will be inserted in the abbreviation table as a signed leb value. .P For a successful call the function returns \f(CWDW_DLV_OK.\fP and a pointer to the created argument is returned through the pointer \f(CWoutaddr.\fP .P In case of error the function returns \f(CWDW_DLV_ERROR\fP and no attribute is created. .H 3 "dwarf_add_AT_any_value_uleb_a()" .DS \f(CWint dwarf_add_AT_any_value_uleb_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_uleb_a\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_udata\fP (unsigned leb number) and the attribute is \f(CWattrnum\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the newly created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. The function was created 01 December 2018. .H 4 "dwarf_add_AT_any_value_uleb()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_any_value_uleb( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_uleb\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_udata\fP (unsigned leb number) and the attribute is \f(CWattrnum\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. The function was created 13 August 2013. .H 3 "dwarf_add_AT_const_value_unsignedint_a()" .DS \f(CWint dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_const_value_unsignedint_a\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. On success it returns \f(CWDW_DLV_OK\fP. and sets \f(CW*attr_out\fP to the newly created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. Created 01 December 2018. .H 4 "dwarf_add_AT_const_value_unsignedint()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_unsignedint\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_const_value_string_a()" .DS \f(CWint dwarf_add_AT_const_value_string_a( Dwarf_P_Die ownerdie, char *string_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_string_afP adds the string value given by \f(CWstring_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. .P On success it returns \f(CWDW_DLV_OK\fP \f(CW*attr_out\fP to a newly created attribute. .P On error, it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_const_value_string()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die ownerdie, char *string_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_stringfP adds the string value given by \f(CWstring_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. .P It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_targ_address_c()" .DS \f(CWint dwarf_add_AT_targ_address_c( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_targ_address_cfP is identical to \f(CWdwarf_add_AT_targ_address_bfP except for the return value and an added argument. Because this is type-safe use this instead of \f(CWdwarf_add_AT_targ_address_bfP. .P \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP \f(CWDwarf_P_Attribute\fP and \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. On failure it returns \f(CWDW_DLV_ERROR\fP. Do not use this function for attr \f(CWDW_AT_high_pc\fP if the value to be recorded is an offset (not a pc) [ use \f(CWdwarf_add_AT_unsigned_const_afP or \f(CWdwarf_add_AT_any_value_uleb_afP instead]. On failure the function returns \f(CWDW_DLV_ERROR\fP Function created 01 December 2018. .H 4 "dwarf_add_AT_targ_address()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_targ_address( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_targ_address\fP adds an attribute that belongs to the "address" class to the die specified by \f(CWownerdie\fP. The attribute is specified by \f(CWattr\fP, and the object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The relocatable address that is the value of the attribute is specified by \f(CWpc_value\fP. The symbol to be used for relocation is specified by the \f(CWsym_index\fP, which is the index of the symbol in the Elf symbol table. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 4 "dwarf_add_AT_targ_address_b()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_targ_address_b( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE Please use \f(CWdwarf_add_AT_targ_address_c\fP instead of \f(CWdwarf_add_AT_targ_address_b\fP or \f(CWdwarf_add_AT_targ_address\fP when is is convenient for you. The function \f(CWdwarf_add_AT_targ_address_b\fP is identical to \f(CWdwarf_add_AT_targ_address\fP except that \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for attr \f(CWDW_AT_high_pc\fP if the value to be recorded is an offset (not a pc) [ use \f(CWdwarf_add_AT_unsigned_const_a\fP or \f(CWdwarf_add_AT_any_value_uleb_a\fP instead]. .H 3 "dwarf_add_AT_block_a()" .DS \f(CWint dwarf_add_AT_block_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_P_Attribute* attr_out, Dwarf_Error *error) .DE This function works with all \f(CWDW_FORM_block\fP forms as well as \f(CWDW_FORM_exprloc\fP. On success this returns \f(CWDW_DLV_OK\fP an attribute with a \f(CWDW_FORM_block\fP instance (does not create \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, or \f(CWDW_FORM_block4\fP at present) and returns a pointer to the new attribute through the pointer \f(CWattr_out\fP. On failure this returns \f(CWDW_DLV_ERROR\fP /* New December 2018. Preferred version. */ .H 4 "dwarf_add_AT_block()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_block( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_Error *error) .DE On success this returns an attribute pointer just as \f(CWdwarf_add_AT_block_a\fP does and returns the attribute. On failure it returns \f(CWDW_DLV_BADADDR\fP. jjk .H 3 "dwarf_add_AT_dataref_a()" .DS \f(CWint dwarf_add_AT_dataref_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b\fP but results in a different FORM (results in DW_FORM_data4 or DW_FORM_data8). Useful for adding relocatable addresses in location lists. \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success it returns \f(CWDW_DLV_OK\fP and the \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP, use \f(CWdwarf_add_AT_unsigned_const\fP or \f(CWdwarf_add_AT_any_value_uleb\fP [ if the value to be recorded is an offset of \f(CWDW_AT_low_pc\fP] or \f(CWdwarf_add_AT_targ_address_b\fP [ if the value to be recorded is an address]. Function created 01 December 2018. .H 4 "dwarf_add_AT_dataref()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b\fP but results in a different FORM (results in DW_FORM_data4 or DW_FORM_data8). Useful for adding relocatable addresses in location lists. \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP, use \f(CWdwarf_add_AT_unsigned_const\fP or \f(CWdwarf_add_AT_any_value_uleb\fP [ if the value to be recorded is an offset of \f(CWDW_AT_low_pc\fP] or \f(CWdwarf_add_AT_targ_address_b\fP [ if the value to be recorded is an address]. .H 3 "dwarf_add_AT_ref_address_a" .DS \f(CWint dwarf_add_AT_ref_address_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_c\fP but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP being generated). Useful for \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes. \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP and \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. On failure the function returns \f(CWDW_DLV_ERROR\fP. Do not use this function for \f(CWDW_AT_high_pc\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_ref_address()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_ref_address( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP being generated). Useful for \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes. \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index()\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP. .H 3 "dwarf_add_AT_unsigned_const_a()" .DS \f(CWint dwarf_add_AT_unsigned_const_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_unsigned_const_a()\fP adds an attribute with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the newly created attribute. It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_AT_unsigned_const()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_unsigned_const( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_unsigned_const()\fP adds an attribute with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_signed_const_a()" .DS \f(CWint dwarf_add_AT_signed_const_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_P_Attribute *out_addr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_signed_const_a()\fP adds an attribute with a \f(CWDwarf_Signed\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_addr\fP with a pointer to the new attribute. On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_signed_const()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_signed_const( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_signed_const()\fP adds an attribute with a \f(CWDwarf_Signed\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_reference_c()" .DS \f(CWint dwarf_add_AT_reference_c( Dwarf_P_Debug dbg, Dwarf_Half attr, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference_c()\fP is the same as \f(CWdwarf_add_AT_reference_b()\fP except that \f(CWdwarf_add_AT_reference_c()\fP returns a simple error code. \f(CWdwarf_add_AT_reference_c()\fP accepts a NULL \f(CWotherdie\fP with the assumption that \f(CWdwarf_fixup_AT_reference_die()\fP will be called by user code to fill in the missing \f(CWotherdie\fP before the DIEs are transformed to disk form. On success it returns \f(CWDW_DLV_OK\fP and returns a pointer to the new attribute through \f(CW*attr_out\fP. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_reference()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_reference( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference()\fP adds an attribute with a value that is a reference to another \f(CWDIE\fP in the same compilation-unit to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and the other \f(CWDIE\fP being referred to is specified by \f(CWotherdie\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. This cannot generate DW_FORM_ref_addr references to \f(CWDIE\fPs in other compilation units. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 4 "dwarf_add_AT_reference_b()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_reference_b( Dwarf_P_Debug dbg, Dwarf_Half attr, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference_b()\fP is the same as \f(CWdwarf_add_AT_reference()\fP except that \f(CWdwarf_add_AT_reference_b()\fP accepts a NULL \f(CWotherdie\fP with the assumption that \f(CWdwarf_fixup_AT_reference_die()\fP will be called by user code to fill in the missing \f(CWotherdie\fP before the DIEs are transformed to disk form. .H 3 "dwarf_fixup_AT_reference_die()" .DS \f(CWint dwarf_fixup_AT_reference_die( Dwarf_Half attrnum, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_fixup_AT_reference_die()\fP is provided to set the NULL \f(CWotherdie\fP that \f(CWdwarf_add_AT_reference_c()\fP allows to the reference target DIE. This must be done before transforming to disk form. \f(CWattrnum()\fP should be the attribute number of the attribute of \fCWownerdie\fP which is to be updated. For example, if a local forward reference was in a \fCWDW_AT_sibling\fP attribute in ownerdie, pass the value \fCWDW_AT_sibling\fP as attrnum. .P Since no attribute number can appear more than once on a given DIE the \f(CWattrnum()\fP suffices to uniquely identify which attribute of \fCWownerdie\fP to update .P It returns either \f(CWDW_DLV_OK\fP (on success) or \f(CWDW_DLV_ERROR\fP (on error). Calling this on an attribute where \f(CWotherdie\fP was already set is an error. New 22 October, 2013. .H 3 "dwarf_add_AT_flag_a()" .DS \f(CWint dwarf_add_AT_flag_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_flag_a()\fP adds an attribute with a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP. On success it returns \f(CWDW_DLV_OK\fP and passes back a pointer to the new attribute through \f(CW*attr_out\fP. On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_flag()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_flag( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_flag()\fP adds an attribute with a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_string_a()" .DS \f(CWint dwarf_add_AT_string_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a value that is a character string to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is pointed to by \f(CWstring\fP. On success it returns \f(CWDW_DLV_OK\fP and set \f(CW*attr_out\fP with a pointer to the new attribute. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_string()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_string( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a value that is a character string to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is pointed to by \f(CWstring\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_with_ref_sig8_a()" .DS \f(CWint dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_P_Attribute *attr_out, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_add_AT_with_sig8_a\fP creates an attribute containing the 8-byte signature block pointed to by \f(CWsig8_in\fP \f(CWDW_FORM_ref_sig8\fP with form \f(CWDW_FORM_ref_sig8\fP. On success it returns \f(CWDW_DLV_OK\fP and sets *attr_out \f(CW*attr_out\fP to the newly created attribute. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_with_ref_sig8()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_add_AT_with_sig8\fP creates an attribute containing the 8-byte signature block pointed to by \f(CWsig8_in\fP \f(CWDW_FORM_ref_sig8\fP with form \f(CWDW_FORM_ref_sig8\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the new attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_data16()" .DS \f(CWint dwarf_add_AT_data16( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Form_Data16 *ptr_to_val, Dwarf_P_Attribute * attr_out, Dwarf_Error * error)\fP .DE The DWARF5 standard refers to 16 byte as simply data. It is up to the eventual reader of the DWARF entry this call creates to understand what the sixteen bytes mean. .P On success it returns \f(CWDW_DLV_OK\fP and returns the new attribute through the pointer \f(CWattr_out\fP. On failure it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_compress_integer_block()" .DS \f(CWvoid* dwarf_compress_integer_block( Dwarf_P_Debug dbg, Dwarf_Bool unit_is_signed, Dwarf_Small unit_length_in_bits, void* input_block, Dwarf_Unsigned input_length_in_units, Dwarf_Unsigned* output_length_in_bytes_ptr, Dwarf_Error* error) .DE This was created in 2016 in support of the attribute DW_AT_SUN_func_offsets but the particular DWARF project involving this seems to have died. We have not provided a way to create the attribute. So this is pretty useless at this time. .H 2 "Expression Creation" The following functions are used to convert location expressions into blocks so that attributes with values that are location expressions can store their values as a \f(CWDW_FORM_blockn\fP value. This is for both .debug_info and .debug_loc expression blocks. To create an expression, first call \f(CWdwarf_new_expr()\fP to get a \f(CWDwarf_P_Expr\fP descriptor that can be used to build up the block containing the location expression. Then insert the parts of the expression in prefix order (exactly the order they would be interpreted in in an expression interpreter). The bytes of the expression are then built-up as specified by the user. .H 3 "dwarf_new_expr_a()" .DS \f(CWint dwarf_new_expr_a( Dwarf_P_Debug dbg, Dwarf_P_Expr *expr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_expra()\fP creates a new expression area in which a location expression stream can be created. On success it returns \f(CWDW_DLV_OK\fP and returns a Dwarf_Expr \f(CWDwarf_Expr\fP through the pointer which can be used to add operators a to build up a location expression. On failure it returns \f(CWDW_DLV_OK\fP. Function created 01 December 2018. .H 4 "dwarf_new_expr()" .DS \f(CWDwarf_P_Expr dwarf_new_expr( Dwarf_P_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_expr()\fP creates a new expression area in which a location expression stream can be created. It returns a \f(CWDwarf_P_Expr\fP descriptor that can be used to add operators to build up a location expression. It returns \f(CWNULL\fP on error. .H 3 "dwarf_add_expr_gen_a()" .DS \f(CWint dwarf_add_expr_gen_a( Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Unsigned *stream_length_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP, and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and appends the bytes to the byte stream being assembled for the location expression represented by \f(CWexpr\fP. The first operand, if present, to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present, is in \f(CWval2\fP. Both the operands may actually be signed or unsigned depending on \f(CWopcode\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_length_out\fP to the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of \f(CWopcode\fP. It returns \f(CWDW_DLV_ERROR\fP on error. The function \f(CWdwarf_add_expr_gen_a()\fP works for all opcodes except those that have a target address as an operand. This is because the function cannot not set up a relocation record that is needed when target addresses are involved. Function created 01 December 2018. .H 4 "dwarf_add_expr_gen()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP, and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and appends the bytes to the byte stream being assembled for the location expression represented by \f(CWexpr\fP. The first operand, if present, to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present, is in \f(CWval2\fP. Both the operands may actually be signed or unsigned depending on \f(CWopcode\fP. It returns the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of \f(CWopcode\fP. It returns \f(CWDW_DLV_NOCOUNT\fP on error. The function \f(CWdwarf_add_expr_gen()\fP works for all opcodes except those that have a target address as an operand. This is because the function cannot not set up a relocation record that is needed when target addresses are involved. .H 3 "dwarf_add_expr_addr_c()" .DS \f(CWint dwarf_add_expr_addr_c( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Unsigned sym_index, Dwarf_Unsigned *stream_length_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr_c()\fP is identical to \f(CWdwarf_add_expr_addr_b()\fP except that \f(CWdwarf_add_expr_addr_c()\fP returns a simple integer code. .P \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_length_out\fP to to the total length of the expression stream in \f(CWexpr\fP. On failure the function returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_expr_addr()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Signed sym_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr()\fP is used to add the \f(CWDW_OP_addr\fP opcode to the location expression represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. The value of the relocatable address is given by \f(CWaddress\fP. The symbol to be used for relocation is given by \f(CWsym_index\fP, which is the index of the symbol in the Elf symbol table. It returns the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of the \f(CWDW_OP_addr\fP operator. It returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 4 "dwarf_add_expr_addr_b()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Unsigned sym_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr_b()\fP is identical to \f(CWdwarf_add_expr_addr()\fP except that \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. .H 3 "dwarf_expr_current_offset_a()" .DS \f(CWint dwarf_expr_current_offset_a( Dwarf_P_Expr expr, Dwarf_Unsigned *stream_offset_out, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_expr_current_offset_a()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_offset_out\fP to the current length in bytes of the expression stream. On failure the function returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_expr_current_offset()" .DS \f(CWDwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr expr, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_expr_current_offset()\fP returns the number of bytes currently in the byte stream for the location expression represented by the given \fCW(Dwarf_P_Expr\fP descriptor, \f(CWexpr\fP. It returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_expr_into_block_a()" .DS \f(CWint dwarf_expr_into_block_a( Dwarf_P_Expr expr, Dwarf_Unsigned *length, Dwarf_Small **address, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_expr_into_block_a()\fP returns \f(CWDW_DLV_OK\fP and sets the length of the \f(CWexpr\fP expression into \f(CW*length\fP and sets the value of a pointer into memory where the expression is currently held in the executing libdwarf into \f(CW*address\fP. .P On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_expr_into_block()" .DS \f(CWDwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr expr, Dwarf_Unsigned *length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_expr_into_block()\fP returns the address of the start of the byte stream generated for the location expression represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. The address is a pointer into the current application memory known to libdwarf (stored in a Dwarf_Addr). The length of the byte stream is returned in the location pointed to by \f(CWlength\fP. It returns f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_expr_reset()" .DS \f(CWvoid dwarf_expr_reset( Dwarf_P_Expr expr, Dwarf_Error *error)\fP .DE This resets the expression content of \f(CWexpr()\fP to be empty. .H 2 "Line Number Operations" These are operations on the .debug_line section. They provide information about instructions in the program and the source lines the instruction come from. Typically, code is generated in contiguous blocks, which may then be relocated as contiguous blocks. To make the provision of relocation information more efficient, the information is recorded in such a manner that only the address of the start of the block needs to be relocated. This is done by providing the address of the first instruction in a block using the function \f(CWdwarf_lne_set_address()\fP. Information about the instructions in the block are then added using the function \f(CWdwarf_add_line_entry()\fP, which specifies offsets from the address of the first instruction. The end of a contiguous block is indicated by calling the function \f(CWdwarf_lne_end_sequence()\fP. .P Line number operations do not support \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. .H 3 "dwarf_add_line_entry_c()" .DS \f(CWint dwarf_add_line_entry_c( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)\fP .DE This is the same as \f(CWdwarf_add_line_entry_b()\fP except that it returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_line_entry_b()" .DS \f(CWDwarf_Unsigned dwarf_add_line_entry_b( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_line_entry_b()\fP adds an entry to the section containing information about source lines. It specifies in \f(CWcode_offset\fP, the address of this line. The function subtracts \f(CWcode_offset\fP from the value given as the address of a previous line call to compute an offset, and the offset is what is recorded in the line instructions so no relocation will be needed on the line instruction generated. .P The source file that gave rise to the instruction is specified by \f(CWfile_index\fP, the source line number is specified by \f(CWlineno\fP, and the source column number is specified by \f(CWcolumn_number\fP (column numbers begin at 1) (if the source column is unknown, specify 0). \f(CWfile_index\fP is the index of the source file in a list of source files which is built up using the function \f(CWdwarf_add_file_decl()\fP. \f(CWis_source_stmt_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction in the sequence generated for the source line at \f(CWlineno\fP. Similarly, \f(CWis_basic_block_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction of a basic block. \f(CWis_epilogue_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction in the sequence generated for the function epilogue code. Similarly, \f(CWis_prolgue_end\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the last instruction of the sequence generated for the function prologue. \f(CWisa\fP should be zero unless the code at \f(CWcode_address\fP is generated in a non-standard isa. The values assigned to non-standard isas are defined by the compiler implementation. \f(CWdiscriminator\fP should be zero unless the line table needs to distinguish among multiple blocks associated with the same source file, line, and column. The values assigned to \f(CWdiscriminator\fP are defined by the compiler implementation. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. This function is defined as of December 2011. .H 4 "dwarf_add_line_entry()" .DS \f(CWDwarf_Unsigned dwarf_add_line_entry( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Error *error)\fP .DE This function is the same as \f(CWdwarf_add_line_entry_b()\fP except this older version is missing the new DWARF3/4 line table fields. .H 3 "dwarf_lne_set_address_a()" .DS \f(CWint dwarf_lne_set_address_a( Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_set_address_a()\fP sets the target address at which a contiguous block of instructions begin. Information about the instructions in the block is added to .debug_line using calls to \f(CWdwarfdwarf_add_line_entry_c()\fP which specifies the offset of each instruction in the block relative to the start of the block. This is done so that a single relocation record can be used to obtain the final target address of every instruction in the block. The relocatable address of the start of the block of instructions is specified by \f(CWoffs\fP. The symbol used to relocate the address is given by \f(CWsymidx\fP, which is normally the index of the symbol in the Elf symbol table. It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_lne_set_address()" .DS \f(CWDwarf_Unsigned dwarf_lne_set_address( Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_set_address()\fP sets the target address at which a contiguous block of instructions begin. Information about the instructions in the block is added to .debug_line using calls to \f(CWdwarfdwarf_add_line_entry()\fP which specifies the offset of each instruction in the block relative to the start of the block. This is done so that a single relocation record can be used to obtain the final target address of every instruction in the block. The relocatable address of the start of the block of instructions is specified by \f(CWoffs\fP. The symbol used to relocate the address is given by \f(CWsymidx\fP, which is normally the index of the symbol in the Elf symbol table. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_lne_end_sequence_a()" .DS \f(CWint dwarf_lne_end_sequence_a( Dwarf_P_Debug dbg, Dwarf_Addr address; Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_end_sequence_a()\fP indicates the end of a contiguous block of instructions. \f(CWaddress()\fP should be just higher than the end of the last address in the sequence of instructions. Before the next block of instructions (if any) a call to \f(CWdwarf_lne_set_address_a()\fP will have to be made to set the address of the start of the target address of the block, followed by calls to \f(CWdwarf_add_line_entry_a()\fP for each of the instructions in the block. It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_lne_end_sequence()" .DS \f(CWDwarf_Unsigned dwarf_lne_end_sequence( Dwarf_P_Debug dbg, Dwarf_Addr address; Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_end_sequence()\fP indicates the end of a contiguous block of instructions. \f(CWaddress()\fP should be just higher than the end of the last address in the sequence of instructions. Before the next block of instructions (if any) a call to \f(CWdwarf_lne_set_address()\fP will have to be made to set the address of the start of the target address of the block, followed by calls to \f(CWdwarf_add_line_entry()\fP for each of the instructions in the block. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_add_directory_decl_a()" .DS \f(CWint dwarf_add_directory_decl_a( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned *index_in_directories, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_directory_decl()\fP adds the string specified by \f(CWname\fP to the list of include directories in the statement program prologue of the .debug_line section. The string should therefore name a directory from which source files have been used to create the present object. On success it returns \f(CWDW_DLV_OK\fP and sets the index of the string just added, in the list of include directories for the object. This index is then used to refer to this string. The index is passed back through the pointer argument \f(CWindex_in_directories\fP The first successful call of this function returns one, not zero, to be consistent with the directory indices that \f(CWdwarf_add_file_decl()\fP (below) expects.. DWARF5 is a bit different. TBD FIXME It returns \f(CWDW_DLV_ERROR\fP on error. .H 4 "dwarf_add_directory_decl()" .DS \f(CWDwarf_Unsigned dwarf_add_directory_decl( Dwarf_P_Debug dbg, char *name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_directory_decl()\fP adds the string specified by \f(CWname\fP to the list of include directories in the statement program prologue of the .debug_line section. The string should therefore name a directory from which source files have been used to create the present object. It returns the index of the string just added, in the list of include directories for the object. This index is then used to refer to this string. The first successful call of this function returns one, not zero, to be consistent with the directory indices that \f(CWdwarf_add_file_decl()\fP (below) expects.. \f(CWdwarf_add_directory_decl()\fP returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_add_file_decl_a()" .DS \f(CWint dwarf_add_file_decl_a( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Unsigned *file_entry_count_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_file_decl_a()\fP adds the name of a source file that contributed to the present object. The name of the file is specified by \f(CWname\fP (which must not be the empty string or a null pointer, it must point to a string with length greater than 0). In case the name is not a fully-qualified pathname, it is considered prefixed with the name of the directory specified by \f(CWdir_idx\fP (which does not mean the \f(CWname\fP is changed or physically prefixed by this producer function, we simply describe the meaning here). \f(CWdir_idx\fP is the index of the directory to be prefixed in the list builtup using \f(CWdwarf_add_directory_decl_a()\fP. As specified by the DWARF spec, a \f(CWdir_idx\fP of zero will be interpreted as meaning the directory of the compilation and another index must refer to a valid directory as FIXME .P \f(CWtime_mod\fP gives the time at which the file was last modified, and \f(CWlength\fP gives the length of the file in bytes. .P On success, it returns \f(CWDW_DLV_OK\fP and returns the index of the source file in the list built up so far through the pointer \f(CWfile_entry_count_out\fP. This index can then be used to refer to this source file in calls to \f(CWdwarf_add_line_entry_a()\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_file_decl()" .DS \f(CWDwarf_Unsigned dwarf_add_file_decl( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_file_decl()\fP adds the name of a source file that contributed to the present object. The name of the file is specified by \f(CWname\fP (which must not be the empty string or a null pointer, it must point to a string with length greater than 0). In case the name is not a fully-qualified pathname, it is considered prefixed with the name of the directory specified by \f(CWdir_idx\fP (which does not mean the \f(CWname\fP is changed or physically prefixed by this producer function, we simply describe the meaning here). \f(CWdir_idx\fP is the index of the directory to be prefixed in the list builtup using \f(CWdwarf_add_directory_decl()\fP. As specified by the DWARF spec, a \f(CWdir_idx\fP of zero will be interpreted as meaning the directory of the compilation and another index must refer to a valid directory as FIXME .P \f(CWtime_mod\fP gives the time at which the file was last modified, and \f(CWlength\fP gives the length of the file in bytes. .P It returns the index of the source file in the list built up so far using this function, on success. This index can then be used to refer to this source file in calls to \f(CWdwarf_add_line_entry()\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 2 "Fast Access (aranges) Operations" These functions operate on the .debug_aranges section. .H 3 "dwarf_add_arange_c()" .DS \f(CWint dwarf_add_arange_c( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange_c()\fP adds another address range to be added to the section containing address range information, .debug_aranges. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWbegin_address\fP is the offset from the symbol specified by \f(CWsymbol_index\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWlength\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end - \\ ( start_symbol + begin_address) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a length (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 The function returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_arange()" .DS \f(CWDwarf_Unsigned dwarf_add_arange( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Signed symbol_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange()\fP adds another address range to be added to the section containing address range information, .debug_aranges. The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. It returns a non-zero value on success, and \f(CW0\fP on error. .H 4 "dwarf_add_arange_b()" .DS \f(CWDwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange_b()\fP adds another address range to be added to the section containing address range information, .debug_aranges. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWbegin_address\fP is the offset from the symbol specified by \f(CWsymbol_index\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWlength\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end - \\ ( start_symbol + begin_address) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a length (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "DWARF5 .debug_sup section creation" The .debug_sup section (see the DWARF5 standard) enables symbolically linking two DWARF5 object files together. .sp .H 3 "dwarf_add_debug_sup()" This call provides all the information that the .debug_sup section has. .DS \f(CWint dwarf_add_debug_sup( Dwarf_P_Debug dbg, Dwarf_Half version, Dwarf_Small is_supplementary, char * filename, Dwarf_Unsigned checksum_len, Dwarf_Small * checksum, Dwarf_Error *error)\fP .DE On success it returns \f(CWDW_DLV_OK\fP and records the fields for creating the section. .sp The fields are as follows. .sp \f(CWversion\fP should be passed in as 2. .sp \f(CWfilename\fP must be a null-terminated string. .sp \f(CWis_supplementary\fP should be passed in as 0 or 1 depending on which type of object file is involved (see the DWARF5 standard). .sp \f(CWchecksum\fP must be a byte array of length \f(CWchecksum_len\fP used to validate (by a debugger) the use of the target object file. .sp \f(CWDW_DLV_NO ENTRY\fP is never returned. .sp \f(CWDW_DLV_ERROR\fP is returned in case of an error, and \f(CW*error\fP is set as usual in libdwarf. .H 2 "Fast Access (pubnames) Operations" These functions operate on the .debug_pubnames section. .sp .H 3 "dwarf_add_pubname_a()" .DS \f(CWint dwarf_add_pubname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_pubname()" .DS \f(CWDwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_pubname()\fP adds the pubname specified by \f(CWpubname_name\fP to the section containing pubnames, i.e. .debug_pubnames. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Fast Access (pubtypes) Operations" These functions operate on the .debug_pubtypes section. An SGI-defined extension. Not part of standard DWARF. .sp .H 3 "dwarf_add_pubtype_a()" .DS \f(CWint dwarf_add_pubtype_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_pubtype()" .DS \f(CWDwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_pubtype()\fP adds the pubtype specified by \f(CWpubtype_name\fP to the section containing pubtypes, i.e. .debug_pubtypes. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Fast Access (weak names) Operations" These functions operate on the .debug_weaknames section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_weakname_a()" .DS \f(CWint dwarf_add_weakname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_weakname()" .DS \f(CWDwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_weakname()\fP adds the weak name specified by \f(CWweak_name\fP to the section containing weak names, i.e. .debug_weaknames. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Static Function Names Operations" The .debug_funcnames section contains the names of static function names defined in the object, and also the offsets of the \f(CWDIE\fPs that represent the definitions of the functions in the .debug_info section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_funcname_a()" .DS \f(CWint dwarf_add_funcname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *func_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_funcname_a()\fP adds the name of a static function specified by \f(CWfunc_name\fP to the section containing the names of static functions defined in the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the function is specified by \f(CWdie\fP. .P It returns \f(CWDW_DLV_OK\fP on success. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_funcname()" .DS \f(CWDwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *func_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_funcname()\fP adds the name of a static function specified by \f(CWfunc_name\fP to the section containing the names of static functions defined in the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the function is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "File-scope User-defined Type Names Operations" The .debug_typenames section contains the names of file-scope user-defined types in the given object, and also the offsets of the \f(CWDIE\fPs that represent the definitions of the types in the .debug_info section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_typename_a()" .DS \f(CWint dwarf_add_typename_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error *error)\fP .DE This the same as \f(CWdwarf_add_typename()\fP except that on success this returns \f(CWDW_DLV_OK\fP and on failure this returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_typename()" .DS \f(CWDwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_typename()\fP adds the name of a file-scope user-defined type specified by \f(CWtype_name\fP to the section that contains the names of file-scope user-defined type. The object that this section belongs to is specified by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the type is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "File-scope Static Variable Names Operations" The .debug_varnames section contains the names of file-scope static variables in the given object, and also the offsets of the \f(CWDIE\fPs that represent the definition of the variables in the .debug_info section. An SGI-defined section. .H 3 "dwarf_add_varname_a()" .DS \f(CWint dwarf_add_varname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error *error)\fP .DE This the same as \f(CWdwarf_add_varname()\fP except that on success this returns \f(CWDW_DLV_OK\fP and on failure this returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_varname()" .DS \f(CWDwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_varname()\fP adds the name of a file-scope static variable specified by \f(CWvar_name\fP to the section that contains the names of file-scope static variables defined by the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the static variable is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Macro Information Creation" All strings passed in by the caller are copied by these functions, so the space in which the caller provides the strings may be ephemeral (on the stack, or immediately reused or whatever) without this causing any difficulty. .H 3 "dwarf_def_macro()" .DS \f(CWint dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name char *value, Dwarf_Error *error);\fP .DE Adds a macro definition. The \f(CWname\fP argument should include the parentheses and parameter names if this is a function-like macro. Neither string should contain extraneous whitespace. \f(CWdwarf_def_macro()\fP adds the mandated space after the name and before the value in the output DWARF section(but does not change the strings pointed to by the arguments). If this is a definition before any files are read, \f(CWlineno\fP should be 0. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_undef_macro()" .DS \f(CWint dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, Dwarf_Error *error);\fP .DE Adds a macro un-definition note. If this is a definition before any files are read, \f(CWlineno\fP should be 0. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_start_macro_file()" .DS \f(CWint dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, Dwarf_Unsigned fileindex, Dwarf_Error *error);\fP .DE \f(CWfileindex\fP is an index in the .debug_line header: the index of the file name. See the function \f(CWdwarf_add_file_decl()\fP. The \f(CWlineno\fP should be 0 if this file is the file of the compilation unit source itself (which, of course, is not a #include in any file). Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_end_macro_file()" .DS \f(CWint dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error *error);\fP .DE Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_vendor_ext()" .DS \f(CWint dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char * string, Dwarf_Error* error); \fP .DE The meaning of the \f(CWconstant\fP and the\f(CWstring\fP in the macro info section are undefined by DWARF itself, but the string must be an ordinary null terminated string. This call is not an extension to DWARF. It simply enables storing macro information as specified in the DWARF document. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 2 "Low Level (.debug_frame) operations" These functions operate on the .debug_frame section. Refer to \f(CWlibdwarf.h\fP for the register names and register assignment mapping. Both of these are necessarily machine dependent. .H 3 "dwarf_new_fde_a()" .DS \f(CWint dwarf_new_fde_a( Dwarf_P_Debug dbg, Dwarf_P_Fde *fde_out, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_new_fde_a()\fP returns \f(CWDW_DLV_OK\fP and returns a pointer to the fde through \f(CWfde_out\fP. The descriptor should be used to build a complete \f(CWFDE\fP. Subsequent calls to routines that build up the \f(CWFDE\fP should use the same \f(CWDwarf_P_Fde\fP descriptor. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_new_fde()" .DS \f(CWDwarf_P_Fde dwarf_new_fde( Dwarf_P_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_fde()\fP returns a new \f(CWDwarf_P_Fde\fP descriptor that should be used to build a complete \f(CWFDE\fP. Subsequent calls to routines that build up the \f(CWFDE\fP should use the same \f(CWDwarf_P_Fde\fP descriptor. It returns a valid \f(CWDwarf_P_Fde\fP descriptor on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_frame_cie_a()" .DS \f(CWint dwarf_add_frame_cie_a( Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_bytes_len, Dwarf_Unsigned *cie_index_out, Dwarf_Error *error);\fP .DE On success The function \f(CWdwarf_add_frame_cie_a()\fP returns \f(CWDW_DLV_OK\fP, creates a \f(CWCIE\fP, and returns an index to it through the pointer \f(CWcie_index_out\fP. .P \f(CWCIE\fPs are used by \f(CWFDE\fPs to setup initial values for frames. The augmentation string for the \f(CWCIE\fP is specified by \f(CWaugmenter\fP. The code alignment factor, data alignment factor, and the return address register for the \f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP, and \f(CWret_addr_reg\fP respectively. \f(CWinit_bytes\fP points to the bytes that represent the instructions for the \f(CWCIE\fP being created, and \f(CWinit_bytes_len\fP specifies the number of bytes of instructions. .P There is no convenient way to generate the \f(CWinit_bytes\fP stream. One just has to calculate it by hand or separately generate something with the correct sequence and use dwarfdump -v and readelf (or objdump) and some kind of hex dumper to see the bytes. This is a serious inconvenience! On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_cie()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_cie( Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_bytes_len, Dwarf_Error *error);\fP .DE The function \f(CWDwarf_Unsigned dwarf_add_frame_cie()\fP creates a \f(CWCIE\fP, and returns an index to it, that should be used to refer to this \f(CWCIE\fP. \f(CWCIE\fPs are used by \f(CWFDE\fPs to setup initial values for frames. The augmentation string for the \f(CWCIE\fP is specified by \f(CWaugmenter\fP. The code alignment factor, data alignment factor, and the return address register for the \f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP, and \f(CWret_addr_reg\fP respectively. \f(CWinit_bytes\fP points to the bytes that represent the instructions for the \f(CWCIE\fP being created, and \f(CWinit_bytes_len\fP specifies the number of bytes of instructions. There is no convenient way to generate the \f(CWinit_bytes\fP stream. One just has to calculate it by hand or separately generate something with the correct sequence and use dwarfdump -v and readelf (or objdump) and some kind of hex dumper to see the bytes. This is a serious inconvenience! It returns an index to the \f(CWCIE\fP just created on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_add_frame_fde_c()" .DS \f(CWint dwarf_add_frame_fde_c( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned sym_idx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Unsigned *index_to_fde, Dwarf_Error* error)\fP .DE This function is like \f(CWdwarf_add_frame_fde()\fP except that \f(CWdwarf_add_frame_fde_c()\fP has new arguments to allow use with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP and a new argument to return the fde index.. The function \f(CWdwarf_add_frame_fde_c()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. If \f(CWsym_idx_of_end\fP is zero (may be \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWsym_idx_of_end\fP and \f(CWoffset_from_end_sym\fP are unused. .in -2 .sp If \f(CWsym_idx_of_end\fP is non-zero (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful): .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_sym\fP is the offset from the symbol specified by \f(CWsym_idx_of_end\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + begin - \\ ( start_symbol + offset_from_end) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 On success it returns \f(CWDW_DLV_OK\fP and returns index to the given \f(CWfde\fP through the pointer \f(CWindex_to_fde\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_fde()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. It returns an index to the given \f(CWfde\fP. .H 4 "dwarf_add_frame_fde_b()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned sym_idx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Error* error)\fP .DE This function is like \f(CWdwarf_add_frame_fde()\fP except that \f(CWdwarf_add_frame_fde_b()\fP has new arguments to allow use with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The function \f(CWdwarf_add_frame_fde_b()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. If \f(CWsym_idx_of_end\fP is zero (may be \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWsym_idx_of_end\fP and \f(CWoffset_from_end_sym\fP are unused. .in -2 .sp If \f(CWsym_idx_of_end\fP is non-zero (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful): .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_sym\fP is the offset from the symbol specified by \f(CWsym_idx_of_end\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + begin - \\ ( start_symbol + offset_from_end) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 It returns an index to the given \f(CWfde\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_add_frame_info_c()" .DS \f(CWint dwarf_add_frame_info_c( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Unsigned *index_to_fde, Dwarf_Error* error)\fP .DE New December 2018, this function has a simpler return value so checking for failure is easier. Otherwise \f(CWdwarf_add_frame_fde_c()\fP is essentially similar to \f(CWdwarf_add_frame_fde_b()\fP. .P On success The function \f(CWdwarf_add_frame_fde_c()\fP returns \f(CWDW_DLV_OK\fP, adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP, and. passes the index of the fde back through the pointer \f(CWindex_to_fde\fP On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_info_b()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. This function refers to MIPS/IRIX specific exception tables and is not a function other targets need. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWoffset_into_exception_tables\fP specifies the MIPS/IRIX specific offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables for this function begins. \f(CWexception_table_symbol\fP is also MIPS/IRIX specific and it specifies the index of the relocatable symbol to be used to relocate this offset. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end_symbol - \\ ( start_symbol + virt_addr) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a code_len value (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWvirt_addr\fP, and the length of the address range is specified by \f(CWcode_len\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 It returns an index to the given \f(CWfde\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 4 "dwarf_add_frame_info()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_info()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWoffset_into_exception_tables\fP specifies the offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables for this function begins. \f(CWexception_table_symbol\fP gives the index of the relocatable symbol to be used to relocate this offset. These arguments are MIPS/IRIX specific, pass in 0 for other targets. On success it returns an index to the given \f(CWfde\fP. On failure it returns DW_DLV_NOCOUNT. .H 3 "dwarf_fde_cfa_offset_a()" .DS \f(CWint dwarf_fde_cfa_offset_a( Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)\fP .DE New December 2018, this function has a simpler return value so checking for failure is easier. .P The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP operation to the \f(CWFDE\fP, specified by \f(CWfde\fP, being constructed. The first operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWreg\P. The register specified should not exceed 6 bits. The second operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP. .P It returns \f(CWDW_DLV_OK\fP on success. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_fde_cfa_offset()" .DS \f(CWDwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP operation to the \f(CWFDE\fP, specified by \f(CWfde\fP, being constructed. The first operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWreg\P. The register specified should not exceed 6 bits. The second operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP. It returns the given \f(CWfde\fP on success. It returns \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_fde_inst_a()" .DS \f(CWint dwarf_add_fde_inst_a( Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP. Up to two operands can be specified in \f(CWval1\fP, and \f(CWval2\fP. Based on the operand specified \f(CWLibdwarf\fP decides how many operands are meaningful for the operand. It also converts the operands to the appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP as \f(CWDwarf_Unsigned\fP). .P It returns \f(CWDW_DLV_OK\fP on success. It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_fde_inst()" .DS \f(CWDwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP. Up to two operands can be specified in \f(CWval1\fP, and \f(CWval2\fP. Based on the operand specified \f(CWLibdwarf\fP decides how many operands are meaningful for the operand. It also converts the operands to the appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP as \f(CWDwarf_Unsigned\fP). It returns the given \f(CWfde\fP on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_insert_fde_inst_bytes()" .DS \f(CWint dwarf_insert_fde_inst_bytes( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_Unsigned len, Dwarf_Ptr ibytes, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_insert_fde_inst_bytes()\fP inserts the byte array (pointed at by \f(CWibytes\fP and of length \f(CWlen\fP) of frame instructions into the fde \f(CWfde\fP. It is incompatible with \f(CWdwarf_add_fde_inst()\fP, do not use both functions on any given Dwarf_P_Debug. At present it may only be called once on a given \f(CWfde\fP. The \f(CWlen\fP bytes \f(CWibytes\fP may be constructed in any way, but the assumption is they were copied from an object file such as is returned by the libdwarf consumer function \f(CWdwarf_get_fde_instr_bytes\fP. It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_ERROR\fP on error. .S .TC 1 1 4 .CS libdwarf-20210528/libdwarf/pro_arange.c0000664000175000017500000002616513764007262014570 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_arange.h" #include "pro_section.h" #include "pro_reloc.h" #define SIZEOFT32 4 /* This function adds another address range to the list of address ranges for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Signed symbol_index, Dwarf_Error * error) { int res = 0; res = dwarf_add_arange_b(dbg, begin_address, length, symbol_index, /* end_symbol_index */ 0, /* offset_from_end_sym */ 0, error); if (res != DW_DLV_OK) { return 0; } return 1; } /* This function adds another address range to the list of address ranges for the given Dwarf_P_Debug. It returns DW_DLV_ERROR on error, and DW_DLV_OK otherwise. */ Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { int res = 0; res = dwarf_add_arange_c(dbg,begin_address,length, symbol_index, end_symbol_index, offset_from_end_sym,error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_arange_c(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { Dwarf_P_Arange arange; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } arange = (Dwarf_P_Arange) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s)); if (arange == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } arange->ag_begin_address = begin_address; arange->ag_length = length; arange->ag_symbol_index = symbol_index; arange->ag_end_symbol_index = end_symbol_index; arange->ag_end_symbol_offset = offset_from_end_sym; if (dbg->de_arange == NULL) dbg->de_arange = dbg->de_last_arange = arange; else { dbg->de_last_arange->ag_next = arange; dbg->de_last_arange = arange; } dbg->de_arange_count++; return DW_DLV_OK; } int _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_aranges section. */ Dwarf_Unsigned arange_num_bytes = 0; /* Adjustment to align the start of the actual address ranges on a boundary aligned with twice the address size. */ Dwarf_Small remainder = 0; /* Total number of bytes excluding the length field. */ Dwarf_Unsigned adjusted_length = 0; /* Points to first byte of .debug_aranges buffer. */ Dwarf_Small *arange = 0; /* Fills in the .debug_aranges buffer. */ Dwarf_Small *arange_ptr = 0; /* Scans the list of address ranges provided by user. */ Dwarf_P_Arange given_arange = 0; /* Used to fill in 0. */ const Dwarf_Signed big_zero = 0; int extension_word_size = dbg->de_64bit_extension ? 4 : 0; int offset_size = dbg->de_dwarf_offset_size; int upointer_size = dbg->de_pointer_size; /* All dwarf versions so far use 2 here. */ Dwarf_Half version = 2; int res = 0; /* ***** BEGIN CODE ***** */ /* Size of the .debug_aranges section header. */ arange_num_bytes = extension_word_size + offset_size + /* Size of length field. */ DWARF_HALF_SIZE + /* Size of version field. */ offset_size + /* Size of .debug_info offset. */ sizeof(Dwarf_Small) + /* Size of address size field. */ sizeof(Dwarf_Small); /* Size of segment size field. */ /* Adjust the size so that the set of aranges begins on a boundary that aligned with twice the address size. This is a Libdwarf requirement. */ remainder = arange_num_bytes % (2 * upointer_size); if (remainder != 0) arange_num_bytes += (2 * upointer_size) - remainder; /* Add the bytes for the actual address ranges. */ arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1); GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES], arange, (unsigned long) arange_num_bytes, error); arange_ptr = arange; if (extension_word_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *)&v4[0] , SIZEOFT32, extension_word_size); arange_ptr += extension_word_size; } /* Write the total length of .debug_aranges section. */ adjusted_length = arange_num_bytes - offset_size - extension_word_size; { Dwarf_Unsigned du = adjusted_length; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &du, sizeof(du), offset_size); arange_ptr += offset_size; } /* Write the version as 2 bytes. */ { Dwarf_Half verstamp = version; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &verstamp, sizeof(verstamp), DWARF_HALF_SIZE); arange_ptr += DWARF_HALF_SIZE; } /* Write the .debug_info offset. This is always 0. */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), offset_size); arange_ptr += offset_size; { unsigned long count = dbg->de_arange_count + 1; int res2 = 0; Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[DEBUG_ARANGES]; if (dbg->de_relocate_pair_by_symbol) { count = (3 * dbg->de_arange_count) + 1; } /* The following is a small optimization: not needed for correctness. Does nothing if preloc->pr_first_block is non-null */ res2 = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, p_reloc, count); if (res2 != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* reloc for .debug_info */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, extension_word_size + offset_size + DWARF_HALF_SIZE, dbg->de_sect_name_idx[DEBUG_INFO], dwarf_drt_data_reloc, offset_size); if (res == DW_DLV_NO_ENTRY) { return res; } if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error,DW_DLE_RELOCS_ERROR); return res; } /* Write the size of addresses. */ *arange_ptr = dbg->de_pointer_size; arange_ptr++; /* Write the size of segment addresses. This is zero for MIPS architectures. */ *arange_ptr = 0; arange_ptr++; /* Skip over the padding to align the start of the actual address ranges to twice the address size. */ if (remainder != 0) arange_ptr += (2 * upointer_size) - remainder; /* The arange address, length are pointer-size fields of the target machine. */ for (given_arange = dbg->de_arange; given_arange != NULL; given_arange = given_arange->ag_next) { /* Write relocation record for beginning of address range. */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ (long) given_arange->ag_symbol_index, dwarf_drt_data_reloc, upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Copy beginning address of range. */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &given_arange->ag_begin_address, sizeof(given_arange->ag_begin_address), upointer_size); arange_ptr += upointer_size; if (dbg->de_relocate_pair_by_symbol && given_arange->ag_end_symbol_index != 0 && given_arange->ag_length == 0) { /* Symbolic reloc, need reloc for length What if we really know the length? If so, should use the other part of 'if'. */ Dwarf_Unsigned val; res = dbg->de_relocate_pair_by_symbol(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ given_arange->ag_symbol_index, given_arange->ag_end_symbol_index, dwarf_drt_first_of_length_pair, upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* arange pre-calc so assem text can do .word end - begin + val (gets val from stream) */ val = given_arange->ag_end_symbol_offset - given_arange->ag_begin_address; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &val, sizeof(val), upointer_size); arange_ptr += upointer_size; } else { /* plain old length to copy, no relocation at all */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &given_arange->ag_length, sizeof(given_arange->ag_length), upointer_size); arange_ptr += upointer_size; } } WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), upointer_size); arange_ptr += upointer_size; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), upointer_size); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_error.h0000644000175000017500000000440713743575426014776 00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_ERROR_H #define DWARF_ERROR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval); void _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval, char *msg); #define DE_STANDARD 0 /* Normal alloc attached to dbg. */ #define DE_STATIC 1 /* Using global static var */ #define DE_MALLOC 2 /* Using malloc space */ struct Dwarf_Error_s { Dwarf_Signed er_errval; void * er_msg; /* If non-zero the Dwarf_Error_s struct is not malloc'd. To aid when malloc returns NULL. If zero a normal dwarf_dealloc will work. er_static_alloc only accessed by dwarf_alloc.c. If er_static_alloc is 1 in a Dwarf_Error_s struct (set by libdwarf) and client code accidentally turns that 0 to zero through a wild pointer reference (the field is hidden from clients...) then chaos will eventually follow. */ int er_static_alloc; }; extern struct Dwarf_Error_s _dwarf_failsafe_error; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ERROR_H */ libdwarf-20210528/libdwarf/pro_line.c0000664000175000017500000003746513771421456014272 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_encode_nm.h" #include "pro_line.h" static int _dwarf_pro_add_line_entry(Dwarf_P_Debug, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned symidx, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Ubyte opc, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error); /* Add a entry to the line information section file_index: index of file in file entries, obtained from add_file_entry() call. This function actually calls _dwarf_pro_add_line_entry(), with an extra parameter, the opcode. Done so that interface calls dwarf_lne_set_address() and dwarf_lne_end_sequence() can use this internal routine. The return value of the original interfaces is really signed. Bogus interface. With dwarf_add_line_entry_c the interface is corrected. */ Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { Dwarf_Unsigned retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg,isprolend,isa,discriminator, error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_add_line_entry_c(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg,isprolend,isa,discriminator, error); return retval; } /* The return value is really signed. Bogus interface.*/ Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, /* Wrong, should be unsigned. */ Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg, isprolend, isa, discriminator, error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } void _dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg) { dbg->de_line_inits.pi_linetable_version = dbg->de_output_version; dbg->de_line_inits.pi_default_is_stmt = /* is false pro_line.h */ DEFAULT_IS_STMT; dbg->de_line_inits.pi_minimum_instruction_length = /* is 1 or 4 depending on ifdefs in pro_line.h */ MIN_INST_LENGTH; dbg->de_line_inits.pi_maximum_operations_per_instruction = /* Assuming the instruction set is not VLIW, used in the line table */ 1; dbg->de_line_inits.pi_opcode_base = /* is 10 in pro_line.h but should be 13 in DWARF3 and later. */ OPCODE_BASE; dbg->de_line_inits.pi_line_base = /* is -1 in pro_line.h */ LINE_BASE; dbg->de_line_inits.pi_line_range = /* is 4 in pro_line.h */ LINE_RANGE; /* Applies to line table and everywhere else for a CU. */ dbg->de_line_inits.pi_address_size = dbg->de_pointer_size; /* Assuming no segments. */ dbg->de_line_inits.pi_segment_selector_size = 0; dbg->de_line_inits.pi_segment_size = 0; } /* Ask to emit DW_LNE_set_address opcode explicitly. Used by be to emit start of a new .text section, or to force a relocated address into debug line information entry. */ Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error * error) { int res = 0; res = dwarf_lne_set_address_a(dbg,offs,symidx,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_lne_set_address_a(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned line_no = 0; Dwarf_Signed col_no = 0; Dwarf_Bool is_stmt = 0; Dwarf_Bool is_bb = 0; Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; opc = DW_LNE_set_address; retval = _dwarf_pro_add_line_entry(dbg, file_index, offs, symidx, line_no, col_no, is_stmt, is_bb, opc, isepilbeg, isprolend, isa, discriminator, error); return retval; } /* Ask to emit end_seqence opcode. Used normally at the end of a compilation unit. Can also be used in the middle if there are gaps in the region described by the code address. */ Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr end_address, Dwarf_Error * error) { int retval = 0; retval = dwarf_lne_end_sequence_a(dbg,end_address,error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_lne_end_sequence_a(Dwarf_P_Debug dbg, Dwarf_Addr end_address, Dwarf_Error * error) { Dwarf_Ubyte opc = 0; int retval = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned symidx = 0; Dwarf_Unsigned line_no = 0; Dwarf_Bool is_stmt = 0; Dwarf_Bool is_bb = 0; Dwarf_Signed col_no = 0;/* Wrong, should be unsigned. */ Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; opc = DW_LNE_end_sequence; retval = _dwarf_pro_add_line_entry(dbg, file_index, end_address, symidx, line_no, col_no, is_stmt, is_bb, opc, isepilbeg, isprolend, isa, discriminator, error); return retval; } /* As of December 2018 this returns DW_DLV_OK, DW_DLV_ERROR not 0, DW_DLV_NOCOUNT*/ /* Add an entry in the internal list of lines maintained by producer. Opc indicates if an opcode needs to be generated, rather than just an entry in the matrix. During opcodes generation time, these opcodes will be used. */ static int _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned symidx, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Ubyte opc, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { if (dbg->de_lines == NULL) { dbg->de_lines = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_lines == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_lines; _dwarf_pro_reg_init(dbg,dbg->de_lines); } else { dbg->de_last_line->dpl_next = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_last_line->dpl_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_last_line->dpl_next; _dwarf_pro_reg_init(dbg,dbg->de_last_line); } dbg->de_last_line->dpl_address = code_address; dbg->de_last_line->dpl_file = (unsigned long) file_index; dbg->de_last_line->dpl_line = (unsigned long) line_no; dbg->de_last_line->dpl_column = (unsigned long) col_no; dbg->de_last_line->dpl_is_stmt = is_stmt_begin; dbg->de_last_line->dpl_basic_block = is_bb_begin; dbg->de_last_line->dpl_opc = opc; dbg->de_last_line->dpl_r_symidx = symidx; dbg->de_last_line->dpl_prologue_end = isprolend; dbg->de_last_line->dpl_epilogue_begin = isepilbeg; dbg->de_last_line->dpl_isa = isa; dbg->de_last_line->dpl_discriminator = discriminator; return DW_DLV_OK; } /* Add a directory declaration to the debug_line section. Stored in linked list. */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; /* DW_DLV_NOCOUNT on error, de_n_inc_dirs on success. */ res = dwarf_add_directory_decl_a(dbg,name,&index,error); if (res != DW_DLV_OK) { return (Dwarf_Unsigned)DW_DLV_NOCOUNT; } return index; } int dwarf_add_directory_decl_a(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned *index_in_directories, Dwarf_Error * error) { if (dbg->de_inc_dirs == NULL) { dbg->de_inc_dirs = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_inc_dirs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_ERROR); } dbg->de_last_inc_dir = dbg->de_inc_dirs; dbg->de_n_inc_dirs = 1; } else { dbg->de_last_inc_dir->dfe_next = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_last_inc_dir->dfe_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_ERROR); } dbg->de_last_inc_dir = dbg->de_last_inc_dir->dfe_next; dbg->de_n_inc_dirs++; } dbg->de_last_inc_dir->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); if (dbg->de_last_inc_dir->dfe_name == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_ERROR); } strcpy(dbg->de_last_inc_dir->dfe_name, name); dbg->de_last_inc_dir->dfe_next = NULL; *index_in_directories = dbg->de_n_inc_dirs; return DW_DLV_OK; } /* Add a file entry declaration to the debug_line section. Stored in linked list. The data is immediately encoded as leb128 and stored in Dwarf_P_F_Entry_s struct. */ Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error * error) { Dwarf_Unsigned filecount = 0; int res = 0; res = dwarf_add_file_decl_a(dbg,name,dir_idx, time_mod,length,&filecount,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return filecount; } int dwarf_add_file_decl_a(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Unsigned *file_entry_count_out, Dwarf_Error * error) { Dwarf_P_F_Entry cur; char *ptr = 0; int nbytes_idx, nbytes_time, nbytes_len; char buffidx[ENCODE_SPACE_NEEDED]; char bufftime[ENCODE_SPACE_NEEDED]; char bufflen[ENCODE_SPACE_NEEDED]; int res = 0; if (dbg->de_file_entries == NULL) { dbg->de_file_entries = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_file_entries == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, DW_DLV_ERROR); } cur = dbg->de_file_entries; dbg->de_last_file_entry = cur; dbg->de_n_file_entries = 1; } else { cur = dbg->de_last_file_entry; cur->dfe_next = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (cur->dfe_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, DW_DLV_ERROR); } cur = cur->dfe_next; dbg->de_last_file_entry = cur; dbg->de_n_file_entries++; } cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); if (cur->dfe_name == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } strcpy((char *) cur->dfe_name, name); res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, buffidx, sizeof(buffidx)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time, bufftime, sizeof(bufftime)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, bufflen, sizeof(bufflen)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR,DW_DLV_ERROR); } cur->dfe_args = (char *) _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len); if (cur->dfe_args == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } ptr = cur->dfe_args; memcpy((void *) ptr, buffidx, nbytes_idx); ptr += nbytes_idx; memcpy((void *) ptr, bufftime, nbytes_time); ptr += nbytes_time; memcpy((void *) ptr, bufflen, nbytes_len); cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; cur->dfe_next = NULL; *file_entry_count_out = dbg->de_n_file_entries; return DW_DLV_OK; } /* Initialize a row of the matrix for line numbers, meaning initialize the struct corresponding to it */ void _dwarf_pro_reg_init(Dwarf_P_Debug dbg, Dwarf_P_Line cur_line) { cur_line->dpl_address = 0; cur_line->dpl_file = 1; cur_line->dpl_line = 1; cur_line->dpl_column = 0; cur_line->dpl_is_stmt = dbg->de_line_inits.pi_default_is_stmt; cur_line->dpl_basic_block = false; cur_line->dpl_next = NULL; cur_line->dpl_prologue_end = 0; cur_line->dpl_epilogue_begin = 0; cur_line->dpl_isa = 0; cur_line->dpl_discriminator = 0; cur_line->dpl_opc = 0; } libdwarf-20210528/libdwarf/dwarf_str_offsets.c0000664000175000017500000004667013764007262016202 00000000000000/* Copyright (C) 2018-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_str_offsets.h" #define TRUE 1 #define FALSE 0 #define STR_OFFSETS_MAGIC 0x2feed2 #define VALIDATE_SOT(xsot) \ if (!xsot) { \ _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULLARGUMENT);\ return DW_DLV_ERROR; \ } \ if (!xsot->so_dbg) { \ _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG);\ return DW_DLV_ERROR; \ } \ if (xsot->so_magic_value != STR_OFFSETS_MAGIC) { \ _dwarf_error(xsot->so_dbg,error, \ DW_DLE_STR_OFFSETS_NO_MAGIC); \ return DW_DLV_ERROR; \ } #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif int dwarf_open_str_offsets_table_access(Dwarf_Debug dbg, Dwarf_Str_Offsets_Table * table_data, Dwarf_Error * error) { int res = 0; Dwarf_Str_Offsets_Table local_table_data = 0; Dwarf_Small *offsets_start_ptr = 0; Dwarf_Unsigned sec_size = 0; if (!dbg) { _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG); return DW_DLV_ERROR; } if (!table_data) { _dwarf_error(dbg,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); return DW_DLV_ERROR; } /* Considered testing for *table_data being NULL, but not doing such a test. */ res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } offsets_start_ptr = dbg->de_debug_str_offsets.dss_data; if (!offsets_start_ptr) { return DW_DLV_NO_ENTRY; } sec_size = dbg->de_debug_str_offsets.dss_size; local_table_data = (Dwarf_Str_Offsets_Table)_dwarf_get_alloc(dbg, DW_DLA_STR_OFFSETS,1); if (!local_table_data) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } local_table_data->so_dbg = dbg; local_table_data->so_magic_value = STR_OFFSETS_MAGIC; local_table_data->so_section_start_ptr = offsets_start_ptr; local_table_data->so_section_end_ptr = offsets_start_ptr + sec_size; local_table_data->so_section_size = sec_size; local_table_data->so_next_table_offset = 0; local_table_data->so_wasted_section_bytes = 0; /* get_alloc zeroed all the bits, no need to repeat that here. */ *table_data = local_table_data; return DW_DLV_OK; } int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table table_data, Dwarf_Error * error) { Dwarf_Debug dbg = 0; VALIDATE_SOT(table_data) dbg = table_data->so_dbg; table_data->so_magic_value = 0xdead; dwarf_dealloc(dbg,table_data, DW_DLA_STR_OFFSETS); return DW_DLV_OK; } int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned index, Dwarf_Unsigned *stroffset, Dwarf_Error *error) { Dwarf_Small *entryptr = 0; Dwarf_Unsigned val = 0; VALIDATE_SOT(sot) if (index >= sot->so_array_entry_count) { _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG); return DW_DLV_ERROR; } entryptr = sot->so_array_ptr + (index * sot->so_array_entry_size); READ_UNALIGNED_CK(sot->so_dbg, val, Dwarf_Unsigned, entryptr, sot->so_array_entry_size,error,sot->so_end_cu_ptr); *stroffset = val; return DW_DLV_OK; } /* The minimum possible area .debug_str_offsets header . */ #define MIN_HEADER_LENGTH 8 /* New April 2018. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ static int is_all_zeroes(Dwarf_Small*start, Dwarf_Small*end) { if (start >= end) { /* We should not get here, this is just a defensive test. */ return TRUE; } for ( ; start < end; ++start) { if (!*start) { /* There is some garbage here. */ return FALSE; } } /* All just zero bytes. */ return TRUE; } int _dwarf_trial_read_dwarf_five_hdr(Dwarf_Debug dbg, Dwarf_Small *table_start_ptr, Dwarf_Unsigned secsize, Dwarf_Small * secendptr, Dwarf_Unsigned *length_out, Dwarf_Half *local_offset_size_out, Dwarf_Half *local_extension_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Error *error) { Dwarf_Unsigned length = 0; /* length following the local_offset_size + local_extension_size */ Dwarf_Unsigned local_offset_size = 0; Dwarf_Unsigned local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; READ_AREA_LENGTH_CK(dbg,length,Dwarf_Unsigned, table_start_ptr,local_offset_size, local_extension_size,error, secsize,secendptr); /* The 'length' part of any header is local_extension_size + local_offset_size. The length of an offset in the section is just local_offset_size. Standard DWARF2 sums to 4. Standard DWARF3,4,5 sums to 4 or 12. Nonstandard SGI IRIX 64bit dwarf sums to 8 (SGI IRIX was all DWARF2 and could not have a .debug_str_offsets section). The header includes 2 bytes of version and two bytes of padding. */ if (length < 4) { /* Usually DW4-style .debug_str_offsets starts off with a zero value to ref the base string in .debug_str. Any tiny value is guaranteed not to be a legal DWARF5 .debug_str_offsets section. */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_SECTION_SIZE_ERROR: " "header length 0x%x is too small " "to be a real .debug_str_offsets " "DWARF5 section", length); _dwarf_error_string(dbg,error, DW_DLE_SECTION_SIZE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (length > secsize || secsize < /* 4 is for the version and padding bytes. */ (length+local_extension_size +local_offset_size)) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_STR_OFFSETS_ARRAY_SIZE: " " header length 0x%x is bigger than ", length); dwarfstring_append_printf_u(&m, ".debug_str_offsets section size of 0x%x." " Perhaps the section is a GNU DWARF4" " extension with a different format.", secsize); _dwarf_error_string(dbg,error, DW_DLE_STR_OFFSETS_ARRAY_SIZE, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* table_start_ptr was incremented past the length data. */ READ_UNALIGNED_CK(dbg, version, Dwarf_Half, table_start_ptr, DWARF_HALF_SIZE, error,secendptr); table_start_ptr += DWARF_HALF_SIZE; if (version != DW_STR_OFFSETS_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_STR_OFFSETS_VERSION_WRONG: " "%u. Only version 5 is supported " "when reading .debug_str_offsets." " Perhaps the section is a GNU DWARF4" " extension with a different format.", version); _dwarf_error_string(dbg,error, DW_DLE_STR_OFFSETS_VERSION_WRONG, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, padding, Dwarf_Half, table_start_ptr, DWARF_HALF_SIZE, error,secendptr); /* padding should be zero, but we are not checking it here at present. */ *length_out = length; *local_offset_size_out = local_offset_size; *local_extension_size_out = local_extension_size; *version_out = version; *padding_out = padding; return DW_DLV_OK; } /* Used by code reading attributes/forms and also by code reading the raw .debug_str_offsets section, hence the code allows for output arguments to be zero. If cucontext is null it means the call part of trying to print the section without accessing any context. dwarfdump option --print-str-offsets. New 30 August 2020. */ int _dwarf_read_str_offsets_header(Dwarf_Debug dbg, Dwarf_Small* table_start_ptr, Dwarf_Unsigned secsize, Dwarf_Small* secendptr, Dwarf_CU_Context cucontext, /* Followed by return values/error */ Dwarf_Unsigned *length_out, Dwarf_Half *offset_size_out, Dwarf_Half *extension_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned *header_length_out, Dwarf_Error *error) { Dwarf_Unsigned length = 0; Dwarf_Half local_offset_size = 0; Dwarf_Half local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; Dwarf_Unsigned headerlength = 0; int res = 0; Dwarf_Bool is_dwarf_five = TRUE; if (cucontext) { if (cucontext->cc_str_offsets_header_length_present) { /* cu_context has what it needs already and we do not need the rest of what the interface provides */ return DW_DLV_OK; } } { res = _dwarf_trial_read_dwarf_five_hdr(dbg, table_start_ptr,secsize, secendptr, &length, &local_offset_size, &local_extension_size, &version, &padding, error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } /* If it's really DWARF5 but with a serious problem this will think...NOT 5! */ is_dwarf_five = FALSE; } } if ( !is_dwarf_five) { length = secsize; /* This is likely GNU Dwarf4 extension .debug_str_offsets, and offset size is not going to be 8 de_length_size is most likely a guess and not set properly at this point */ local_offset_size = 4; local_extension_size = 0; version = DW_STR_OFFSETS_VERSION4; padding = 0; } if (length_out) { *length_out = length; } if (offset_size_out) { *offset_size_out = local_offset_size; } if (extension_size_out) { *extension_size_out = local_extension_size; } if (version_out) { *version_out = version; } if (padding_out) { *padding_out = padding; } if (is_dwarf_five) { headerlength = local_offset_size + local_extension_size + 2*DWARF_HALF_SIZE; } else { /* DWARF4 */ headerlength = 0; } if (header_length_out) { *header_length_out = headerlength; } if (cucontext) { cucontext->cc_str_offsets_header_length_present = TRUE; cucontext->cc_str_offsets_header_length = headerlength; cucontext->cc_str_offsets_offset_size = local_offset_size; } return DW_DLV_OK; } int dwarf_next_str_offsets_table(Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned *unit_length_out, Dwarf_Unsigned *unit_length_offset_out, Dwarf_Unsigned *table_start_offset_out, Dwarf_Half *entry_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned *table_value_count_out, Dwarf_Error * error) { Dwarf_Small *table_header_ptr = 0; Dwarf_Small *array_start_ptr = 0; Dwarf_Small *table_end_ptr = 0; Dwarf_Unsigned table_header_offset = 0; Dwarf_Unsigned table_end_offset = 0; Dwarf_Unsigned array_start_offset = 0; Dwarf_Unsigned length = 0; Dwarf_Half local_length_size = 0; Dwarf_Half local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; Dwarf_Unsigned header_length = 0; int res = 0; VALIDATE_SOT(sot) table_header_offset = sot->so_next_table_offset; if (table_header_offset >= sot->so_section_size) { return DW_DLV_NO_ENTRY; } table_header_ptr = sot->so_section_start_ptr + table_header_offset; sot->so_header_ptr = table_header_ptr; if (table_header_ptr >= sot->so_section_end_ptr) { if (table_header_ptr == sot->so_section_end_ptr) { /* At end of section. Done. */ return DW_DLV_NO_ENTRY; } else { /* bogus table offset. */ Dwarf_Unsigned len = 0; dwarfstring m; /* ptrdiff_t is generated but not named */ len = (sot->so_section_end_ptr >= table_header_ptr)? (sot->so_section_end_ptr - table_header_ptr): 0xffffffff; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "DW_DLE_STR_OFFSETS_EXTRA_BYTES: " "Table Offset is %" DW_PR_DSd " bytes past end of section",len); _dwarf_error_string(sot->so_dbg,error, DW_DLE_STR_OFFSETS_EXTRA_BYTES, dwarfstring_string(&m)); dwarfstring_destructor(&m); } } if ((table_header_ptr + MIN_HEADER_LENGTH) > sot->so_section_end_ptr) { /* We have a too-short section it appears. Should we generate error? Or ignore? As of March 10 2020 we check for garbage bytes in-section. */ dwarfstring m; Dwarf_Small *hend = 0; Dwarf_Unsigned len = 0; if (is_all_zeroes(table_header_ptr,sot->so_section_end_ptr)){ return DW_DLV_NO_ENTRY; } hend = table_header_ptr + MIN_HEADER_LENGTH; /* ptrdiff_t is generated but not named */ len = (hend >= sot->so_section_end_ptr)? (hend - sot->so_section_end_ptr): 0xffffffff; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "DW_DLE_STR_OFFSETS_EXTRA_BYTES: " "Table Offset plus a minimal header is %" DW_PR_DSd " bytes past end of section" " and some bytes in-section are non-zero",len); _dwarf_error_string(sot->so_dbg,error, DW_DLE_STR_OFFSETS_EXTRA_BYTES, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } res = _dwarf_read_str_offsets_header(sot->so_dbg, table_header_ptr,sot->so_section_size, sot->so_section_end_ptr, 0, &length, &local_length_size, &local_extension_size, &version, &padding, &header_length, error); if (res != DW_DLV_OK) { return res; } if (version == DW_STR_OFFSETS_VERSION5) { array_start_ptr = table_header_ptr + header_length; array_start_offset = table_header_offset +header_length; table_end_ptr = table_header_ptr + local_length_size +local_extension_size + length; table_end_offset = table_header_offset + local_length_size +local_extension_size + +length; } else { array_start_ptr = table_header_ptr; array_start_offset = table_header_offset; table_end_ptr = table_header_ptr + sot->so_section_size; table_end_offset = table_header_offset + sot->so_section_size; } /* So now table_start_ptr points to a table of local_length_size entries. Each entry in this table is local_length_size bytes long: 4 or 8. */ { Dwarf_Unsigned entrycount = 0; Dwarf_Unsigned entrybytes = 0; entrybytes = table_end_offset - array_start_offset; if (entrybytes % local_length_size) { _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_ARRAY_SIZE); return DW_DLV_ERROR; } entrycount = entrybytes/local_length_size; sot->so_next_table_offset = table_end_offset; sot->so_end_cu_ptr = table_end_ptr; sot->so_table_start_offset = table_header_offset; sot->so_array_ptr = array_start_ptr; sot->so_array_start_offset = array_start_offset; sot->so_array_entry_count = entrycount; sot->so_array_entry_size = local_length_size; sot->so_table_count += 1; /* The data length in bytes following the unit_length field of the header. */ *unit_length_out = length; /* Where the unit_length field starts in the section. */ *unit_length_offset_out = sot->so_table_start_offset; /* Where the table of offsets starts in the section. */ *table_start_offset_out = sot->so_array_start_offset; /* Entrysize: 4 or 8 */ *entry_size_out = local_length_size; /* Version is 5. */ *version_out = version; /* This is supposed to be zero. */ *padding_out = padding; /* How many entry_size entries are in the array. */ *table_value_count_out = entrycount; return DW_DLV_OK; } } /* Meant to be called after all tables accessed using dwarf_next_str_offsets_table(). */ int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table table_data, Dwarf_Unsigned * wasted_byte_count, Dwarf_Unsigned * table_count, Dwarf_Error * error) { VALIDATE_SOT(table_data) if (wasted_byte_count) { *wasted_byte_count = table_data->so_wasted_section_bytes; } if (table_count) { *table_count = table_data->so_table_count; } return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_types.h0000644000175000017500000000243513743575426014505 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* pro_types.h */ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,/* in de_elf_sects etc */ Dwarf_Signed *nbufs_out, Dwarf_Error * error); libdwarf-20210528/libdwarf/dwarf_elf_reloc_386.h0000664000175000017500000000653613644370703016175 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_386(unsigned long); #ifndef R_386_NONE #define R_386_NONE 0 #endif /* R_386_NONE */ #ifndef R_386_32 #define R_386_32 1 #endif /* R_386_32 */ #ifndef R_386_PC32 #define R_386_PC32 2 #endif /* R_386_PC32 */ #ifndef R_386_GOT32 #define R_386_GOT32 3 #endif /* R_386_GOT32 */ #ifndef R_386_PLT32 #define R_386_PLT32 4 #endif /* R_386_PLT32 */ #ifndef R_386_COPY #define R_386_COPY 5 #endif /* R_386_COPY */ #ifndef R_386_GLOB_DAT #define R_386_GLOB_DAT 6 #endif /* R_386_GLOB_DAT */ #ifndef R_386_JMP_SLOT #define R_386_JMP_SLOT 7 #endif /* R_386_JMP_SLOT */ #ifndef R_386_RELATIVE #define R_386_RELATIVE 8 #endif /* R_386_RELATIVE */ #ifndef R_386_GOTOFF #define R_386_GOTOFF 9 #endif /* R_386_GOTOFF */ #ifndef R_386_GOTPC #define R_386_GOTPC 10 #endif /* R_386_GOTPC */ #ifndef R_386_32PLT #define R_386_32PLT 11 #endif /* R_386_32PLT */ #ifndef R_386_TLS_TPOFF #define R_386_TLS_TPOFF 14 #endif /* R_386_TLS_TPOFF */ #ifndef R_386_TLS_IE #define R_386_TLS_IE 15 #endif /* R_386_TLS_IE */ #ifndef R_386_TLS_GOTIE #define R_386_TLS_GOTIE 16 #endif /* R_386_TLS_GOTIE */ #ifndef R_386_TLS_LE #define R_386_TLS_LE 17 #endif /* R_386_TLS_LE */ #ifndef R_386_TLS_LDM #define R_386_TLS_LDM 19 #endif /* R_386_TLS_LDM */ #ifndef R_386_16 #define R_386_16 20 #endif /* R_386_16 */ #ifndef R_386_PC16 #define R_386_PC16 21 #endif /* R_386_PC16 */ #ifndef R_386_8 #define R_386_8 22 #endif /* R_386_8 */ #ifndef R_386_PC8 #define R_386_PC8 23 #endif /* R_386_PC8 */ #ifndef R_386_TLS_GD_32 #define R_386_TLS_GD_32 24 #endif /* R_386_TLS_GD_32 */ #ifndef R_386_TLS_GD_PUSH #define R_386_TLS_GD_PUSH 25 #endif /* R_386_TLS_GD_PUSH */ #ifndef R_386_TLS_GD_CALL #define R_386_TLS_GD_CALL 26 #endif /* R_386_TLS_GD_CALL */ #ifndef R_386_TLS_GD_POP #define R_386_TLS_GD_POP 27 #endif /* R_386_TLS_GD_POP */ #ifndef R_386_TLS_LDM_32 #define R_386_TLS_LDM_32 28 #endif /* R_386_TLS_LDM_32 */ #ifndef R_386_TLS_LDM_PUSH #define R_386_TLS_LDM_PUSH 29 #endif /* R_386_TLS_LDM_PUSH */ #ifndef R_386_TLS_LDM_CALL #define R_386_TLS_LDM_CALL 30 #endif /* R_386_TLS_LDM_CALL */ #ifndef R_386_TLS_LDM_POP #define R_386_TLS_LDM_POP 31 #endif /* R_386_TLS_LDM_POP */ #ifndef R_386_TLS_LDO_32 #define R_386_TLS_LDO_32 32 #endif /* R_386_TLS_LDO_32 */ #ifndef R_386_TLS_IE_32 #define R_386_TLS_IE_32 33 #endif /* R_386_TLS_IE_32 */ #ifndef R_386_TLS_LE_32 #define R_386_TLS_LE_32 34 #endif /* R_386_TLS_LE_32 */ #ifndef R_386_TLS_DTPMOD32 #define R_386_TLS_DTPMOD32 35 #endif /* R_386_TLS_DTPMOD32 */ #ifndef R_386_TLS_DTPOFF32 #define R_386_TLS_DTPOFF32 36 #endif /* R_386_TLS_DTPOFF32 */ #ifndef R_386_TLS_TPOFF32 #define R_386_TLS_TPOFF32 37 #endif /* R_386_TLS_TPOFF32 */ #ifndef R_386_SIZE32 #define R_386_SIZE32 38 #endif /* R_386_SIZE32 */ #ifndef R_386_TLS_GOTDESC #define R_386_TLS_GOTDESC 39 #endif /* R_386_TLS_GOTDESC */ #ifndef R_386_TLS_DESC_CALL #define R_386_TLS_DESC_CALL 40 #endif /* R_386_TLS_DESC_CALL */ #ifndef R_386_TLS_DESC #define R_386_TLS_DESC 41 #endif /* R_386_TLS_DESC */ #ifndef R_386_IRELATIVE #define R_386_IRELATIVE 42 #endif /* R_386_IRELATIVE */ libdwarf-20210528/libdwarf/dwarf_reloc_ppc64.h0000644000175000017500000003260013763277233015756 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_PPC64_H #define DWARF_RELOC_PPC64_H /* Definitions for PPC64 */ #define DWARF_RELOC_PPC64 /* Include the definitions only in the case of Windows */ #ifdef _WIN32 #include "dwarf_reloc_ppc.h" /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE #define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */ #define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned.*/ #define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */ /* lower 16bits of abs. address. */ #define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* high 16bits of abs. address. */ #define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI #define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ #define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned.*/ #define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN #define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN #define R_PPC64_REL24 R_PPC_REL24 /*PC relative 26 bit, word aligned*/ #define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */ #define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN #define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN #define R_PPC64_GOT16 R_PPC_GOT16 #define R_PPC64_GOT16_LO R_PPC_GOT16_LO #define R_PPC64_GOT16_HI R_PPC_GOT16_HI #define R_PPC64_GOT16_HA R_PPC_GOT16_HA #define R_PPC64_COPY R_PPC_COPY #define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT #define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT #define R_PPC64_RELATIVE R_PPC_RELATIVE #define R_PPC64_UADDR32 R_PPC_UADDR32 #define R_PPC64_UADDR16 R_PPC_UADDR16 #define R_PPC64_REL32 R_PPC_REL32 #define R_PPC64_PLT32 R_PPC_PLT32 #define R_PPC64_PLTREL32 R_PPC_PLTREL32 #define R_PPC64_PLT16_LO R_PPC_PLT16_LO #define R_PPC64_PLT16_HI R_PPC_PLT16_HI #define R_PPC64_PLT16_HA R_PPC_PLT16_HA #define R_PPC64_SECTOFF R_PPC_SECTOFF #define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO #define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI #define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA #define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ #define R_PPC64_ADDR64 38 /* doubleword64 S + A. */ #define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ #define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ #define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ #define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ #define R_PPC64_UADDR64 43 /* doubleword64 S + A. */ #define R_PPC64_REL64 44 /* doubleword64 S + A - P. */ #define R_PPC64_PLT64 45 /* doubleword64 L + A. */ #define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ #define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ #define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ #define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ #define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ #define R_PPC64_TOC 51 /* doubleword64 .TOC. */ #define R_PPC64_PLTGOT16 52 /* half16* M + A. */ #define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ #define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ #define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ #define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ #define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ #define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ #define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ #define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ #define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ #define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ #define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ #define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2.*/ #define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ #define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ /* PowerPC64 relocations defined for the TLS access ABI. */ #define R_PPC64_TLS 67 /* none (sym+add)@tls */ #define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ #define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ #define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ #define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ #define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ #define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ #define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ #define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ #define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ #define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ #define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ #define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ #define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ #define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ #define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ #define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ #define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ #define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ #define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ #define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ /* half16ds (sym+add)@got@tprel@l */ #define R_PPC64_GOT_TPREL16_LO_DS 88 #define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ #define R_PPC64_GOT_TPREL16_HA 90 /*half16 (sym+add)@got@tprel@ha */ #define R_PPC64_GOT_DTPREL16_DS 91 /*half16ds* (sym+add)@got@dtprel */ /*half16ds (sym+add)@got@dtprel@l */ #define R_PPC64_GOT_DTPREL16_LO_DS 92 #define R_PPC64_GOT_DTPREL16_HI 93 /*half16 (sym+add)@got@dtprel@h */ #define R_PPC64_GOT_DTPREL16_HA 94 /*half16 (sym+add)@got@dtprel@ha */ #define R_PPC64_TPREL16_DS 95 /*half16ds* (sym+add)@tprel */ #define R_PPC64_TPREL16_LO_DS 96 /*half16ds (sym+add)@tprel@l */ #define R_PPC64_TPREL16_HIGHER 97 /*half16 (sym+add)@tprel@higher */ #define R_PPC64_TPREL16_HIGHERA 98 /*half16 (sym+add)@tprel@highera */ #define R_PPC64_TPREL16_HIGHEST 99 /* half16(sym+add)@tprel@highest */ /* half16 (sym+add)@tprel@highesta */ #define R_PPC64_TPREL16_HIGHESTA 100 #define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ #define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ /* half16 (sym+add)@dtprel@higher */ #define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@highera */ #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highest */ #define R_PPC64_DTPREL16_HIGHEST 105 /*half16 (sym+add)@dtprel@highesta */ #define R_PPC64_DTPREL16_HIGHESTA 106 /* Additional relocation types */ #define R_PPC64_TOC32 107 #define R_PPC64_DTPMOD32 108 #define R_PPC64_TPREL32 109 #define R_PPC64_DTPREL32 110 /* Keep this the last entry. */ #define R_PPC64_NUM 111 #endif /* _WIN32 */ /* PowerPC64 relocations defined by the ABIs */ static const char *reloc_type_names_PPC64[] = { "R_PPC64_NONE", /* 00 */ "R_PPC64_ADDR32", /* 01 */ "R_PPC64_ADDR24", /* 02 */ "R_PPC64_ADDR16", /* 03 */ "R_PPC64_ADDR16_LO", /* 04 */ "R_PPC64_ADDR16_HI", /* 05 */ "R_PPC64_ADDR16_HA", /* 06 */ "R_PPC64_ADDR14", /* 07 */ "R_PPC64_ADDR14_BRTAKEN", /* 08 */ "R_PPC64_ADDR14_BRNTAKEN", /* 09 */ "R_PPC64_REL24", /* 10 */ "R_PPC64_REL14", /* 11 */ "R_PPC64_REL14_BRTAKEN", /* 12 */ "R_PPC64_REL14_BRNTAKEN", /* 13 */ "R_PPC64_GOT16", /* 14 */ "R_PPC64_GOT16_LO", /* 15 */ "R_PPC64_GOT16_HI", /* 16 */ "R_PPC64_GOT16_HA", /* 17 */ "R_PPC64_PLTREL24", /* 18 */ "R_PPC64_COPY", /* 19 */ "R_PPC64_GLOB_DAT", /* 20 */ "R_PPC64_JMP_SLOT", /* 21 */ "R_PPC64_RELATIVE", /* 22 */ "R_PPC64_LOCAL24PC", /* 23 */ "R_PPC64_UADDR32", /* 24 */ "R_PPC64_UADDR16", /* 25 */ "R_PPC64_REL32", /* 26 */ "R_PPC64_PLT32", /* 27 */ "R_PPC64_PLTREL32", /* 28 */ "R_PPC64_PLT16_LO", /* 29 */ "R_PPC64_PLT16_HI", /* 30 */ "R_PPC64_PLT16_HA", /* 31 */ "R_PPC64_SDAREL16", /* 32 */ "R_PPC64_SECTOFF", /* 33 */ "R_PPC64_SECTOFF_LO", /* 34 */ "R_PPC64_SECTOFF_HI", /* 35 */ "R_PPC64_SECTOFF_HA", /* 36 */ "R_PPC64_REL30", /* 37 */ "R_PPC64_ADDR64", /* 38 */ "R_PPC64_ADDR16_HIGHER", /* 39 */ "R_PPC64_ADDR16_HIGHERA", /* 40 */ "R_PPC64_ADDR16_HIGHEST", /* 41 */ "R_PPC64_ADDR16_HIGHESTA", /* 42 */ "R_PPC64_UADDR64", /* 43 */ "R_PPC64_REL64", /* 44 */ "R_PPC64_PLT64", /* 45 */ "R_PPC64_PLTREL64", /* 46 */ "R_PPC64_TOC16", /* 47 */ "R_PPC64_TOC16_LO", /* 48 */ "R_PPC64_TOC16_HI", /* 49 */ "R_PPC64_TOC16_HA", /* 50 */ "R_PPC64_TOC", /* 51 */ "R_PPC64_PLTGOT16", /* 52 */ "R_PPC64_PLTGOT16_LO", /* 53 */ "R_PPC64_PLTGOT16_HI", /* 54 */ "R_PPC64_PLTGOT16_HA", /* 55 */ "R_PPC64_ADDR16_DS", /* 56 */ "R_PPC64_ADDR16_LO_DS", /* 57 */ "R_PPC64_GOT16_DS", /* 58 */ "R_PPC64_GOT16_LO_DS", /* 59 */ "R_PPC64_PLT16_LO_DS", /* 60 */ "R_PPC64_SECTOFF_DS", /* 61 */ "R_PPC64_SECTOFF_LO_DS", /* 62 */ "R_PPC64_TOC16_DS", /* 63 */ "R_PPC64_TOC16_LO_DS", /* 64 */ "R_PPC64_PLTGOT16_DS", /* 65 */ "R_PPC64_PLTGOT16_LO_DS", /* 66 */ "R_PPC64_TLS", /* 67 */ "R_PPC64_DTPMOD32", /* 68 */ "R_PPC64_TPREL16", /* 69 */ "R_PPC64_TPREL16_LO", /* 70 */ "R_PPC64_TPREL16_HI", /* 71 */ "R_PPC64_TPREL16_HA", /* 72 */ "R_PPC64_TPREL32", /* 73 */ "R_PPC64_DTPREL16", /* 74 */ "R_PPC64_DTPREL16_LO", /* 75 */ "R_PPC64_DTPREL16_HI", /* 76 */ "R_PPC64_DTPREL16_HA", /* 77 */ "R_PPC64_DTPREL64", /* 78 */ "R_PPC64_GOT_TLSGD16", /* 79 */ "R_PPC64_GOT_TLSGD16_LO", /* 80 */ "R_PPC64_GOT_TLSGD16_HI", /* 81 */ "R_PPC64_GOT_TLSGD16_HA", /* 82 */ "R_PPC64_GOT_TLSLD16", /* 83 */ "R_PPC64_GOT_TLSLD16_LO", /* 84 */ "R_PPC64_GOT_TLSLD16_HI", /* 85 */ "R_PPC64_GOT_TLSLD16_HA", /* 86 */ "R_PPC64_GOT_TPREL16_DS", /* 87 */ "R_PPC64_GOT_TPREL16_LO", /* 88 */ "R_PPC64_GOT_TPREL16_HI", /* 89 */ "R_PPC64_GOT_TPREL16_HA", /* 90 */ "R_PPC64_GOT_DTPREL16", /* 91 */ "R_PPC64_GOT_DTPREL16_LO", /* 92 */ "R_PPC64_GOT_DTPREL16_HI", /* 93 */ "R_PPC64_GOT_DTPREL16_HA", /* 94 */ "R_PPC64_TPREL16_DS", /* 95 */ "R_PPC64_TPREL16_LO_DS", /* 96 */ "R_PPC64_TPREL16_HIGHER", /* 97 */ "R_PPC64_TPREL16_HIGHERA", /* 98 */ "R_PPC64_TPREL16_HIGHEST", /* 99 */ "R_PPC64_TPREL16_HIGHESTA", /* 100 */ "R_PPC64_DTPREL16_DS", /* 101 */ "R_PPC64_DTPREL16_LO_DS", /* 102 */ "R_PPC64_DTPREL16_HIGHER", /* 103 */ "R_PPC64_DTPREL16_HIGHERA", /* 104 */ "R_PPC64_DTPREL16_HIGHEST", /* 105 */ "R_PPC64_DTPREL16_HIGHESTA", /* 106 */ "R_PPC64_TOC32", /* 107 */ "R_PPC64_DTPMOD32", /* 108 */ "R_PPC64_TPREL32", /* 109 */ "R_PPC64_DTPREL32", /* 110 */ }; #endif /* DWARF_RELOC_PPC64_H */ libdwarf-20210528/libdwarf/dwarf_object_read_common.h0000664000175000017500000000327613644370703017452 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_OBJECT_READ_COMMON_H #define DWARF_OBJECT_READ_COMMON_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int _dwarf_object_read_random(int fd,char *buf,off_t loc, size_t size,off_t filesize,int *errc); void _dwarf_safe_strcpy(char *out, long outlen, const char *in, long inlen); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_OBJECT_READ_COMMON_H */ libdwarf-20210528/libdwarf/CHANGES0000664000175000017500000000747613644370703013306 00000000000000 ------------------------------------------------------------- April 14, 2000 davea@sgi.com Corrected minor bugs in production of 32bit dwarf with 64 bit pointers. Fixed omissions in legal DIE children of a DIE. Make small changes in description of regster output in frame information access. ------------------------------------------------------------- Mar 7, 2000 davea@sgi.com Corrected line table reading so it will handle reading an object with a diffent number of standard op codes than at libdwarf compile time. This was possible all along, but libdwarf did not do it right. ------------------------------------------------------------- Dec 8, 1999 davea@sgi.com Changed nearly all files. Adding the capability to read and produce the new, accepted by committee, but not released-publically 64bit extension proposal dwarf data. This allows dwarf compilation units with 64bit section offsets and 32bit sections offsets to be mixed. So that offsets can grow very large with 64-bit pointer applications (though 64bit pointers and 64bit offsets are not the same notion). In addition, removed all the contents (or nearly all) of the dwarf_funcs.c dwarf_weaks.c dwarf_vars.c, and dwarf_types.c, as the data format is identical to dwarf globals (pubnames) and there is no need to duplicate all that code. All these sections whose contents were gutted are things that are formatted exactly like pubnames, and all are sgi extensions. Now the implementation uses pubnames code (dwarf_global.c) to do the work for all the pubnames-like sections. The (minor, IMO) difference is that in case of an incorrect dwarf file (leading to libdwarf being unable to process something in one of the sgi-specific pubnames-like sections) the dwarf error string may reference pubnames when weaks, static functions, static variables, or global typenames are actually the problem. This is fixable, however the price would appear to be that even globals would need to call a helper function (to pass in the correct error return). Right now the dwarf_weaks.c calls the dwarf_global.c function, for example, with no extra arguments indicating the true section involved. (Other approaches keeping the original error codes exist. Producing the code uniquely via macros seems unappealing. Inline functions would be ok though. This version does not inline the functions we are talking about, such as dwarf_global_name_offsets() when called from dwarf_type_name_offsets().) Since these extra sections are SGI only and only really used by SGI's workshop product, and the performance hit is small, the extra function calls in reading each seem acceptable. ------------------------------------------------------------- Sep 29,1999 davea@sgi.com Changed many files, so that it is easy to switch from 32bit-offset-only (like cygnus and dwarf2 v 2.0.0) to sgi/mips 64 bit dwarf. See NEWS for more info on 32bit-offset. ------------------------------------------------------------- Since Oct 95 and before May, 1996 Added the function dwarf_get_cie_of_fde() which makes it possible to remember a single fde/cie set out of a block usefully. Enhanced doc of dwarf_bitoffset() Added new function dwarf_global_formref() so all reference forms can be retrieved. Fixed bug in retrieving array bounds: was failing to sign extend formsdata. Added function dwarf_get_fde_info_for_all_regs(), which makes retrieval of the complete set of registers (as needed by debuggers and exception handlers) effectively N times faster than getting them one a time where N is the number of registers. Added support for exception table handling (really just support for a reference to an exception table for c++ exceptions). Fixed a bug where useless extra space (several megabytes) were malloc'ed for the abbreviations table by the libdwarf consumer code. davea@sgi.com ------------------------------------------------------------- libdwarf-20210528/libdwarf/runtests.sh0000775000175000017500000000233613763455500014530 00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run in the libdwarf directory # Run only after config.h created in a configure # in the source directory top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/libdwarf goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status was $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } CC=cc CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf" $CC $CFLAGS $srcdir/dwarf_leb_test.c $srcdir/dwarf_leb.c $srcdir/pro_encode_nm.c -o dwarfleb chkres $? "compiling dwarfleb test" ./dwarfleb chkres $? "Running dwarfleb test" rm ./dwarfleb $CC $CFLAGS $srcdir/dwarf_tied_test.c $srcdir/dwarf_tied.c $srcdir/dwarf_tsearchhash.c -o dwarftied chkres $? "compiling dwarftied test" ./dwarftied chkres $? "Running dwarftiedtest test" rm ./dwarftied $CC $CFLAGS $srcdir/test_headersok.c -o dwarfheadersok chkres $? "compiling test_headersok.c" rm ./test_headersok if [ $failcount -ne 0 ] then echo "FAIL $failcount in libdwarf/runtests.sh" exit 1 fi exit 0 libdwarf-20210528/libdwarf/dwarf_opaque.h0000664000175000017500000011650114012266121015113 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Following the nomenclature of the DWARF standard Section Version Numbers (DWARF 5): * means not applicable. - means not defined in that version. The version numbers for .debug_info is the same as .debug_info.dwo (etc for the other dwo sections). The versions applicable by section are: . DWARF2 DWARF3 DWARF4 DWARF5 .debug_abbrev * * * * .debug_addr - - - 5 .debug_aranges 2 2 2 2 .debug_frame 1 3 4 4 .debug_info 2 3 4 5 .debug_line 2 3 4 5 .debug_line_str - - - 5 .debug_loc * * * - .debug_loclists - - - 5 .debug_macinfo * * * - .debug_macro - - - 5 .debug_names - - - 5 .debug_pubnames 2 2 2 - .debug_pubtypes - 2 2 - .debug_ranges - * * - .debug_rnglists - - - 5 .debug_str * * * * .debug_str_offsets - - - 5 .debug_sup - - - 5 .debug_types - - 4 - .debug_abbrev.dwo - - - * .debug_info.dwo - - - 5 .debug_line.dwo - - - 5 .debug_loc.dwo - - - - .debug_loclists.dwo - - - 5 .debug_macro.dwo - - - 5 .debug_rnglists.dwo - - - 5 .debug_str.dwo - - - * .debug_str_offsets.dwo - - - 5 .debug_cu_index - - - 5 .debug_tu_index - - - 5 */ struct Dwarf_Rnglists_Context_s; typedef struct Dwarf_Rnglists_Context_s *Dwarf_Rnglists_Context; struct Dwarf_Loclists_Context_s; typedef struct Dwarf_Loclists_Context_s *Dwarf_Loclists_Context; struct Dwarf_Die_s { Dwarf_Byte_Ptr di_debug_ptr; Dwarf_Abbrev_List di_abbrev_list; Dwarf_CU_Context di_cu_context; int di_abbrev_code; /* TRUE if part of debug_info. FALSE if part of .debug_types. */ Dwarf_Bool di_is_info; }; struct Dwarf_Attribute_s { Dwarf_Half ar_attribute; /* Attribute Value. */ Dwarf_Half ar_attribute_form; /* Attribute Form. */ Dwarf_Half ar_attribute_form_direct; /* Identical to ar_attribute_form except that if the original form uleb was DW_FORM_indirect, ar_attribute_form_direct contains DW_FORM_indirect but ar_attribute_form contains the true form. */ Dwarf_CU_Context ar_cu_context; /* The following points to either debug_info or debug_types depending on if context is cc_is_info or not. */ Dwarf_Small *ar_debug_ptr; /* If DW_FORM_implicit const, the value is here, not in the DIE. */ Dwarf_Signed ar_implicit_const; Dwarf_Debug ar_dbg; /* dbg owning the attr */ Dwarf_Die ar_die;/* Access to the DIE owning the attribute */ Dwarf_Attribute ar_next; }; /* This structure provides the context for a compilation unit. Thus, it contains the Dwarf_Debug, cc_dbg, that this cu belongs to. It contains the information in the compilation unit header, cc_length, cc_version_stamp, cc_abbrev_offset, and cc_address_size, in the .debug_info section for that cu. In addition, it contains the count, cc_count_cu, of the cu number of that cu in the list of cu's in the .debug_info. The count starts at 1, ie cc_count_cu is 1 for the first cu, 2 for the second and so on. This struct also contains a pointer, to a list of pairs of abbrev code and a pointer to the start of that abbrev in the .debug_abbrev section. Each die will also contain a pointer to such a struct to record the context for that die. Notice that a pointer to the CU DIE itself is Dwarf_Off off2 = cu_context->cc_debug_info_offset; cu_die_info_ptr = dbg->de_debug_info.dss_data + off2 + _dwarf_length_of_cu_header(dbg, off2); Or similar for de_debug_types. **Updated by dwarf_next_cu_header in dwarf_die_deliv.c */ struct Dwarf_CU_Context_s { Dwarf_Debug cc_dbg; /* The sum of cc_length, cc_length_size, and cc_extension_size is the total length of the CU including its header. cc_length is the length of the compilation unit excluding cc_length_size and cc_extension_size. */ Dwarf_Unsigned cc_length; /* cc_length_size is the size in bytes of an offset. Should probably be renamed cc_offset_size. 4 for 32bit dwarf, 8 for 64bit dwarf (whether MIPS/IRIX 64bit dwarf or standard 64bit dwarf using the extension mechanism). */ Dwarf_Small cc_length_size; /* cc_extension_size is zero unless this is standard DWARF3 and later 64bit dwarf using the extension mechanism. 64bit DWARF3 and later: cc_extension_size is 4. 64bit DWARF2 MIPS/IRIX: cc_extension_size is zero. 32bit DWARF: cc_extension_size is zero. */ Dwarf_Small cc_extension_size; /* cc_version_stamp is the DWARF version number applicable to the DWARF in this compilation unit. 2,3,4,... */ Dwarf_Half cc_version_stamp; /* cc_abbrev_offset is the section-global offset of the .debug_abbrev section this CU uses. Data from CU header. Includes DWP adjustment made as soon as we create a cu_context. */ Dwarf_Unsigned cc_abbrev_offset; /* cc_address_size is the size of an address in this compilation unit. */ Dwarf_Small cc_address_size; Dwarf_Small cc_segment_selector_size; /* cc_debug_offset is the global offset in the section of the area length field of the CU. The CU header of the CU is at offset cc_debug_offset+cc_length_size+cc_extension_size; This is a section global offset. May be debug_info or debug_types. Even in DWP this is set to true global offset right away when cu_context created. See cc_is_info flag. */ Dwarf_Unsigned cc_debug_offset; /* === START DEBUG FISSION (Split Dwarf) data cc_signature is in the TU header of a type unit of a TU DIE (or for DW5 in the skeleton or split_compile header is a dwo_id). Ignore this field if cc_signature_present is zero. (TU CUs signature is not the same namespace as DW_AT_dwo_id signatures. The two must be kept separate (for DWARF5)) If cc_unit_type == DW_UT_compile or DW_UT_partial the signature is a CU signature (dwo_id). Some early DW5 drafts encouraged DWARF4 output of some compilers to include dwo_id, but in a messier way(lacking DW_UT_*). If cc_unit_type == DW_UT_split_type the signature is a type signature. */ Dwarf_Half cc_cu_die_tag; Dwarf_Sig8 cc_signature; /* cc_type_signature_offset contains the section-local DIE offset of the type the signature applies to if the cc_unit_type is DW_UT_type or DW_UT_split_type. */ Dwarf_Unsigned cc_signature_offset; /* For each CU and each TU in a dwp package file there is is a hash and a set of offsets indexed by DW_SECT_* id. Only one such set per CU or TU. The data on all that is in cc_dwp_offsets If it is a TU the signature in cc_dwp_offsets must match the signature in cc_signature. */ struct Dwarf_Debug_Fission_Per_CU_s cc_dwp_offsets; Dwarf_Bool cc_signature_present; /* Meaning type signature in TU header or, for CU header, signature in CU DIE. */ Dwarf_Bool cc_low_pc_present; Dwarf_Bool cc_addr_base_present; /* Not TRUE in .dwo */ Dwarf_Bool cc_cu_die_has_children; Dwarf_Bool cc_dwo_name_present; Dwarf_Bool cc_at_strx_present; /* Non zero if this context is a dwo section. Either dwo or dwp file. */ Dwarf_Bool cc_is_dwo; /* cc_cu_die_offset_present is non-zero if cc_cu_die_global_sec_offset is meaningful. */ Dwarf_Bool cc_cu_die_offset_present; /* if present, is base address of CU */ Dwarf_Unsigned cc_low_pc; /* from DW_AT_addr_base in CU DIE, offset to .debug_addr table */ Dwarf_Unsigned cc_addr_base; /* Zero in .dwo */ /* DW_SECT_LINE */ Dwarf_Bool cc_line_base_present; /*DW5 */ Dwarf_Unsigned cc_line_base; /*DW5 */ Dwarf_Unsigned cc_line_base_contr_size; /*DW5 */ /* From DW_AT_loclists_base or DW_SECT_LOCLISTS */ Dwarf_Unsigned cc_loclists_base; Dwarf_Unsigned cc_loclists_base_contr_size; Dwarf_Bool cc_loclists_base_present; Dwarf_Bool cc_loclists_header_length_present; /* .debug_str_offsets DW_SECT_STR_OFFSETS DW4 DW5 vs DW_AT_str_offsets_base (table array off) */ Dwarf_Bool cc_str_offsets_base_present; Dwarf_Bool cc_str_offsets_header_length_present; Dwarf_Unsigned cc_str_offsets_header_offset; /* from cu/tu*/ Dwarf_Unsigned cc_str_offsets_contr_size; Dwarf_Unsigned cc_str_offsets_base; /* to get from the start of a str_offsets table to the offsets array entries. See cc_str_offsets_header_length_present, though not normally needed. If header_length is zero all CUs in this DWP use a DWARF4 extension simple offset array, not a DWARF5 set of tables. */ Dwarf_Unsigned cc_str_offsets_header_length; Dwarf_Unsigned cc_str_offsets_offset_size; /* DW_SECT_MACRO */ Dwarf_Unsigned cc_macro_base; /*DW5 */ Dwarf_Unsigned cc_macro_base_contr_size; /*DW5 */ Dwarf_Bool cc_macro_base_present; Dwarf_Bool cc_macro_header_length_present; /* DW_SECT_RNGLISTS */ Dwarf_Unsigned cc_rnglists_base; /*DW5 */ Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */ /* DW_AT_GNU_ranges_base was a GNU extension that appeared but was unused. See dwarf_die_deliv.c for details. */ Dwarf_Unsigned cc_ranges_base; /* DW_AT_GNU_ranges_base is a GNU extension, DW4 */ Dwarf_Bool cc_ranges_base_present; /* .debug_rnglists */ Dwarf_Bool cc_rnglists_base_present; /* DW5 */ Dwarf_Bool cc_rnglists_header_length_present; char * cc_dwo_name; /* === END DEBUG FISSION (Split Dwarf) data */ /* Global section offset to the bytes of the CU die for this CU. Set when the CU die is accessed by dwarf_siblingof_b(). */ Dwarf_Unsigned cc_cu_die_global_sec_offset; Dwarf_Byte_Ptr cc_last_abbrev_ptr; Dwarf_Byte_Ptr cc_last_abbrev_endptr; Dwarf_Hash_Table cc_abbrev_hash_table; Dwarf_Unsigned cc_highest_known_code; Dwarf_CU_Context cc_next; Dwarf_Bool cc_is_info; /* TRUE means context is in debug_info, FALSE means is in debug_types. FALSE only possible for DWARF4 .debug_types section CUs. For DWARF5 all DIEs are in .debug_info[.dwo] */ Dwarf_Half cc_unit_type; /* DWARF5 Set from header as a DW_UT_ value. For DWARF 2,3,4 this is filled in initially from the CU header and refined by inspecting the CU DIE to detect the correct setting. */ }; /* Consolidates section-specific data in one place. Section is an Elf specific term, intended as a general term (for non-Elf objects some code must synthesize the values somehow). */ struct Dwarf_Section_s { Dwarf_Small * dss_data; Dwarf_Unsigned dss_size; /* Some Elf sections have a non-zero dss_entrysize which is the size in bytes of a table entry in the section. Relocations and symbols are both in tables, so have a non-zero entrysize. Object formats which do not care about this should leave this field zero. */ Dwarf_Unsigned dss_entrysize; /* dss_index is the section index as things are numbered in an object file being read. An Elf section number. */ Dwarf_Unsigned dss_index; /* dss_addr is the 'section address' which is only non-zero for a GNU eh section. Purpose: to handle DW_EH_PE_pcrel encoding. Leaving it zero is fine for non-elf. */ Dwarf_Addr dss_addr; Dwarf_Small dss_data_was_malloc; /* is_in_use set during initial object reading to detect duplicates. Ignored after setup done. */ Dwarf_Small dss_is_in_use; /* When loading COMDAT they refer (sometimes) to base sections, so we need to have the BASE group sections filled in when the corresponding is not in the COMDAT group list. .debug_abbrev is an example. */ Dwarf_Unsigned dss_group_number; /* These for reporting compression */ Dwarf_Unsigned dss_uncompressed_length; Dwarf_Unsigned dss_compressed_length; /* If this is zdebug, to start data/size are the raw section bytes. Initially for all sections dss_data_was_malloc set FALSE and dss_requires_decompress set FALSE. For zdebug set dss_zdebug_requires_decompress set TRUE In that case it is likely ZLIB compressed but we do not know that just scanning section headers. If not .zdebug but it is SHF_COMPRESSED then decompress is required. On translation (ie zlib use and malloc) Set dss_data dss_size to point to malloc space and malloc size. Set dss_did_decompress FALSE Set dss_was_malloc TRUE */ Dwarf_Small dss_zdebug_requires_decompress; Dwarf_Small dss_did_decompress; Dwarf_Small dss_shf_compressed; /* section flag SHF_COMPRESS */ /* Section compression starts with ZLIB chars*/ Dwarf_Small dss_ZLIB_compressed; /* For non-elf, leaving the following fields zero will mean they are ignored. */ /* dss_link should be zero unless a section has a link to another (sh_link). Used to access relocation data for a section (and for symtab section, access its strtab). */ Dwarf_Unsigned dss_link; /* The following is used when reading .rela sections (such sections appear in some .o files). */ Dwarf_Half dss_reloc_index; /* Zero means ignore the reloc fields. */ Dwarf_Small * dss_reloc_data; Dwarf_Unsigned dss_reloc_size; Dwarf_Unsigned dss_reloc_entrysize; Dwarf_Addr dss_reloc_addr; /* dss_reloc_symtab is the sh_link of a .rela to its .symtab, leave it 0 if non-meaningful. */ Dwarf_Addr dss_reloc_symtab; /* dss_reloc_link should be zero unless a reloc section has a link to another (sh_link). Used to access the symtab for relocating a section. */ Dwarf_Unsigned dss_reloc_link; /* Pointer to the elf symtab, used for elf .rela. Leave it 0 if not relevant. */ struct Dwarf_Section_s *dss_symtab; /* dss_name, dss_standard_name must never be freed, they are static strings in libdwarf. */ const char * dss_name; const char * dss_standard_name; /* Object section number in object file. */ unsigned dss_number; /* These are elf flags and non-elf object should just leave these fields zero. Which is essentially automatic as they are not in Dwarf_Obj_Access_Section_s. */ Dwarf_Unsigned dss_flags; Dwarf_Unsigned dss_addralign; /* Set when loading .group section as those are special and neither compressed nor have relocations so never malloc space for libdwarf. */ Dwarf_Small dss_ignore_reloc_group_sec; char dss_is_rela; }; /* Overview: if next_to_use== first, no error slots are used. If next_to_use+1 (mod maxcount) == first the slots are all used */ struct Dwarf_Harmless_s { unsigned dh_maxcount; unsigned dh_next_to_use; unsigned dh_first; unsigned dh_errs_count; char ** dh_errors; }; /* Data needed separately for debug_info and debug_types as we may be reading both interspersed. So we always select the one we need. */ struct Dwarf_Debug_InfoTypes_s { /* Context for the compilation_unit just read by a call to dwarf_next_cu_header. **Updated by dwarf_next_cu_header in dwarf_die_deliv.c */ Dwarf_CU_Context de_cu_context; /* Points to linked list of CU Contexts for the CU's already read. These are only CU's read by dwarf_next_cu_header(). */ Dwarf_CU_Context de_cu_context_list; /* Points to the last CU Context added to the list by dwarf_next_cu_header(). */ Dwarf_CU_Context de_cu_context_list_end; /* Offset of last byte of last CU read. Actually one-past that last byte. So use care and compare as offset >= de_last_offset to know if offset is too big. */ Dwarf_Unsigned de_last_offset; /* de_last_di_info_ptr and de_last_die are used with dwarf_siblingof, dwarf_child, and dwarf_validate_die_sibling. dwarf_validate_die_sibling will not give meaningful results if called inappropriately. */ Dwarf_Byte_Ptr de_last_di_ptr; Dwarf_Die de_last_die; }; typedef struct Dwarf_Debug_InfoTypes_s *Dwarf_Debug_InfoTypes; /* As the tasks performed on a debug related section is the same, in order to make the process of adding a new section (very unlikely) a little bit easy and to reduce the possibility of errors, a simple table build dynamically, will contain the relevant information. */ struct Dwarf_dbg_sect_s { /* Debug section name must not be freed, is quoted string. This is the name from the object file itself. */ const char *ds_name; /* The section number in object section numbering. */ unsigned ds_number; /* Debug section information, points to de_debug_*member (or the like) of the dbg struct. */ struct Dwarf_Section_s *ds_secdata; unsigned ds_groupnumber; int ds_duperr; /* Error code for duplicated section */ int ds_emptyerr; /* Error code for empty section */ int ds_have_dwarf; /* Section contains DWARF */ int ds_have_zdebug; /* Section compressed: .zdebug name */ }; /* As the number of debug sections does not change very often, in the case a new section is added in 'enter_section_in_array()' the 'MAX_DEBUG_SECTIONS' must be updated accordingly. This does not yet allow for section-groups in object files, for which many .debug_info (and other) sections may exist. */ #define DWARF_MAX_DEBUG_SECTIONS 50 #define DWARFSTRING_ALLOC_SIZE 200 /* All the Dwarf_Debug tied-file info in one place. */ struct Dwarf_Tied_Data_s { /* Used to access executable from .dwo or .dwp object. Pointer to the tied_to Dwarf_Debug*/ Dwarf_Debug td_tied_object; /* TRUE if this tied object is tied to. It's extra work to look for a DW_AT_dwo_id. Set when tied dbg (on the base) was created. This helps us do it only when it may be productive. */ Dwarf_Bool td_is_tied_object; /* Used for Type Unit signatures. Type Units are in .debug_types in DW4 but in .debug_info in DW5. Some .debug_info point to them symbolically via DW_AT_signature attributes. If non-zero is a dwarf_tsearch 'tree'. Only non-zero if td_is_tied_object is set and we had a reason to build the search tree.. Type Units have a Dwarf_Sig8 signature in the header, and such is recorded here. Type Unit signatures can conflict with signatures in split-dwarf (dwo/dwp) sections. The Key for each record is a Dwarf_Sig8 (8 bytes). The data for each is a pointer to a Dwarf_CU_context record in this dbg (cu_context in one of tied dbg's de_cu_context_list). */ void *td_tied_search; }; /* dg_groupnum 0 does not exist. dg_groupnum 1 is base dg_groupnum 2 is dwo dg_groupnum 3 and higher are COMDAT groups (if any). */ struct Dwarf_Group_Data_s { /* For traditional DWARF the value is one, just one group. */ unsigned gd_number_of_groups; /* Raw elf (elf-like) section count. */ unsigned gd_number_of_sections; unsigned gd_map_entry_count; /* A map from section number to group number. */ void *gd_map; }; struct Dwarf_Debug_s { /* All file access methods and support data are hidden in this structure. We get a pointer, callers control the lifetime of the structure and contents. */ struct Dwarf_Obj_Access_Interface_s *de_obj_file; Dwarf_Handler de_errhand; Dwarf_Ptr de_errarg; /* Enabling us to close an fd if we own it, as in the case of dwarf_init_path(). de_fd is only meaningful if de_owns_fd is set. Each object file type has any necessary fd recorded under de_obj_file. */ int de_fd; char de_owns_fd; /* DW_PATHSOURCE_BASIC or MACOS or DEBUGLINK */ unsigned char de_path_source; unsigned char de_using_libelf; /* de_path is only set automatically if dwarf_init_path() was used to initialize things. Used with the .gnu_debuglink section. */ const char *de_path; const char ** de_gnu_global_paths; unsigned de_gnu_global_path_count; struct Dwarf_Debug_InfoTypes_s de_info_reading; struct Dwarf_Debug_InfoTypes_s de_types_reading; /* DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, DW_GROUPNUMBER_DWO, or a comdat group number > 2 Selected at init time of this dbg based on user request and on data in the object. */ unsigned de_groupnumber; /* Supporting data for groupnumbers. */ struct Dwarf_Group_Data_s de_groupnumbers; /* Number of bytes in the length, and offset field in various .debu* sections. It's not very meaningful, and is only used in one 'approximate' calculation. de_offset_size would be a more apropos name. */ Dwarf_Small de_length_size; /* Size of the object file in bytes. If Unknown leave this zero. */ Dwarf_Unsigned de_filesize; /* number of bytes in a pointer of the target in various .debug_ sections. 4 in 32bit, 8 in MIPS 64, ia64. */ Dwarf_Small de_pointer_size; /* set at creation of a Dwarf_Debug to say if form_string should be checked for valid length at every call. 0 means do the check. non-zero means do not do the check. */ Dwarf_Small de_assume_string_in_bounds; /* Keep track of allocations so a dwarf_finish call can clean up. Null till a tree is created */ void * de_alloc_tree; /* These fields are used to process debug_frame section. Updated by dwarf_get_fde_list in dwarf_frame.h */ /* Points to contiguous block of pointers to Dwarf_Cie_s structs. */ Dwarf_Cie *de_cie_data; /* Count of number of Dwarf_Cie_s structs. */ Dwarf_Signed de_cie_count; /* Keep eh (GNU) separate!. */ Dwarf_Cie *de_cie_data_eh; Dwarf_Signed de_cie_count_eh; /* Points to contiguous block of pointers to Dwarf_Fde_s structs. */ Dwarf_Fde *de_fde_data; /* Count of number of Dwarf_Fde_s structs. */ Dwarf_Unsigned de_fde_count; /* Keep eh (GNU) separate!. */ Dwarf_Fde *de_fde_data_eh; Dwarf_Unsigned de_fde_count_eh; struct Dwarf_Section_s de_debug_info; struct Dwarf_Section_s de_debug_types; struct Dwarf_Section_s de_debug_abbrev; struct Dwarf_Section_s de_debug_line; struct Dwarf_Section_s de_debug_line_str; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_loc; struct Dwarf_Section_s de_debug_aranges; struct Dwarf_Section_s de_debug_macinfo; struct Dwarf_Section_s de_debug_macro; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_names; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_pubnames; struct Dwarf_Section_s de_debug_str; struct Dwarf_Section_s de_debug_sup; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_loclists; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_rnglists; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_frame; struct Dwarf_Section_s de_gnu_debuglink; /* New Sept. 2019 */ struct Dwarf_Section_s de_note_gnu_buildid; /* New Sept. 2019 */ /* gnu: the g++ eh_frame section */ struct Dwarf_Section_s de_debug_frame_eh_gnu; /* DWARF3 .debug_pubtypes */ struct Dwarf_Section_s de_debug_pubtypes; /* Four SGI IRIX extensions essentially identical to DWARF3 .debug_pubtypes. Only on SGI IRIX. */ struct Dwarf_Section_s de_debug_funcnames; struct Dwarf_Section_s de_debug_typenames; struct Dwarf_Section_s de_debug_varnames; struct Dwarf_Section_s de_debug_weaknames; struct Dwarf_Section_s de_debug_ranges; /* Following two part of DebugFission and DWARF5 */ struct Dwarf_Section_s de_debug_str_offsets; struct Dwarf_Section_s de_debug_addr; /* For the .debug_rnglists[.dwo] section */ Dwarf_Unsigned de_rnglists_context_count; /* pointer to array of pointers to rnglists context instances */ Dwarf_Rnglists_Context * de_rnglists_context; /* For the .debug_loclists[.dwo] section */ Dwarf_Unsigned de_loclists_context_count; /* pointer to array of pointers to loclists context instances */ Dwarf_Loclists_Context * de_loclists_context; /* Following for the .gdb_index section. */ struct Dwarf_Section_s de_debug_gdbindex; /* Types in DWARF5 are in .debug_info and in DWARF4 are in .debug_types. These indexes first standardized in DWARF5, DWARF4 can have them as an extension. The next to refer to the DWP index sections and the tu and cu indexes sections are distinct in DWARF4 & 5. */ struct Dwarf_Section_s de_debug_cu_index; struct Dwarf_Section_s de_debug_tu_index; struct Dwarf_Section_s de_debug_gnu_pubnames; struct Dwarf_Section_s de_debug_gnu_pubtypes; /* For non-elf, simply leave the following two structs zeroed and they will be ignored. */ struct Dwarf_Section_s de_elf_symtab; struct Dwarf_Section_s de_elf_strtab; /* For a .dwp object file . For DWARF4, type units are in .debug_types (DWP is a GNU extension in DW4).. For DWARF5, type units are in .debug_info. */ Dwarf_Xu_Index_Header de_cu_hashindex_data; Dwarf_Xu_Index_Header de_tu_hashindex_data; void (*de_copy_word) (void *, const void *, unsigned long); unsigned char de_same_endian; unsigned char de_elf_must_close; /* If non-zero, then it was dwarf_init (not dwarf_elf_init) so must elf_end() */ /* Default is DW_FRAME_INITIAL_VALUE from header. */ Dwarf_Half de_frame_rule_initial_value; /* Default is DW_FRAME_LAST_REG_NUM. */ Dwarf_Half de_frame_reg_rules_entry_count; Dwarf_Half de_frame_cfa_col_number; Dwarf_Half de_frame_same_value_number; Dwarf_Half de_frame_undefined_value_number; unsigned char de_big_endian_object; /* Non-zero if object being read is big-endian. */ /* Non-zero if dwarf_get_globals(), dwarf_get_funcs, dwarf_get_types,dwarf_get_pubtypes, dwarf_get_vars,dwarf_get_weaks should create and return a special zero-die-offset for the corresponding pubnames-style section CU header with zero pubnames-style named DIEs. In that case the list returned will have an entry with a zero for the die-offset (which is an impossible debug_info die_offset). New March 2019. See dwarf_return_empty_pubnames() */ unsigned char de_return_empty_pubnames; struct Dwarf_dbg_sect_s de_debug_sections[ DWARF_MAX_DEBUG_SECTIONS]; /* Number actually used. */ unsigned de_debug_sections_total_entries; struct Dwarf_Harmless_s de_harmless_errors; struct Dwarf_Printf_Callback_Info_s de_printf_callback; void * de_printf_callback_null_device_handle; /* Used in a tied dbg to hold global info on the tied object (DW_AT_dwo_id). And for Type Unit signatures whether tied or not. It is not defined whether the main object is executable and the tied file is a dwo/dwp or the reverse. The focus of reporting is on the main file, but the tied file is sometimes needed and referenced.*/ struct Dwarf_Tied_Data_s de_tied_data; }; /* New style. takes advantage of dwarfstrings capability. This not a public function. */ int _dwarf_printf(Dwarf_Debug dbg, const char * data); typedef struct Dwarf_Chain_s *Dwarf_Chain; struct Dwarf_Chain_s { void *ch_item; int ch_itemtype; /* Needed to dealloc chain contents */ Dwarf_Chain ch_next; }; typedef struct Dwarf_Chain_o *Dwarf_Chain_2; struct Dwarf_Chain_o { Dwarf_Off ch_item; Dwarf_Chain_2 ch_next; }; /* Size of cu header version stamp field. */ #define CU_VERSION_STAMP_SIZE DWARF_HALF_SIZE /* Size of cu header address size field. */ #define CU_ADDRESS_SIZE_SIZE sizeof(Dwarf_Small) #define ORIGINAL_DWARF_OFFSET_SIZE 4 /* The DISTINGUISHED VALUE is 4 byte value defined by DWARF since DWARF3. */ #define DISTINGUISHED_VALUE 0xffffffff #define DISTINGUISHED_VALUE_OFFSET_SIZE 8 #define DISTINGUISHED_VALUE_ARRAY(x) char x[4] = \ { 0xff,0xff,0xff,0xff } int _dwarf_ignorethissection(const char *scn_name); /* We don't load the sections until they are needed. This function is used to load the section. */ int _dwarf_load_section(Dwarf_Debug, struct Dwarf_Section_s *, Dwarf_Error *); void _dwarf_dealloc_rnglists_context(Dwarf_Debug dbg); void _dwarf_dealloc_loclists_context(Dwarf_Debug dbg); int _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *sbase_out, Dwarf_Error *error); int _dwarf_read_str_offsets_header(Dwarf_Debug dbg, Dwarf_Small* table_start_ptr, Dwarf_Unsigned secsize, Dwarf_Small* secendptr, Dwarf_CU_Context cucontext, /* Followed by return values/error */ Dwarf_Unsigned *length, Dwarf_Half *offset_size_out, Dwarf_Half *extension_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned * header_length_out, Dwarf_Error *error); int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *data_ptr, Dwarf_Small *end_data_ptr, Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, Dwarf_Unsigned *str_sect_offset_out, Dwarf_Error *error); int _dwarf_look_in_local_and_tied_by_index( Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *return_addr, Dwarf_Error *error); #if 0 /* Never implemented. */ int _dwarf_get_base_and_size_given_signature( Dwarf_CU_Context *context, Dwarf_Sig8 *signature_in, /* xu_sect_index means DW_SECT_info etc. */ Dwarf_Unsigned xu_sect_index, Dwarf_Unsigned *base_out, Dwarf_Unsigned *size_out, Dwarf_Error *err); #endif Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg); Dwarf_Bool _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg); Dwarf_Bool _dwarf_file_has_debug_fission_index(Dwarf_Debug dbg); /* This should only be called on a CU. Never a TU. */ int _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg, Dwarf_Off offset_wanted, const char *keytype, /* "cu" or "tu" */ Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error *error); /* whichone: must be a valid DW_SECT* macro value. */ Dwarf_Unsigned _dwarf_get_dwp_extra_offset( struct Dwarf_Debug_Fission_Per_CU_s* dwp, unsigned whichone, Dwarf_Unsigned * size); /* This will look into the tied Dwarf_Debug to which should have a skeleton CU DIE and an addr_base and also have the .debug_addr section. */ int _dwarf_get_addr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned addrindex, Dwarf_Addr *addr_out, Dwarf_Error *error); int _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index, Dwarf_Unsigned* offset, Dwarf_Unsigned*size, Dwarf_Error *error); int _dwarf_get_addr_index_itself(int theform, Dwarf_Small *info_ptr, Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned *val_out, Dwarf_Error * error); Dwarf_Bool _dwarf_addr_form_is_indexed(int form); int _dwarf_load_die_containing_section(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Error *error); int _dwarf_create_a_new_cu_context_record_on_list( Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis, Dwarf_Bool is_info, Dwarf_Unsigned section_size, Dwarf_Unsigned new_cu_offset, Dwarf_CU_Context *context_out, Dwarf_Error *error); Dwarf_Unsigned _dwarf_calculate_next_cu_context_offset( Dwarf_CU_Context cu_context); int _dwarf_search_for_signature(Dwarf_Debug dbg, Dwarf_Sig8 sig, Dwarf_CU_Context *context_out, Dwarf_Error *error); int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Debug tieddbg, Dwarf_CU_Context *tiedcontext_out, Dwarf_Error *error); void _dwarf_tied_destroy_free_node(void *node); void _dwarf_destroy_group_map(Dwarf_Debug dbg); int _dwarf_section_get_target_group(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber, Dwarf_Error * error); int _dwarf_dwo_groupnumber_given_name( const char *name, unsigned *grpnum_out); int _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber_out, UNUSEDARG Dwarf_Error * error); int _dwarf_insert_in_group_map(Dwarf_Debug dbg, unsigned groupnum, unsigned section_index, const char *name, Dwarf_Error * error); /* returns TRUE/FALSE: meaning this section name is in map for this groupnum or not.*/ int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, const char * scn_name, unsigned groupnum); int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Half * offset_size, Dwarf_Half * extension_size, Dwarf_Sig8 * signature, Dwarf_Bool * has_signature, Dwarf_Unsigned *typeoffset, Dwarf_Unsigned * next_cu_offset, Dwarf_Half * header_cu_type, Dwarf_Error * error); /* Relates to .debug_addr */ int _dwarf_look_in_local_and_tied(Dwarf_Half attr_form, Dwarf_CU_Context context, Dwarf_Small *info_ptr, Dwarf_Addr *return_addr, Dwarf_Error *error); int _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned * ranges_base_out, Dwarf_Unsigned * addr_base_out, Dwarf_Error * error); int _dwarf_get_string_from_tied(Dwarf_Debug dbg, Dwarf_Unsigned offset, char **return_str, Dwarf_Error*error); int _dwarf_valid_form_we_know(Dwarf_Unsigned at_form, Dwarf_Unsigned at_name); int _dwarf_extract_local_debug_str_string_given_offset( Dwarf_Debug dbg, unsigned attrform, Dwarf_Unsigned offset, char ** return_str, Dwarf_Error * error); int _dwarf_file_name_is_full_path(Dwarf_Small *fname); /* This is an elf-only extension to get SHF_COMPRESSED flag from sh_flags. if pointer not set (which is normal for non-elf objects) it is fine. */ typedef int (*_dwarf_get_elf_flags_func_ptr_type)( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error); extern _dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; /* This is libelf access to Elf object. */ extern int _dwarf_elf_setup(int fd, char *true_path_out_buffer, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); /* This is non-libelf Elf access */ extern int _dwarf_elf_nlsetup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_elf_nlaccess( struct Dwarf_Obj_Access_Interface_s *aip); extern int _dwarf_macho_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_macho_access( struct Dwarf_Obj_Access_Interface_s *aip); extern int _dwarf_pe_setup(int fd, char *path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_pe_access( struct Dwarf_Obj_Access_Interface_s *aip); void _dwarf_create_address_size_dwarf_error(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned addrsize, int errcode,const char *errname); extern Dwarf_Bool _dwarf_allow_formudata(unsigned form); extern int _dwarf_formudata_internal(Dwarf_Debug dbg, unsigned form, Dwarf_Byte_Ptr data, Dwarf_Byte_Ptr section_end, Dwarf_Unsigned *return_uval, Dwarf_Unsigned *bytes_read, Dwarf_Error *error); Dwarf_Byte_Ptr _dwarf_calculate_info_section_start_ptr( Dwarf_CU_Context context, Dwarf_Unsigned *section_len_out); Dwarf_Byte_Ptr _dwarf_calculate_info_section_end_ptr( Dwarf_CU_Context context); Dwarf_Byte_Ptr _dwarf_calculate_abbrev_section_end_ptr( Dwarf_CU_Context context); int _dwarf_formblock_internal(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_CU_Context cu_context, Dwarf_Block * return_block, Dwarf_Error * error); int _dwarf_extract_data16(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Small *section_start, Dwarf_Small *section_end, Dwarf_Form_Data16 * returned_val, Dwarf_Error *error); unsigned int _dwarf_crc32(unsigned int init, const unsigned char * buf, size_t len); void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig, int lineno); libdwarf-20210528/libdwarf/pro_alloc.h0000644000175000017500000000272113743575426014431 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRO_ALLOC_H #define PRO_ALLOC_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned); void dwarf_p_dealloc(Dwarf_Small * ptr); /* DO NOT USE. */ void _dwarf_p_dealloc(Dwarf_P_Debug,Dwarf_Small * ptr); void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRO_ALLOC_H */ libdwarf-20210528/libdwarf/malloc_check.h0000644000175000017500000000366513763272574015073 00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* malloc_check.h */ /* A simple libdwarf-aware malloc checker. define WANT_LIBBDWARF_MALLOC_CHECK and rebuild libdwarf do make a checking-for-alloc-mistakes libdwarf. NOT recommended for production use. When defined, also add malloc_check.c to the list of files in Makefile. */ #undef WANT_LIBBDWARF_MALLOC_CHECK /*#define WANT_LIBBDWARF_MALLOC_CHECK 1 */ #ifdef WANT_LIBBDWARF_MALLOC_CHECK void dwarf_malloc_check_alloc_data(void * addr,unsigned char code); void dwarf_malloc_check_dealloc_data(void * addr,unsigned char code); /* called at exit of app */ void dwarf_malloc_check_complete(char *wheremsg); #else /* !WANT_LIBBDWARF_MALLOC_CHECK */ #define dwarf_malloc_check_alloc_data(a,b) /* nothing */ #define dwarf_malloc_check_dealloc_data(a,b) /* nothing */ #define dwarf_malloc_check_complete(a) /* nothing */ #endif /* WANT_LIBBDWARF_MALLOC_CHECK */ libdwarf-20210528/libdwarf/dwarf_loc.h0000664000175000017500000002612514012266121014400 00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2015-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_LOC_H #define DWARF_LOC_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain; struct Dwarf_Loc_Chain_s { Dwarf_Small lc_atom; Dwarf_Unsigned lc_raw1; Dwarf_Unsigned lc_raw2; Dwarf_Unsigned lc_raw3; Dwarf_Unsigned lc_number; Dwarf_Unsigned lc_number2; Dwarf_Unsigned lc_number3; Dwarf_Unsigned lc_offset; Dwarf_Unsigned lc_opnumber; Dwarf_Loc_Chain lc_next; }; /* Dwarf_Loclists_Context_s contains the data from the .debug_loclists section headers (if that section exists). Dwarf 2,3,4 .debug_loc has no such data. The array (one of these per header in .debug_loclists) is recorded in Dwarf_Debug. These are filled in at startup at the same time .debug_info is opened. Nothing of this struct is exposed to libdwarf callers */ typedef struct Dwarf_Loclists_Context_s *Dwarf_Loclists_Context; struct Dwarf_Loclists_Context_s { Dwarf_Debug lc_dbg; Dwarf_Unsigned lc_index; /* An index assigned by libdwarf to each loclists context. Starting with zero at the zero offset in .debug_loclists. */ /* Offset of the .debug_loclists header involved. */ Dwarf_Unsigned lc_header_offset; Dwarf_Unsigned lc_length; /* Many places in in libdwarf this is called length_size. */ Dwarf_Small lc_offset_size; /* rc_extension_size is zero unless this is standard DWARF3 and later 64bit dwarf using the extension mechanism. 64bit DWARF3 and later: rc_extension_size is 4. 64bit DWARF2 MIPS/IRIX: rc_extension_size is zero. 32bit DWARF: rc_extension_size is zero. */ Dwarf_Small lc_extension_size; unsigned lc_version; /* 5 */ Dwarf_Small lc_address_size; Dwarf_Small lc_segment_selector_size; Dwarf_Unsigned lc_offset_entry_count; /* offset in the section of the offset entries */ Dwarf_Unsigned lc_offsets_off_in_sect; /* Do not free. Points into section memory */ Dwarf_Small * lc_offsets_array; /* Offset in the .debug_loclists section of the first loclist in the set of loclists for the CU. */ Dwarf_Unsigned lc_first_loclist_offset; Dwarf_Unsigned lc_past_last_loclist_offset; /* pointer to 1st byte of loclist header*/ Dwarf_Small * lc_loclists_header; /* pointer to first byte of the loclist data for loclist involved. Do not free. */ Dwarf_Small *lc_startaddr; /* pointer one past end of the loclist data. */ Dwarf_Small *lc_endaddr; }; /* Contains info on an uninterpreted block of data, the data is DWARF location expression operators. */ struct Dwarf_Block_c_s { /* length of block bl_data points at */ Dwarf_Unsigned bl_len; /* Uninterpreted data, location expressions, DW_OP_reg31 etc */ Dwarf_Ptr bl_data; /* DW_LKIND, see libdwarf.h.in */ Dwarf_Small bl_kind; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; /* Section offset where the location description itself starts. So a few bytes lower than bl_section_offset */ Dwarf_Unsigned bl_locdesc_offset; }; typedef struct Dwarf_Block_c_s Dwarf_Block_c; /* Location record. Records up to 3 operand values. For DWARF5 ops with a 1 byte size and then a block of data of that size we the size in an operand and follow that with the next operand as a pointer to the block. The pointer is inserted via cast, so an ugly hack. This struct is opaque. Not visible to callers. */ typedef struct Dwarf_Loc_Expr_Op_s *Dwarf_Loc_Expr_Op; struct Dwarf_Loc_Expr_Op_s { Dwarf_Small lr_atom; /* Location operation */ /* Operands exactly as in DWARF. */ Dwarf_Unsigned lr_raw1; Dwarf_Unsigned lr_raw2; Dwarf_Unsigned lr_raw3; Dwarf_Unsigned lr_number; /* First operand */ /* Second operand. For OP_bregx, OP_bit_piece, OP_[GNU_]const_type, OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value, OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type, */ Dwarf_Unsigned lr_number2; /* Third Operand. For OP_[GNU_]const type, pointer to block of length 'lr_number2' FIXME: retrieve the value at the pointer, store the value here instead*/ Dwarf_Unsigned lr_number3; /* The number assigned. 0 to the number-of-ops - 1 in the expression we are expanding. */ Dwarf_Unsigned lr_opnumber; Dwarf_Unsigned lr_offset; /* offset for OP_BRA etc */ Dwarf_Loc_Expr_Op lr_next; /* When a list is useful.*/ }; /* Used at construction to enable verifying we set sensibly before returning to callers. */ #define DW_LLE_VALUE_BOGUS 254 /* Location description DWARF 2,3,4,5 Adds the DW_LLE value (new in DWARF5). This struct is opaque. Not visible to callers. */ struct Dwarf_Locdesc_c_s { Dwarf_Small ld_kind; /* DW_LKIND */ /* A DW_LLEX or DW_LLE value, real or synthesized */ Dwarf_Small ld_lle_value; /* Failed means .debug_addr section needed but missing. (possibly tied file needed) */ Dwarf_Bool ld_index_failed; /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_rawlow; /* Translated to address */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, or a length, never a pc value. */ Dwarf_Addr ld_rawhigh; /* Translated to address */ Dwarf_Addr ld_highpc; /* Byte length of the entire record for this entry, including any DW_OP entries */ Dwarf_Unsigned ld_entrylen; /* For .debug_loclists, eases building record. */ Dwarf_Block_c ld_opsblock; /* count of struct Dwarf_Loc_Expr_Op_s (expression operators) in array. */ Dwarf_Half ld_cents; /* pointer to array of expression operator structs */ Dwarf_Loc_Expr_Op ld_s; /* Section (not CU) offset where loc-expr begins*/ Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where location descr begins*/ Dwarf_Unsigned ld_locdesc_offset; /* Pointer to our header (in which we are located). */ Dwarf_Loc_Head_c ld_loclist_head; Dwarf_Locdesc_c ld_next; /*helps building the locdescs*/ }; int _dwarf_locdesc_c_constructor(Dwarf_Debug dbg, void *locd); /* A 'header' to the loclist and the location description(s) attached to an attribute. This struct is opaque. The contents not visible to callers. */ struct Dwarf_Loc_Head_c_s { /* The array (1 or more entries) of struct Loc_Desc_c_s If 1 it may really be a locexpr */ Dwarf_Locdesc_c ll_locdesc; /* Entry count of the ll_locdesc array. */ Dwarf_Unsigned ll_locdesc_count; unsigned ll_attrnum; unsigned ll_attrform; unsigned ll_cuversion; unsigned ll_address_size; unsigned ll_offset_size; /* The CU Context of this loclist or locexpr. */ Dwarf_CU_Context ll_context; /* DW_LKIND* */ Dwarf_Small ll_kind; Dwarf_Debug ll_dbg; /* If ll_kind == DW_LKIND_loclists the following pointer is non-null and index is the index of the localcontext */ Dwarf_Unsigned ll_index; Dwarf_Loclists_Context ll_localcontext; /* rh_last and rh_first used during build-up. Zero when array rh_loclists built. */ Dwarf_Locdesc_c ll_first; Dwarf_Locdesc_c ll_last; Dwarf_Unsigned ll_bytes_total; unsigned ll_segment_selector_size; /* DW_AT_loclists_base */ Dwarf_Bool ll_at_loclists_base_present; Dwarf_Unsigned ll_at_loclists_base; /* DW_AT_low_pc of CU or zero if none. */ Dwarf_Bool ll_cu_base_address_present; Dwarf_Unsigned ll_cu_base_address; /* DW_AT_addr_base, so we can use .debug_addr if such is needed. */ Dwarf_Bool ll_cu_addr_base_present; Dwarf_Unsigned ll_cu_addr_base; Dwarf_Small * ll_llepointer; Dwarf_Unsigned ll_llearea_offset; Dwarf_Small * ll_end_data_area; }; int _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, Dwarf_Unsigned locdesc_index, Dwarf_Loc_Head_c loc_head, Dwarf_Block_c * loc_block, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small version_stamp, Dwarf_Addr lowpc, Dwarf_Addr highpc, Dwarf_Half lle_op, Dwarf_Error * error); int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error*error); int _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, Dwarf_Small *end_data, Dwarf_Unsigned offset, Dwarf_Loclists_Context buildhere, Dwarf_Unsigned *next_offset, Dwarf_Error *error); void _dwarf_loclists_head_destructor(void *l); int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Loc_Head_c llhead, Dwarf_Error *error); int _dwarf_loclists_expression_build(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Loc_Head_c* llhead, Dwarf_Error *error); int _dwarf_read_loc_expr_op(Dwarf_Debug dbg, Dwarf_Block_c * loc_block, /* Caller: Start numbering at 0. */ Dwarf_Signed opnumber, /* 2 for DWARF 2 etc. */ Dwarf_Half version_stamp, Dwarf_Half offset_size, /* 4 or 8 */ Dwarf_Half address_size, /* 2,4, 8 */ Dwarf_Signed startoffset_in, /* offset in block, not section offset */ Dwarf_Small *section_end, /* nextoffset_out so caller knows next entry startoffset */ Dwarf_Unsigned *nextoffset_out, /* The values picked up. */ Dwarf_Loc_Expr_Op curr_loc, Dwarf_Error * error); void _dwarf_free_loclists_head_content(Dwarf_Loc_Head_c head); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_LOC_H */ libdwarf-20210528/libdwarf/libdwarf_version.h0000664000175000017500000000033414054205525016000 00000000000000/* This date string is hereby put into the public domain. Copyrighting this is crazy. It's just a date string and is modified from time to time. */ #define DW_VERSION_DATE_STR " 2021-05-28 08:25:09-07:00 " libdwarf-20210528/libdwarf/dwarf_object_read_common.c0000664000175000017500000000641513764007262017443 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* memcpy */ #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #include typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" /* For error codes. */ #include "dwarf_object_read_common.h" /* Neither off_t nor ssize_t is in C90. However, both are in Posix: IEEE Std 1003.1-1990, aka ISO/IEC 9954-1:1990. */ int _dwarf_object_read_random(int fd, char *buf, off_t loc, size_t size, off_t filesize, int *errc) { off_t scode = 0; ssize_t rcode = 0; off_t endpoint = 0; if (loc >= filesize) { /* Seek can seek off the end. Lets not allow that. The object is corrupt. */ *errc = DW_DLE_SEEK_OFF_END; return DW_DLV_ERROR; } endpoint = loc+size; if (endpoint > filesize) { /* Let us -not- try to read past end of object. The object is corrupt. */ *errc = DW_DLE_READ_OFF_END; return DW_DLV_ERROR; } scode = lseek(fd,loc,SEEK_SET); if (scode == (off_t)-1) { *errc = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } rcode = read(fd,buf,size); if (rcode == -1 || (size_t)rcode != size) { *errc = DW_DLE_READ_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } void _dwarf_safe_strcpy(char *out, long outlen, const char *in, long inlen) { if (inlen >= (outlen - 1)) { strncpy(out, in, outlen - 1); out[outlen - 1] = 0; } else { strcpy(out, in); } } libdwarf-20210528/libdwarf/mips_extensions.mm0000664000175000017500000013746013771667103016076 00000000000000\." \." the following line may be removed if the ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." ============================================== \." Put current date in the following at each rev .ds vE rev 1.18, 31 March 2005 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 4 .SA 1 .TL MIPS Extensions to DWARF Version 2.0 .AF "" .AU "Silicon Graphics Computer Systems" .PF "'\*(vE'- \\\\nP -''" .AS 1 This document describes the MIPS/Silicon Graphics extensions to the "DWARF Information Format" (version 2.0.0 dated July 27, 1993). DWARF3 draft 8 (or draft 9) is out as of 2005, and is mentioned below where applicable. MIPS/IRIX compilers emit DWARF2 (with extensions). .P Rather than alter the base documents to describe the extensions we provide this separate document. .P The extensions documented here are subject to change. .P It also describes known bugs resulting in incorrect dwarf usage. .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" .P This document describes MIPS extensions to the DWARF debugging information format. The extensions documented here are subject to change at any time. .H 1 "64 BIT DWARF" .P The DWARF2 spec has no provision for 64 bit offsets. SGI-IRIX/MIPS Elf64 objects contain DWARF 2 with all offsets (and addresses) as 64bit values. This non-standard extension was adopted in 1992. Nothing in the dwarf itself identifies the dwarf as 64bit. This extension 64bit-offset dwarf cannot be mixed with 32bit-offset dwarf in a single object or executable, and SGI-IRIX/MIPS compilers and tools do not mix the sizes. .P In 2001 DWARF3 adopted a very different 64bit-offset format which can be mixed usefully with 32bit-offset DWARF2 or DWARF3. It is not very likely SGI-IRIX/MIPS compilers will switch to the now-standard DWARF3 64bit-offset scheme, but such a switch is theoretically possible and would be a good idea. .P SGI-IRIX/MIPS Elf32 objects contain DWARF2 with all offsets (and addresses) 32 bits. .H 1 "How much symbol information is emitted" The following standard DWARF V2 sections may be emitted: .AL .LI Section .debug_abbrev contains abbreviations supporting the .debug_info section. .LI Section .debug_info contains Debug Information Entries (DIEs). .LI Section .debug_frame contains stack frame descriptions. .LI Section .debug_line contains line number information. .LI Section .debug_aranges contains address range descriptions. .LI Section .debug_pubnames contains names of global functions and data. .P The following are MIPS extensions. Theses were created to allow debuggers to know names without having to look at the .debug_info section. .LI Section .debug_weaknames is a MIPS extension containing .debug_pubnames-like entries describing weak symbols. .LI Section .debug_funcnames is a MIPS extension containing .debug_pubnames-like entries describing file-static functions (C static functions). The gcc extension of nested subprograms (like Pascal) adds non-global non-static functions. These should be treated like static functions and gcc should add such to this section so that IRIX libexc(3C) will work correctly. Similarly, Ada functions which are non-global should be here too so that libexc(3C) can work. Putting it another way, every function (other than inline code) belongs either in .debug_pubnames or in .debug_funcnames or else libexc(3C) cannot find the function name. .LI Section .debug_varnames is a MIPS extension containing .debug_pubnames-like entries describing file-static data symbols (C static variables). .LI Section .debug_typenames is a MIPS extension containing .debug_pubnames-like entries describing file-level types. .P The following are not currently emitted. .LI Section .debug_macinfo Macro information is not currently emitted. .LI Section .debug_loc Location lists are not currently emitted. .LI Section .debug_str The string section is not currently emitted. .LE .H 2 "Overview of information emitted" We emit debug information in 3 flavors. We mention C here. The situation is essentially identical for f77, f90, and C++. .AL .LI "default C" We emit line information and DIEs for each subprogram. But no local symbols and no type information. Frame information is output. The DW_AT_producer string has the optimization level: for example "-O2". We put so much in the DW_AT_producer that the string is a significant user of space in .debug_info -- this is perhaps a poor use of space. When optimizing the IRIX CC/cc option -DEBUG:optimize_space eliminates such wasted space. Debuggers only currently use the lack of -g of DW_AT_producer as a hint as to how a 'step' command should be interpreted, and the rest of the string is not used for anything (unless a human looks at it for some reason), so if space-on-disk is an issue, it is quite appropriate to use -DEBUG:optimize_space and save disk space. Every function definition (not inline instances though) is mentioned in either .debug_pubnames or .debug_funcnames. This is crucial to allow libexc(3C) stack-traceback to work and show function names (for all languages). .LI "C with full symbols" All possible info is emitted. DW_AT_producer string has all options that might be of interest, which includes -D's, -U's, and the -g option. These options look like they came from the command line. We put so much in the DW_AT_producer that the string is a significant user of space in .debug_info. this is perhaps a poor use of space. Debuggers only currently use the -g of DW_AT_producer as a hint as to how a 'step' command should be interpreted, and the rest of the string is not used for anything (unless a human looks at it for some reason). Every function definition (not inline instances though) is mentioned in either .debug_pubnames or .debug_funcnames. This is crucial to allow libexc(3C) stack-traceback to work and show function names (for all languages). .LI "Assembler (-g, non -g are the same)" Frame information is output. No type information is emitted, but DIEs are prepared for globals. .LE .H 2 "Detecting 'full symbols' (-g)" The debugger depends on the existence of the DW_AT_producer string to determine if the compilation unit has full symbols or not. It looks for -g or -g[123] and accepts these as full symbols but an absent -g or a present -g0 is taken to mean that only basic symbols are defined and there are no local symbols and no type information. .P In various contexts the debugger will think the program is stripped or 'was not compiled with -g' unless the -g is in the DW_AT_producer string. .H 2 "DWARF and strip(1)" The DWARF section ".debug_frame" is marked SHF_MIPS_NOSTRIP and is not stripped by the strip(1) program. This is because the section is needed for doing stack back traces (essential for C++ and Ada exception handling). .P All .debug_* sections are marked with elf type SHT_MIPS_DWARF. Applications needing to access the various DWARF sections must use the section name to discriminate between them. .H 2 "Evaluating location expressions" When the debugger evaluates location expressions, it does so in 2 stages. In stage one it simply looks for the trivial location expressions and treats those as special cases. .P If the location expression is not trivial, it enters stage two. In this case it uses a stack to evaluate the expression. .P If the application is a 32-bit application, it does the operations on 32-bit values (address size values). Even though registers can be 64 bits in a 32-bit program all evaluations are done in 32-bit quantities, so an attempt to calculate a 32-bit quantity by taking the difference of 2 64-bit register values will not work. The notion is that the stack machine is, by the dwarf definition, working in address size units. .P These values are then expanded to 64-bit values (addresses or offsets). This extension does not involve sign-extension. .P If the application is a 64-bit application, then the stack values are all 64 bits and all operations are done on 64 bits. .H 3 "The fbreg location op" Compilers shipped with IRIX 6.0 and 6.1 do not emit the fbreg location expression and never emit the DW_AT_frame_base attribute that it depends on. However, this changes with release 6.2 and these are now emitted routinely. .H 1 "Frame Information" .H 2 "Initial Instructions" The DWARF V2 spec provides for "initial instructions" in each CIE (page 61, section 6.4.1). However, it does not say whether there are default values for each column (register). .P Rather than force every CIE to have a long list of bytes to initialize all 32 integer registers, we define that the default values of all registers (as returned by libdwarf in the frame interface) are 'same value'. This is a good choice for many non-register-windows implementations. .H 2 "Augmentation string in debug_frame" The augmentation string we use in shipped compilers (up thru irix6.2) is the empty string. IRIX6.2 and later has an augmentation string the empty string ("") or "z" or "mti v1" where the "v1" is a version number (version 1). .P We do not believe that "mti v1" was emitted as the augmentation string in any shipped compiler. .P .H 3 "CIE processing based on augmentation string:" If the augmentation string begins with 'z', then it is followed immediately by a unsigned_leb_128 number giving the code alignment factor. Next is a signed_leb_128 number giving the data alignment factor. Next is a unsigned byte giving the number of the return address register. Next is an unsigned_leb_128 number giving the length of the 'augmentation' fields (the length of augmentation bytes, not including the unsigned_leb_128 length itself). As of release 6.2, the length of the CIE augmentation fields is 0. What this means is that it is possible to add new augmentations, z1, z2, etc and yet an old consumer to understand the entire CIE as it can bypass the augmentation it does not understand because the length of the augmentation fields is present. Presuming of course that all augmentation fields are simply additional information, not some 'changing of the meaning of an existing field'. Currently there is no CIE data in the augmentation for things beginning with 'z'. .P If the augmentation string is "mti v1" or "" then it is followed immediately by a unsigned_leb_128 number giving the code alignment factor. Next is a signed_leb_128 number giving the data alignment factor. Next is a unsigned byte giving the number of the return address register. .P If the augmentation string is something else, then the code alignment factor is assumed to be 4 and the data alignment factor is assumed to be -1 and the return address register is assumed to be 31. Arbitrarily. The library (libdwarf) assumes it does not understand the rest of the CIE. .P .H 3 "FDE processing based on augmentation" If the CIE augmentation string for an fde begins with 'z' then the next FDE field after the address_range field is an unsigned_leb_128 number giving the length of the 'augmentation' fields, and those fields follow immediately. .H 4 "FDE augmentation fields" .P If the CIE augmentation string is "mti v1" or "" then the FDE is exactly as described in the Dwarf Document section 6.4.1. .P Else, if the CIE augmentation string begins with "z" then the next field after the FDE augmentation length field is a Dwarf_Sword size offset into exception tables. If the CIE augmentation string does not begin with "z" (and is neither "mti v1" nor "") the FDE augmentation fields are skipped (not understood). Note that libdwarf actually (as of MIPSpro7.3 and earlier) only tests that the initial character of the augmentation string is 'z', and ignores the rest of the string, if any. So in reality the test is for a _prefix_ of 'z'. .P If the CIE augmentation string neither starts with 'z' nor is "" nor is "mti v1" then libdwarf (incorrectly) assumes that the table defining instructions start next. Processing (in libdwarf) will be incorrect. .H 2 "Stack Pointer recovery from debug_frame" There is no identifiable means in DWARF2 to say that the stack register is recovered by any particular operation. A 'register rule' works if the caller's stack pointer was copied to another register. An 'offset(N)' rule works if the caller's stack pointer was stored on the stack. However if the stack pointer is some register value plus/minus some offset, there is no means to say this in an FDE. For MIPS/IRIX, the recovered stack pointer of the next frame up the stack (towards main()) is simply the CFA value of the current frame, and the CFA value is precisely a register (value of a register) or a register plus offset (value of a register plus offset). This is a software convention. .H 1 "egcs dwarf extensions (egcs-1.1.2 extensions)" This and following egcs sections describe the extensions currently shown in egcs dwarf2. Note that egcs has chosen to adopt tag and attribute naming as if their choices were standard dwarf, not as if they were extensions. However, they are properly numbered as extensions. .H 2 "DW_TAG_format_label 0x4101" For FORTRAN 77, Fortran 90. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_TAG_function_template 0x4102" For C++. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_TAG_class_template 0x4103" For C++. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_AT_sf_names 0x2101" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_src_info 0x2102" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_mac_info 0x2103" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_src_coords 0x2104" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_body_begin 0x2105" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_body_end 0x2106" Apparently only output in DWARF1, not DWARF2. .H 1 "egcs .eh_frame (non-sgi) (egcs-1.1.2 extensions)" egcs-1.1.2 (and earlier egcs) emits by default a section named .eh_frame for ia32 (and possibly other platforms) which is nearly identical to .debug_frame in format and content. This section is used for helping handle C++ exceptions. .P Because after linking there are sometimes zero-ed out bytes at the end of the eh_frame section, the reader code in dwarf_frame.c considers a zero cie/fde length as an indication that it is the end of the section. .P .H 2 "CIE_id 0" The section is an ALLOCATED section in an executable, and is therefore mapped into memory at run time. The CIE_pointer (aka CIE_id, section 6.4.1 of the DWARF2 document) is the field that distinguishes a CIE from an FDE. The designers of the egcs .eh_frame section decided to make the CIE_id be 0 as the CIE_pointer definition is .in +2 the number of bytes from the CIE-pointer in the FDE back to the applicable CIE. .in -2 In a dwarf .debug_frame section, the CIE_pointer is the offset in .debug_frame of the CIE for this fde, and since an offset can be zero of some CIE, the CIE_id cannot be 0, but must be all 1 bits . Note that the dwarf2.0 spec does specify the value of CIE_id as 0xffffffff (see section 7.23 of v2.0.0), though earlier versions of this extensions document incorrectly said it was not specified in the dwarf document. .H 2 "augmentation eh" The augmentation string in each CIE is "eh" which, with its following NUL character, aligns the following word to a 32bit boundary. Following the augmentation string is a 32bit word with the address of the __EXCEPTION_TABLE__, part of the exception handling data for egcs. .H 2 "DW_CFA_GNU_window_save 0x2d" This is effectively a flag for architectures with register windows, and tells the unwinder code that it must look to a previous frame for the correct register window set. As of this writing, egcs gcc/frame.c indicates this is for SPARC register windows. .H 2 "DW_CFA_GNU_args_size 0x2e" DW_CFA_GNU_args_size has a single uleb128 argument which is the size, in bytes, of the function's stack at that point in the function. .H 2 "__EXCEPTION_TABLE__" A series of 3 32bit word entries by default: 0 word: low pc address 1 word: high pc address 2 word: pointer to exception handler code The end of the table is signaled by 2 words of -1 (not 3 words!). .H 1 "Interpretations of the DWARF V2 spec" .H 2 "template TAG spellings" The DWARF V2 spec spells two attributes in two ways. DW_TAG_template_type_param (listed in Figure 1, page 7) is spelled DW_TAG_template_type_parameter in the body of the document (section 3.3.7, page 28). We have adopted the spelling DW_TAG_template_type_param. .P DW_TAG_template_value_param (listed in Figure 1, page 7) is spelled DW_TAG_template_value_parameter in the body of the document (section 3.3.7, page 28). We have adopted the spelling DW_TAG_template_value_parameter. .P We recognize that the choices adopted are neither consistently the longer nor the shorter name. This inconsistency was an accident. .H 2 DW_FORM_ref_addr confusing Section 7.5.4, Attribute Encodings, describes DW_FORM_ref_addr. The description says the reference is the size of an address on the target architecture. This is surely a mistake, because on a 16bit-pointer-architecture it would mean that the reference could not exceed 16 bits, which makes only a limited amount of sense as the reference is from one part of the dwarf to another, and could (in theory) be *on the disk* and not limited to what fits in memory. Since MIPS is 32 bit pointers (at the smallest) the restriction is not a problem for MIPS/SGI. The 32bit pointer ABIs are limited to 32 bit section sizes anyway (as a result of implementation details). And the 64bit pointer ABIs currently have the same limit as a result of how the compilers and tools are built (this has not proven to be a limit in practice, so far). .P This has been clarified in the DWARF3 spec and the IRIX use of DW_FORM_ref_addr being an offset is correct. .H 2 "Section .debug_macinfo in a debugger" It seems quite difficult, in general, to tie specific text(code) addresses to points in the stream of macro information for a particular compilation unit. So it's been difficult to see how to design a consumer interface to libdwarf for macro information. .P The best (simple to implement, easy for a debugger user to understand) candidate seems to be that the debugger asks for macros of a given name in a compilation unit, and the debugger responds with *all* the macros of that name. .H 3 "only a single choice exists" If there is exactly one, that is usable in expressions, if the debugger is able to evaluate such. .H 3 "multiple macros with same name". If there are multiple macros with the same name in a compilation unit, the debugger (and the debugger user and the application programmer) have a problem: confusion is quite possible. If the macros are simple the debugger user can simply substitute by hand in an expression. If the macros are complicated hand substitution will be impractical, and the debugger will have to identify the choices and let the debugger user choose an interpretation. .H 2 "Section 6.1.2 Lookup by address problem" Each entry is a beginning-address followed by a length. And the distinguished entry 0,0 is used to denote the end of a range of entries. .P This means that one must be careful not to emit a zero length, as in a .o (object file) the beginning address of a normal entry might be 0 (it is a section offset after all), and the resulting 0,0 would be taken as end-of-range, not as a valid entry. A dwarf dumper would have trouble with such data in an object file. .P In an a.out or shared object (dynamic shared object, DSO) no text will be at address zero so in such this problem does not arise. .H 2 "Section 5.10 Subrange Type Entries problem" It is specified that DW_AT_upper_bound (and lower bound) must be signed entries if there is no object type info to specify the bound type (Sec 5.10, end of section). One cannot tell (with some dwarf constant types) what the signedness is from the form itself (like DW_FORM_data1), so it is necessary to determine the object and type according to the rules in 5.10 and then if all that fails, the type is signed. It's a bit complicated and earlier versions of mips_extensions incorrectly said signedness was not defined. .H 2 "Section 5.5.6 Class Template Instantiations problem" Lots of room for implementor to canonicalize template declarations. Ie various folks won't agree. This is not serious since a given compiler will be consistent with itself and debuggers will have to cope! .H 2 "Section 2.4.3.4 # 11. operator spelling" DW_OP_add should be DW_OP_plus (page 14) (this mistake just one place on the page). .H 2 "No clear specification of C++ static funcs" There is no clear way to tell if a C++ member function is a static member or a non-static member function. (dwarf2read.c in gdb 4.18, for example, has this observation) .H 2 "Misspelling of DW_AT_const_value" Twice in appendix 1, DW_AT_const_value is misspelled as DW_AT_constant_value. .H 2 "Mistake in Attribute Encodings" Section 7.5.4, "Attribute Encodings" has a brief discussion of "constant" which says there are 6 forms of constants. It is incorrect in that it fails to mention (or count) the block forms, which are clearly allowed by section 4.1 "Data Object Entries" (see entry number 9 in the numbered list, on constants). .H 2 "DW_OP_bregx" The description of DW_OP_bregx in 2.4.3.2 (Register Based Addressing) is slightly misleading, in that it lists the offset first. As section 7.7.1 (Location Expression) makes clear, in the encoding the register number comes first. .H 1 "MIPS attributes" .H 2 "DW_AT_MIPS_fde" This extension to Dwarf appears only on subprogram TAGs and has as its value the offset, in the .debug_frame section, of the fde which describes the frame of this function. It is an optimization of sorts to have this present. .H 2 "DW_CFA_MIPS_advance_loc8 0x1d" This obvious extension to dwarf line tables enables encoding of 8 byte advance_loc values (for cases when such must be relocatable, and thus must be full length). Applicable only to 64-bit objects. .H 2 "DW_TAG_MIPS_loop 0x4081" For future use. Not currently emitted. Places to be emitted and attributes that this might own not finalized. .H 2 "DW_AT_MIPS_loop_begin 0x2002" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_tail_loop_begin 0x2003" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_epilog_begin 0x2004" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_loop_unroll_factor 0x2005" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_software_pipeline_depth 0x2006" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_linkage_name 0x2007" The rules for mangling C++ names are not part of the C++ standard and are different for different versions of C++. With this extension, the compiler emits both the DW_AT_name for things with mangled names (recall that DW_AT_name is NOT the mangled form) and also emits DW_AT_MIPS_linkage_name whose value is the mangled name. .P This makes looking for the mangled name in other linker information straightforward. It also is passed (by the debugger) to the libmangle routines to generate names to present to the debugger user. .H 2 "DW_AT_MIPS_stride 0x2008" F90 allows assumed shape arguments and pointers to describe non-contiguous memory. A (runtime) descriptor contains address, bounds and stride information - rank and element size is known during compilation. The extent in each dimension is given by the bounds in a DW_TAG_subrange_type, but the stride cannot be represented in conventional dwarf. DW_AT_MIPS_stride was added as an attribute of a DW_TAG_subrange_type to describe the location of the stride. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. .P If the stride is constant (ie: can be inferred from the type in the usual manner) DW_AT_MIPS_stride is absent. .P If DW_AT_MIPS_stride is present, the attribute contains a reference to a DIE which describes the location holding the stride, and the DW_AT_stride_size field of DW_TAG_array_type is ignored if present. The value of the stride is the number of 4 byte words between elements along that axis. .P This applies to .nf a) Intrinsic types whose size is greater or equal to 4bytes ie: real*4,integer*8 complex etc, but not character types. b) Derived types (ie: structs) of any size, unless all components are of type character. .fi .H 2 "DW_AT_MIPS_abstract_name 0x2009" This attribute only appears in a DA_TAG_inlined_subroutine DIE. The value of this attribute is a string. When IPA inlines a routine and the abstract origin is in another compilation unit, there is a problem with putting in a reference, since the ordering and timing of the creation of references is unpredictable with reference to the DIE and compilation unit the reference refers to. .P Since there may be NO ordering of the compilation units that allows a correct reference to be done without some kind of patching, and since even getting the information from one place to another is a problem, the compiler simply passes the problem on to the debugger. .P The debugger must match the DW_AT_MIPS_abstract_name in the concrete inlined instance DIE with the DW_AT_MIPS_abstract_name in the abstract inlined subroutine DIE. .P A dwarf-consumer-centric view of this and other inline issues could be expressed as follows: .nf If DW_TAG_subprogram If has DW_AT_inline is abstract instance root If has DW_AT_abstract_origin, is out-of-line instance of function (need abstract origin for some data) (abstract root in same CU (conceptually anywhere a ref can reach, but reaching outside of CU is a problem for ipa: see DW_AT_MIPS_abstract_name)) If has DW_AT_MIPS_abstract_name is abstract instance root( must have DW_AT_inline) and this name is used to match with the abstract root If DW_TAG_inline_subroutine Is concrete inlined subprogram instance. If has DW_AT_abstract_origin, it is a CU-local inline. If it has DW_AT_MIPS_abstract_name it is an inline whose abstract root is in another file (CU). .fi .H 2 "DW_AT_MIPS_clone_origin 0x200a" This attribute appears only in a cloned subroutine. The procedure is cloned from the same compilation unit. The value of this attribute is a reference to the original routine in this compilation unit. .P The 'original' routine means the routine which has all the original code. The cloned routines will always have been 'specialized' by IPA. A routine with DW_AT_MIPS_clone_origin will also have the DW_CC_nocall value of the DW_AT_calling_convention attribute. .H 2 "DW_AT_MIPS_has_inlines 0x200b" This attribute may appear in a DW_TAG_subprogram DIE. If present and it has the value True, then the subprogram has inlined functions somewhere in the body. .P By default, at startup, the debugger may not look for inlined functions in scopes inside the outer function. .P This is a hint to the debugger to look for the inlined functions so the debugger can set breakpoints on these in case the user requests 'stop in foo' and foo is inlined. .H 2 "DW_AT_MIPS_stride_byte 0x200c" Created for f90 pointer and assumed shape arrays. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. A variant of DW_AT_MIPS_stride. This stride is interpreted as a byte count. Used for integer*1 and character arrays and arrays of derived type whose components are all character. .H 2 "DW_AT_MIPS_stride_elem 0x200d" Created for f90 pointer and assumed shape arrays. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. A variant of DW_AT_MIPS_stride. This stride is interpreted as a byte-pair (2 byte) count. Used for integer*2 arrays. .H 2 "DW_AT_MIPS_ptr_dopetype 0x200e" See following. .H 2 "DW_AT_MIPS_allocatable_dopetype 0x200f" See following. .H 2 "DW_AT_MIPS_assumed_shape_dopetype 0x2010" DW_AT_MIPS_assumed_shape_dopetype, DW_AT_MIPS_allocatable_dopetype, and DW_AT_MIPS_ptr_dopetype have an attribute value which is a reference to a Fortran 90 Dope Vector. These attributes are introduced in MIPSpro7.3. They only apply to f90 arrays (where they are needed to describe arrays never properly described before in debug information). C, C++, f77, and most f90 arrays continue to be described in standard dwarf. .P The distinction between these three attributes is the f90 syntax distinction: keywords 'pointer' and 'allocatable' with the absence of these keywords on an assumed shape array being the third case. .P A "Dope Vector" is a struct (C struct) which describes a dynamically-allocatable array. In objects with full debugging the C struct will be in the dwarf information (of the f90 object, represented like C). A debugger will use the link to find the main struct DopeVector and will use that information to decode the dope vector. At the outer allocatable/assumed-shape/pointer the DW_AT_location points at the dope vector (so debugger calculations use that as a base). .H 2 "Overview of debugger use of dope vectors" Fundamentally, we build two distinct representations of the arrays and pointers. One, in dwarf, represents the statically-representable information (the types and variable/type-names, without type size information). The other, using dope vectors in memory, represents the run-time data of sizes. A debugger must process the two representations in parallel (and merge them) to deal with user expressions in a debugger. .H 2 "Example f90 code for use in explanation" [Note We want dwarf output with *exactly* this little (arbitrary) example. Not yet available. end Note] Consider the following code. .nf type array_ptr real :: myvar real, dimension (:), pointer :: ap end type array_ptr type (array_ptr), allocatable, dimension (:) :: arrays allocate (arrays(20)) do i = 1,20 allocate (arrays(i)%ap(i)) end do .fi arrays is an allocatable array (1 dimension) whose size is not known at compile time (it has a Dope Vector). At run time, the allocate statement creates 20 array_ptr dope vectors and marks the base arrays dopevector as allocated. The myvar variable is just there to add complexity to the example :-) .nf In the loop, arrays(1)%ap(1) is allocated as a single element array of reals. In the loop, arrays(2)%ap(2) is allocated as an array of two reals. ... In the loop, arrays(20)%ap(20) is allocated as an array of twenty reals. .fi .H 2 "the problem with standard dwarf and this example" .sp In dwarf, there is no way to find the array bounds of arrays(3)%ap, for example, (which are 1:3 in f90 syntax) since any location expression in an ap array lower bound attribute cannot involve the 3 (the 3 is known at debug time and does not appear in the running binary, so no way for the location expression to get to it). And of course the 3 must actually index across the array of dope vectors in 'arrays' in our implementation, but that is less of a problem than the problem with the '3'. .sp Plus dwarf has no way to find the 'allocated' flag in the dope vector (so the debugger can know when the allocate is done for a particular arrays(j)%ap). .sp Consequently, the calculation of array bounds and indices for these dynamically created f90 arrays is now pushed of into the debugger, which must know the field names and usages of the dope vector C structure and use the field offsets etc to find data arrays. C, C++, f77, and most f90 arrays continue to be described in standard dwarf. At the outer allocatable/assumed-shape/pointer the DW_AT_location points at the dope vector (so debugger calculations use that as a base). .P It would have been nice to design a dwarf extension to handle the above problems, but the methods considered to date were not any more consistent with standard dwarf than this dope vector centric approach: essentially just as much work in the debugger appeared necessary either way. A better (more dwarf-ish) design would be welcome information. .H 2 "A simplified sketch of the dwarf information" [Note: Needs to be written. end Note] .H 2 "A simplified sketch of the dope vector information" [Note: This one is simplified. Details left out that should be here. Amplify. end Note] This is an overly simplified version of a dope vector, presented as an initial hint. Full details presented later. .nf struct simplified{ void *base; // pointer to the data this describes long el_len; int assoc:1 int ptr_alloc:1 int num_dims:3; struct dims_s { long lb; long ext; long str_m; } dims[7]; }; .fi Only 'num_dims' elements of dims[] are actually used. .H 2 "The dwarf information" Here is dwarf information from the compiler for the example above, as printed by dwarfdump(1) .nf [Note: The following may not be the test. Having field names with '.' in the name is not such a good idea, as it conflicts with the use of '.' in dbx extended naming. Something else, like _$, would be much easier to work with in dbx (customers won't care about this, for the most part, but folks working on dbx will, and in those rare circumstances when a customer cares, the '.' will be a real problem in dbx.). Note that to print something about .base., in dbx one would have to do whatis `.base.` where that is the grave accent, or back-quote I am using. With extended naming one do whatis `.dope.`.`.base.` which is hard to type and hard to read. end Note] <2>< 388> DW_TAG_array_type DW_AT_name .base. DW_AT_type <815> DW_AT_declaration yes(1) <3>< 401> DW_TAG_subrange_type DW_AT_lower_bound 0 DW_AT_upper_bound 0 <2>< 405> DW_TAG_pointer_type DW_AT_type <388> DW_AT_byte_size 4 DW_AT_address_class 0 <2>< 412> DW_TAG_structure_type DW_AT_name .flds. DW_AT_byte_size 28 <3>< 421> DW_TAG_member DW_AT_name el_len DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 0 <3>< 436> DW_TAG_member DW_AT_name assoc DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 0 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 453> DW_TAG_member DW_AT_name ptr_alloc DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 1 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 474> DW_TAG_member DW_AT_name p_or_a DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 2 DW_AT_bit_size 2 DW_AT_data_member_location DW_OP_consts 4 <3>< 492> DW_TAG_member DW_AT_name a_contig DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 4 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 532> DW_TAG_member DW_AT_name num_dims DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 29 DW_AT_bit_size 3 DW_AT_data_member_location DW_OP_consts 8 <3>< 572> DW_TAG_member DW_AT_name type_code DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 0 DW_AT_bit_size 32 DW_AT_data_member_location DW_OP_consts 16 <3>< 593> DW_TAG_member DW_AT_name orig_base DW_AT_type <841> DW_AT_data_member_location DW_OP_consts 20 <3>< 611> DW_TAG_member DW_AT_name orig_size DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 24 <2>< 630> DW_TAG_structure_type DW_AT_name .dope_bnd. DW_AT_byte_size 12 <3>< 643> DW_TAG_member DW_AT_name lb DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 0 <3>< 654> DW_TAG_member DW_AT_name ext DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 4 <3>< 666> DW_TAG_member DW_AT_name str_m DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 8 <2>< 681> DW_TAG_array_type DW_AT_name .dims. DW_AT_type <630> DW_AT_declaration yes(1) <3>< 694> DW_TAG_subrange_type DW_AT_lower_bound 0 DW_AT_upper_bound 0 <2>< 698> DW_TAG_structure_type DW_AT_name .dope. DW_AT_byte_size 44 <3>< 707> DW_TAG_member DW_AT_name base DW_AT_type <405> DW_AT_data_member_location DW_OP_consts 0 <3>< 720> DW_TAG_member DW_AT_name .flds DW_AT_type <412> DW_AT_data_member_location DW_OP_consts 4 <3>< 734> DW_TAG_member DW_AT_name .dims. DW_AT_type <681> DW_AT_data_member_location DW_OP_consts 32 <2>< 750> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -32 DW_AT_artificial yes(1) <2>< 759> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -28 DW_AT_artificial yes(1) <2>< 768> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -24 DW_AT_artificial yes(1) <2>< 777> DW_TAG_array_type DW_AT_type <815> DW_AT_declaration yes(1) <3>< 783> DW_TAG_subrange_type DW_AT_lower_bound <750> DW_AT_count <759> DW_AT_MIPS_stride <768> <2>< 797> DW_TAG_variable DW_AT_decl_file 1 DW_AT_decl_line 1 DW_AT_name ARRAY DW_AT_type <698> DW_AT_location DW_OP_fbreg -64 DW_OP_deref <1>< 815> DW_TAG_base_type DW_AT_name INTEGER_4 DW_AT_encoding DW_ATE_signed DW_AT_byte_size 4 <1>< 828> DW_TAG_base_type DW_AT_name INTEGER_8 DW_AT_encoding DW_ATE_signed DW_AT_byte_size 8 <1>< 841> DW_TAG_base_type DW_AT_name INTEGER*4 DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 4 <1>< 854> DW_TAG_base_type DW_AT_name INTEGER*8 DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 8 .fi .H 2 "The dope vector structure details" A dope vector is the following C struct, "dopevec.h". Not all the fields are of use to a debugger. It may be that not all fields will show up in the f90 dwarf (since not all are of interest to debuggers). .nf [Note: Need details on the use of each field. And need to know which are really 32 bits and which are 32 or 64. end Note] The following struct is a representation of all the dope vector fields. It suppresses irrelevant detail and may not exactly match the layout in memory (a debugger must examine the dwarf to find the fields, not compile this structure into the debugger!). .nf struct .dope. { void *base; // pointer to data struct .flds. { long el_len; // length of element in bytes? unsigned int assoc:1; //means? unsigned int ptr_alloc:1; //means? unsigned int p_or_a:2; //means? unsigned int a_contig:1; // means? unsigned int num_dims: 3; // 0 thru 7 unsigned int type_code:32; //values? unsigned int orig_base; //void *? means? long orig_size; // means? } .flds; struct .dope_bnd. { long lb ; // lower bound long ext ; // means? long str_m; // means? } .dims[7]; } .fi .H 2 "DW_AT_MIPS_assumed_size 0x2011" This flag was invented to deal with f90 arrays. For example: .nf pointer (rptr, axx(1)) pointer (iptr, ita(*)) rptr = malloc (100*8) iptr = malloc (100*4) .fi This flag attribute has the value 'yes' (true, on) if and only if the size is unbounded, as iptr is. Both may show an explicit upper bound of 1 in the dwarf, but this flag notifies the debugger that there is explicitly no user-provided size. So if a user asks for a printout of the rptr allocated array, the default will be of a single entry (as there is a user slice bound in the source). In contrast, there is no explicit upper bound on the iptr (ita) array so the default slice will use the current bound (a value calculated from the malloc size, see the dope vector). Given explicit requests, more of rptr(axx) can me shown than the default. .H 1 "Line information and Source Position" DWARF does not define the meaning of the term 'source statement'. Nor does it define any way to find the first user-written executable code in a function. .P It does define that a source statement has a file name, a line number, and a column position (see Sec 6.2, Line Number Information of the Dwarf Version 2 document). We will call those 3 source coordinates a 'source position' in this document. We'll try not to accidentally call the source position a 'line number' since that is ambiguous as to what it means. .H 2 "Definition of Statement" .P A function prolog is a statement. .P A C, C++, Pascal, or Fortran statement is a statement. .P Each initialized local variable in C,C++ is a statement in that its initialization generates a source position. This means that x =3, y=4; is two statements. .P For C, C++: The 3 parts a,b,c in for(a;b;c) {d;} are individual statements. The condition portion of a while() and do {} while() is a statement. (of course d; can be any number of statements) .P For Fortran, the controlling expression of a DO loop is a statement. Is a 'continue' statement in Fortran a DWARF statement? .P Each function return, whether user coded or generated by the compiler, is a statement. This is so one can step over (in a debugger) the final user-coded statement (exclusive of the return statement if any) in a function wile not leaving the function scope. .P .H 2 "Finding The First User Code in a Function" .nf Consider: int func(int a) { /* source position 1 */ float b = a; /* source position 2 */ int x; x = b + 2; /* source position 3 */ } /* source position 4 */ .fi .P The DIE for a function gives the address range of the function, including function prolog(s) and epilog(s) .P Since there is no scope block for the outer user scope of a function (and thus no beginning address range for the outer user scope: the DWARF committee explicitly rejected the idea of having a user scope block) it is necessary to use the source position information to find the first user-executable statement. .P This means that the user code for a function must be presumed to begin at the code location of the second source position in the function address range. .P If a function has exactly one source position, the function presumably consists solely of a return. .P If a function has exactly two source positions, the function may consist of a function prolog and a return or a single user statement and a return (there may be no prolog code needed in a leaf function). In this case, there is no way to be sure which is the first source position of user code, so the rule is to presume that the first address is user code. .P If a function consists of 3 or more source positions, one should assume that the first source position is function prolog and the second is the first user executable code. .H 2 "Using debug_frame Information to find first user statement" In addition to the line information, the debug_frame information can be useful in determining the first user source line. .P Given that a function has more than 1 source position, Find the code location of the second source position, then examine the debug_frame information to determine if the Canonical Frame Address (cfa) is updated before the second source position code location. If the cfa is updated, then one can be pretty sure that the code for the first source position is function prolog code. .P Similarly, if the cfa is restored in the code for a source position, the source position is likely to represent a function exit block. .H 2 "Debugger Use Of Source Position" Command line debuggers, such as dbx and gdb, will ordinarily want to consider multiple statements on one line to be a single statement: doing otherwise is distressing to users since it causes a 'step' command to appear to have no effect. .P An exception for command line debuggers is in determining the first user statement: as detailed above, there one wants to consider the full source position and will want to consider the function return a separate statement. It is difficult to make the function return a separate statement 'step' reliably however if a function is coded all on one line or if the last line of user code before the return is on the same line as the return. .P A graphical debugger has none of these problems if it simply highlights the portion of the line being executed. In that case, stepping will appear natural even stepping within a line. .H 1 "Known Bugs" Up through at least MIPSpro7.2.1 the compiler has been emitting form DW_FORM_DATA1,2, or 4 for DW_AT_const_value in DW_TAG_enumerator. And dwarfdump and debuggers have read this with dwarf_formudata() or form_sdata() and gotten some values incorrect. For example, a value of 128 was printed by debuggers as a negative value. Since dwarfdump and the compilers were not written to use the value the same way, their output differed. For negative enumerator values the compiler has been emitting 32bit values in a DW_FORM_DATA4. The compiler should probably be emitting a DW_FORM_sdata for enumerator values. And consumers of enumerator values should then call form_sdata(). However, right now, debuggers should call form_udata() and only if it fails, call form_sdata(). Anything else will break backward compatibility with the objects produced earlier. .SK .S .TC 1 1 4 .CS libdwarf-20210528/libdwarf/dwarf_error.c0000664000175000017500000001516213764007262014762 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarfstring.h" #include "dwarf_error.h" #undef DEBUG /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be added to this Array */ #include "dwarf_errmsg_list.h" /* 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. */ /* The user provides an explanatory string, the error number itself explains little. This prepends DW_DLE_USER_DECLARED_ERROR to the caller-provided string. New in April, 2020 . Used by dwarfdump in a few circumstances. */ void dwarf_error_creation(Dwarf_Debug dbg, Dwarf_Error *err, char *errmsg) { dwarfstring m; if (!dbg) { return; } dwarfstring_constructor(&m); dwarfstring_append(&m,"DW_DLE_USER_DECLARED_ERROR: "); dwarfstring_append(&m,errmsg); _dwarf_error_string(dbg,err, DW_DLE_USER_DECLARED_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); } void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval) { _dwarf_error_string(dbg,error,errval,0); } void _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval,char *msg) { 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) { /* If dbg is NULL, use the alternate error struct. However, this will overwrite the earlier error. */ if (dbg) { 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; #ifdef DEBUG printf("libdwarfdetector no dbg, " "using DE_STATIC alloc, addr" " 0x%lx line %d %s\n", (unsigned long)errptr, __LINE__,__FILE__); #endif /* DEBUG */ } else { errptr->er_static_alloc = DE_MALLOC; #ifdef DEBUG printf("libdwarfdetector no dbg, " "static DE_MALLOC alloc, addr" " 0x%lx line %d %s\n", (unsigned long)errptr, __LINE__,__FILE__); #endif /* DEBUG */ } } errptr->er_errval = errval; if (msg) { dwarfstring *em = 0; #ifdef DEBUG printf("libdwarfdetector ALLOC creating error string" " %s errval %ld errptr 0x%lx \n", msg,(long)errval,(unsigned long)errptr); #endif em = (dwarfstring *)calloc(1,sizeof(dwarfstring)); if (em) { dwarfstring_constructor(em); dwarfstring_append(em,msg); errptr->er_msg = (void*)em; } } *error = errptr; return; } if (dbg && 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(); } Dwarf_Unsigned dwarf_errno(Dwarf_Error error) { if (!error) { return (0); } return (error->er_errval); } char* dwarf_errmsg_by_number(Dwarf_Unsigned errornum ) { if (errornum >= (Dwarf_Signed)(sizeof(_dwarf_errmsgs) / sizeof(char *))) { return "Dwarf_Error value out of range"; } return ((char *) _dwarf_errmsgs[errornum]); } /* */ char * dwarf_errmsg(Dwarf_Error error) { if (!error) { return "Dwarf_Error is NULL"; } if (error->er_msg) { return dwarfstring_string(error->er_msg); } return dwarf_errmsg_by_number(error->er_errval); } libdwarf-20210528/libdwarf/dwarf_types.c0000664000175000017500000000667113764007262015002 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" int dwarf_get_types(Dwarf_Debug dbg, Dwarf_Type ** types, Dwarf_Signed * ret_type_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_typenames, error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_typenames.dss_size) { return DW_DLV_NO_ENTRY; } return _dwarf_internal_get_pubnames_like_data(dbg, ".debug_typenames", dbg->de_debug_typenames.dss_data, dbg->de_debug_typenames.dss_size, (Dwarf_Global **) types, /* type punning, Dwarf_Type is never a completed type */ ret_type_count, error, DW_DLA_TYPENAME_CONTEXT, DW_DLA_TYPENAME, DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD, DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_types_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count); return; } int dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; if (type == NULL) { _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return DW_DLV_ERROR; } *ret_name = (char *) (type->gl_name); return DW_DLV_OK; } int dwarf_type_die_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_die_offset(type, ret_offset, error); } int dwarf_type_cu_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_cu_offset(type, ret_offset, error); } int dwarf_type_name_offsets(Dwarf_Type type_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_name_offsets(type, returned_name, die_offset, cu_die_offset, error); } libdwarf-20210528/libdwarf/dwarf_elfread.c0000664000175000017500000006504114004650653015230 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of an Elf file appropriate to reading DWARF debugging data. Overview: _dwarf_elf_nlsetup() Does all elf setup. calls _dwarf_elf_access_init() calls _dwarf_elf_object_access_internals_init() Creates internals record 'M', dwarf_elf_object_access_internals_t Sets flags/data in internals record Loads elf object data needed later. Sets methods struct to access elf object. calls _dwarf_object_init_b() Creates Dwarf_Debug, independent of any elf code. Sets internals record into dbg. ---------------------- _dwarf_destruct_elf_nlaccess(). This frees the elf internals record created in _dwarf_elf_object_access_internals_init() in case of errors during setup or when dwarf_finish() is called. Works safely for partially or fully set-up elf internals record. Other than in _dwarf_elf_nlsetup() the elf code knows nothing about Dwarf_Debug, and the rest of libdwarf knows nothing about the content of the object-type-specific (for Elf here) internals record. */ #include "config.h" #include #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* open() */ #endif /* HAVE_SYS_STAT_H */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #include "dwarf_elfstructs.h" #include "dwarf_elf_defines.h" #include "dwarf_elf_rel_detector.h" #include "dwarf_elfread.h" #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ #ifdef WORDS_BIGENDIAN #define READ_UNALIGNED_SAFE(dbg,dest, source, length) \ do { \ Dwarf_Unsigned _ltmp = 0; \ dbg->de_copy_word( (((char *)(&_ltmp)) + \ sizeof(_ltmp) - length),source, length); \ dest = _ltmp; \ } while (0) #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((char *)source) +srclength-len_out, \ len_out) ; \ } #else /* LITTLE ENDIAN */ #define READ_UNALIGNED_SAFE(dbg,dest, source, srclength) \ do { \ Dwarf_Unsigned _ltmp = 0; \ dbg->de_copy_word( (char *)(&_ltmp), \ source, srclength) ; \ dest = _ltmp; \ } while (0) #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((char *)source) , \ len_out) ; \ } #endif /* *-ENDIAN */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int _dwarf_elf_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static Dwarf_Endianness elf_get_nolibelf_byte_order (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_endian; } static Dwarf_Small elf_get_nolibelf_length_size (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_offsetsize/8; } static Dwarf_Small elf_get_nolibelf_pointer_size (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_pointersize/8; } static Dwarf_Unsigned elf_get_nolibelf_section_count (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_loc_shdr.g_count; } static int elf_get_nolibelf_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); if (section_index < elf->f_loc_shdr.g_count) { struct generic_shdr *sp = 0; sp = elf->f_shdr + section_index; return_section->addr = sp->gh_addr; return_section->type = sp->gh_type; return_section->size = sp->gh_size; return_section->name = sp->gh_namestring; return_section->link = sp->gh_link; return_section->info = sp->gh_info; return_section->entrysize = sp->gh_entsize; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int elf_load_nolibelf_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); if (0 < section_index && section_index < elf->f_loc_shdr.g_count) { int res = 0; struct generic_shdr *sp = elf->f_shdr + section_index; if (sp->gh_content) { *return_data = (Dwarf_Small *)sp->gh_content; return DW_DLV_OK; } if (!sp->gh_size) { return DW_DLV_NO_ENTRY; } /* Guarding against bad values and against overflow */ if (sp->gh_size > elf->f_filesize || sp->gh_offset > elf->f_filesize || (sp->gh_size + sp->gh_offset) > elf->f_filesize) { *error = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } sp->gh_content = malloc((size_t)sp->gh_size); if (!sp->gh_content) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(elf->f_fd, sp->gh_content, (off_t)sp->gh_offset, (size_t)sp->gh_size, (off_t)elf->f_filesize, error); if (res != DW_DLV_OK) { free(sp->gh_content); sp->gh_content = 0; return res; } *return_data = (Dwarf_Small *)sp->gh_content; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int _dwarf_get_elf_flags_func_nl( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error) { dwarf_elf_object_access_internals_t *ep = 0; struct generic_shdr *shp = 0; ep = (dwarf_elf_object_access_internals_t *)obj_in; if (section_index == 0) { /* Nothing to do. Empty section */ return DW_DLV_OK; } if (section_index >= ep->f_loc_shdr.g_count) { *error = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } shp = ep->f_shdr + section_index; *flags_out = shp->gh_flags; *addralign_out = shp->gh_addralign; return DW_DLV_OK; } #define MATCH_REL_SEC(i_,s_,r_) \ if (i_ == s_.dss_index) { \ *r_ = &s_; \ return DW_DLV_OK; \ } static int find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, struct Dwarf_Section_s **relocatablesec, int *error) { MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_funcnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_typenames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_varnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_weaknames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_rnglists, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loclists, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_sup, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_addr,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_gnu_pubnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_gnu_pubtypes, relocatablesec); /* dbg-> de_debug_tu_index,reloctablesec); */ /* dbg-> de_debug_cu_index,reloctablesec); */ /* dbg-> de_debug_gdbindex,reloctablesec); */ /* dbg-> de_debug_str,syms); */ /* de_elf_symtab,syms); */ /* de_elf_strtab,syms); */ *error = DW_DLE_RELOC_SECTION_MISMATCH; return DW_DLV_ERROR; } /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. The caller may decide to ignore the errors or report them. */ static int update_entry(Dwarf_Debug dbg, dwarf_elf_object_access_internals_t*obj, struct generic_rela *rela, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, int *error) { unsigned int type = 0; unsigned int sym_idx = 0; Dwarf_Unsigned offset = 0; Dwarf_Signed addend = 0; Dwarf_Unsigned reloc_size = 0; Dwarf_Half machine = obj->f_machine; struct generic_symentry *symp = 0; int is_rela = rela->gr_is_rela; offset = rela->gr_offset; addend = rela->gr_addend; type = (unsigned int)rela->gr_type; sym_idx = (unsigned int)rela->gr_sym; if (sym_idx >= obj->f_loc_symtab.g_count) { *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; return DW_DLV_ERROR; } symp = obj->f_symtab + sym_idx; if (offset >= target_section_size) { /* If offset really big, any add will overflow. So lets stop early if offset is corrupt. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } /* Determine relocation size */ if (_dwarf_is_32bit_abs_reloc(type, machine)) { reloc_size = 4; } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { reloc_size = 8; } else if (machine == EM_X86_64 && type == R_X86_64_NONE) { /* There is nothing to do. */ return DW_DLV_OK; } else { *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; } if ( (offset + reloc_size) < offset) { /* Another check for overflow. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if ( (offset + reloc_size) > target_section_size) { *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } /* Assuming we do not need to do a READ_UNALIGNED here at target_section + offset and add its value to outval. Some ABIs say no read (for example MIPS), but if some do then which ones? */ { /* .rel. (addend is 0), or .rela. */ Dwarf_Small *targ = target_section+offset; Dwarf_Unsigned presentval = 0; Dwarf_Unsigned outval = 0; /* See also: READ_UNALIGNED_SAFE in dwarf_elf_access.c */ if (!is_rela) { READ_UNALIGNED_SAFE(dbg,presentval, targ,reloc_size); } /* There is no addend in .rel. Normally presentval is correct and st_value will be zero. But a few compilers have presentval zero and st_value set. */ outval = presentval + symp->gs_value + addend; WRITE_UNALIGNED_LOCAL(dbg,targ, &outval,sizeof(outval),reloc_size); } return DW_DLV_OK; } /* Somewhat arbitrarily, we attempt to apply all the relocations we can and still notify the caller of at least one error if we found any errors. */ static int apply_rela_entries( Dwarf_Debug dbg, /* Section_index of the relocation section, .rela entries */ Dwarf_Half r_section_index, dwarf_elf_object_access_internals_t*obj, /* relocatablesec is the .debug_info(etc) in Dwarf_Debug */ struct Dwarf_Section_s * relocatablesec, int *error) { int return_res = DW_DLV_OK; struct generic_shdr * rels_shp = 0; Dwarf_Unsigned relcount; Dwarf_Unsigned i = 0; if (r_section_index >= obj->f_loc_shdr.g_count) { *error = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } rels_shp = obj->f_shdr + r_section_index; relcount = rels_shp->gh_relcount; if (!relcount) { /* Nothing to do. */ return DW_DLV_OK; } if (!rels_shp->gh_rels) { /* something wrong. */ *error = DW_DLE_RELOCS_ERROR; return DW_DLV_ERROR; } for (i = 0; i < relcount; i++) { int res = update_entry(dbg,obj, rels_shp->gh_rels+i, relocatablesec->dss_data, relocatablesec->dss_size, error); if (res != DW_DLV_OK) { /* We try to keep going, not stop. */ return_res = res; } } return return_res; } /* Find the section data in dbg and find all the relevant sections. Then do relocations. section_index is the index of a .debug_info (for example) so we have to find the section(s) with relocations targeting section_index. Normally there is exactly one such, though. */ static int elf_relocations_nolibelf(void* obj_in, Dwarf_Half section_index, Dwarf_Debug dbg, int* error) { int res = DW_DLV_ERROR; dwarf_elf_object_access_internals_t*obj = 0; struct Dwarf_Section_s * relocatablesec = 0; unsigned section_with_reloc_records = 0; if (section_index == 0) { return DW_DLV_NO_ENTRY; } obj = (dwarf_elf_object_access_internals_t*)obj_in; /* The section to relocate must already be loaded into memory. This just turns section_index into a pointer to a de_debug_info or other section record in Dwarf_Debug. */ res = find_section_to_relocate(dbg, section_index, &relocatablesec, error); if (res != DW_DLV_OK) { return res; } /* Now we know the Dwarf_Section_s section we need to relocate. So lets find the rela section(s) targeting this. */ /* Sun and possibly others do not always set sh_link in .debug_* sections. So we cannot do full consistency checks. FIXME: This approach assumes there is only one relocation section applying to section section_index! */ section_with_reloc_records = relocatablesec->dss_reloc_index; if (!section_with_reloc_records) { /* Something is wrong. */ *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; return DW_DLV_ERROR; } /* The relocations, if they exist, have been loaded. */ /* The symtab was already loaded. */ if (!obj->f_symtab || !obj->f_symtab_sect_strings) { *error = DW_DLE_DEBUG_SYMTAB_ERR; return DW_DLV_ERROR; } if (obj->f_symtab_sect_index != relocatablesec->dss_reloc_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; return DW_DLV_ERROR; } /* We have all the data we need in memory. */ /* Now we apply the relocs in section_with_reloc_records to the target, relocablesec */ res = apply_rela_entries(dbg,section_with_reloc_records, obj, relocatablesec,error); return res; } void _dwarf_destruct_elf_nlaccess( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_elf_object_access_internals_t *ep = 0; struct generic_shdr *shp = 0; Dwarf_Unsigned shcount = 0; Dwarf_Unsigned i = 0; ep = (dwarf_elf_object_access_internals_t *)aip->object; free(ep->f_ehdr); shp = ep->f_shdr; shcount = ep->f_loc_shdr.g_count; for (i = 0; i < shcount; ++i,++shp) { free(shp->gh_rels); shp->gh_rels = 0; free(shp->gh_content); shp->gh_content = 0; free(shp->gh_sht_group_array); shp->gh_sht_group_array = 0; shp->gh_sht_group_array_count = 0; } free(ep->f_shdr); ep->f_loc_shdr.g_count = 0; free(ep->f_phdr); free(ep->f_elf_shstrings_data); free(ep->f_dynamic); free(ep->f_symtab_sect_strings); free(ep->f_dynsym_sect_strings); free(ep->f_symtab); free(ep->f_dynsym); /* if TRUE close f_fd on destruct.*/ if (ep->f_destruct_close_fd) { close(ep->f_fd); } ep->f_ident[0] = 'X'; free(ep->f_path); free(ep); free(aip); } int _dwarf_elf_nlsetup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_elf_object_access_internals_t *intfc = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_elf_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_elf_nlaccess(binary_interface); return res; } intfc = binary_interface->object; intfc->f_path = strdup(true_path); return res; } /* dwarf_elf_access method table for use with non-libelf. See also the methods table in dwarf_elf_access.c for libelf. */ static Dwarf_Obj_Access_Methods const elf_nlmethods = { elf_get_nolibelf_section_info, elf_get_nolibelf_byte_order, elf_get_nolibelf_length_size, elf_get_nolibelf_pointer_size, elf_get_nolibelf_section_count, elf_load_nolibelf_section, elf_relocations_nolibelf }; /* On any error this frees internals argument. */ static int _dwarf_elf_object_access_internals_init( dwarf_elf_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_elf_object_access_internals_t * intfc = internals; Dwarf_Unsigned i = 0; struct Dwarf_Obj_Access_Interface_s *localdoas; int res = 0; /* Must malloc as _dwarf_destruct_elf_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); /* E is used with libelf. F with this elf reader. */ intfc->f_ident[0] = 'F'; intfc->f_ident[1] = '1'; intfc->f_fd = fd; intfc->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->f_offsetsize = offsetsize; intfc->f_pointersize = offsetsize; intfc->f_filesize = filesize; intfc->f_ftype = ftype; intfc->f_destruct_close_fd = FALSE; #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->f_copy_word = _dwarf_memcpy_swap_bytes; intfc->f_endian = DW_OBJECT_LSB; } else { intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; intfc->f_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; intfc->f_endian = DW_OBJECT_LSB; } else { intfc->f_copy_word = _dwarf_memcpy_swap_bytes; intfc->f_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func_nl; /* The following sets f_machine. */ res = _dwarf_load_elf_header(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } /* Not loading progheaders */ res = _dwarf_load_elf_sectheaders(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } /* We are not looking at symbol strings for now. */ res = _dwarf_load_elf_symstr(intfc,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } res = _dwarf_load_elf_symtab_symbols(intfc,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } for ( i = 1; i < intfc->f_loc_shdr.g_count; ++i) { struct generic_shdr *shp = 0; Dwarf_Unsigned section_type = 0; enum RelocRela localrel = RelocIsRela; shp = intfc->f_shdr +i; section_type = shp->gh_type; if (!shp->gh_namestring) { /* A serious error which we ignore here as it will be caught elsewhere if necessary. */ continue; } else if (section_type == SHT_REL || (!strncmp(".rel.",shp->gh_namestring,5))) { localrel = RelocIsRel; } else if (section_type == SHT_RELA || (!strncmp(".rela.",shp->gh_namestring,6))) { localrel = RelocIsRela; } else { continue; } /* ASSERT: local rel is either RelocIsRel or RelocIsRela. Never any other value. */ /* Possibly we should check if the target section is one we care about before loading rela FIXME */ res = _dwarf_load_elf_relx(intfc,i,localrel,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } } free(localdoas); localdoas = 0; return DW_DLV_OK; } static int _dwarf_elf_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_elf_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_elf_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ return res; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &elf_nlmethods; *binary_interface = intfc; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_line_table_reader_common.h0000664000175000017500000032033414053207546020625 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This is #included twice. Once for libdwarf callers and one for dwarfdump which prints the internals. This way we have just one blob of code that reads the table operations. */ #define TRUE 1 #define FALSE 0 static unsigned char dwarf_standard_opcode_operand_count[ STANDARD_OPERAND_COUNT_TWO_LEVEL] = { /* DWARF2 */ 0, 1, 1, 1, 1, 0, 0, 0, 1, /* Following are new for DWARF3. */ 0, 0, 1, /* Experimental opcodes. */ 1, 2, 0, }; /* We have a normal standard opcode base, but an arm compiler emitted a non-standard table! This could lead to problems... ARM C/C++ Compiler, RVCT4.0 [Build 4 00] seems to get the table wrong . */ static unsigned char dwarf_arm_standard_opcode_operand_count[ STANDARD_OPERAND_COUNT_DWARF3] = { /* DWARF2 */ 0, 1, 1, 1, 1, 0, 0, 0, 0, /* <<< --- this is wrong */ /* Following are new for DWARF3. */ 0, 0, 1 }; /* Rather like memcmp but identifies which value pair mismatches (the return value is non-zero if mismatch, zero if match).. mismatch_entry returns the table index that mismatches. tabval returns the table byte value. lineval returns the value from the line table header. */ static int operandmismatch(unsigned char * table,unsigned table_length, unsigned char *linetable, unsigned check_count, unsigned * mismatch_entry, unsigned * tabval,unsigned *lineval) { unsigned i = 0; /* check_count better be <= table_length */ for (i = 0; i table_length) { *mismatch_entry = i; *lineval = linetable[i]; *tabval = 0; /* No entry present. */ /* A kind of mismatch */ return TRUE; } if (table[i] == linetable[i]) { continue; } *mismatch_entry = i; *tabval = table[i]; *lineval = linetable[i]; return TRUE; } /* Matches. */ return FALSE; } /* Encapsulates DECODE_LEB128_UWORD_CK so the caller can free resources in case of problems. */ static int read_uword_de(Dwarf_Small **lp, Dwarf_Unsigned *out_p, Dwarf_Debug dbg, Dwarf_Error *err, Dwarf_Small *lpend) { Dwarf_Small *inptr = *lp; Dwarf_Unsigned out = 0; DECODE_LEB128_UWORD_CK(inptr, out, dbg,err,lpend); *lp = inptr; *out_p = out; return DW_DLV_OK; } static int read_sword_de(Dwarf_Small **lp, Dwarf_Signed *out_p, Dwarf_Debug dbg, Dwarf_Error *err, Dwarf_Small *lpend) { Dwarf_Small *inptr = *lp; Dwarf_Signed out = 0; DECODE_LEB128_SWORD_CK(inptr, out, dbg,err,lpend); *lp = inptr; *out_p = out; return DW_DLV_OK; } /* Common line table header reading code. Returns DW_DLV_OK, DW_DLV_ERROR. DW_DLV_NO_ENTRY cannot be returned, but callers should assume it is possible. The line_context area must be initialized properly before calling this. Has the side effect of allocating arrays which must be freed (see the Line_Table_Context which holds the pointers to space we allocate here). bogus_bytes_ptr and bogus_bytes are output values which let a print-program notify the user of some surprising bytes after a line table header and before the line table instructions. These can be ignored unless one is printing. And are ignored if NULL passed as the pointer. err_count_out may be NULL, in which case we make no attempt to count checking-type errors. Checking-type errors do not stop us, we just report them. See dw-linetableheader.txt for the ordering of text fields across the various dwarf versions. The code follows this ordering closely. Some of the arguments remaining are in line_context so can be deleted from the argument list (after a close look for correctness). */ static int _dwarf_read_line_table_header(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Small * section_start, Dwarf_Small * data_start, Dwarf_Unsigned section_length, Dwarf_Small ** updated_data_start_out, Dwarf_Line_Context line_context, Dwarf_Small ** bogus_bytes_ptr, Dwarf_Unsigned *bogus_bytes, Dwarf_Error * err, int *err_count_out) { Dwarf_Small *line_ptr = data_start; Dwarf_Small *starting_line_ptr = data_start; Dwarf_Unsigned total_length = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Unsigned prologue_length = 0; Dwarf_Half version = 0; /* Both of the next two should point *one past* the end of actual data of interest. */ Dwarf_Small *section_end = section_start + section_length; Dwarf_Small *line_ptr_end = 0; Dwarf_Small *lp_begin = 0; int res = 0; Dwarf_Unsigned htmp = 0; if (bogus_bytes_ptr) *bogus_bytes_ptr = 0; if (bogus_bytes) *bogus_bytes= 0; line_context->lc_line_ptr_start = starting_line_ptr; /* READ_AREA_LENGTH updates line_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, total_length, Dwarf_Unsigned, line_ptr, local_length_size, local_extension_size, err, section_length,section_end); line_ptr_end = line_ptr + total_length; line_context->lc_line_ptr_end = line_ptr_end; line_context->lc_length_field_length = local_length_size + local_extension_size; line_context->lc_section_offset = starting_line_ptr - dbg->de_debug_line.dss_data; /* ASSERT: line_context->lc_length_field_length == line_ptr -line_context->lc_line_ptr_start; */ if (line_ptr_end > section_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return DW_DLV_ERROR; } line_context->lc_total_length = total_length; /* READ_UNALIGNED_CK(dbg, version, Dwarf_Half, line_ptr, DWARF_HALF_SIZE, err,line_ptr_end); */ res = _dwarf_read_unaligned_ck_wrapper(dbg, &htmp,line_ptr,DWARF_HALF_SIZE,line_ptr_end,err); if (res == DW_DLV_ERROR) { return res; } version = htmp; line_context->lc_version_number = version; line_ptr += DWARF_HALF_SIZE; if (version != DW_LINE_VERSION2 && version != DW_LINE_VERSION3 && version != DW_LINE_VERSION4 && version != DW_LINE_VERSION5 && version != EXPERIMENTAL_LINE_TABLES_VERSION) { _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } if (version == DW_LINE_VERSION5) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_address_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_segment_selector_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); } else { line_context->lc_address_size = cu_context->cc_address_size; line_context->lc_segment_selector_size = cu_context->cc_segment_selector_size; } READ_UNALIGNED_CK(dbg, prologue_length, Dwarf_Unsigned, line_ptr, local_length_size, err,line_ptr_end); line_context->lc_prologue_length = prologue_length; line_ptr += local_length_size; line_context->lc_line_prologue_start = line_ptr; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_minimum_instruction_length = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (version == DW_LINE_VERSION4 || version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_maximum_ops_per_instruction = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); } if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_default_is_stmt = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_line_base = *(signed char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Sbyte); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } line_context->lc_line_range = *(unsigned char *) line_ptr; if (!line_context->lc_line_range) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_RANGE_ZERO); return DW_DLV_ERROR; } line_ptr = line_ptr + sizeof(Dwarf_Small); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } line_context->lc_opcode_base = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); /* Set up the array of standard opcode lengths. */ /* We think this works ok even for cross-endian processing of objects. It might be wrong, we might need to specially process the array of ubyte into host order. */ line_context->lc_opcode_length_table = line_ptr; /* lc_opcode_base is one greater than the size of the array. */ line_ptr += line_context->lc_opcode_base - 1; line_context->lc_std_op_count = line_context->lc_opcode_base -1; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } { /* Determine (as best we can) whether the lc_opcode_length_table holds 9 or 12 standard-conforming entries. gcc4 upped to DWARF3's 12 without updating the version number. EXPERIMENTAL_LINE_TABLES_VERSION upped to 15. */ unsigned check_count = line_context->lc_std_op_count; unsigned tab_count = sizeof(dwarf_standard_opcode_operand_count); int operand_ck_fail = true; if (line_context->lc_std_op_count > tab_count) { _dwarf_print_header_issue(dbg, "Too many standard operands in linetable header: ", data_start, line_context->lc_std_op_count, 0,0,0, err_count_out); check_count = tab_count; } { unsigned entrynum = 0; unsigned tabv = 0; unsigned linetabv = 0; int mismatch = operandmismatch( dwarf_standard_opcode_operand_count, tab_count, line_context->lc_opcode_length_table, check_count,&entrynum,&tabv,&linetabv); if (mismatch) { if (err_count_out) { _dwarf_print_header_issue(dbg, "standard-operands did not match, checked", data_start, check_count, entrynum,tabv,linetabv,err_count_out); } if (check_count > sizeof(dwarf_arm_standard_opcode_operand_count)) { check_count = sizeof( dwarf_arm_standard_opcode_operand_count); } mismatch = operandmismatch( dwarf_arm_standard_opcode_operand_count, sizeof(dwarf_arm_standard_opcode_operand_count), line_context->lc_opcode_length_table, check_count,&entrynum,&tabv,&linetabv); if (!mismatch && err_count_out) { _dwarf_print_header_issue(dbg, "arm (incorrect) operands in use: ", data_start, check_count, entrynum,tabv,linetabv,err_count_out); } } if (!mismatch) { if (version == 2) { if (line_context->lc_std_op_count == STANDARD_OPERAND_COUNT_DWARF3) { _dwarf_print_header_issue(dbg, "standard DWARF3 operands matched," " but is DWARF2 linetable: count", data_start, check_count, 0,0,0, err_count_out); } } operand_ck_fail = false; } } if (operand_ck_fail) { /* Here we are not sure what the lc_std_op_count is. */ _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD); return (DW_DLV_ERROR); } } /* At this point we no longer need to check operand counts. */ if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version < DW_LINE_VERSION5){ Dwarf_Unsigned directories_count = 0; Dwarf_Unsigned directories_malloc = 5; line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) * directories_malloc); if (line_context->lc_include_directories == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(line_context->lc_include_directories, 0, sizeof(Dwarf_Small *) * directories_malloc); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } while ((*(char *) line_ptr) != '\0') { if (directories_count >= directories_malloc) { Dwarf_Unsigned expand = 2 * directories_malloc; Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand; Dwarf_Small **newdirs = realloc(line_context->lc_include_directories, bytesalloc); if (!newdirs) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Doubled size, zero out second half. */ memset(newdirs + directories_malloc, 0, sizeof(Dwarf_Small *) * directories_malloc); directories_malloc = expand; line_context->lc_include_directories = newdirs; } line_context->lc_include_directories[directories_count] = line_ptr; res = _dwarf_check_string_valid(dbg, data_start,line_ptr,line_ptr_end, DW_DLE_LINE_STRING_BAD,err); if (res != DW_DLV_OK) { return res; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; directories_count++; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } line_ptr++; line_context->lc_include_directories_count = directories_count; } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* Empty old style dir entry list. */ line_ptr++; } else if (version == DW_LINE_VERSION5) { /* handled below */ } else { /* No old style directory entries. */ } if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version < DW_LINE_VERSION5) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } while (*(char *) line_ptr != '\0') { Dwarf_Unsigned utmp; Dwarf_Unsigned dir_index = 0; Dwarf_Unsigned lastmod = 0; Dwarf_Unsigned file_length = 0; int resl = 0; Dwarf_File_Entry currfile = 0; currfile = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (currfile == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(currfile,0,sizeof(struct Dwarf_File_Entry_s)); /* Insert early so in case of error we can find and free the record. */ _dwarf_add_to_files_list(line_context,currfile); currfile->fi_file_name = line_ptr; resl = _dwarf_check_string_valid(dbg, data_start,line_ptr,line_ptr_end, DW_DLE_LINE_STRING_BAD,err); if (resl != DW_DLV_OK) { return resl; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; /* DECODE_LEB128_UWORD_CK(line_ptr, utmp,dbg, err,line_ptr_end); */ res = read_uword_de(&line_ptr,&utmp, dbg,err,line_ptr_end); if (res == DW_DLV_ERROR) { return DW_DLV_ERROR; } dir_index = (Dwarf_Unsigned) utmp; if (dir_index > line_context->lc_include_directories_count) { _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD); return (DW_DLV_ERROR); } currfile->fi_dir_index = dir_index; currfile->fi_dir_index_present = TRUE; /*DECODE_LEB128_UWORD_CK(line_ptr,lastmod, dbg,err, line_ptr_end); */ res = read_uword_de( &line_ptr,&lastmod, dbg,err,line_ptr_end); if (res == DW_DLV_ERROR) { return DW_DLV_ERROR; } currfile->fi_time_last_mod = lastmod; currfile->fi_time_last_mod_present = TRUE; DECODE_LEB128_UWORD_CK(line_ptr,file_length, dbg,err, line_ptr_end); currfile->fi_file_length = file_length; currfile->fi_file_length_present = TRUE; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } /* Skip trailing nul byte */ ++line_ptr; } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (*line_ptr != 0) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } line_ptr++; } else if (version == 5) { /* handled below */ } else { /* No old style filenames entries. */ } if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { static unsigned char expbytes[5] = {0,0xff,0xff,0x7f, 0x7f }; Dwarf_Unsigned logicals_table_offset = 0; Dwarf_Unsigned actuals_table_offset = 0; unsigned i = 0; for ( ; i < 5; ++i) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (*line_ptr != expbytes[i]) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } line_ptr++; } READ_UNALIGNED_CK(dbg, logicals_table_offset, Dwarf_Unsigned, line_ptr, local_length_size,err,line_ptr_end); line_context->lc_logicals_table_offset = logicals_table_offset; line_ptr += local_length_size; READ_UNALIGNED_CK(dbg, actuals_table_offset, Dwarf_Unsigned, line_ptr, local_length_size,err,line_ptr_end); line_context->lc_actuals_table_offset = actuals_table_offset; line_ptr += local_length_size; if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } } if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* DWARF 5. directory names.*/ Dwarf_Unsigned directory_format_count = 0; struct Dwarf_Unsigned_Pair_s * format_values = 0; Dwarf_Unsigned directories_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } directory_format_count = *(unsigned char *) line_ptr; line_context->lc_directory_entry_format_count = directory_format_count; line_ptr = line_ptr + sizeof(Dwarf_Small); if (directory_format_count > 0) { format_values = malloc( sizeof(struct Dwarf_Unsigned_Pair_s) * directory_format_count); if (format_values == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < directory_format_count; i++) { dres=read_uword_de(&line_ptr, &format_values[i].up_first, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(format_values); format_values = 0; return dres; } dres=read_uword_de(&line_ptr, &format_values[i].up_second, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(format_values); format_values = 0; return dres; } } } dres = read_uword_de(&line_ptr,&directories_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(format_values); format_values = 0; return dres; } line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) * directories_count); if (line_context->lc_include_directories == NULL) { free(format_values); format_values = 0; _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } if (directory_format_count == 0 && directories_count > 0) { free(format_values); format_values = 0; _dwarf_error_string(dbg, err, DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH, "DW_DLE_DIRECTORY_FORMAT_COUNT_" "VS_DIRECTORIES_MISMATCH" ": format count is zero yet directories count > 0"); return (DW_DLV_ERROR); } memset(line_context->lc_include_directories, 0, sizeof(Dwarf_Small *) * directories_count); for (i = 0; i < directories_count; i++) { for (j = 0; j < directory_format_count; j++) { Dwarf_Unsigned lntype = format_values[j].up_first; Dwarf_Unsigned lnform = format_values[j].up_second; switch (lntype) { case DW_LNCT_path: { char *inc_dir_ptr = 0; res = _dwarf_decode_line_string_form(dbg, lntype,lnform, local_length_size, &line_ptr, line_ptr_end, &inc_dir_ptr, err); if (res != DW_DLV_OK) { free(format_values); format_values = 0; return res; } line_context->lc_include_directories[i] = (unsigned char *)inc_dir_ptr; break; } default: free(format_values); format_values = 0; _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } if (line_ptr > line_ptr_end) { free(format_values); format_values = 0; _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } line_context->lc_directory_format_values = format_values; format_values = 0; line_context->lc_include_directories_count = directories_count; } if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* DWARF 5. file names.*/ struct Dwarf_Unsigned_Pair_s * filename_entry_pairs = 0; Dwarf_Unsigned filename_format_count = 0; Dwarf_Unsigned files_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } filename_format_count = *(unsigned char *) line_ptr; line_context->lc_file_name_format_count = filename_format_count; line_ptr = line_ptr + sizeof(Dwarf_Small); filename_entry_pairs = malloc( sizeof(struct Dwarf_Unsigned_Pair_s) * filename_format_count); if (!filename_entry_pairs) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } for (i = 0; i < filename_format_count; i++) { dres=read_uword_de(&line_ptr, &filename_entry_pairs[i].up_first, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_pairs); return dres; } dres=read_uword_de(&line_ptr, &filename_entry_pairs[i]. up_second, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_pairs); return dres; } } /* DECODE_LEB128_UWORD_CK(line_ptr, files_count, dbg,err,line_ptr_end); */ dres=read_uword_de(&line_ptr,&files_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_pairs); return dres; } for (i = 0; i < files_count; i++) { Dwarf_File_Entry curline = 0; curline = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (curline == NULL) { free(filename_entry_pairs); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(curline,0,sizeof(*curline)); _dwarf_add_to_files_list(line_context,curline); for (j = 0; j < filename_format_count; j++) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned lntype = filename_entry_pairs[j].up_first; Dwarf_Unsigned lnform = filename_entry_pairs[j].up_second; switch (lntype) { /* The LLVM LNCT is documented in https://releases.llvm.org/9.0.0/docs /AMDGPUUsage.html */ /* Cannot find the GNU items documented.? */ case DW_LNCT_GNU_decl_file: /* FORM udata*/ res = _dwarf_decode_line_udata_form(dbg, lntype,lnform, &line_ptr, &dirindex, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_gnu_decl_file = dirindex; curline->fi_gnu_decl_file_present = TRUE; break; case DW_LNCT_GNU_decl_line: /* FORM udata */ res = _dwarf_decode_line_udata_form(dbg, lntype,lnform, &line_ptr, &dirindex, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_gnu_decl_line = dirindex; curline->fi_gnu_decl_line_present = TRUE; break; case DW_LNCT_path: { res = _dwarf_decode_line_string_form(dbg, lntype, lnform, local_length_size, &line_ptr, line_ptr_end, (char **)&curline->fi_file_name, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } } break; case DW_LNCT_GNU_subprogram_name: { res = _dwarf_decode_line_string_form(dbg, lntype, lnform, local_length_size, &line_ptr, line_ptr_end, (char **)&curline->fi_gnu_subprogram_name, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } } break; case DW_LNCT_LLVM_source: { res = _dwarf_decode_line_string_form(dbg, lntype, lnform, local_length_size, &line_ptr, line_ptr_end, (char **)&curline->fi_llvm_source, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } } break; case DW_LNCT_directory_index: res = _dwarf_decode_line_udata_form(dbg, lntype,lnform, &line_ptr, &dirindex, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_dir_index = dirindex; curline->fi_dir_index_present = TRUE; break; case DW_LNCT_timestamp: res = _dwarf_decode_line_udata_form(dbg, lntype, lnform, &line_ptr, &curline->fi_time_last_mod, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_time_last_mod_present = TRUE; break; case DW_LNCT_size: res = _dwarf_decode_line_udata_form(dbg, lntype, lnform, &line_ptr, &curline->fi_file_length, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_file_length_present = TRUE; break; case DW_LNCT_MD5: { /* form DW_FORM_data16 */ if (filename_entry_pairs[j].up_second != DW_FORM_data16) { free(filename_entry_pairs); _dwarf_error(dbg, err, DW_DLE_LNCT_MD5_WRONG_FORM); return DW_DLV_ERROR; } res = _dwarf_extract_data16(dbg, line_ptr, line_ptr, line_ptr_end, &curline->fi_md5_value, err); if (res != DW_DLV_OK) { free(filename_entry_pairs); return res; } curline->fi_md5_present = TRUE; line_ptr = line_ptr + sizeof(curline->fi_md5_value); } break; default: free(filename_entry_pairs); _dwarf_report_bad_lnct(dbg, lntype, DW_DLE_LINE_NUMBER_HEADER_ERROR, "DW_DLE_LINE_NUMBER_HEADER_ERROR", err); return (DW_DLV_ERROR); } if (line_ptr > line_ptr_end) { free(filename_entry_pairs); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } } line_context->lc_file_format_values = filename_entry_pairs; filename_entry_pairs = 0; } /* For two-level line tables, read the subprograms table. */ if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { Dwarf_Unsigned subprog_format_count = 0; Dwarf_Unsigned *subprog_entry_types = 0; Dwarf_Unsigned *subprog_entry_forms = 0; Dwarf_Unsigned subprogs_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } subprog_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); subprog_entry_types = malloc(sizeof(Dwarf_Unsigned) * subprog_format_count); if (subprog_entry_types == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } subprog_entry_forms = malloc(sizeof(Dwarf_Unsigned) * subprog_format_count); if (subprog_entry_forms == NULL) { free(subprog_entry_types); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < subprog_format_count; i++) { dres=read_uword_de(&line_ptr,subprog_entry_types+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } dres=read_uword_de(&line_ptr,subprog_entry_forms+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } } dres=read_uword_de(&line_ptr,&subprogs_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } line_context->lc_subprogs = malloc(sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count); if (line_context->lc_subprogs == NULL) { free(subprog_entry_types); free(subprog_entry_forms); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(line_context->lc_subprogs, 0, sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count); for (i = 0; i < subprogs_count; i++) { struct Dwarf_Subprog_Entry_s *curline = line_context->lc_subprogs + i; for (j = 0; j < subprog_format_count; j++) { Dwarf_Unsigned lntype = subprog_entry_types[j]; Dwarf_Unsigned lnform = subprog_entry_forms[j]; switch (lntype) { case DW_LNCT_GNU_subprogram_name: res = _dwarf_decode_line_string_form(dbg, lntype,lnform, local_length_size, &line_ptr, line_ptr_end, (char **)&curline->ds_subprog_name, err); if (res != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return res; } break; case DW_LNCT_GNU_decl_file: res = _dwarf_decode_line_udata_form(dbg, lntype,lnform, &line_ptr, &curline->ds_decl_file, line_ptr_end, err); if (res != DW_DLV_OK) { free(subprog_entry_forms); free(subprog_entry_types); return res; } break; case DW_LNCT_GNU_decl_line: res = _dwarf_decode_line_udata_form(dbg, lntype,lnform, &line_ptr, &curline->ds_decl_line, line_ptr_end, err); if (res != DW_DLV_OK) { free(subprog_entry_forms); free(subprog_entry_types); return res; } break; default: free(subprog_entry_forms); free(subprog_entry_types); _dwarf_report_bad_lnct(dbg, lntype, DW_DLE_LINE_NUMBER_HEADER_ERROR, "DW_DLE_LINE_NUMBER_HEADER_ERROR", err); return (DW_DLV_ERROR); } if (line_ptr >= line_ptr_end) { free(subprog_entry_types); free(subprog_entry_forms); _dwarf_error_string(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR, "DW_DLE_LINE_NUMBER_HEADER_ERROR:" " Reading suprogram entry DW_LNCT* types " " we run off the end of the table"); return (DW_DLV_ERROR); } } } free(subprog_entry_types); free(subprog_entry_forms); line_context->lc_subprogs_count = subprogs_count; } if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { lp_begin = line_context->lc_line_prologue_start + line_context->lc_logicals_table_offset; } else { lp_begin = line_context->lc_line_prologue_start + line_context->lc_prologue_length; } if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (line_ptr != lp_begin) { if (line_ptr > lp_begin) { _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD); return (DW_DLV_ERROR); } else { /* Bug in compiler. These bytes are really part of the instruction stream. The line_context->lc_prologue_length is wrong (12 too high). */ if (bogus_bytes_ptr) { *bogus_bytes_ptr = line_ptr; } if (bogus_bytes) { /* How far off things are. We expect the value 12 ! Negative value seems impossible. */ /* ptrdiff_t is generated but not named */ *bogus_bytes = (lp_begin - line_ptr); } } /* Ignore the lp_begin calc. Assume line_ptr right. Making up for compiler bug. */ lp_begin = line_ptr; } line_context->lc_line_ptr_start = lp_begin; if (line_context->lc_actuals_table_offset) { /* This means two tables. */ line_context->lc_table_count = 2; } else { if (line_context->lc_line_ptr_end > lp_begin) { line_context->lc_table_count = 1; } else { line_context->lc_table_count = 0; } } *updated_data_start_out = lp_begin; return DW_DLV_OK; } /* Read one line table program. For two-level line tables, this function is called once for each table. */ static int read_line_table_program(Dwarf_Debug dbg, Dwarf_Small *line_ptr, Dwarf_Small *line_ptr_end, UNUSEDARG Dwarf_Small *orig_line_ptr, Dwarf_Small *section_start, Dwarf_Line_Context line_context, Dwarf_Half address_size, Dwarf_Bool doaddrs, /* Only true if SGI IRIX rqs calling. */ Dwarf_Bool dolines, Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table, Dwarf_Error *error, UNUSEDARG int *err_count_out) { Dwarf_Unsigned i = 0; Dwarf_File_Entry cur_file_entry = 0; Dwarf_Line *logicals = line_context->lc_linebuf_logicals; Dwarf_Unsigned logicals_count = line_context->lc_linecount_logicals; struct Dwarf_Line_Registers_s regs; /* This is a pointer to the current line being added to the line matrix. */ Dwarf_Line curr_line = 0; /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in bytes. */ Dwarf_Unsigned leb128_num = 0; Dwarf_Signed advance_line = 0; /* This is the operand of the latest fixed_advance_pc extended opcode. */ Dwarf_Half fixed_advance_pc = 0; /* Counts the number of lines in the line matrix. */ Dwarf_Unsigned line_count = 0; /* This is the length of an extended opcode instr. */ Dwarf_Unsigned instr_length = 0; /* Used to chain together pointers to line table entries that are later used to create a block of Dwarf_Line entries. */ Dwarf_Chain chain_line = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Chain curr_chain = NULL; /* This points to a block of Dwarf_Lines, a pointer to which is returned in linebuf. */ Dwarf_Line *block_line = 0; /* Mark a line record as being DW_LNS_set_address */ Dwarf_Bool is_addr_set = false; /* Initialize the one state machine variable that depends on the prefix. */ _dwarf_set_line_table_regs_default_values(®s, line_context->lc_version_number, line_context->lc_default_is_stmt); /* Start of statement program. */ while (line_ptr < line_ptr_end) { int type = 0; Dwarf_Small opcode = 0; #ifdef PRINTING_DETAILS { dwarfstring m9a; dwarfstring_constructor(&m9a); dwarfstring_append_printf_u(&m9a, " [0x%06" DW_PR_DSx "] ", /* ptrdiff_t generated but not named */ (line_ptr - section_start)); _dwarf_printf(dbg,dwarfstring_string(&m9a)); dwarfstring_destructor(&m9a); } #endif /* PRINTING_DETAILS */ opcode = *(Dwarf_Small *) line_ptr; line_ptr++; /* 'type' is the output */ WHAT_IS_OPCODE(type, opcode, line_context->lc_opcode_base, line_context->lc_opcode_length_table, line_ptr, line_context->lc_std_op_count); if (type == LOP_DISCARD) { int oc = 0; int opcnt = line_context->lc_opcode_length_table[opcode]; #ifdef PRINTING_DETAILS { dwarfstring m9b; dwarfstring_constructor(&m9b); dwarfstring_append_printf_i(&m9b, "*** DWARF CHECK: DISCARD standard opcode %d ", opcode); dwarfstring_append_printf_i(&m9b, "with %d operands: not understood.", opcnt); _dwarf_printf(dbg,dwarfstring_string(&m9b)); *err_count_out += 1; dwarfstring_destructor(&m9b); } #endif /* PRINTING_DETAILS */ for (oc = 0; oc < opcnt; oc++) { int ocres = 0; /* Read and discard operands we don't understand. arbitrary choice of unsigned read. signed read would work as well. */ UNUSEDARG Dwarf_Unsigned utmp2 = 0; ocres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (ocres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); curr_line = 0; } return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS { dwarfstring m9e; dwarfstring_constructor(&m9e); dwarfstring_append_printf_u(&m9e, " %" DW_PR_DUu, utmp2); dwarfstring_append_printf_u(&m9e, " (0x%" DW_PR_XZEROS DW_PR_DUx ")", utmp2); _dwarf_printf(dbg,dwarfstring_string(&m9e)); dwarfstring_destructor(&m9e); } #endif /* PRINTING_DETAILS */ } #ifdef PRINTING_DETAILS _dwarf_printf(dbg,"***\n"); #endif /* PRINTING_DETAILS */ } else if (type == LOP_SPECIAL) { /* This op code is a special op in the object, no matter that it might fall into the standard op range in this compile. That is, these are special opcodes between opcode_base and MAX_LINE_OP_CODE. (including opcode_base and MAX_LINE_OP_CODE) */ #ifdef PRINTING_DETAILS unsigned origop = opcode; #endif /* PRINTING_DETAILS */ Dwarf_Unsigned operation_advance = 0; opcode = opcode - line_context->lc_opcode_base; operation_advance = (opcode / line_context->lc_line_range); if (line_context->lc_maximum_ops_per_instruction < 2) { regs.lr_address = regs.lr_address + (operation_advance * line_context->lc_minimum_instruction_length); } else { regs.lr_address = regs.lr_address + (line_context->lc_minimum_instruction_length * ((regs.lr_op_index + operation_advance)/ line_context->lc_maximum_ops_per_instruction)); regs.lr_op_index = (regs.lr_op_index +operation_advance)% line_context->lc_maximum_ops_per_instruction; } regs.lr_line = regs.lr_line + line_context->lc_line_base + opcode % line_context->lc_line_range; if ((Dwarf_Signed)regs.lr_line < 0) { /* Something is badly wrong */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR " "The line number computes as %d " "and negative line numbers " "are not correct.",(Dwarf_Signed)regs.lr_line); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); regs.lr_line = 0; _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); curr_line = 0; } return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS { dwarfstring ma; dwarfstring mb; dwarfstring_constructor(&ma); dwarfstring_constructor(&mb); dwarfstring_append_printf_u(&mb,"Specialop %3u", origop); _dwarf_printf(dbg,dwarfstring_string(&ma)); dwarfstring_destructor(&ma); print_line_detail(dbg,dwarfstring_string(&mb), opcode,line_count+1, ®s,is_single_table, is_actuals_table); dwarfstring_destructor(&mb); dwarfstring_destructor(&ma); } #endif /* PRINTING_DETAILS */ if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg,DW_DLA_LINE,1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Mark a line record as being DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data.li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data.li_end_sequence = curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data.li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } chain_line->ch_itemtype = DW_DLA_LINE; chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain, &curr_chain); curr_line = 0; } regs.lr_basic_block = false; regs.lr_prologue_end = false; regs.lr_epilogue_begin = false; regs.lr_discriminator = 0; #ifdef PRINTING_DETAILS #endif /* PRINTING_DETAILS */ } else if (type == LOP_STANDARD) { #ifdef PRINTING_DETAILS dwarfstring mb; #endif /* PRINTING_DETAILS */ switch (opcode) { case DW_LNS_copy:{ #ifdef PRINTING_DETAILS print_line_detail(dbg,"DW_LNS_copy", opcode,line_count+1, ®s,is_single_table, is_actuals_table); #endif /* PRINTING_DETAILS */ if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Mark a line record as DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data. li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data. li_end_sequence = regs.lr_end_sequence; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data. li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_itemtype = DW_DLA_LINE; chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain, &curr_chain); curr_line = 0; } regs.lr_basic_block = false; regs.lr_prologue_end = false; regs.lr_epilogue_begin = false; regs.lr_discriminator = 0; } break; case DW_LNS_advance_pc:{ Dwarf_Unsigned utmp2 = 0; int advres = 0; advres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (advres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_advance_pc val %" DW_PR_DSd, utmp2); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", utmp2); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ leb128_num = utmp2; regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * leb128_num; } break; case DW_LNS_advance_line:{ Dwarf_Signed stmp = 0; int alres = 0; alres = read_sword_de( &line_ptr,&stmp, dbg,error,line_ptr_end); if (alres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } advance_line = (Dwarf_Signed) stmp; #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_advance_line val %" DW_PR_DSd, advance_line); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", advance_line); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ regs.lr_line = regs.lr_line + advance_line; if ((Dwarf_Signed)regs.lr_line < 0) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR" " The line number is %d " "and negative line numbers after " "DW_LNS_ADVANCE_LINE ", (Dwarf_Signed)regs.lr_line); dwarfstring_append_printf_i(&m, " of %d " "are not correct.",stmp); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); regs.lr_line = 0; if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } } break; case DW_LNS_set_file:{ Dwarf_Unsigned utmp2 = 0; int sfres = 0; sfres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (sfres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_file = utmp2; #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_set_file %ld\n", regs.lr_file); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_set_column:{ Dwarf_Unsigned utmp2 = 0; int scres = 0; scres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (scres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_column = utmp2; #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_set_column val %" DW_PR_DSd , regs.lr_column); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", regs.lr_column); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_negate_stmt:{ regs.lr_is_stmt = !regs.lr_is_stmt; #ifdef PRINTING_DETAILS _dwarf_printf(dbg, "DW_LNS_negate_stmt\n"); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_set_basic_block:{ regs.lr_basic_block = true; #ifdef PRINTING_DETAILS _dwarf_printf(dbg, "DW_LNS_set_basic_block\n"); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_const_add_pc:{ opcode = MAX_LINE_OP_CODE - line_context->lc_opcode_base; if (line_context->lc_maximum_ops_per_instruction < 2){ Dwarf_Unsigned operation_advance = (opcode / line_context->lc_line_range); regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * operation_advance; } else { Dwarf_Unsigned operation_advance = (opcode / line_context->lc_line_range); regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * ((regs.lr_op_index + operation_advance)/ line_context->lc_maximum_ops_per_instruction); regs.lr_op_index = (regs.lr_op_index +operation_advance)% line_context->lc_maximum_ops_per_instruction; } #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_u(&mb, "DW_LNS_const_add_pc new address 0x%" DW_PR_XZEROS DW_PR_DSx "\n", regs.lr_address); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_fixed_advance_pc:{ Dwarf_Unsigned fpc = 0; int apres = 0; /*READ_UNALIGNED_CK(dbg, fixed_advance_pc, Dwarf_Half, line_ptr, DWARF_HALF_SIZE,error,line_ptr_end); */ apres = _dwarf_read_unaligned_ck_wrapper(dbg, &fpc,line_ptr,DWARF_HALF_SIZE,line_ptr_end, error); fixed_advance_pc = fpc; if (apres == DW_DLV_ERROR) { if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return apres; } line_ptr += DWARF_HALF_SIZE; if (line_ptr > line_ptr_end) { dwarfstring g; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNS_fixed_advance_pc we are " "off this line table at section " "offset. 0x%x .", localoff); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } regs.lr_address = regs.lr_address + fixed_advance_pc; regs.lr_op_index = 0; #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_fixed_advance_pc val %" DW_PR_DSd, fixed_advance_pc); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx, fixed_advance_pc); dwarfstring_append_printf_u(&mb, " new address 0x%" DW_PR_XZEROS DW_PR_DSx "\n", regs.lr_address); _dwarf_printf(dbg, dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; /* New in DWARF3 */ case DW_LNS_set_prologue_end:{ regs.lr_prologue_end = true; } break; /* New in DWARF3 */ case DW_LNS_set_epilogue_begin:{ regs.lr_epilogue_begin = true; #ifdef PRINTING_DETAILS _dwarf_printf(dbg, "DW_LNS_set_prologue_end set true.\n"); #endif /* PRINTING_DETAILS */ } break; /* New in DWARF3 */ case DW_LNS_set_isa:{ Dwarf_Unsigned utmp2 = 0; int sires = 0; sires = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (sires == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_isa = utmp2; #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_u(&mb, "DW_LNS_set_isa new value 0x%" DW_PR_XZEROS DW_PR_DUx ".\n", utmp2); _dwarf_printf(dbg,dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ if (regs.lr_isa != utmp2) { /* The value of the isa did not fit in our local so we record it wrong. declare an error. */ if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg, head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_LINE_NUM_OPERANDS_BAD); return (DW_DLV_ERROR); } } break; /* Experimental two-level line tables */ /* DW_LNS_set_address_from_logical and DW_LNS_set_subprogram share the same opcode. Disambiguate by checking is_actuals_table. */ case DW_LNS_set_subprogram: if (is_actuals_table) { /* DW_LNS_set_address_from_logical */ Dwarf_Signed stmp = 0; int atres = 0; atres = read_sword_de( &line_ptr,&stmp, dbg,error,line_ptr_end); if (atres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } advance_line = (Dwarf_Signed) stmp; regs.lr_line = regs.lr_line + advance_line; if ((Dwarf_Signed)regs.lr_line < 0) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "\nERROR: DW_DLE_LINE_TABLE_LINENO_ERROR" " The line number is %d " "and negative line numbers after " "DW_LNS_set_subprogram ", (Dwarf_Signed)regs.lr_line); dwarfstring_append_printf_i(&m, " of %d applied " "are not correct.",stmp); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); regs.lr_line = 0; _dwarf_free_chain_entries(dbg, head_chain,line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } if (regs.lr_line >= 1 && regs.lr_line - 1 < logicals_count) { regs.lr_address = logicals[regs.lr_line - 1]->li_address; regs.lr_op_index = 0; #ifdef PRINTING_DETAILS /* block 1 print */ dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_set_address_from" "_logical " "%" DW_PR_DSd, stmp); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx, stmp); dwarfstring_append_printf_u(&mb, " newaddr=" " 0x%" DW_PR_XZEROS DW_PR_DUx ".\n", regs.lr_address); _dwarf_printf(dbg, dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } else { #ifdef PRINTING_DETAILS /* block 2 print */ dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_set_address_from_logical line" " is %" DW_PR_DSd , regs.lr_line); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx ".\n", regs.lr_line); _dwarf_printf(dbg, dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } } else { /* DW_LNS_set_subprogram, building logicals table. */ Dwarf_Unsigned utmp2 = 0; int spres = 0; regs.lr_call_context = 0; spres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (spres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_subprogram = utmp2; #ifdef PRINTING_DETAILS /* block 3 print */ dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_set_subprogram " "%" DW_PR_DSd, utmp2); dwarfstring_append_printf_u(&mb, " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", utmp2); _dwarf_printf(dbg, dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; /* Experimental two-level line tables */ case DW_LNS_inlined_call: { Dwarf_Signed stmp = 0; Dwarf_Unsigned ilcuw = 0; int icres = 0; icres = read_sword_de( &line_ptr,&stmp, dbg,error,line_ptr_end); if (icres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_call_context = line_count + stmp; icres = read_uword_de(&line_ptr,&ilcuw, dbg,error,line_ptr_end); regs.lr_subprogram = ilcuw; if (icres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS dwarfstring_constructor(&mb); dwarfstring_append_printf_i(&mb, "DW_LNS_inlined_call " "%" DW_PR_DSd ,stmp); dwarfstring_append_printf_u(&mb, " (0x%" DW_PR_XZEROS DW_PR_DSx "),", stmp); dwarfstring_append_printf_i(&mb, "%" DW_PR_DSd, regs.lr_subprogram); dwarfstring_append_printf_u(&mb, " (0x%" DW_PR_XZEROS DW_PR_DSx ")", regs.lr_subprogram); dwarfstring_append_printf_i(&mb, " callcontext=" "%" DW_PR_DSd , regs.lr_call_context); dwarfstring_append_printf_u(&mb, " (0x%" DW_PR_XZEROS DW_PR_DSx ")\n", regs.lr_call_context); _dwarf_printf(dbg, dwarfstring_string(&mb)); dwarfstring_destructor(&mb); #endif /* PRINTING_DETAILS */ } break; /* Experimental two-level line tables */ case DW_LNS_pop_context: { Dwarf_Unsigned logical_num = regs.lr_call_context; Dwarf_Chain logical_chain = head_chain; Dwarf_Line logical_line = 0; if (logical_num > 0 && logical_num <= line_count) { for (i = 1; i < logical_num; i++) { logical_chain = logical_chain->ch_next; } logical_line = (Dwarf_Line) logical_chain->ch_item; regs.lr_file = logical_line->li_addr_line.li_l_data.li_file; regs.lr_line = logical_line->li_addr_line.li_l_data.li_line; regs.lr_column = logical_line-> li_addr_line.li_l_data.li_column; regs.lr_discriminator = logical_line-> li_addr_line.li_l_data.li_discriminator; regs.lr_is_stmt = logical_line-> li_addr_line.li_l_data.li_is_stmt; regs.lr_call_context = logical_line-> li_addr_line.li_l_data.li_call_context; regs.lr_subprogram = logical_line-> li_addr_line.li_l_data.li_subprogram; #ifdef PRINTING_DETAILS { dwarfstring pcon; dwarfstring_constructor(&pcon); dwarfstring_append_printf_u(&pcon, "DW_LNS_pop_context set" " from logical " "%" DW_PR_DUu ,logical_num); dwarfstring_append_printf_u(&pcon, " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", logical_num); _dwarf_printf(dbg, dwarfstring_string(&pcon)); dwarfstring_destructor(&pcon); } } else { dwarfstring pcon; dwarfstring_constructor(&pcon); dwarfstring_append_printf_u(&pcon, "DW_LNS_pop_context does nothing, logical" "%" DW_PR_DUu , logical_num); dwarfstring_append_printf_u(&pcon, " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", logical_num); _dwarf_printf(dbg, dwarfstring_string(&pcon)); dwarfstring_destructor(&pcon); #endif /* PRINTING_DETAILS */ } } break; } /* End switch (opcode) */ } else if (type == LOP_EXTENDED) { Dwarf_Unsigned utmp3 = 0; Dwarf_Small ext_opcode = 0; int leres = 0; leres = read_uword_de( &line_ptr,&utmp3, dbg,error,line_ptr_end); if (leres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } instr_length = utmp3; /* Dwarf_Small is a ubyte and the extended opcode is a ubyte, though not stated as clearly in the 2.0.0 spec as one might hope. */ if (line_ptr >= line_ptr_end) { dwarfstring g; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned localoffset = (line_ptr >= section_start)? (line_ptr - section_start) : 0; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "extended op we are " "off this line table at section " "offset 0x%x .", localoffset); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain,line_count); return DW_DLV_ERROR; } ext_opcode = *(Dwarf_Small *) line_ptr; line_ptr++; if (line_ptr > line_ptr_end) { dwarfstring g; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "extended op opcode we are " "off this line table at section " "offset 0x%x .", localoff); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); _dwarf_free_chain_entries(dbg,head_chain,line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } switch (ext_opcode) { case DW_LNE_end_sequence:{ regs.lr_end_sequence = true; if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (!curr_line) { _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } #ifdef PRINTING_DETAILS print_line_detail(dbg, "DW_LNE_end_sequence extended", ext_opcode, line_count+1,®s, is_single_table, is_actuals_table); #endif /* PRINTING_DETAILS */ curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data. li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data. li_end_sequence = regs.lr_end_sequence; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data. li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } chain_line->ch_itemtype = DW_DLA_LINE; chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line, &head_chain,&curr_chain); curr_line = 0; } _dwarf_set_line_table_regs_default_values(®s, line_context->lc_version_number, line_context->lc_default_is_stmt); } break; case DW_LNE_set_address:{ int sares = 0; /* READ_UNALIGNED_CK(dbg, regs.lr_address, Dwarf_Addr, line_ptr, address_size,error,line_ptr_end); */ sares = _dwarf_read_unaligned_ck_wrapper(dbg, ®s.lr_address,line_ptr, address_size,line_ptr_end, error); if (sares == DW_DLV_ERROR) { if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return sares; } /* Mark a line record as being DW_LNS_set_address */ is_addr_set = true; #ifdef PRINTING_DETAILS { dwarfstring sadd; dwarfstring_constructor(&sadd); dwarfstring_append_printf_u(&sadd, "DW_LNE_set_address address 0x%" DW_PR_XZEROS DW_PR_DUx "\n", regs.lr_address); _dwarf_printf(dbg,dwarfstring_string(&sadd)); dwarfstring_destructor(&sadd); } #endif /* PRINTING_DETAILS */ if (doaddrs) { /* SGI IRIX rqs processing only. */ curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (!curr_line) { _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Mark a line record as being DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; #ifdef __sgi /* SGI IRIX ONLY */ /* ptrdiff_t is generated but not named */ curr_line->li_addr_line.li_offset = line_ptr - dbg->de_debug_line.dss_data; #endif /* __sgi */ line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_itemtype = DW_DLA_LINE; chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line, &head_chain,&curr_chain); curr_line = 0; } regs.lr_op_index = 0; line_ptr += address_size; if (line_ptr > line_ptr_end) { dwarfstring g; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE_set_address we are " "off this line table at section " "offset 0x%x .", localoff); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } } break; case DW_LNE_define_file: if (dolines) { int dlres = 0; Dwarf_Unsigned value = 0; cur_file_entry = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (cur_file_entry == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } memset(cur_file_entry,0, sizeof(struct Dwarf_File_Entry_s)); _dwarf_add_to_files_list(line_context, cur_file_entry); cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr; dlres = _dwarf_check_string_valid(dbg, line_ptr,line_ptr,line_ptr_end, DW_DLE_DEFINE_FILE_STRING_BAD,error); if (dlres != DW_DLV_OK) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return dlres; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; dlres = read_uword_de( &line_ptr,&value, dbg,error,line_ptr_end); if (dlres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } cur_file_entry->fi_dir_index = (Dwarf_Signed)value; cur_file_entry->fi_dir_index_present = TRUE; dlres = read_uword_de( &line_ptr,&value, dbg,error,line_ptr_end); if (dlres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } cur_file_entry->fi_time_last_mod = value; dlres = read_uword_de( &line_ptr,&value, dbg,error,line_ptr_end); if (dlres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } cur_file_entry->fi_file_length = value; cur_file_entry->fi_dir_index_present = TRUE; cur_file_entry->fi_time_last_mod_present = TRUE; cur_file_entry->fi_file_length_present = TRUE; #ifdef PRINTING_DETAILS { dwarfstring m9c; dwarfstring_constructor(&m9c); dwarfstring_append_printf_s(&m9c, "DW_LNE_define_file %s \n", (char *)cur_file_entry->fi_file_name); dwarfstring_append_printf_i(&m9c, " dir index %d\n", (int) cur_file_entry->fi_dir_index); { time_t tt3 = (time_t) cur_file_entry-> fi_time_last_mod; /* ctime supplies newline */ dwarfstring_append_printf_u(&m9c, " last time 0x%x ", (Dwarf_Unsigned)tt3); dwarfstring_append_printf_s(&m9c, "%s", ctime(&tt3)); } dwarfstring_append_printf_i(&m9c, " file length %ld ", cur_file_entry->fi_file_length); dwarfstring_append_printf_u(&m9c, "0x%lx\n", cur_file_entry->fi_file_length); _dwarf_printf(dbg,dwarfstring_string(&m9c)); dwarfstring_destructor(&m9c); } #endif /* PRINTING_DETAILS */ } break; case DW_LNE_set_discriminator:{ /* New in DWARF4 */ int sdres = 0; Dwarf_Unsigned utmp2 = 0; sdres = read_uword_de( &line_ptr,&utmp2, dbg,error,line_ptr_end); if (sdres == DW_DLV_ERROR) { _dwarf_free_chain_entries(dbg,head_chain, line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } return DW_DLV_ERROR; } regs.lr_discriminator = utmp2; #ifdef PRINTING_DETAILS { dwarfstring mk; dwarfstring_constructor(&mk); dwarfstring_append_printf_u(&mk, "DW_LNE_set_discriminator 0x%" DW_PR_XZEROS DW_PR_DUx "\n", utmp2); _dwarf_printf(dbg,dwarfstring_string(&mk)); dwarfstring_destructor(&mk); } #endif /* PRINTING_DETAILS */ } break; default:{ /* This is an extended op code we do not know about, other than we know now many bytes it is and the op code and the bytes of operand. */ Dwarf_Unsigned remaining_bytes = instr_length -1; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned space_left = (line_ptr <= line_ptr_end)? (line_ptr_end - line_ptr):0xfffffff; /* By catching this here instead of PRINTING_DETAILS we avoid reading off of our data of interest*/ if (instr_length < 1 || space_left < remaining_bytes || remaining_bytes > DW_LNE_LEN_MAX) { dwarfstring g; /* ptrdiff_t is generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "unknown DW_LNE_extended op opcode 0x%x ", ext_opcode); dwarfstring_append_printf_u(&g, "we are " "off this line table at section " "offset 0x%x and ", localoff); dwarfstring_append_printf_u(&g, "instruction length " "%u.",instr_length); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS { dwarfstring m9d; dwarfstring_constructor(&m9d); dwarfstring_append_printf_u(&m9d, "DW_LNE extended op 0x%x ", ext_opcode); dwarfstring_append_printf_u(&m9d, "Bytecount: %" DW_PR_DUu , (Dwarf_Unsigned)instr_length); if (remaining_bytes > 0) { /* If remaining bytes > distance to end we will have an error. */ dwarfstring_append(&m9d," linedata: 0x"); while (remaining_bytes > 0) { dwarfstring_append_printf_u(&m9d, "%02x", (unsigned char)(*(line_ptr))); line_ptr++; #if 0 /* A test above (see space_left above) proves we will not run off the end here. The following test is too late anyway, we might have read off the end just before line_ptr incremented! */ if (line_ptr >= line_ptr_end) { dwarfstring g; /* ptrdiff_t generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE extended op remaining bytes " "we are " "off this line table at section " "offset 0x%x .", localoff); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); dwarfstring_destructor(&m9d); if (curr_line) { dwarf_dealloc(dbg,curr_line, DW_DLA_LINE); } _dwarf_free_chain_entries(dbg, head_chain,line_count); return DW_DLV_ERROR; } #endif remaining_bytes--; } } _dwarf_printf(dbg,dwarfstring_string(&m9d)); dwarfstring_destructor(&m9d); } #else /* ! PRINTING_DETAILS */ line_ptr += remaining_bytes; if (line_ptr > line_ptr_end) { dwarfstring g; /* ptrdiff_t generated but not named */ Dwarf_Unsigned localoff = (line_ptr >= section_start)? (line_ptr - section_start):0xfffffff; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE extended op remaining bytes " "we are " "off this line table at section " "offset 0x%x .", localoff); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); } _dwarf_free_chain_entries(dbg,head_chain, line_count); return DW_DLV_ERROR; } #endif /* PRINTING_DETAILS */ _dwarf_printf(dbg,"\n"); } break; } /* End switch. */ } } block_line = (Dwarf_Line *) _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count); if (block_line == NULL) { curr_chain = head_chain; _dwarf_free_chain_entries(dbg,head_chain,line_count); if (curr_line) { dwarf_dealloc(dbg,curr_line,DW_DLA_LINE); curr_line = 0; } _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_chain = head_chain; for (i = 0; i < line_count; i++) { Dwarf_Chain t = 0; *(block_line + i) = curr_chain->ch_item; curr_chain->ch_item = 0; curr_chain->ch_itemtype = 0; t = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, t, DW_DLA_CHAIN); } if (is_single_table || !is_actuals_table) { line_context->lc_linebuf_logicals = block_line; line_context->lc_linecount_logicals = line_count; } else { line_context->lc_linebuf_actuals = block_line; line_context->lc_linecount_actuals = line_count; } #ifdef PRINTING_DETAILS { dwarfstring mc; dwarfstring_constructor(&mc); if (is_single_table) { if (!line_count) { dwarfstring_append_printf_u(&mc, " Line table is present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no lines present\n", line_context->lc_section_offset); } } else if (is_actuals_table) { if (!line_count) { dwarfstring_append_printf_u(&mc, " Line table present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no actuals lines present\n", line_context->lc_section_offset); } } else { if (!line_count) { dwarfstring_append_printf_u(&mc, " Line table present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no logicals lines present\n", line_context->lc_section_offset); } } if (dwarfstring_strlen(&mc)) { _dwarf_printf(dbg,dwarfstring_string(&mc)); } dwarfstring_destructor(&mc); } #endif /* PRINTING_DETAILS */ return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_gdbindex.h0000664000175000017500000000550714012266121015410 00000000000000/* Copyright (C) 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The following is based on The gdb online documentation at https://sourceware.org/gdb/onlinedocs/gdb/ Appendix J, ".gdb_index section format". */ /* These are the two types .gdb_index uses. the offset_type (32 bits) and other fields defined 64 bits. We use our own Dwarf_Unsigned for all the interfaces, these are just for reading the section data. The section data is defined to be in little-endian regardless of the target machine. We use our host endianness in all interfaces. We simply assume unsigned int is 32 bits FIXME. */ typedef Dwarf_Unsigned gdbindex_64; enum gdbindex_type_e { git_unknown, git_std, git_address, git_cuvec }; struct Dwarf_Gdbindex_array_instance_s { Dwarf_Small * dg_base; Dwarf_Unsigned dg_count; /* the in_object struct size. */ Dwarf_Unsigned dg_entry_length; /* The size of a single field in the in-object struct */ int dg_fieldlen; /* The address_area type is a bit irregular. */ enum gdbindex_type_e dg_type; }; struct Dwarf_Gdbindex_s { Dwarf_Debug gi_dbg; Dwarf_Small * gi_section_data; Dwarf_Unsigned gi_section_length; Dwarf_Unsigned gi_version; Dwarf_Unsigned gi_cu_list_offset; Dwarf_Unsigned gi_types_cu_list_offset; Dwarf_Unsigned gi_address_area_offset; Dwarf_Unsigned gi_symbol_table_offset; Dwarf_Unsigned gi_constant_pool_offset; struct Dwarf_Gdbindex_array_instance_s gi_culisthdr; struct Dwarf_Gdbindex_array_instance_s gi_typesculisthdr; struct Dwarf_Gdbindex_array_instance_s gi_addressareahdr; struct Dwarf_Gdbindex_array_instance_s gi_symboltablehdr; struct Dwarf_Gdbindex_array_instance_s gi_cuvectorhdr; Dwarf_Small * gi_string_pool; }; libdwarf-20210528/libdwarf/dwarf_gnu_index.h0000664000175000017500000000665613701441253015617 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This is for accessing .debug_gnu_pubnames and .debug_gnu_pubtypes. It has nothing to do with .gdb_index. */ struct DGI_Entry_s { char * ge_string; Dwarf_Unsigned ge_debug_info_offset; char ge_flag_byte; #if 0 /* Following is DW_GNUIVIS bit 7 of flag byte shifted right 7. */ char ge_flag_global_static; /* Following is DW_GNUIKIND bits 4,5,6 of flag byte shifted right 4. Bits 0-3 are reserved and should de zero. */ char ge_flag_type; #endif }; /* each block data on disk looks like: LENGTH (which determines offset size) version offset into .debug_info (offsetsize) size of area in .debug_info (offsetsize) For each entry offset in debug_info of DIE (offsetsize) 1 byte flag strlen+1 string Trailing LENGTH 4 bytes zero. */ struct Dwarf_Gnu_IBlock_s { Dwarf_Gnu_Index_Head ib_head; Dwarf_Unsigned ib_index; /*of this ib */ Dwarf_Unsigned ib_block_length_offset; Dwarf_Unsigned ib_block_length; Dwarf_Half ib_offset_size; /* 4 or 8 */ Dwarf_Half ib_extension_size; /* 0 or 4 */ Dwarf_Half ib_version; Dwarf_Bool ib_counted_entries; /* see ib_entry_count*/ Dwarf_Unsigned ib_offset_in_debug_info; Dwarf_Unsigned ib_size_in_debug_info; /* following the length field*/ Dwarf_Unsigned ib_b_data_offset; Dwarf_Unsigned ib_b_offset; /* offset of entry area */ Dwarf_Small * ib_b_data; /* the entry area */ /* entrylength = LENGTH - 2 - 2*offsetsize */ Dwarf_Unsigned ib_b_entrylength; Dwarf_Unsigned ib_entry_count; struct DGI_Entry_s *ib_entryarray; }; struct Dwarf_Gnu_Index_Head_s { Dwarf_Debug gi_dbg; Dwarf_Small * gi_section_data; Dwarf_Unsigned gi_section_length; struct Dwarf_Gnu_IBlock_s *gi_blockarray; Dwarf_Unsigned gi_blockcount; Dwarf_Bool gi_is_pubnames; /* if false is pubtypes */ }; void _dwarf_gnu_index_head_destructor(void *incoming); void _dwarf_free_gnu_index_head_content(Dwarf_Gnu_Index_Head); libdwarf-20210528/libdwarf/README0000664000175000017500000002425713644370703013167 00000000000000To build libdwarf.a, type ./configure make To build libdwarf.so, type ./configure --enable-shared --disable-nonshared make To build both, type ./configure --enable-shared make April 16, 2017: Some people have had build problems, getting errors like: "dwarf_elf_access.c:238:21: warning: assignment makes pointer from integer without a cast [enabled by default] if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {" That suggests that the libelf headers needed are missing. On Ubuntu the command 'sudo apt-get install libelf-dev' should solve this problem. January 30, 2013: libdwarf.h is no longer in the distribution, but libdwarf.h.in is identical to libdwarf.h. 'configure' copies libdwarf.h.in to libdwarf.h and whether libelf.h defines 'struct _Elf' or 'struct Elf' configure attempts to create libdwarf.h appropriately. No real install target is provided here, so 'make install' does not do much. One can copy either or both of libdwarf.a libdwarf.so to somewhere fairly standard (but intended for software you build) like '/usr/local/lib'. Or anywhere else you want to copy it. To use dwarf or libdwarf, you may want to copy dwarf.h and a generated libdwarf.h somewhere convenient (possibly /usr/local/include), and you may need to copy the libdwarf to a convenient spot (/usr/local/lib is a traditional place for libraries one builds oneself on Unix and Linux). This copying is not needed to build dwarfdump. Multi Threading, or using threads with libdwarf (Thread Safety): Nothing in libdwarf does any locking. Every Dwarf_Debug (such as returned by dwarf_init()) is fully independent of all other Dwarf_Debug-s. However, calls to libdwarf can change a Dwarf_Debug. So it is unsafe to have two different threads accessing a single Dwarf_Debug simultaneously. It is therefore sufficient to ensure than any one Dwarf_Debug is only accessed from a single thread. Warnings like "warning: cast from pointer to integer of different size" at compile time are to be expected in dwarf_frame.c and dwarf_frame2.c. Do not be alarmed. Warnings like "warning: passing argument 1 of ‘dbg->de_callback_func_c’ discards ‘const’ qualifier from pointer target type [enabled by default]" at compile time are to be expected in some pro*.c source files. Fixing the public prototype could cause some producer-library user's code to fail to compile so we live with the warnings. When cross-compiling, gennames has to be built by the native compiler. So try make HOSTCC=cc gennames as a first step before the normal make. If your headers are not in the expected places, use the make command line to add flags and include directories. For example ./configure PREINCS="-I /usr/local/share/include" POSTINCS="-I /home/x/include" make PREINCS content is inserted before CFLAGS as make(1) is running. POSTINCS content is added after the CFLAGS value. To set LDFLAGS (which is used when building a .so and in building gennames to create some source here), do so at configure time, for example: ./configure LDFLAGS="-L /var/tmp" Or use PRELIBS and/or POSTLIBS at 'make' time similar to the use of PREINCS and POSTINCS. If you are using the old frame interfaces and depend on the use of DW_FRAME_CFA_COL you must add --enable-oldframecol to the ./configure options to configure libdwarf. See NEWS and libdwarf2.1.mm/pdf . To generate SGI IRIX 64 bit offsets (in the producer code) configure with --enable-dwarf-format-sgi-irix. To configure with only 32bit offsets (aka DWARF2) configure with --enable-dwarf-format-strict-32bit. By default the producer now generates 32bit offsets by default but one can turn on DWARF3 64bit offset generation at runtime by ORing DW_DLC_OFFSET_SIZE_64 onto the flags in the call to dwarf_producer_init() (or dwarf_producer_init_b) [when the address size is specified as 64 bit]. Mac OSX (June 2010): Since MacOSX does not use elf, there is no elf.h header in the headers provided on MacOSX. Use a search engine (like google) to find an elf.h you can use. http://www.rockbox.org/tracker/9006?getfile=16683 might be useful. In addition, the archive (ar) program on MacOSX does not automatically generate some data so modify the generated Makefile to add -s to the options to ar. Windows (February 2016): Those wishing to read DWARF2 or later from Windows PE files (using Mingw) should take a look at https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp which shows simple LGPL code that implements the necessary object reading interfaces for PE objects. dwarf_pe.cpp fills out the Dwarf_Obj_Access_Methods object interface and opens an object (see dwarf_object_init()) using the PE object access making the full libdwarf API available. To enable dection of Windows pathnames as full paths add --enable-windowspath. Doing this does mean things like A:foo and \anything are treated as full paths (these are unlikely path names on a POSIX system but are legal POSIX partial paths). Back to Linux/Unix: It is possible to request a shared library (libdwarf.so) build with --enable-shared To turn off the build of the archive library (libdwarf.a) specify --disable-nonshared but in this case you must specify --enable-shared or nothing will build! TARGET DEPENDENCIES of .debug_frame: dwarf.h These should be revised if you have more than the defined 63 'normal' registers. It's not harmful to have these too large! Too small will lead to errors reading .debug_frame and .eh_frame. DW_FRAME_HIGHEST_NORMAL_REGISTER DW_FRAME_LAST_REG_NUM These you might revise, but can safely ignore if simply using dwarfdump. If using the producer code you will want to get these exactly right for your architecture. DW_FRAME_RA_COL DW_FRAME_STATIC_LINK DW_FRAME_CFA_COL libdwarf.h The DW_FRAME_REG_INITIAL_VALUE #define should be set to the value appropriate to your architecture. See libdwarf.h for details. If DW_REG_TABLE_SIZE is not set large enough attempts to fill in the .debug_frame tables will get an error. Should be at least as large as DW_FRAME_LAST_REG_NUM. If it's too large nothing is harmed (but some extra space taken at run time). If your printf does not support C standard %llx etc, (such as MSWindows with long long), configure option --enable-nonstandardprintf and defines like DW_PR_DUx etc in libdwarf.h provide a way to configure for that relatively easily. The .debug_frame is so very architecture dependent and because the host (where libdwarf/dwarfdump are executed) and target (the objects read) could be different. It's currently not supported to have dwarfdump/libdwarf determine the architecture on-the-fly and do-the-right-thing. Just setting DW_FRAME_LAST_REG_NUM and DW_FRAME_HIGHEST_NORMAL_REGISTER and DW_REG_TABLE_SIZE high enough will likely suffice for most purposes and most compilers/architectures.. See comments in dwarf.h/libdwarf.h. It's perfectly safe to ignore the above suggestions as long as libdwarf does not get a DW_DLE_DF_REG_NUM_TOO_HIGH error. (which would only happen on reading .debug_frame or .eh_frame data). If you intend to use the libdwarf dwarf-producer code for .debug_frame information you must do a thorough analysys and revise dwarf.h substantially to match the output target architecture. In general, in the producer code, numbers are copied from and to integers with memcpy(). In case of endianness problems, constants set in dwarf_producer_init() can fix the problems. If one wants to produce a *different-endian* output the best solution is to change the integer memcpy calls to call thru a new dbg-based function pointer and have it 'do the right thing' to adjust endianness. Set the function pointer correctly in dwarf_producer_init() and the rest of the code will just call thru the function pointer. Tedious work to find and change the memcpy calls to be dbg->de_memcpy(), but once done the code is no longer endian dependent (right now there is no way to ask for cross-endian: a new flag needed or ?). leb128 numbers are endian-independent, so nothing need be done with those for cross-endian support (the storage of leb128 on disk is always little-endian). The .ps files are postscript. So those who cannot deal with mm format files but do have a postscript printer (or have ghostscript) can print the documents. This form was chosen before pdf format existed... libdwarf2.1.pdf documents a way for a debugger to read dwarf information. libdwarf2p.1.pdf documents a way for a compiler to generate dwarf information. mips_extensions.ps documents the mips/sgi extensions to dwarf. See the Makefile for the commands used to build pdf files libdwarf.2.1.pdf and libdwarf1p.1.pdf. pic is a picture processing tool (ATT command). tbl is a table-processing tool. (part of Documentor's Work Bench on ATT-like systems). tbl and pic are available on linux. psroff is a name for a troff-like processor, part of Documentor's Work Bench on IRIX. Substitute a troff-like or nroff-like processor (GNU groff works fine). To use dwarf or libdwarf, you may want to install dwarf.h and libdwarf.h somewhere convenient. You will also need libelf (libelf.a and/or libelf.so) and libelf.h installed. These are available from GNU repositories and from the normal Linux repositories for Linux releases. On Ubuntu Linux for example: sudo apt-get install libelf-dev libelf1 Compiler warnings: A few Warnings like: dwarf_frame.c:715:29: warning: cast from pointer to integer of different size [- Wpointer-to-int-cast] dwarf_arange.c:113:13: warning: variable ‘local_extension_size’ set but not used [-Wunused-but-set-variable] are considered normal. As of January 2013 the code compiles with gcc without problems with -Wall and -Wsign-compare aside from the warnings hinted at above. The following gcc/clang options have not all been tried as of January 2013, but will be as time permits. -Wsystem-headers -Wall -Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign $Source: /home/davea/dwarf/dwarf-working/trunk/libdwarf/README,v $ $Revision: 1.1 $ $Date: 2009/11/23 17:15:37 $ libdwarf-20210528/libdwarf/pro_reloc.c0000664000175000017500000001740313771421776014442 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2008-2020 David Anderson, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_reloc.h" /* Do initial alloc of newslots slots. Fails only if malloc fails. Supposed to be called before any relocs allocated. Ignored if after any allocated. Part of an optimization, so that for a known 'newslots' relocations count we can preallocate the right size block. Called from just 2 places. We use 'slots' so we don't have to do a new allocation for every relocation, just a new allocation every n slots. slots_in_block. returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_pre_alloc_specific_reloc_slots(Dwarf_P_Debug dbg, Dwarf_P_Per_Reloc_Sect prel, Dwarf_Unsigned newslots) { unsigned long len = 0; struct Dwarf_P_Relocation_Block_s *data = 0; unsigned long slots_in_blk = (unsigned long) newslots; unsigned long rel_rec_size = dbg->de_relocation_record_size; if (prel->pr_first_block) { return DW_DLV_OK; /* do nothing */ } len = sizeof(struct Dwarf_P_Relocation_Block_s) + slots_in_blk * rel_rec_size; data = (struct Dwarf_P_Relocation_Block_s *) _dwarf_p_get_alloc(dbg, len); if (!data) { return DW_DLV_ERROR; } data->rb_slots_in_block = slots_in_blk; /* could use default here, as fallback in case our original estimate wrong. When we call this we presumably know what we are doing, so keep this count for now */ data->rb_next_slot_to_use = 0; data->rb_where_to_add_next = ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); data->rb_data = data->rb_where_to_add_next; prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; return DW_DLV_OK; } /*Do alloc of slots. Fails only if malloc fails. Only allocator used. returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index) { unsigned long len = 0; struct Dwarf_P_Relocation_Block_s *data = 0; Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index]; unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc; unsigned long rel_rec_size = dbg->de_relocation_record_size; len = sizeof(struct Dwarf_P_Relocation_Block_s) + slots_in_blk * rel_rec_size; data = (struct Dwarf_P_Relocation_Block_s *) _dwarf_p_get_alloc(dbg, len); if (!data) { return DW_DLV_ERROR; } if (prel->pr_first_block) { prel->pr_last_block->rb_next = data; prel->pr_last_block = data; prel->pr_block_count += 1; } else { prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; } data->rb_slots_in_block = slots_in_blk; data->rb_next_slot_to_use = 0; data->rb_where_to_add_next = ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); data->rb_data = data->rb_where_to_add_next; return DW_DLV_OK; } /* Reserve a slot. return DW_DLV_OK if succeeds. Return DW_DLV_ERROR if fails (malloc error). Use the relrec_to_fill to pass back a pointer to a slot space to use. */ int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, int base_sec_index, void **relrec_to_fill) { struct Dwarf_P_Relocation_Block_s *data = 0; Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index]; unsigned long rel_rec_size = dbg->de_relocation_record_size; char *ret_addr = 0; data = prel->pr_last_block; if ((data == 0) || (data->rb_next_slot_to_use >= data->rb_slots_in_block)) { int res; res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index); if (res != DW_DLV_OK) { return res; } } data = prel->pr_last_block; /* now we have an empty slot */ ret_addr = data->rb_where_to_add_next; data->rb_where_to_add_next += rel_rec_size; data->rb_next_slot_to_use += 1; prel->pr_reloc_total_count += 1; *relrec_to_fill = (void *) ret_addr; return DW_DLV_OK; } /* On success returns count of .rel.* sections that are symbolic thru count_of_relocation_sections. On success, returns DW_DLV_OK. If this is not a 'symbolic' run, returns DW_DLV_NO_ENTRY. No errors are possible. */ /*ARGSUSED*/ int dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, Dwarf_Unsigned * count_of_relocation_sections, int *drd_buffer_version, UNUSEDARG Dwarf_Error * error) { if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { int i = 0; unsigned int count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) { ++count; } } *count_of_relocation_sections = (Dwarf_Unsigned) count; *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; return DW_DLV_OK; } /* Reset to start at beginning of reloc groups. */ dbg->de_reloc_next_to_return = 0; return DW_DLV_NO_ENTRY; } int dwarf_get_relocation_info(Dwarf_P_Debug dbg, Dwarf_Signed * elf_section_index, Dwarf_Signed * elf_section_index_link, Dwarf_Unsigned * relocation_buffer_count, Dwarf_Relocation_Data * reldata_buffer, Dwarf_Error * error) { int next = dbg->de_reloc_next_to_return; if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { int i = 0; for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { /* de_reloc_sect[] and de_elf_sects[] are in direct parallel. */ Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i]; int elf_sect_num = dbg->de_elf_sects[i]; if (prel->pr_reloc_total_count > 0) { /* Set up 'next' for subsequent call to dwarf_get_relocation_info(). */ dbg->de_reloc_next_to_return = i + 1; /* ASSERT: prel->pr_block_count == 1 */ *elf_section_index = prel->pr_sect_num_of_reloc_sect; /* Elf sec num in generated elf */ *elf_section_index_link = elf_sect_num; *relocation_buffer_count = prel->pr_reloc_total_count; *reldata_buffer = (Dwarf_Relocation_Data) (prel->pr_first_block->rb_data); return DW_DLV_OK; } } DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } return DW_DLV_NO_ENTRY; } libdwarf-20210528/libdwarf/dwarf_funcs.h0000644000175000017500000000226213743575426014760 00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Func_Context_s *Dwarf_Func_Context; /* struct never completed: see dwarf_global.h */ libdwarf-20210528/libdwarf/dwarf_abbrev.c0000664000175000017500000003721314014033446015063 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_abbrev.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 /* This is used to print a .debug_abbrev section without knowing about the DIEs that use the abbrevs. dwarf_get_abbrev() and, in dwarf_util.c, _dwarf_get_abbrev_for_code() When we have a simple .o there is at least a hope of iterating through the abbrevs meaningfully without knowing a CU context. This often fails or gets incorrect info because there is no guarantee the .debug_abbrev section is free of garbage bytes. In an object with multiple CU/TUs the output is difficult/impossible to usefully interpret. In a dwp (Package File) it is really impossible to associate abbrevs with a CU. */ int _dwarf_count_abbrev_entries(Dwarf_Debug dbg, Dwarf_Byte_Ptr abbrev_ptr, Dwarf_Byte_Ptr abbrev_section_end, Dwarf_Unsigned *abbrev_count_out, Dwarf_Byte_Ptr *abbrev_ptr_out, Dwarf_Error *error) { Dwarf_Unsigned abbrev_count = 0; Dwarf_Unsigned attr_name = 0; Dwarf_Unsigned attr_form = 0; UNUSEDARG Dwarf_Unsigned implicit_const = 0; /* The abbreviations table ends with an entry with a single byte of zero for the abbreviation code. Padding bytes following that zero are allowed, but here we simply stop looking past that zero abbrev. We also stop looking if the block/section ends, though the DWARF2 and later standards do not specifically allow section/block end to terminate an abbreviations list. */ do { DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name, dbg,error,abbrev_section_end); if (attr_name > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form, dbg,error,abbrev_section_end); /* If we have attr, form as 0,0, fall through to end */ if (!_dwarf_valid_form_we_know(attr_form,attr_name)) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_UNKNOWN_FORM: Abbrev form 0x%" DW_PR_DUx, attr_form); if (attr_name) { dwarfstring_append_printf_u(&m, " DW_DLE_UNKNOWN_FORM: Abbrev form 0x%" DW_PR_DUx, attr_form); dwarfstring_append_printf_u(&m, " with attribute 0x%" DW_PR_DUx, attr_name); } else { dwarfstring_append_printf_u(&m, " DW_DLE_UNKNOWN_FORM(really unknown attr)" ": Abbrev form 0x%" DW_PR_DUx, attr_form); dwarfstring_append_printf_u(&m, " with attribute 0x%" DW_PR_DUx, attr_name); } dwarfstring_append(&m," so abbreviations unusable. "); _dwarf_error_string(dbg, error, DW_DLE_UNKNOWN_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_section_end); } abbrev_count++; } while ((abbrev_ptr < abbrev_section_end) && (attr_name != 0 || attr_form != 0)); /* We counted one too high,we included the 0,0 */ *abbrev_count_out = abbrev_count-1; *abbrev_ptr_out = abbrev_ptr; return DW_DLV_OK; } int dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Abbrev * returned_abbrev, Dwarf_Unsigned * length, Dwarf_Unsigned * abbr_count, Dwarf_Error * error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_ptr_out = 0; Dwarf_Byte_Ptr abbrev_section_end = 0; Dwarf_Abbrev ret_abbrev = 0; Dwarf_Unsigned labbr_count = 0; Dwarf_Unsigned utmp = 0; int res = 0; if (!dbg) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (dbg->de_debug_abbrev.dss_data == 0) { /* Loads abbrev section (and .debug_info as we do those together). */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } if (offset >= dbg->de_debug_abbrev.dss_size) { return DW_DLV_NO_ENTRY; } ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1); if (ret_abbrev == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_abbrev->dab_dbg = dbg; if (returned_abbrev == 0 || abbr_count == 0) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *abbr_count = 0; if (length) { *length = 1; } abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset; abbrev_section_end = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; #if 0 DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); #endif res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr, abbrev_section_end,&utmp,error); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); return res; } ret_abbrev->dab_code = utmp; if (ret_abbrev->dab_code == 0) { *returned_abbrev = ret_abbrev; *abbr_count = 0; if (length) { *length = 1; } return DW_DLV_OK; } #if 0 DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); #endif res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr, abbrev_section_end,&utmp,error); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); return res; } if (utmp > DW_TAG_hi_user) { return _dwarf_format_TAG_err_msg(dbg, utmp,"DW_DLE_TAG_CORRUPT", error); } ret_abbrev->dab_tag = utmp; if (abbrev_ptr >= abbrev_section_end) { dwarfstring m; dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " "of the abbrev section reading tag, starting at" " abbrev section offset 0x%x",offset); _dwarf_error_string(dbg, error, DW_DLE_ABBREV_DECODE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } ret_abbrev->dab_has_child = *(abbrev_ptr++); ret_abbrev->dab_abbrev_ptr = abbrev_ptr; ret_abbrev->dab_next_ptr = abbrev_ptr; ret_abbrev->dab_next_index = 0; res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr, abbrev_section_end,&labbr_count,&abbrev_ptr_out,error); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); return res; } abbrev_ptr = abbrev_ptr_out; /* Global section offset. */ ret_abbrev->dab_goffset = offset; ret_abbrev->dab_count = labbr_count; if (abbrev_ptr > abbrev_section_end) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); _dwarf_error_string(dbg, error, DW_DLE_ABBREV_DECODE_ERROR, "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " "of the abbrev section reading abbrev_entries."); _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return DW_DLV_ERROR; } if (length) { *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset; } *returned_abbrev = ret_abbrev; *abbr_count = labbr_count; return DW_DLV_OK; } int dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned * returned_code, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *returned_code = abbrev->dab_code; return DW_DLV_OK; } /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be over 16 bits. */ int dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half * returned_tag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *returned_tag = abbrev->dab_tag; return DW_DLV_OK; } int dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed * returned_flag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *returned_flag = abbrev->dab_has_child; return DW_DLV_OK; } /* This does not return the implicit const, nor does it return all bits of the uleb attribute nor does it return all bits of the uleb form value. See dwarf_get_abbrev_entry_b(). */ int dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed indx, Dwarf_Half * returned_attr_num, Dwarf_Signed * returned_form, Dwarf_Off * returned_offset, Dwarf_Error * error) { int res; Dwarf_Unsigned attr = 0; Dwarf_Unsigned form = 0; Dwarf_Signed implicitconst = 0; Dwarf_Unsigned uindex = (Dwarf_Unsigned)indx; Dwarf_Bool filter_outliers = TRUE; res = dwarf_get_abbrev_entry_b(abbrev, uindex, filter_outliers, &attr, &form, &implicitconst, returned_offset, error); if (res != DW_DLV_OK) { return res; } /* returned_offset already set by dwarf_get_abbrev_entry_b; */ if (returned_attr_num) { *returned_attr_num = (Dwarf_Half)attr; } if (returned_form) { *returned_form = (Dwarf_Signed)form; } return DW_DLV_OK; } /* If filter_outliers is non-zero then the routine will return DW_DLV_ERROR if the leb reading generates a number that is so large it cannot be correct. If filter_outliers is 0 the uleb/sleb values read are returned, even if the values are unreasonable. This is a useful option if one wishes to have callers examine the return values in greater detail than the checking here provides. */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned indx, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implicitconst, Dwarf_Off * offset, Dwarf_Error * error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Byte_Ptr mark_abbrev_ptr = 0; Dwarf_Unsigned attr = 0; Dwarf_Unsigned form = 0; Dwarf_Unsigned implicitconst = 0; Dwarf_Debug dbg = 0; Dwarf_Signed local_indx = (Dwarf_Signed)indx; if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } if (abbrev->dab_code == 0) { return DW_DLV_NO_ENTRY; } if (abbrev->dab_dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } dbg = abbrev->dab_dbg; abbrev_ptr = abbrev->dab_abbrev_ptr; abbrev_end = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; if ((Dwarf_Unsigned)local_indx >= abbrev->dab_next_index) { /* We want a part not yet scanned , so we can start closer to the desired value. */ abbrev_ptr = abbrev->dab_next_ptr; local_indx -= abbrev->dab_next_index; } for (attr = 1, form = 1; local_indx >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || form != 0); local_indx--) { mark_abbrev_ptr = abbrev_ptr; DECODE_LEB128_UWORD_CK(abbrev_ptr, attr,dbg, error,abbrev_end); if (filter_outliers && attr > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(abbrev_ptr, form,dbg, error,abbrev_end); if (filter_outliers && !_dwarf_valid_form_we_know(form,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } if (form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK( abbrev_ptr, implicitconst, dbg,error,abbrev_end); } else { implicitconst = 0; } } if (abbrev_ptr >= abbrev_end) { _dwarf_error_string(dbg, error, DW_DLE_ABBREV_DECODE_ERROR, "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " "of the abbrev section reading abbrev entries.."); return DW_DLV_ERROR; } if (local_indx >= 0) { return DW_DLV_NO_ENTRY; } if (returned_form != NULL) { *returned_form = form; } if (offset != NULL) { *offset = mark_abbrev_ptr - dbg->de_debug_abbrev.dss_data; } if (returned_attr_num) { *returned_attr_num = attr; } if (returned_implicitconst) { /* Callers should only examine implicit const value if the form is DW_FORM_implicit_const. */ *returned_implicitconst = implicitconst; } abbrev->dab_next_ptr = abbrev_ptr; abbrev->dab_next_index = (Dwarf_Unsigned)local_indx ; return DW_DLV_OK; } /* This function is not entirely safe to call. The problem is that the DWARF[234] specification does not insist that bytes in .debug_abbrev that are not referenced by .debug_info or .debug_types need to be initialized to anything specific. Any garbage bytes may cause trouble. Not all compilers/linkers leave unreferenced garbage bytes in .debug_abbrev, so this may work for most objects. In case of error could return a bogus value, there is no documented way to detect error. */ int dwarf_get_abbrev_count(Dwarf_Debug dbg) { Dwarf_Abbrev ab; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned attr_count = 0; Dwarf_Unsigned abbrev_count = 0; int abres = DW_DLV_OK; Dwarf_Error err = 0; while ((abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &attr_count, &err)) == DW_DLV_OK) { ++abbrev_count; offset += length; dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); } if (err) { dwarf_dealloc(dbg,err,DW_DLA_ERROR); err = 0; } return abbrev_count; } libdwarf-20210528/libdwarf/generated_libdwarf.h.in0000664000175000017500000065106614050775030016673 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct _Elf Elf; typedef struct _Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; /* Dwarf_Bool as int is wasteful, but for compatibility it must stay as int, not unsigned char. */ typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain location information functions, a frame expression function, and also used with DW_FORM_block<> functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* See libdwarf.h DW_LKIND* */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location description */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW July 2020. */ /* This provides access to data from sections .debug_gnu_pubtypes or .debug_gnu_pubnames. These are not standard DWARF, and can appear with gcc -gdwarf-5 */ struct Dwarf_Gnu_Index_Head_s; typedef struct Dwarf_Gnu_Index_Head_s * Dwarf_Gnu_Index_Head; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_number2; Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { /* Offset of string attribute data */ Dwarf_Unsigned sa_offset; Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s *Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s *Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ /* Dwarf_Frame Block (not used) */ #define DW_DLA_FRAME_BLOCK 0x17 #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x34 (52) reserved for internal to libdwarf types. */ /* .debug_gnu_typenames/pubnames, 2020 */ #define DW_DLA_GNU_INDEX_HEAD 0x35 #define DW_DLA_RNGLISTS_HEAD 0x36 /* .debug_rnglists DW5 */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ /* struct Dwarf_Str_Offsets_Table_s */ #define DW_DLA_STR_OFFSETS 0x40 /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() 'access' argument values. Used for reading/consuming DWARF, not relevant to the producer portion of libdwarf. None of the following three arguments do anything. The following short set is useless. Only DW_DLC_READ has a documented effect but... it is useless and irrelevant as it means 'do the default'. In the 1990's there was an option DW_DLC_MMAP (deleted from libdwarf.h many years ago). The old option libdwarf told IRIX libelf to mmap the object file. */ #define DW_DLC_READ 0 /* Pointless. Ok to use. */ #define DW_DLC_WRITE 1 /* DO NOT USE */ #define DW_DLC_RDWR 2 /* DO NOT USE */ /* ===== the following DW_DLC options are for producing DWARF, not used for reading/consuming DWARF. */ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so. See the Dwarf_Rel_Type enum relocation indicators. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* old spelling */ #define DW_DLC_POINTER64 0x40000000 /* correct spelling */ /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* old spelling */ #define DW_DLC_POINTER32 0x20000000 /* correct spelling */ /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* DO NOT USE */ /* DW_DLC_OFFSET32 is the default, the bit is not checked. */ #define DW_DLC_OFFSET32 0x00010000 /* default offset size */ /* 64-bit offset-size DWARF offsets */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* old spelling */ #define DW_DLC_OFFSET64 0x10000000 /* correct spelling */ /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* DO NOT USE. */ /* Special for IRIX only. For producing DWARF with Elf 64bit offset headers and non-standard IRIX 64bit offset DWARF .debug_info etc compilation unit headers. */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Old style Elf binary relocation (.rel) records. The default. For producing DWARF */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* ===== END DW_DLC options LIBDWARF */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 #define DW_DLE_ELF_RELOC_SECTION_ERROR 466 #define DW_DLE_USER_DECLARED_ERROR 467 #define DW_DLE_RNGLISTS_ERROR 468 #define DW_DLE_LOCLISTS_ERROR 469 #define DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE 470 #define DW_DLE_GDBINDEX_STRING_ERROR 471 #define DW_DLE_GNU_PUBNAMES_ERROR 472 #define DW_DLE_GNU_PUBTYPES_ERROR 473 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES 474 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES 475 #define DW_DLE_DEBUG_SUP_STRING_ERROR 476 #define DW_DLE_DEBUG_SUP_ERROR 477 #define DW_DLE_LOCATION_ERROR 478 #define DW_DLE_DEBUGLINK_PATH_SHORT 479 #define DW_DLE_SIGNATURE_MISMATCH 480 #define DW_DLE_MACRO_VERSION_ERROR 481 #define DW_DLE_NEGATIVE_SIZE 482 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 482 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the separation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN = 0, DW_FORM_CLASS_ADDRESS = 1, DW_FORM_CLASS_BLOCK = 2, DW_FORM_CLASS_CONSTANT =3, DW_FORM_CLASS_EXPRLOC = 4, DW_FORM_CLASS_FLAG = 5, DW_FORM_CLASS_LINEPTR = 6, DW_FORM_CLASS_LOCLISTPTR=7, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR = 8, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR=9, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE=10, DW_FORM_CLASS_STRING = 11, DW_FORM_CLASS_FRAMEPTR= 12, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR= 13, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR = 14, /* DWARF5 */ DW_FORM_CLASS_LOCLIST = 15, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR=16, /* DWARF5 */ DW_FORM_CLASS_RNGLIST =17, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR=18, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR=19 /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects and Elf SHT_GROUP blocks of DWARF sections. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*==================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur, nor will the GNU_debuglink processing occur. In case GNU debuglink data was followed or MacOS dSYM applies the true_path_out will not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* New October 2020. Following GNU debuglink to the true-path with DWARF if there is appropriate debuglink data available. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. In case GNU debuglink data was followed the true_path_out will not match path. If debuglink missing from the Elf executable or shared-object (ie, it is a normal object!) or unusable by libdwarf or true_path_buffer len is zero or true_path_out_buffer is zero the accepts the path given as the object to report on. Passing dl_path_array and dl_path_array size zero suffices unless one has unusual locations for debuglink objects. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur either. */ int dwarf_init_path_dl(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, char ** /* dl_path array */, unsigned int /* dl_path array size */, unsigned char * /* path_source */, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned int /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned int /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* New 4 February 2021. returns DIE and is_info flag if it finds the referenced DW_UT_split_type or DW_UT_type CU. */ int dwarf_find_die_given_sig8(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*ref*/, Dwarf_Die * /*die_out*/, Dwarf_Bool * /*is_info*/, Dwarf_Error * /*error*/); /* Returns the is_info flag. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New December 2020. Any Dwarf_Die will work. The values returned are about the CU itself, not a DIE. */ int dwarf_cu_header_basics(Dwarf_Die die, Dwarf_Half * /*version*/, Dwarf_Bool * /*is_info*/, Dwarf_Bool * /*is_dwo*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*extension_size*/, Dwarf_Sig8 ** /*signature*/, Dwarf_Off * /*offset_of_length*/, Dwarf_Unsigned * /*total_byte_length*/, Dwarf_Error * /*error*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* Reading a CU DIE with DW_AT_low_pc an indexed value can be problematic as that interacts with DW_AT_addr_base in that DIE. Here is a test readers may find useful */ Dwarf_Bool dwarf_addr_form_is_indexed(int form); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/, Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: debug_gnu_pubnames/typenames access, calling these Gnu_Index as a general reference. */ int dwarf_get_gnu_index_head(Dwarf_Debug /*dbg*/, /* The following arg false to select gnu_pubtypes */ Dwarf_Bool /*for_gdb_pubnames*/ , Dwarf_Gnu_Index_Head * /*index_head_out*/, Dwarf_Unsigned * /*index_block_count_out*/, Dwarf_Error * /*error*/); /* Frees all resources used for the indexes. */ void dwarf_gnu_index_dealloc(Dwarf_Gnu_Index_Head /*head*/); int dwarf_get_gnu_index_block(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*number*/, Dwarf_Unsigned * /*block_length */, Dwarf_Half * /*version */, Dwarf_Unsigned * /*offset_into_debug_info*/, Dwarf_Unsigned * /*size_of_debug_info_area*/, Dwarf_Unsigned * /*count_of_index_entries*/, Dwarf_Error * /*error*/); int dwarf_get_gnu_index_block_entry(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*blocknumber*/, Dwarf_Unsigned /*entrynumber*/, Dwarf_Unsigned * /*offset_in_debug_info*/, const char ** /*name_string*/, unsigned char * /*flagbyte*/, unsigned char * /*staticorglobal*/, unsigned char * /*typeofentry*/, Dwarf_Error * /*error*/); /* END: debug_gnu_pubnames/typenames access, */ /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); #define DW_LKIND_expression 0 /* DWARF2,3,4*/ #define DW_LKIND_loclist 1 /* DWARF 2,3,4 */ #define DW_LKIND_GNU_exp_list 2 /* GNU DWARF4 .dwo extension */ #define DW_LKIND_loclists 5 /* DWARF5 loclists */ #define DW_LKIND_unknown 99 /* DWARF2 kind is 2. DWARF3/4 kind is 3, DWARF5 kind is 5 */ int dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c /*ll_header*/, unsigned int * /*lkind*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Unsigned * /*rawlowpc*/, Dwarf_Unsigned * /*rawhipc*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); /* New June 2020 for DWARF5 (and all earlier). */ int dwarf_get_location_op_value_d(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*rawop1*/, Dwarf_Unsigned * /*rawop2*/, Dwarf_Unsigned * /*rawop3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count( Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data( Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/ Separate-Debug-Files.html If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. Caller frees space returned by debuglink_fullpath_returned. See libdwarf2.1.mm revision 3.13 or later for additional important details. */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*debuglink_path_returned */, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_fullpath_returned free this*/, unsigned int * /*debuglink_path_count_returned */, unsigned int * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned int * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned int * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* Only useful inside dwarfexample/dwdebuglink.c so we can show all that is going on. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* crc32 used for debuglink crc calculation. Caller passes pointer to array of 4 unsigned char provided by the caller and if this returns DW_DLV_OK that is filled in. */ int dwarf_crc32 (Dwarf_Debug /*dbg*/,unsigned char * /*crcbuf*/, Dwarf_Error * /*error*/); /* Public interface to the real crc calculation just in case some find it useful. */ unsigned int dwarf_basic_crc32 (const unsigned char * /*buf*/, unsigned long /*len*/, unsigned int /*init*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Special for dwarfdump. Sets a flag in the dbg. Always returns DW_DLV_OK and (as of March 2020) never touches error */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* jUser-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) DO NOT USE, it cannot deal with recent dwarf or CUs with different address sizes. Use dwarf_get_locdesc_entry_c() instead. */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned /*indx*/, Dwarf_Bool /*filter_outliers*/, Dwarf_Unsigned * /*returned_attr_num*/, Dwarf_Unsigned * /*returned_form*/, Dwarf_Signed * /*returned_implicit_const*/, Dwarf_Off * /*offset*/, Dwarf_Error * /*error*/); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable3* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); /* New December 2020. Sometimes its necessary to know a context total length including macro 5 header */ int dwarf_macro_context_total_length(Dwarf_Macro_Context /*head*/, Dwarf_Unsigned * /*mac_total_len*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned int * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. The last op has 0 as opcode_number,operand_count and operand_array */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file( Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. Use dwarf_check_lineheader_b() (new 14 April 2020) in place of dwarf_check_lineheader(). */ int dwarf_check_lineheader_b(Dwarf_Die /*cu_die*/, int * /*errcount_out*/, Dwarf_Error * /*error*/); void dwarf_check_lineheader(Dwarf_Die /*cu_die*/, int * /*errcount_out*/); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. Completely different than .debug_gnu_pubnames or .debug_gnu_pubtypes sections. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); void dwarf_error_creation(Dwarf_Debug /*dbg*/ , Dwarf_Error * /*error*/, char * /*errmsg*/); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Never Implemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* These convenience functions allow type checking at the call, whereas dwarf_dealloc itself uses void * so ... easy to misuse. */ void dwarf_dealloc_error(Dwarf_Debug /*dbg*/, Dwarf_Error /*err*/); void dwarf_dealloc_die( Dwarf_Die /*die*/); void dwarf_dealloc_attribute(Dwarf_Attribute /*attr*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New July 2020 for testing DWARF5 */ int dwarf_add_debug_sup(Dwarf_P_Debug /*dbg*/, Dwarf_Half /*version*/, Dwarf_Small /*is_supplementary*/, char * /*filename*/, Dwarf_Unsigned /*checksum_len*/, Dwarf_Small * /*checksum*/, Dwarf_Error * /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* Adds return of the final offset to accommodate DWARF4 GNU split-dwarf. Other than for split-dwarf the realoffset will be set by the function to be the same as rangesoffset. New September 10, 2020. */ int dwarf_get_ranges_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /*diepointer */, Dwarf_Off * /*realoffset */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New July 2020 for DWARF5 */ int dwarf_get_debug_sup(Dwarf_Debug /*dbg*/, Dwarf_Half * /*version*/, Dwarf_Small * /*is_supplementary*/, char ** /*filename*/, Dwarf_Unsigned * /*checksum_len*/, Dwarf_Small ** /*checksum*/, Dwarf_Error * /*error*/); /* ======= START .debug_rnglists interfaces. New May 2020 */ struct Dwarf_Rnglists_Entry_s; typedef struct Dwarf_Rnglists_Entry_s * Dwarf_Rnglists_Entry; struct Dwarf_Rnglists_Head_s; typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; /* For DWARF5 DW_AT_ranges: DW_FORM_sec_offset DW_FORM_rnglistx */ int dwarf_rnglists_get_rle_head(Dwarf_Attribute /*attr*/, Dwarf_Half /*theform*/, Dwarf_Unsigned /*index_or_offset_value*/, Dwarf_Rnglists_Head * /*head_out*/, Dwarf_Unsigned * /*count_of_entries_in_head*/, Dwarf_Unsigned * /*global_offset_of_rle_set*/, Dwarf_Error * /*error*/); /* Get the rnglist entries details */ int dwarf_get_rnglists_entry_fields_a( Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned * /*entrylen*/, unsigned * /*rle_value_out*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*err*/); /* The following is not complete. DO NOT USE. Use dwarf_get_rnglists_entry_fields_a() instead. */ int dwarf_get_rnglists_entry_fields(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); int dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head ); /* Loads all the rnglists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of rnglists headers in the section through rnglists_count. */ int dwarf_load_rnglists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*rnglists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th rangelists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_rnglists section offset of the range list. */ int dwarf_get_rnglist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_rnglists_index_get_rle_head() or dwarf_rnglists_offset_get_rle_head. */ int dwarf_get_rnglist_head_basics(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned * /*rle_count*/, Dwarf_Unsigned * /*rnglists_version*/, Dwarf_Unsigned * /*rnglists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*rnglists_base_present*/, Dwarf_Unsigned * /*rnglists_base*/, Dwarf_Bool * /*rnglists_base_address_present*/, Dwarf_Unsigned * /*rnglists_base_address*/, Dwarf_Bool * /*rnglists_debug_addr_base_present*/, Dwarf_Unsigned * /*rnglists_debug_addr_base*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_rnglists section may contain any number of Range List Table Headers with their details. */ int dwarf_get_rnglist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_rangeentry*/, Dwarf_Unsigned * /*offset_past_last_rangeentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_rangeentry. Stop when the returned *next_entry_offset is == offset_past_last_rangentry (from dwarf_get_rnglist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single rnglist header, meaning a a single Dwarf_Rnglists_Context. This interface assumes there is no segment selector. */ int dwarf_get_rnglist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_rnglist_rle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Error * /*err*/); /* ======= END .debug_rnglists interfaces. */ /* ======= START .debug_loclists interfaces. New May 2020 */ /* These interfaces allow reading the .debug_loclists section. Normal use of .debug_loclists uses dwarf_get_loclist_c() to open access to any kind of location or loclist and uses dwarf_loc_head_c_dealloc() to deallocate that memory once one is finished with that data. So for most purposes you do not need to use these functions */ struct Dwarf_Loclists_Entry_s; typedef struct Dwarf_Loclists_Entry_s * Dwarf_Loclists_Entry; /* See dwarf_get_loclist_c() to open a Dwarf_Loc_Head_c on any type of location list or expression. */ /* Get the loclists entries details */ int dwarf_get_loclists_entry_fields(Dwarf_Loc_Head_c /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); /* Loads all the loclists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of loclists headers in the section through loclists_count. */ int dwarf_load_loclists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*loclists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th loclists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_loclists section offset of the range list. */ int dwarf_get_loclist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_loclists_index_get_lle_head() or dwarf_loclists_offset_get_lle_head. */ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c /*head*/, Dwarf_Small * /*lkind*/, Dwarf_Unsigned * /*lle_count*/, Dwarf_Unsigned * /*loclists_version*/, Dwarf_Unsigned * /*loclists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*loclists_base_present*/, Dwarf_Unsigned * /*loclists_base*/, Dwarf_Bool * /*loclists_base_address_present*/, Dwarf_Unsigned * /*loclists_base_address*/, Dwarf_Bool * /*loclists_debug_addr_base_present*/, Dwarf_Unsigned * /*loclists_debug_addr_base*/, Dwarf_Unsigned * /*offset_this_lle_area*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_loclists section may contain any number of Location List Table Headers with their details. */ int dwarf_get_loclist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_locentry*/, Dwarf_Unsigned * /*offset_past_last_locentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_locentry. Stop when the returned *next_entry_offset is == offset_past_last_locentry (from dwarf_get_loclist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single loclist header, meaning a a single Dwarf_Loclists_Context. This interface assumes there is no segment selector. */ int dwarf_get_loclist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_loclist_lle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*expr_ops_blocksize*/, Dwarf_Unsigned * /*expr_ops_offset*/, Dwarf_Small ** /*expr_opsdata*/, Dwarf_Error * /*err*/); /* ======= END .debug_loclists interfaces. */ /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned int /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned int * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned int dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned int /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIKIND_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIVIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is for a GNU extension. Not defined by the GNU folks nor a DWARF standard but it seemed essential. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ extern int dwarf_get_FORM_CLASS_name(enum Dwarf_Form_Class /*fc*/, const char ** /*s_out*/); /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* New May 2017. So users can find out what groups (dwo or COMDAT) are in the object and how much to allocate so one can get the group-section map data. */ int dwarf_sec_group_sizes(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' values and this function fills in the array entries. Output ordered by group number and section number. */ int dwarf_sec_group_map(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/)) (void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Same for LEB decoding routines. caller sets endptr to an address one past the last valid address the library should be allowed to access. */ int dwarf_decode_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Unsigned * /*outval*/, char * /*endptr*/); int dwarf_decode_signed_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Signed * /*outval*/, char * /*endptr*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ /* Defined March 7 2020. Allows a caller to avoid most tracking by the de_alloc_tree hash table if called with v of zero. Returns the value the flag was before this call. */ int dwarf_set_de_alloc_flag(int v); /* Solely looks for debuglink */ int dwarf_object_detector_path(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); /* Solely looks for debuglink */ int dwarf_object_detector_path_b(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, char ** /* gl_pathnames*/, unsigned /* gl_pathcount*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, unsigned char * /*pathsource*/, int * /*errcode*/); /* Solely looks for dSYM */ int dwarf_object_detector_path_dSYM( const char *path, char *outpath, unsigned long outpath_len, char ** gl_pathnames, unsigned gl_pathcount, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, unsigned char *pathsource, int *errcode); #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 #define DW_PATHSOURCE_dsym 2 /* MacOS dSYM */ #define DW_PATHSOURCE_debuglink 3 /* GNU debuglink */ /* Returns the pathsource value set up at init time*/ int dwarf_get_path_source_type(Dwarf_Debug /* dbg*/, unsigned char * /*path_source*/, Dwarf_Error * /*error*/); int dwarf_object_detector_fd(int /*fd*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ libdwarf-20210528/libdwarf/pro_die.h0000664000175000017500000000461514012266121014061 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This struct holds the abbreviation table, before they are written on disk. Holds a linked list of abbreviations, each consisting of a bitmap for attributes and a bitmap for forms */ typedef struct Dwarf_P_Abbrev_s *Dwarf_P_Abbrev; struct Dwarf_P_Abbrev_s { Dwarf_Unsigned abb_idx; /* index of abbreviation */ Dwarf_Tag abb_tag; /* tag of die */ Dwarf_Ubyte abb_children; /* if children are present */ Dwarf_Unsigned *abb_attrs; /* holds names of attrs */ Dwarf_Unsigned *abb_forms; /* forms of attributes */ /* 0 but if DW_FORM_implicit_value is value */ Dwarf_Signed *abb_implicits; int abb_n_attr; /* num of attrs = # of forms */ Dwarf_P_Abbrev abb_next; }; /* used in pro_section.c */ int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error); int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error); int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Unsigned offset, Dwarf_Error * error); int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, Dwarf_P_Debug dbg, char *name, Dwarf_Error *error); /* adds an attribute to a die */ void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr); libdwarf-20210528/libdwarf/dwarf_ranges.c0000664000175000017500000003023214004647256015104 00000000000000/* Copyright (C) 2008-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #define FALSE 0 #define TRUE 1 struct ranges_entry { struct ranges_entry *next; Dwarf_Ranges cur; }; static void free_allocated_ranges( struct ranges_entry *base) { struct ranges_entry *cur = 0; struct ranges_entry *next = 0; for ( cur = base ; cur ; cur = next ) { next = cur->next; free(cur); } } /* We encapsulate the macro use so we can free local malloc resources that would otherwise leak. See the call points below. */ static int read_unaligned_addr_check(Dwarf_Debug dbg, Dwarf_Addr *addr_out, Dwarf_Small *rangeptr, unsigned address_size, Dwarf_Error *error, Dwarf_Small *section_end) { Dwarf_Addr a = 0; READ_UNALIGNED_CK(dbg,a, Dwarf_Addr, rangeptr, address_size, error,section_end); *addr_out = a; return DW_DLV_OK; } /* As of DWARF5 the ranges section each range list set has a range-list-table header. See "7.28 Range List Table" in the DWARF5 standard. For DWARF5 the offset should be the offset of the range-list-table-header for that range list. For DWARF3 and DWARF4 the offset has to be that of a range list. */ /* Ranges and pc values can be in a split dwarf object. In that case the appropriate values need to be incremented by data from the executable in the compilation unit with the same dwo_id. We return an error which is on the incoming dbg, not the possibly-tied-dbg localdbg. If incoming die is NULL there is no context, so do not look for a tied file, and address_size is the size of the overall object, not the address_size of the context. */ #define MAX_ADDR ((address_size == 8)? \ 0xffffffffffffffffULL:0xffffffff) int dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Die die, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, Dwarf_Error * error) { Dwarf_Off finaloffset = 0; int res = 0; res = dwarf_get_ranges_b( dbg,rangesoffset,die, &finaloffset,rangesbuf,listlen, bytecount,error); return res; } /* New 10 September 2020 to accomodate the GNU extension of DWARF4 split-dwarf. The actual_offset field is set by the function to the actual final offset of the ranges in the separate tied (a.out) file. */ int dwarf_get_ranges_b(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Die die, Dwarf_Off *actual_offset, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, Dwarf_Error * error) { Dwarf_Small *rangeptr = 0; Dwarf_Small *beginrangeptr = 0; Dwarf_Small *section_end = 0; unsigned entry_count = 0; struct ranges_entry *base = 0; struct ranges_entry *last = 0; struct ranges_entry *curre = 0; Dwarf_Ranges * ranges_data_out = 0; unsigned copyindex = 0; Dwarf_Half address_size = 0; int res = DW_DLV_ERROR; Dwarf_Unsigned ranges_base = 0; Dwarf_Debug localdbg = dbg; Dwarf_Error localerror = 0; Dwarf_Half die_version = 3; /* default for dwarf_get_ranges() */ UNUSEDARG Dwarf_Half offset_size = 4; Dwarf_CU_Context cucontext = 0; Dwarf_Bool rangeslocal = TRUE; if (!dbg) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } address_size = localdbg->de_pointer_size; /* default */ if (die) { /* If we wind up using the tied file the die_version had better match! It cannot be other than a match. */ /* Can return DW_DLV_ERROR, not DW_DLV_NO_ENTRY. Add err code if error. Version comes from the cu context, not the DIE itself. */ res = dwarf_get_version_of_die(die,&die_version, &offset_size); if (res == DW_DLV_ERROR) { _dwarf_error(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } if (!die->di_cu_context) { _dwarf_error(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } cucontext = die->di_cu_context; /* The DW4 ranges base was never used in GNU but did get emitted, the note says, but the note is probably obsolete (so, now wrong). http://llvm.1065342.n5.nabble.com/DebugInfo\ -DW-AT-GNU-ranges-base-in-non-fission-\ td64194.html */ /* ranges_base was merged from tied context. */ ranges_base = cucontext->cc_ranges_base; address_size = cucontext->cc_address_size; } localdbg = dbg; res = _dwarf_load_section(localdbg, &localdbg->de_debug_ranges, error); if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_NO_ENTRY) { /* data is in a.out, not dwp */ localdbg = dbg->de_tied_data.td_tied_object; if (!localdbg) { return DW_DLV_NO_ENTRY; } res = _dwarf_load_section(localdbg, &localdbg->de_debug_ranges, &localerror); if (res == DW_DLV_ERROR) { _dwarf_error_mv_s_to_t(localdbg,&localerror,dbg,error); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } rangeslocal = FALSE; } /* Be safe in case adding rangesoffset and rangebase overflows. */ if (rangesoffset >= localdbg->de_debug_ranges.dss_size) { /* Documented behavior in libdwarf2.1.mm */ return DW_DLV_NO_ENTRY; } if (ranges_base >= localdbg->de_debug_ranges.dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_RANGES_OFFSET_BAD: " " ranges base is 0x%lx ",ranges_base); dwarfstring_append_printf_u(&m, " and section size is 0x%lx.", localdbg->de_debug_ranges.dss_size); _dwarf_error_string(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (!rangeslocal && ((rangesoffset +ranges_base) >= localdbg->de_debug_ranges.dss_size)) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_RANGES_OFFSET_BAD: " " ranges base+offset is 0x%lx ", ranges_base+rangesoffset); dwarfstring_append_printf_u(&m, " and section size is 0x%lx.", localdbg->de_debug_ranges.dss_size); _dwarf_error_string(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* tied address_size must match the dwo address_size */ section_end = localdbg->de_debug_ranges.dss_data + localdbg->de_debug_ranges.dss_size; rangeptr = localdbg->de_debug_ranges.dss_data; if (!rangeslocal) { /* printing ranges where range source is dwp, here we just assume present. */ rangesoffset += ranges_base; } rangeptr += rangesoffset; beginrangeptr = rangeptr; for (;;) { struct ranges_entry * re = 0; if (rangeptr == section_end) { break; } if (rangeptr > section_end) { dwarfstring m; free_allocated_ranges(base); dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_RANGES_OFFSET_BAD: " " ranges pointer ran off the end " "of the section"); _dwarf_error_string(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } re = calloc(sizeof(struct ranges_entry),1); if (!re) { free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return DW_DLV_ERROR; } if ((rangeptr + (2*address_size)) > section_end) { free(re); free_allocated_ranges(base); _dwarf_error_string(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD, "DW_DLE_DEBUG_RANGES_OFFSET_BAD: " " Not at the end of the ranges section " " but there is not enough room in the section " " for the next ranges entry"); return DW_DLV_ERROR; } entry_count++; res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr1, rangeptr, address_size,error,section_end); if (res != DW_DLV_OK) { free(re); free_allocated_ranges(base); return res; } rangeptr += address_size; res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr2, rangeptr, address_size,error,section_end); if (res != DW_DLV_OK) { free(re); free_allocated_ranges(base); return res; } rangeptr += address_size; if (!base) { base = re; last = re; } else { last->next = re; last = re; } if (re->cur.dwr_addr1 == 0 && re->cur.dwr_addr2 == 0) { re->cur.dwr_type = DW_RANGES_END; break; } else if (re->cur.dwr_addr1 == MAX_ADDR) { re->cur.dwr_type = DW_RANGES_ADDRESS_SELECTION; } else { re->cur.dwr_type = DW_RANGES_ENTRY; } } /* We return ranges on dbg, so use that to allocate. */ ranges_data_out = (Dwarf_Ranges *) _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count); if (!ranges_data_out) { /* Error, apply to original, not local dbg. */ free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return DW_DLV_ERROR; } curre = base; *rangesbuf = ranges_data_out; *listlen = entry_count; for (copyindex = 0; curre && (copyindex < entry_count); ++copyindex,++ranges_data_out) { *ranges_data_out = curre->cur; curre = curre->next; } /* ASSERT: curre == NULL */ free_allocated_ranges(base); base = 0; /* Callers will often not care about the bytes used. */ if (actual_offset) { *actual_offset = rangesoffset; } if (bytecount) { *bytecount = rangeptr - beginrangeptr; } return DW_DLV_OK; } int dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, Dwarf_Error * error) { Dwarf_Die die = 0; int res = dwarf_get_ranges_a(dbg,rangesoffset,die, rangesbuf,listlen,bytecount,error); return res; } void dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf, UNUSEDARG Dwarf_Signed rangecount) { dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); } libdwarf-20210528/libdwarf/pro_types.c0000664000175000017500000002140213764007262014464 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_types.h" #define SIZEOFT32 4 /* This function adds another type name to the list of type names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_typename(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, type_name, dwarf_snk_typename, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_typename_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, type_name, dwarf_snk_typename, error); return res; } /* The following is the generic 'add a simple name entry' for any of the simple name sections. See enum dwarf_sn_kind in pro_opaque.h */ int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, enum dwarf_sn_kind entrykind, Dwarf_Error * error) { Dwarf_P_Simple_nameentry nameentry; Dwarf_P_Simple_name_header hdr; char *name; int uword_size; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (die == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } nameentry = (Dwarf_P_Simple_nameentry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Simple_nameentry_s)); if (nameentry == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); if (name == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } strcpy(name, entry_name); nameentry->sne_die = die; nameentry->sne_name = name; nameentry->sne_name_len = strlen(name); uword_size = dbg->de_dwarf_offset_size; hdr = &dbg->de_simple_name_headers[entrykind]; if (hdr->sn_head == NULL) hdr->sn_head = hdr->sn_tail = nameentry; else { hdr->sn_tail->sne_next = nameentry; hdr->sn_tail = nameentry; } hdr->sn_count++; hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; return DW_DLV_OK; } /* _dwarf_transform_simplename_to_disk writes ".rel.debug_pubnames", ".rel.debug_funcnames", sgi extension ".rel.debug_typenames", sgi extension ".rel.debug_varnames", sgi extension ".rel.debug_weaknames", sgi extension to disk. section_index indexes one of those sections. entrykind is one of those 'kind's. */ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in de_elf_sects etc */ Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Used to fill in 0. */ const Dwarf_Signed big_zero = 0; /* Used to scan the section data buffers. */ Dwarf_P_Section_Data debug_sect; Dwarf_Signed debug_info_size; Dwarf_P_Simple_nameentry nameentry_original; Dwarf_P_Simple_nameentry nameentry; Dwarf_Small *stream_bytes; Dwarf_Small *cur_stream_bytes_ptr; Dwarf_Unsigned stream_bytes_count; Dwarf_Unsigned adjusted_length; /* count excluding length field */ int uword_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_P_Simple_name_header hdr; /* ***** BEGIN CODE ***** */ debug_info_size = 0; for (debug_sect = dbg->de_debug_sects; debug_sect != NULL; debug_sect = debug_sect->ds_next) { /* We want the size of the .debug_info section for this CU because the dwarf spec requires us to output it below so we look for it specifically. */ if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) { debug_info_size += debug_sect->ds_nbytes; } } hdr = &dbg->de_simple_name_headers[entrykind]; /* Size of the .debug_typenames (or similar) section header. */ stream_bytes_count = extension_size + uword_size + /* Size of length field. */ DWARF_HALF_SIZE + /* Size of version field. */ uword_size + /* Size of .debug_info offset. */ uword_size; /* Size of .debug_names. */ nameentry_original = hdr->sn_head; /* add in the content size */ stream_bytes_count += hdr->sn_net_len; /* Size of the last 0 offset. */ stream_bytes_count += uword_size; /* Now we know how long the entire section is */ GET_CHUNK(dbg, dbg->de_elf_sects[section_index], stream_bytes, (unsigned long) stream_bytes_count, error); cur_stream_bytes_ptr = stream_bytes; if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *)&v4[0],SIZEOFT32 , extension_size); cur_stream_bytes_ptr += extension_size; } /* Write the adjusted length of .debug_*names section. */ adjusted_length = stream_bytes_count - uword_size - extension_size; WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &adjusted_length, sizeof(adjusted_length), uword_size); cur_stream_bytes_ptr += uword_size; /* Write the version as 2 bytes. */ { Dwarf_Half verstamp = CURRENT_VERSION_STAMP; WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &verstamp, sizeof(verstamp), DWARF_HALF_SIZE); cur_stream_bytes_ptr += DWARF_HALF_SIZE; } /* Write the offset of the compile-unit. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &big_zero, sizeof(big_zero), uword_size); cur_stream_bytes_ptr += uword_size; /* now create the relocation for the compile_unit offset */ { int res = dbg->de_relocate_by_name_symbol(dbg, section_index, extension_size + uword_size + DWARF_HALF_SIZE /* r_offset */ , /* debug_info section name symbol */ dbg->de_sect_name_idx[DEBUG_INFO], dwarf_drt_data_reloc, uword_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* Write the size of .debug_info section. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &debug_info_size, sizeof(debug_info_size), uword_size); cur_stream_bytes_ptr += uword_size; for (nameentry = nameentry_original; nameentry != NULL; nameentry = nameentry->sne_next) { /* Copy offset of die from start of compile-unit. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &nameentry->sne_die->di_offset, sizeof(nameentry->sne_die->di_offset), uword_size); cur_stream_bytes_ptr += uword_size; /* Copy the type name. */ strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name); cur_stream_bytes_ptr += nameentry->sne_name_len + 1; } WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &big_zero, sizeof(big_zero), uword_size); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_macho_loader.h0000664000175000017500000021021013771417507016247 00000000000000/* This is a cut-down version of loader.h from cctools-895, shrunk to eliminate aspects unwanted in libdwarf and to avoid #include entirely. All tab characters replaced with 4 spaces so various things no line up as they used to. Comment reformatting for line length may have left some original comments hard to follow. cctools-895 in its original form is available from https://opensource.apple.com/ see Developer Tools version 8.2.1. cctools-895/include/loader.h */ /* * Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or * Modifications of Original Code * as defined in and that are subject to the * Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under * the License are * distributed on an 'AS IS' basis, WITHOUT * WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, * QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the * specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef MACHO_LOADER_H #define MACHO_LOADER_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if 0 /* Not used here. DavidA. September 2018 */ /* * This file describes the format of mach object files. */ #include /* * is needed here for * the cpu_type_t and cpu_subtype_t types * and contains the constants for the possible values of these types. */ #include /* * is needed here for the * vm_prot_t type and contains the * constants that are or'ed together for the * possible values of this type. */ #include /* * is expected to define * the flavors of the thread * states and the structures of those flavors for each machine. */ #include #include #endif /* 0 */ #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYP */ /* * The 32-bit mach header appears at the very * beginning of the object file for * 32-bit architectures. */ struct mach_header { TYP(magic,4); /* mach magic number identifier */ TYP(cputype,4); /* cpu specifier */ TYP(cpusubtype,4); /* machine specifier */ TYP(filetype,4); /* type of file */ TYP(ncmds,4); /* number of load commands */ TYP(sizeofcmds,4); /* the size of all the load commands */ TYP(flags,4); /* flags */ }; /* Constant for the magic field of the mach_header (32-bit architectures) MH_MAGIC MH_MAGIC_64 appear in big-endian objects MH_CIGAM MH_CIGAM_64 appear in little-endian objects */ #define MH_MAGIC 0xfeedface /* the mach magic number */ #define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ /* * The 64-bit mach header appears at the * very beginning of object files for * 64-bit architectures. */ struct mach_header_64 { TYP(magic,4); /* mach magic number identifier */ TYP(cputype,4); /* cpu specifier */ TYP(cpusubtype,4); /* machine specifier */ TYP(filetype,4); /* type of file */ TYP(ncmds,4); /* number of load commands */ TYP(sizeofcmds,4); /* the size of all the load commands */ TYP(flags,4); /* flags */ TYP(reserved,4); /* reserved */ }; /* Constant for the magic field of the mach_header_64 * (64-bit architectures) */ #define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ #define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ /* * The layout of the file depends on the filetype. * For all but the MH_OBJECT * file type the segments are padded * out and aligned on a segment alignment * boundary for efficient demand paging. * The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, * MH_DYLINKER and MH_BUNDLE file types also * have the headers included as part * of their first segment. * * The file type MH_OBJECT is a compact * format intended as output of the * assembler and input (and possibly output) of the link editor (the .o * format). All sections are in one unnamed * segment with no segment padding. * This format is used as an executable * format when the file is so small the * segment padding greatly increases its size. * * The file type MH_PRELOAD is an executable * format intended for things that * are not executed under the kernel (proms, * stand alones, kernels, etc). The * format can be executed under the kernel * but may demand paged it and not * preload it before execution. * * A core file is in MH_CORE format and can be * in any legal * Mach-O file. * * Constants for the filetype field of the mach_header */ #define MH_OBJECT 0x1 /* relocatable object file */ #define MH_EXECUTE 0x2 /* demand paged executable file */ #define MH_FVMLIB 0x3 /* fixed VM shared library file */ #define MH_CORE 0x4 /* core file */ #define MH_PRELOAD 0x5 /* preloaded executable file */ #define MH_DYLIB 0x6 /* dynamically bound shared library */ #define MH_DYLINKER 0x7 /* dynamic link editor */ #define MH_BUNDLE 0x8 /* dynamically bound bundle file */ #define MH_DYLIB_STUB 0x9 /* shared library stub for static */ /* linking only, no section contents */ #define MH_DSYM 0xa /* companion file with only debug */ /* sections */ #define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ /* Constants for the flags field of the mach_header */ #define MH_NOUNDEFS 0x1 /* the object file has no undefined references */ #define MH_INCRLINK 0x2 /* the object file is the output of an incremental link against a base file and can't be link edited again */ #define MH_DYLDLINK 0x4 /* the object file is input for the dynamic linker and can't be staticly link edited again */ #define MH_BINDATLOAD 0x8 /* the object file's undefined references are bound by the dynamic linker when loaded. */ #define MH_PREBOUND 0x10 /* the file has its dynamic undefined references prebound. */ #define MH_SPLIT_SEGS 0x20 /* the file has its read-only and read-write segments split */ #define MH_LAZY_INIT 0x40 /* the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) */ #define MH_TWOLEVEL 0x80 /* the image is using two-level name space bindings */ #define MH_FORCE_FLAT 0x100 /* the executable is forcing all images to use flat name space bindings */ #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple definitions of symbols in its sub-images so the two-level namespace hints can always be used. */ #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the prebinding agent about this executable */ #define MH_PREBINDABLE 0x800 /* the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set. */ #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to all two-level namespace modules of its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set. */ #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000 /* safe to divide up the sections into sub-sections via symbols for dead code stripping */ #define MH_CANONICAL 0x4000 /* the binary has been canonicalized via the unprebind operation */ #define MH_WEAK_DEFINES 0x8000 /* the final linked image contains external weak symbols */ #define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses weak symbols */ #define MH_ALLOW_STACK_EXECUTION 0x20000 /* When this bit is set, all stacks in the task will be given stack execution privilege. Only used in MH_EXECUTE filetypes. */ #define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary declares it is safe for use in processes with uid zero */ #define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary declares it is safe for use in processes when issetugid() is true */ #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported */ #define MH_PIE 0x200000 /* When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes. */ #define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIB load command to the dylib if no symbols are being referenced from the dylib. */ #define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type S_THREAD_LOCAL_VARIABLES */ #define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it. Only used in MH_EXECUTE filetypes. */ #define MH_APP_EXTENSION_SAFE 0x02000000 /* The code was linked for use in an application extension. */ /* * The load commands directly follow the mach_header. * The total size of all * of the commands is given by the sizeofcmds * field in the mach_header. All * load commands must have as their first two * fields cmd and cmdsize. The cmd * field is filled in with a constant for that command type. * Each command type * has a structure specifically for it. * The cmdsize field is the size in bytes * of the particular load command structure * plus anything that follows it that * is a part of the load command (i.e. * section structures, strings, etc.). To * advance to the next load command the * cmdsize can be added to the offset or * pointer of the current load command. * The cmdsize for 32-bit architectures * MUST be a multiple of 4 bytes and for * 64-bit architectures MUST be a multiple * of 8 bytes (these are forever the maximum * alignment of any load commands). * The padded bytes must be zero. * All tables in the object file must also * follow these rules so the file can be memory mapped. * Otherwise the pointers * to these tables will not work well or at all * on some machines. With all * padding zeroed like objects will compare byte for byte. */ struct load_command { TYP(cmd,4); /* type of load command */ TYP(cmdsize,4); /* total size of command in bytes */ }; /* * After MacOS X 10.1 when a new load command * is added that is required to be * understood by the dynamic linker for the * image to execute properly the * LC_REQ_DYLD bit will be or'ed into the load * command constant. If the dynamic * linker sees such a load command it it does * not understand will issue a * "unknown load command required for execution" * error and refuse to use the * image. Other load commands without this bit * that are not understood will * simply be ignored. */ #define LC_REQ_DYLD 0x80000000 /* Constants for the cmd field of all load commands, the type */ #define LC_SEGMENT 0x1 /* segment of this file to be mapped */ #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ #define LC_THREAD 0x4 /* thread */ #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ #define LC_LOADFVMLIB 0x6 /*load a specified fixed VM shared library*/ #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ #define LC_IDENT 0x8 /* object identification info (obsolete) */ #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ #define LC_PREPAGE 0xa /* prepage command (internal use) */ #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ /* linked shared library */ #define LC_ROUTINES 0x11 /* image routines */ #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ #define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ #define LC_SUB_CLIENT 0x14 /* sub client */ #define LC_SUB_LIBRARY 0x15 /* sub library */ #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ /* * load a dynamically linked shared library * that is allowed to be missing * (all symbols are weak imported). */ #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) #define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be mapped */ #define LC_ROUTINES_64 0x1a /* 64-bit image routines */ #define LC_UUID 0x1b /* the uuid */ #define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ #define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ #define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ #define LC_DYLD_INFO 0x22 /* compressed dyld information */ #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ #define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ #define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ #define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ #define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ #define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat like environment variable */ #define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ #define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ #define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ #define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ #define LC_ENCRYPTION_INFO_64 0x2C /* 64-bit encrypted segment information */ #define LC_LINKER_OPTION 0x2D /* linker options in MH_OBJECT files */ #define LC_LINKER_OPTIMIZATION_HINT 0x2E /* optimization hints in MH_OBJECT files */ #define LC_VERSION_MIN_TVOS 0x2F /* build for AppleTV min OS version */ #define LC_VERSION_MIN_WATCHOS 0x30 /* build for Watch min OS version */ /* * A variable length string in a load command * is represented by an lc_str * union. The strings are stored just after * the load command structure and * the offset is from the start of the load * command structure. The size * of the string is reflected in the cmdsize field of the load command. * Once again any padded bytes to bring the cmdsize field to a multiple * of 4 bytes must be zero. */ union lc_str { TYP(offset,4); /* offset to the string */ #ifndef __LP64__ char *ptr; /* pointer to the string */ #endif }; /* * The segment load command indicates that a part of this file is to be * mapped into the task's address space. * The size of this segment in memory, * vmsize, maybe equal to or larger than the amount * to map from this file, * filesize. The file is mapped starting at fileoff * to the beginning of * the segment in memory, vmaddr. * The rest of the memory of the segment, * if any, is allocated zero fill on demand. * The segment's maximum virtual * memory protection and initial virtual memory * protection are specified * by the maxprot and initprot fields. * If the segment has sections then the * section structures directly follow the segment * command and their size is * reflected in cmdsize. */ struct segment_command { /* for 32-bit architectures */ TYP(cmd,4); /* LC_SEGMENT */ TYP(cmdsize,4); /* includes sizeof section structs */ char segname[16]; /* segment name */ TYP(vmaddr,4); /* memory address of this segment */ TYP(vmsize,4); /* memory size of this segment */ TYP(fileoff,4); /* file offset of this segment */ TYP(filesize,4); /* amount to map from the file */ TYP(maxprot,4); /* maximum VM protection */ TYP(initprot,4); /* initial VM protection */ TYP(nsects,4); /* number of sections in segment */ TYP(flags,4); /* flags */ }; /* * The 64-bit segment load command indicates * that a part of this file is to be * mapped into a 64-bit task's address space. * If the 64-bit segment has * sections then section_64 structures directly * follow the 64-bit segment * command and their size is reflected in cmdsize. */ struct segment_command_64 { /* for 64-bit architectures */ TYP(cmd,4); /* LC_SEGMENT_64 */ TYP(cmdsize,4); /* includes sizeof section_64 structs */ char segname[16]; /* segment name */ TYP(vmaddr,8); /* memory address of this segment */ TYP(vmsize,8); /* memory size of this segment */ TYP(fileoff,8); /* file offset of this segment */ TYP(filesize,8); /* amount to map from the file */ TYP(maxprot,4); /* maximum VM protection */ TYP(initprot,4); /* initial VM protection */ TYP(nsects,4); /* number of sections in segment */ TYP(flags,4); /* flags */ }; /* Constants for the flags field of the segment_command */ #define SG_HIGHVM 0x1 /* the file contents for this segment is for the high part of the VM space, the low part is zero filled (for stacks in core files) */ #define SG_FVMLIB 0x2 /* this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor */ #define SG_NORELOC 0x4 /* this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation*/ #define SG_PROTECTED_VERSION_1 0x8 /* This segment is protected. If the segment starts at file offset 0, the first page of the segment is not protected. All other pages of the segment are protected. */ /* * A segment is made up of zero or more sections. * Non-MH_OBJECT files have * all of their segments with the proper sections * in each, and padded to the * specified segment alignment when produced by * the link editor. The first * segment of a MH_EXECUTE and MH_FVMLIB format file * contains the mach_header * and load commands of the object file before its * first section. The zero * fill sections are always last in their segment * (in all formats). This * allows the zeroed segment padding to be mapped * into memory where zero fill * sections might be. The gigabyte zero fill sections, * those with the section * type S_GB_ZEROFILL, can only be in a segment * with sections of this type. * These segments are then placed after all other segments. * * The MH_OBJECT format has all of its sections in one segment for * compactness. There is no padding to a specified * segment boundary and the * mach_header and load commands are not part of the segment. * * Sections with the same section name, sectname, * going into the same segment, * segname, are combined by the link editor. * The resulting section is aligned * to the maximum alignment of the combined sections * and is the new section's * alignment. The combined sections are aligned to * their original alignment in * the combined section. Any padded bytes to get * the specified alignment are * zeroed. * * The format of the relocation entries referenced by * the reloff and nreloc * fields of the section structure for mach * object files is described in the * header file . */ struct section { /* for 32-bit architectures */ char sectname[16]; /* name of this section */ char segname[16]; /* segment this section goes in */ TYP(addr,4); /* memory address of this section */ TYP(size,4); /* size in bytes of this section */ TYP(offset,4); /* file offset of this section */ TYP(align,4); /* section alignment (power of 2) */ TYP(reloff,4); /* file offset of relocation entries */ TYP(nreloc,4); /* number of relocation entries */ TYP(flags,4); /* flags (section type and attributes)*/ TYP(reserved1,4); /* reserved (for offset or index) */ TYP(reserved2,4); /* reserved (for count or sizeof) */ }; struct section_64 { /* for 64-bit architectures */ char sectname[16]; /* name of this section */ char segname[16]; /* segment this section goes in */ TYP(addr,8); /* memory address of this section */ TYP(size,8); /* size in bytes of this section */ TYP(offset,4); /* file offset of this section */ TYP(align,4); /* section alignment (power of 2) */ TYP(reloff,4); /* file offset of relocation entries */ TYP(nreloc,4); /* number of relocation entries */ TYP(flags,4); /* flags (section type and attributes)*/ TYP(reserved1,4); /* reserved (for offset or index) */ TYP(reserved2,4); /* reserved (for count or sizeof) */ TYP(reserved3,4); /* reserved */ }; /* * The flags field of a section structure is * separated into two parts a section * type and section attributes. * The section types are mutually exclusive (it * can only have one type) but the section attributes * are not (it may have more * than one attribute). */ #define SECTION_TYPE 0x000000ff /* 256 section types */ #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ /* Constants for the type of a section */ #define S_REGULAR 0x0 /* regular section */ #define S_ZEROFILL 0x1 /* zero fill on demand section */ #define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ #define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ #define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ #define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ /* literals */ /* * For the two types of symbol pointers * sections and the symbol stubs section * they have indirect symbol table entries. * For each of the entries in the * section the indirect symbol table entries, * in corresponding order in the * indirect symbol table, start at the * index stored in the reserved1 field * of the section structure. Since the indirect symbol table entries * correspond to the entries in the section * the number of indirect symbol table * entries is inferred from the size of the * section divided by the size of the * entries in the section. * For symbol pointers sections the size of the entries * in the section is 4 bytes and for symbol stubs * sections the byte size of the * stubs is stored in the reserved2 field of the section structure. */ #define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy symbol pointers */ #define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol pointers */ #define S_SYMBOL_STUBS 0x8 /* section with only symbol stubs, byte size of stub in the reserved2 field */ #define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function pointers for initialization*/ #define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function pointers for termination */ #define S_COALESCED 0xb /* section contains symbols that are to be coalesced */ #define S_GB_ZEROFILL 0xc /* zero fill on demand section (that can be larger than 4 gigabytes) */ #define S_INTERPOSING 0xd /* section with only pairs of function pointers for interposing */ #define S_16BYTE_LITERALS 0xe /* section with only 16 byte literals */ #define S_DTRACE_DOF 0xf /* section contains DTrace Object Format */ #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy symbol pointers to lazy loaded dylibs */ /* * Section types to support thread local variables */ #define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial values for TLVs */ #define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial values for TLVs */ #define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ #define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV descriptors */ #define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call to initialize TLV values */ /* * Constants for the section attributes part of the * flags field of a section * structure. */ #define SECTION_ATTRIBUTES_USR 0xff000000 /* User setable attributes */ #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section contains only true machine instructions */ #define S_ATTR_NO_TOC 0x40000000 /* section contains coalesced symbols that are not to be in a ranlib table of contents */ #define S_ATTR_STRIP_STATIC_SYMS 0x20000000 /* ok to strip static symbols in this section in files with the MH_DYLDLINK flag */ #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ #define S_ATTR_LIVE_SUPPORT 0x08000000 /* blocks are live if they reference live blocks */ #define S_ATTR_SELF_MODIFYING_CODE 0x04000000 /* Used with i386 code stubs written on by dyld */ /* * If a segment contains any sections marked with S_ATTR_DEBUG then all * sections in that segment must have this attribute. * No section other than * a section marked with this attribute may reference * the contents of this * section. A section with this attribute may * contain no symbols and must have * a section type S_REGULAR. * The static linker will not copy section contents * from sections with this attribute into its output file. * These sections * generally contain DWARF debugging info. */ #define S_ATTR_DEBUG 0x02000000 /* a debug section */ #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some machine instructions */ #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */ #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */ /* * The names of segments and sections in them are * mostly meaningless to the * link-editor. But there are few things to support traditional UNIX * executables that require the link-editor and assembler * to use some names * agreed upon by convention. * * The initial protection of the "__TEXT" segment * has write protection turned * off (not writeable). * * The link-editor will allocate common symbols at * the end of the "__common" * section in the "__DATA" segment. * It will create the section and segment * if needed. */ /* The currently known segment names and the * section names in those segments */ #define SEG_PAGEZERO "__PAGEZERO" /* the pagezero segment which has no */ /* protections and catches NULL */ /* references for MH_EXECUTE files */ #define SEG_TEXT "__TEXT" /* the tradition UNIX text segment */ #define SECT_TEXT "__text" /* the real text part of the text */ /* section no headers, and no padding */ #define SECT_FVMLIB_INIT0 "__fvmlib_init0" /* the fvmlib initialization */ /* section */ #define SECT_FVMLIB_INIT1 "__fvmlib_init1" /* the section following the */ /* fvmlib initialization */ /* section */ #define SEG_DATA "__DATA" /* the tradition UNIX data segment */ #define SECT_DATA "__data" /* the real initialized data section */ /* no padding, no bss overlap */ #define SECT_BSS "__bss" /* the real uninitialized data section*/ /* no padding */ #define SECT_COMMON "__common" /* the section common symbols are */ /* allocated in by the link editor */ #define SEG_OBJC "__OBJC" /* objective-C runtime segment */ #define SECT_OBJC_SYMBOLS "__symbol_table" /* symbol table */ #define SECT_OBJC_MODULES "__module_info" /* module information */ #define SECT_OBJC_STRINGS "__selector_strs" /* string table */ #define SECT_OBJC_REFS "__selector_refs" /* string table */ #define SEG_ICON "__ICON" /* the icon segment */ #define SECT_ICON_HEADER "__header" /* the icon headers */ #define SECT_ICON_TIFF "__tiff" /* the icons in tiff format */ #define SEG_LINKEDIT "__LINKEDIT" /* the segment containing all structs */ /* created and maintained by the link */ /* editor. Created with -seglinkedit */ /* option to ld(1) for MH_EXECUTE and */ /* FVMLIB file types only */ #define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */ #define SEG_IMPORT "__IMPORT" /* the segment for the self (dyld) */ /* modifing code stubs that has read, */ /* write and execute permissions */ /* * Fixed virtual memory shared libraries are * identified by two things. The * target pathname (the name of the library * as found for execution), and the * minor version number. * The address of where the headers are loaded is in * header_addr. (THIS IS OBSOLETE and no longer supported). */ struct fvmlib { union lc_str name; /* library's target pathname */ TYP(minor_version,4); /* library's minor version number */ TYP(header_addr,4); /* library's header address */ }; /* * A fixed virtual shared library (filetype == MH_FVMLIB * in the mach header) * contains a fvmlib_command (cmd == LC_IDFVMLIB) to * identify the library. * An object that uses a fixed virtual shared library also contains a * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. * (THIS IS OBSOLETE and no longer supported). */ struct fvmlib_command { TYP(cmd,4); /* LC_IDFVMLIB or LC_LOADFVMLIB */ TYP(cmdsize,4); /* includes pathname string */ struct fvmlib fvmlib; /* the library identification */ }; /* * Dynamicly linked shared libraries are identified by two things. The * pathname (the name of the library as found for execution), and the * compatibility version number. The pathname must match * and the compatibility * number in the user of the library must be greater than or * equal to the * library being used. The time stamp is used to record the * time a library was * built and copied into user so it can be use to determined * if the library used * at runtime is exactly the same as used to built the program. */ struct dylib { union lc_str name; /* library's path name */ TYP(timestamp,4); /* library's build time stamp */ TYP(current_version,4); /* library's current version number */ TYP(compatibility_version,4); /* library's compatibility vers number*/ }; /* * A dynamically linked shared library (filetype == MH_DYLIB * in the mach header) * contains a dylib_command (cmd == LC_ID_DYLIB) to * identify the library. * An object that uses a dynamically linked shared library * also contains a * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or * LC_REEXPORT_DYLIB) for each library it uses. */ struct dylib_command { TYP(cmd,4); /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB */ TYP(cmdsize,4); /* includes pathname string */ struct dylib dylib; /* the library identification */ }; /* * A dynamically linked shared library may be a * subframework of an umbrella * framework. If so it will be linked with "-umbrella * umbrella_name" where * Where "umbrella_name" is the name of the umbrella framework. * A subframework * can only be linked against by its umbrella framework * or other subframeworks * that are part of the same umbrella framework. * Otherwise the static link * editor produces an error and states to link against * the umbrella framework. * The name of the umbrella framework for subframeworks * is recorded in the * following structure. */ struct sub_framework_command { TYP(cmd,4); /* LC_SUB_FRAMEWORK */ TYP(cmdsize,4); /* includes umbrella string */ union lc_str umbrella; /* the umbrella framework name */ }; /* * For dynamically linked shared libraries that * are subframework of an umbrella * framework they can allow clients other than * the umbrella framework or other * subframeworks in the same umbrella framework. * To do this the subframework * is built with "-allowable_client client_name" * and an LC_SUB_CLIENT load * command is created for each -allowable_client flag. * The client_name is * usually a framework name. * It can also be a name used for bundles clients * where the bundle is built with "-client_name client_name". */ struct sub_client_command { TYP(cmd,4); /* LC_SUB_CLIENT */ TYP(cmdsize,4); /* includes client string */ union lc_str client; /* the client name */ }; /* * A dynamically linked shared library may be a * sub_umbrella of an umbrella * framework. If so it will be linked with * "-sub_umbrella umbrella_name" where * Where "umbrella_name" is the name of the * sub_umbrella framework. When * staticly linking when -twolevel_namespace is * in effect a twolevel namespace * umbrella framework will only cause its subframeworks * and those frameworks * listed as sub_umbrella frameworks to be * implicited linked in. Any other * dependent dynamic libraries will not be linked * it when -twolevel_namespace * is in effect. The primary library recorded * by the static linker when * resolving a symbol in these libraries will * be the umbrella framework. * Zero or more sub_umbrella frameworks may be * use by an umbrella framework. * The name of a sub_umbrella framework is * recorded in the following structure. */ struct sub_umbrella_command { TYP(cmd,4); /* LC_SUB_UMBRELLA */ TYP(cmdsize,4); /* includes sub_umbrella string */ union lc_str sub_umbrella; /* the sub_umbrella framework name */ }; /* * A dynamically linked shared library may be a * sub_library of another shared * library. If so it will be linked with * "-sub_library library_name" where * Where "library_name" is the name of the * sub_library shared library. When * staticly linking when -twolevel_namespace is in * effect a twolevel namespace * shared library will only cause its subframeworks * and those frameworks * listed as sub_umbrella frameworks and libraries * listed as sub_libraries to * be implicited linked in. Any other dependent * dynamic libraries will not be * linked it when -twolevel_namespace is in effect. * The primary library * recorded by the static linker when resolving a * symbol in these libraries * will be the umbrella framework (or dynamic library). * Zero or more sub_library * shared libraries may be use by an umbrella framework * or (or dynamic library). * The name of a sub_library framework is recorded * in the following structure. * For example /usr/lib/libobjc_profile.A.dylib * would be recorded as "libobjc". */ struct sub_library_command { TYP(cmd,4); /* LC_SUB_LIBRARY */ TYP(cmdsize,4); /* includes sub_library string */ union lc_str sub_library; /* the sub_library name */ }; /* * A program (filetype == MH_EXECUTE) that is * prebound to its dynamic libraries has one of * these for each library that * the static linker used in prebinding. * It contains a bit vector for the * modules in the library. * The bits indicate which modules are bound (1) and * which are not (0) from the library. * The bit for module 0 is the low bit * of the first byte. So the bit for the Nth module is: * (linked_modules[N/8] >> N%8) & 1 */ struct prebound_dylib_command { TYP(cmd,4); /* LC_PREBOUND_DYLIB */ TYP(cmdsize,4); /* includes strings */ union lc_str name; /* library's path name */ TYP(nmodules,4); /* number of modules in library */ union lc_str linked_modules; /* bit vector of linked modules */ }; /* * A program that uses a dynamic linker contains a * dylinker_command to identify * the name of the dynamic linker (LC_LOAD_DYLINKER). * And a dynamic linker * contains a dylinker_command to identify the dynamic * linker (LC_ID_DYLINKER). * A file can have at most one of these. * This struct is also used for the * LC_DYLD_ENVIRONMENT load command and * contains string for dyld to treat like environment variable. */ struct dylinker_command { TYP(cmd,4); /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT */ TYP(cmdsize,4); /* includes pathname string */ union lc_str name; /* dynamic linker's path name */ }; /* * Thread commands contain machine-specific * data structures suitable for * use in the thread state primitives. * The machine specific data structures * follow the struct thread_command as follows. * Each flavor of machine specific data structure * is preceded by an unsigned * long constant for the flavor of that data structure, an uint32_t * that is the count of longs of the size of the state * data structure and then * the state data structure follows. This triple may be * repeated for many * flavors. The constants for the flavors, counts and * state data structure * definitions are expected to be in the header file * . * These machine specific data structures sizes must be multiples of * 4 bytes The cmdsize reflects the total size of the thread_command * and all of the sizes of the constants for the flavors, * counts and state * data structures. * * For executable objects that are unix processes there will be one * thread_command (cmd == LC_UNIXTHREAD) created for it * by the link-editor. * This is the same as a LC_THREAD, except that a stack * is automatically * created (based on the shell's limit for the stack size). * Command arguments * and environment variables are copied onto that stack. */ struct thread_command { TYP(cmd,4); /* LC_THREAD or LC_UNIXTHREAD */ TYP(cmdsize,4); /* total size of this command */ /* uint32_t flavor flavor of thread state */ /* uint32_t count count of longs in thread state */ /* struct XXX_thread_state state thread state for this flavor */ /* ... */ }; /* * The routines command contains the address of the * dynamic shared library * initialization routine and an index into the module * table for the module * that defines the routine. Before any modules are * used from the library the * dynamic linker fully binds the module that defines * the initialization routine * and then calls it. This gets called before any * module initialization * routines (used for C++ static constructors) in the library. */ struct routines_command { /* for 32-bit architectures */ TYP(cmd,4); /* LC_ROUTINES */ TYP(cmdsize,4); /* total size of this command */ TYP(init_address,4); /* address of initialization routine */ TYP(init_module,4); /* index into the module table that */ /* the init routine is defined in */ TYP(reserved1,4); TYP(reserved2,4); TYP(reserved3,4); TYP(reserved4,4); TYP(reserved5,4); TYP(reserved6,4); }; /* * The 64-bit routines command. Same use as above. */ struct routines_command_64 { /* for 64-bit architectures */ TYP(cmd,4); /* LC_ROUTINES_64 */ TYP(cmdsize,4); /* total size of this command */ TYP(init_address,8); /* address of initialization routine */ TYP(init_module,8); /* index into the module table that */ /* the init routine is defined in */ TYP(reserved1,8); TYP(reserved2,8); TYP(reserved3,8); TYP(reserved4,8); TYP(reserved5,8); TYP(reserved6,8); }; /* * The symtab_command contains the offsets and sizes * of the link-edit 4.3BSD * "stab" style symbol table information as described * in the header files * and . */ struct symtab_command { TYP(cmd,4); /* LC_SYMTAB */ TYP(cmdsize,4); /* sizeof(struct symtab_command) */ TYP(symoff,4); /* symbol table offset */ TYP(nsyms,4); /* number of symbol table entries */ TYP(stroff,4); /* string table offset */ TYP(strsize,4); /* string table size in bytes */ }; /* * This is the second set of the symbolic information * which is used to support * the data structures for the dynamically link editor. * * The original set of symbolic information in the * symtab_command which contains * the symbol and string tables must also be present * when this load command is * present. When this load command is present the symbol * table is organized * into three groups of symbols: * local symbols (static and debugging symbols) - grouped by module * defined external symbols - grouped by module * (sorted by name if not lib) * undefined external symbols * (sorted by name if MH_BINDATLOAD is not set, * and in order the were seen by the static * linker if MH_BINDATLOAD is set) * In this load command there are offsets * and counts to each of the three groups * of symbols. * * This load command contains a the offsets * and sizes of the following new * symbolic information tables: * table of contents * module table * reference symbol table * indirect symbol table * The first three tables above (the table of contents, * module table and * reference symbol table) are only present if the * file is a dynamically linked * shared library. For executable and object modules, which are files * containing only one module, the information that * would be in these three * tables is determined as follows: * table of contents - the defined external symbols * are sorted by name * module table - the file contains only one module * so everything in the file is part of the module. * reference symbol table - is the defined and * undefined external symbols * * For dynamically linked shared library files this * load command also contains * offsets and sizes to the pool of relocation entries for all sections * separated into two groups: * external relocation entries * local relocation entries * For executable and object modules the * relocation entries continue to hang * off the section structures. */ struct dysymtab_command { TYP(cmd,4); /* LC_DYSYMTAB */ TYP(cmdsize,4); /* sizeof(struct dysymtab_command) */ /* * The symbols indicated by symoff and nsyms * of the LC_SYMTAB load command * are grouped into the following three groups: * local symbols (further grouped by the module they are from) * defined external symbols (further grouped * by the module they are from) * undefined symbols * * The local symbols are used only for debugging. * The dynamic binding * process may have to use them to indicate to the * debugger the local * symbols for a module that is being bound. * * The last two groups are used by the dynamic * binding process to do the * binding (indirectly through the module table * and the reference symbol * table when this is a dynamically linked shared library file). */ TYP(ilocalsym,4); /* index to local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextdefsym,4); /* index to externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(iundefsym,4); /* index to undefined symbols */ TYP(nundefsym,4); /* number of undefined symbols */ /* * For the for the dynamic binding process to * find which module a symbol * is defined in the table of contents is used * (analogous to the ranlib * structure in an archive) which maps defined * external symbols to modules * they are defined in. This exists only in a * dynamically linked shared * library file. For executable and object modules * the defined external * symbols are sorted by name and is use as the table of contents. */ TYP(tocoff,4); /* file offset to table of contents */ TYP(ntoc,4); /* number of entries in table of contents */ /* * To support dynamic binding of "modules" (whole * object files) the symbol * table must reflect the modules that the file was * created from. This is * done by having a module table that has indexes * and counts into the merged * tables for each module. * The module structure that these two entries * refer to is described below. * This exists only in a dynamically linked * shared library file. For executable and object * modules the file only * contains one module so everything in the file belongs * to the module. */ TYP(modtaboff,4); /* file offset to module table */ TYP(nmodtab,4); /* number of module table entries */ /* * To support dynamic module binding the module structure * for each module * indicates the external references (defined and undefined) * each module * makes. For each module there is an offset and a count into the * reference symbol table for the symbols that the module * references. * This exists only in a dynamically linked shared * library file. For * executable and object modules the defined external * symbols and the * undefined external symbols indicates the external references. */ TYP(extrefsymoff,4); /* offset to referenced symbol table */ TYP(nextrefsyms,4);/* number of referenced symbol table entries */ /* * The sections that contain "symbol pointers" and * "routine stubs" have * indexes and (implied counts based on the size of * the section and fixed * size of the entry) into the "indirect symbol" table * for each pointer * and stub. For every section of these two types the * index into the * indirect symbol table is stored in the section header * in the field * reserved1. An indirect symbol table entry is simply * a 32bit index into * the symbol table to the symbol that the pointer or * stub is referring to. * The indirect symbol table is ordered to match the * entries in the section. */ TYP(indirectsymoff,4); /* file offset to the indirect symbol table */ TYP(nindirectsyms,4); /* number of indirect symbol table entries */ /* * To support relocating an individual module in a library * file quickly the * external relocation entries for each module in the * library need to be * accessed efficiently. Since the relocation entries * can't be accessed * through the section headers for a library file * they are separated into * groups of local and external entries further * grouped by module. In this * case the presents of this load command who's extreloff, nextrel, * locreloff and nlocrel fields are non-zero indicates * that the relocation * entries of non-merged sections are not referenced * through the section * structures (and the reloff and nreloc fields * in the section headers are * set to zero). * * Since the relocation entries are not accessed * through the section headers * this requires the r_address field to be something other * than a section * offset to identify the item to be relocated. * In this case r_address is * set to the offset from the vmaddr of the first * LC_SEGMENT command. * For MH_SPLIT_SEGS images r_address is set to * the the offset from the * vmaddr of the first read-write LC_SEGMENT command. * * The relocation entries are grouped by module and the * module table * entries have indexes and counts into them for the * group of external * relocation entries for that the module. * * For sections that are merged across modules there must * not be any * remaining external relocation entries for them * (for merged sections * remaining relocation entries must be local). */ TYP(extreloff,4); /* offset to external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ /* * All the local relocation entries are * grouped together (they are not * grouped by their module since they are only * used if the object is moved * from it staticly link edited address). */ TYP(locreloff,4); /* offset to local relocation entries */ TYP(nlocrel,4); /* number of local relocation entries */ }; /* * An indirect symbol table entry is simply a 32bit index into * the symbol table to the symbol that the pointer or stub is * referring to. Unless it is for a * non-lazy symbol pointer * section for a defined symbol which strip(1) has * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. * If the * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed * with that. */ #define INDIRECT_SYMBOL_LOCAL 0x80000000 #define INDIRECT_SYMBOL_ABS 0x40000000 /* a table of contents entry */ struct dylib_table_of_contents { TYP(symbol_index,4); /* the defined external symbol (index into the symbol table) */ TYP(module_index,4); /* index into the module table this symbol is defined in */ }; /* a module table entry */ struct dylib_module { /* the module name (index into string table) */ TYP(module_name,4); TYP(iextdefsym,4); /* index into externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(irefsym,4); /* index into reference symbol table */ TYP(nrefsym,4); /* number of reference symbol table entries */ TYP(ilocalsym,4); /* index into symbols for local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextrel,4); /* index into external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ TYP(iinit_iterm,4); /* low 16 bits are the index into the init section, high 16 bits are the index into the term section */ TYP(ninit_nterm,4); /* low 16 bits are the number of init section entries, high 16 bits are the number of term section entries */ /* for this module address of the start of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_addr,4); /* for this module size of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_size,4); }; /* a 64-bit module table entry */ struct dylib_module_64 { /* the module name (index into string table) */ TYP(module_name,4); TYP(iextdefsym,4); /* index into externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(irefsym,4); /* index into reference symbol table */ TYP(nrefsym,4); /* number of reference symbol table entries */ TYP(ilocalsym,4); /* index into symbols for local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextrel,4); /* index into external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ TYP(iinit_iterm,4); /* low 16 bits are the index into the init section, high 16 bits are the index into the term section */ TYP(ninit_nterm,4); /* low 16 bits are the number of init section entries, high 16 bits are the number of term section entries */ TYP(objc_module_info_size,4); /* for this module size of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_addr,8); /* for this module address of the start of */ /* the (__OBJC,__module_info) section */ }; /* * The entries in the reference symbol * table are used when loading the module * (both by the static and dynamic link * editors) and if the module is unloaded * or replaced. Therefore all external * symbols (defined and undefined) are * listed in the module's reference table. * The flags describe the type of * reference that is being made. * The constants for the flags are defined in * as they are also used for symbol table entries. */ #if 0 /* dwarf readers not using this */ struct dylib_reference { UNUSED uint32_t isym:24, /* index into the symbol table */ UNUSED flags:8; /* flags to indicate the type of reference */ }; #endif /* 0 */ /* * The twolevel_hints_command contains the * offset and number of hints in the * two-level namespace lookup hints table. */ struct twolevel_hints_command { TYP(cmd,4); /* LC_TWOLEVEL_HINTS */ TYP(cmdsize,4); /* sizeof(struct twolevel_hints_command) */ TYP(offset,4); /* offset to the hint table */ TYP(nhints,4); /* number of hints in the hint table */ }; /* * The entries in the two-level namespace lookup * hints table are twolevel_hint * structs. These provide hints to the * dynamic link editor where to start * looking for an undefined symbol in a two-level namespace image. The * isub_image field is an index into the sub-images (sub-frameworks and * sub-umbrellas list) that made up the * two-level image that the undefined * symbol was found in when it was built by the static link editor. If * isub-image is 0 the the symbol is expected * to be defined in library and not * in the sub-images. * If isub-image is non-zero it is an index into the array * of sub-images for the umbrella with the first * index in the sub-images being * 1. The array of sub-images is the ordered * list of sub-images of the umbrella * that would be searched for a symbol that * has the umbrella recorded as its * primary library. * The table of contents index is an index into the * library's table of contents. * This is used as the starting point of the * binary search or a directed linear search. */ #if 0 /* Not used by dwarf readers. */ struct twolevel_hint { UNUSED uint32_t isub_image:8, /* index into the sub images */ itoc:24; /* index into the table of contents */ }; #endif /* * The prebind_cksum_command contains the value of * the original check sum for * prebound files or zero. * When a prebound file is first created or modified * for other than updating its prebinding information * the value of the check sum * is set to zero. * When the file has it prebinding re-done and if the value of * the check sum is zero the original check sum is * calculated and stored in * cksum field of this load command in the output file. * If when the prebinding * is re-done and the cksum field is non-zero it * is left unchanged from the * input file. */ struct prebind_cksum_command { TYP(cmd,4); /* LC_PREBIND_CKSUM */ TYP(cmdsize,4); /* sizeof(struct prebind_cksum_command) */ TYP(cksum,4); /* the check sum or zero */ }; /* * The uuid load command contains a single 128-bit * unique random number that * identifies an object produced by the static link editor. */ struct uuid_command { TYP(cmd,4); /* LC_UUID */ TYP(cmdsize,4); /* sizeof(struct uuid_command) */ unsigned char uuid[16]; /* the 128-bit uuid */ }; /* * The rpath_command contains a path which * at runtime should be added to * the current run path used to find @rpath prefixed dylibs. */ struct rpath_command { TYP(cmd,4); /* LC_RPATH */ TYP(cmdsize,4); /* includes string */ union lc_str path; /* path to add to run path */ }; /* * The linkedit_data_command contains the offsets and sizes of a blob * of data in the __LINKEDIT segment. */ struct linkedit_data_command { TYP(cmd,4); /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS or LC_LINKER_OPTIMIZATION_HINT. */ TYP(cmdsize,4); /* sizeof(struct linkedit_data_command) */ TYP(dataoff,4); /* file offset of data in __LINKEDIT segment */ TYP(datasize,4); /* file size of data in __LINKEDIT segment */ }; /* * The encryption_info_command contains the file offset and size of an * of an encrypted segment. */ struct encryption_info_command { TYP(cmd,4); /* LC_ENCRYPTION_INFO */ TYP(cmdsize,4); /* sizeof(struct encryption_info_command) */ TYP(cryptoff,4); /* file offset of encrypted range */ TYP(cryptsize,4); /* file size of encrypted range */ TYP(cryptid,4); /* which encryption system, 0 means not-encrypted yet */ }; /* * The encryption_info_command_64 contains * the file offset and size of an * of an encrypted segment (for use in x86_64 targets). */ struct encryption_info_command_64 { TYP(cmd,4); /* LC_ENCRYPTION_INFO_64 */ TYP(cmdsize,4); /* sizeof(struct encryption_info_command_64) */ TYP(cryptoff,4); /* file offset of encrypted range */ TYP(cryptsize,4); /* file size of encrypted range */ TYP(cryptid,4); /* which encryption system, 0 means not-encrypted yet */ TYP(pad,4); /* padding to make this struct's size a multiple of 8 bytes */ }; /* * The version_min_command contains the min OS version on which this * binary was built to run. */ struct version_min_command { TYP(cmd,4); /* LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS or LC_VERSION_MIN_TVOS */ TYP(cmdsize,4); /* sizeof(struct min_version_command) */ TYP(version,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ TYP(sdk,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ }; /* * The dyld_info_command contains the file offsets and sizes of * the new compressed form of the information dyld needs to * load the image. This information is used by dyld on Mac OS X * 10.6 and later. All information pointed to by this command * is encoded using byte streams, so no endian swapping is needed * to interpret it. */ struct dyld_info_command { TYP(cmd,4); /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ TYP(cmdsize,4); /* sizeof(struct dyld_info_command) */ /* * Dyld rebases an image whenever dyld loads it at * an address different * from its preferred address. The rebase information is a stream * of byte sized opcodes whose symbolic names start * with REBASE_OPCODE_. * Conceptually the rebase information is a table of tuples: * * The opcodes are a compressed way to encode the table by only * encoding when a column changes. In addition simple patterns * like "every n'th offset for m times" can be encoded in a few * bytes. */ TYP(rebase_off,4); /* file offset to rebase info */ TYP(rebase_size,4); /* size of rebase info */ /* * Dyld binds an image during the loading process, if the image * requires any pointers to be initialized to symbols * in other images. * The bind information is a stream of byte sized * opcodes whose symbolic names start with BIND_OPCODE_. * Conceptually the bind information is a table of tuples: * * The opcodes are a compressed way to encode the table by only * encoding when a column changes. In addition simple patterns * like for runs of pointers initialzed to the same value can be * encoded in a few bytes. */ TYP(bind_off,4); /* file offset to binding info */ TYP(bind_size,4); /* size of binding info */ /* * Some C++ programs require dyld to unique symbols so that all * images in the process use the same copy of some code/data. * This step is done after binding. The content of the weak_bind * info is an opcode stream like the bind_info. But it is sorted * alphabetically by symbol name. This enable dyld to walk * all images with weak binding information in order and look * for collisions. If there are no collisions, dyld does * no updating. That means that some fixups are also encoded * in the bind_info. For instance, all calls to "operator new" * are first bound to libstdc++.dylib using the information * in bind_info. Then if some image overrides operator new * that is detected when the weak_bind information is processed * and the call to operator new is then rebound. */ TYP(weak_bind_off,4); /* file offset to weak binding info */ TYP(weak_bind_size,4); /* size of weak binding info */ /* * Some uses of external symbols do not need to be * bound immediately. * Instead they can be lazily bound on first use. The lazy_bind * are contains a stream of BIND opcodes to bind all lazy symbols. * Normal use is that dyld ignores the lazy_bind section when * loading an image. Instead the static linker arranged for the * lazy pointer to initially point to a helper function which * pushes the offset into the lazy_bind area for the symbol * needing to be bound, then jumps to dyld which simply adds * the offset to lazy_bind_off to get the information on what * to bind. */ TYP(lazy_bind_off,4); /* file offset to lazy binding info */ TYP(lazy_bind_size,4); /* size of lazy binding infs */ /* * The symbols exported by a dylib are encoded in a trie. This * is a compact representation that factors out common prefixes. * It also reduces LINKEDIT pages in RAM because it encodes all * information (name, address, flags) in one * small, contiguous range. * The export area is a stream of nodes. * The first node sequentially * is the start node for the trie. * * Nodes for a symbol start with a uleb128 that is the length of * the exported symbol information for the string so far. * If there is no exported symbol, the node starts with * a zero byte. * If there is exported info, it follows the length. * * First is a uleb128 containing flags. Normally, it is followed by * a uleb128 encoded offset which is location of the content named * by the symbol from the mach_header for the image. If the flags * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is * a uleb128 encoded library ordinal, then a zero terminated * UTF8 string. If the string is zero length, then the symbol * is re-export from the specified dylib with the same name. * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, * then following * the flags is two uleb128s: the stub offset and * the resolver offset. * The stub is used by non-lazy pointers. The resolver is used * by lazy pointers and must be called to get * the actual address to use. * * After the optional exported symbol information is a byte of * how many edges (0-255) that this node has leaving it, * followed by each edge. * Each edge is a zero terminated UTF8 of the addition chars * in the symbol, followed by a uleb128 offset for the node that * edge points to. * */ TYP(export_off,4); /* file offset to lazy binding info */ TYP(export_size,4); /* size of lazy binding infs */ }; /* * The following are used to encode rebasing information */ #define REBASE_TYPE_POINTER 1 #define REBASE_TYPE_TEXT_ABSOLUTE32 2 #define REBASE_TYPE_TEXT_PCREL32 3 #define REBASE_OPCODE_MASK 0xF0 #define REBASE_IMMEDIATE_MASK 0x0F #define REBASE_OPCODE_DONE 0x00 #define REBASE_OPCODE_SET_TYPE_IMM 0x10 #define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 #define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 #define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 #define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 #define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 /* * The following are used to encode binding information */ #define BIND_TYPE_POINTER 1 #define BIND_TYPE_TEXT_ABSOLUTE32 2 #define BIND_TYPE_TEXT_PCREL32 3 #define BIND_SPECIAL_DYLIB_SELF 0 #define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 #define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 #define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 #define BIND_OPCODE_MASK 0xF0 #define BIND_IMMEDIATE_MASK 0x0F #define BIND_OPCODE_DONE 0x00 #define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 #define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 #define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 #define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 #define BIND_OPCODE_SET_TYPE_IMM 0x50 #define BIND_OPCODE_SET_ADDEND_SLEB 0x60 #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 #define BIND_OPCODE_ADD_ADDR_ULEB 0x80 #define BIND_OPCODE_DO_BIND 0x90 #define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 #define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 #define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 /* * The following are used on the flags byte of a terminal node * in the export information. */ #define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 #define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 #define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 #define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 #define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 #define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 /* * The linker_option_command contains linker * options embedded in object files. */ struct linker_option_command { TYP(cmd,4); /* LC_LINKER_OPTION only used in MH_OBJECT filetypes*/ TYP(cmdsize,4); TYP(count,4); /* number of strings */ /* concatenation of zero terminated UTF8 strings. Zero filled at end to align */ }; /* * The symseg_command contains the offset and size of the GNU style * symbol table information as described in the header file . * The symbol roots of the symbol segments must * also be aligned properly * in the file. So the requirement of keeping the offsets aligned to a * multiple of a 4 bytes translates to the length field of the symbol * roots also being a multiple of a long. * Also the padding must again be * zeroed. (THIS IS OBSOLETE and no longer supported). */ struct symseg_command { TYP(cmd,4); /* LC_SYMSEG */ TYP(cmdsize,4); /* sizeof(struct symseg_command) */ TYP(offset,4); /* symbol segment offset */ TYP(size,4); /* symbol segment size in bytes */ }; /* * The ident_command contains a free format string table following the * ident_command structure. * The strings are null terminated and the size of * the command is padded out with zero bytes to a multiple of 4 bytes/ * (THIS IS OBSOLETE and no longer supported). */ struct ident_command { TYP(cmd,4); /* LC_IDENT */ TYP(cmdsize,4); /* strings that follow this command */ }; /* * The fvmfile_command contains a reference to a * file to be loaded at the * specified virtual address. (Presently, this command is * reserved for internal use. The kernel ignores * this command when loading a program into * memory). */ struct fvmfile_command { TYP(cmd,4); /* LC_FVMFILE */ TYP(cmdsize,4); /* includes pathname string */ union lc_str name; /* files pathname */ TYP(header_addr,4); /* files virtual address */ }; /* * The entry_point_command is a replacement for thread_command. * It is used for main executables to specify the * location (file offset) * of main(). If -stack_size was used at link time, the stacksize * field will contain the stack size need for the main thread. */ struct entry_point_command { TYP(cmd,4); /* LC_MAIN only used in MH_EXECUTE filetypes */ TYP(cmdsize,4); /* 24 */ TYP(entryoff,8); /* file (__TEXT) offset of main() */ TYP(stacksize,8); /* if not zero, initial stack size */ }; /* * The source_version_command is an optional load command containing * the version of the sources used to build the binary. */ struct source_version_command { TYP(cmd,4); /* LC_SOURCE_VERSION */ TYP(cmdsize,4); /* 16 */ TYP(version,8); /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ }; /* * The LC_DATA_IN_CODE load commands uses a linkedit_data_command * to point to an array of data_in_code_entry entries. Each entry * describes a range of data in a code section. */ struct data_in_code_entry { TYP(offset,4); /* from mach_header to start of data range*/ TYP(length,2); /* number of bytes in data range */ TYP(kind,2); /* a DICE_KIND_* value */ }; #define DICE_KIND_DATA 0x0001 #define DICE_KIND_JUMP_TABLE8 0x0002 #define DICE_KIND_JUMP_TABLE16 0x0003 #define DICE_KIND_JUMP_TABLE32 0x0004 #define DICE_KIND_ABS_JUMP_TABLE32 0x0005 /* * Sections of type S_THREAD_LOCAL_VARIABLES contain an array * of tlv_descriptor structures. */ struct tlv_descriptor { void* (*thunk)(struct tlv_descriptor*); unsigned long key; unsigned long offset; }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MACHO_LOADER_H */ libdwarf-20210528/libdwarf/mips_extensions.pdf0000664000175000017500000022414013771667560016235 00000000000000%PDF-1.4 %Çì¢ %%Invocation: path/gs -P- -dSAFER -dCompatibilityLevel=1.4 -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=? -sOutputFile=? -P- -dSAFER -dCompatibilityLevel=1.4 ? 5 0 obj <> stream xœ•XÛrÛÈ}çWÌ[À”9;3¸ ò–µRY¯c1›TY©‚$V À@ÑÊ×çô\’²$»\.I$0Ý}ºûôéù .™ îg±Ÿýð)eÛ~&ØvöûLš/™ûQìÙK< ™Tl¹™Ùw$“Zò8IX’iž„l¹Ÿ?ß|¼eï¿ eÓWmÓ³¡eïæËßf É£ˆ-‹™”ŠÇ*ÂûËõ,ø×ŸéKa¾È¸R¡¶_|>ý…ý:Ï2žéTeG§1ÅÅü?Ë¿Á8&%¹²"åRGl!3ûâmUWþ©›ËˆgY”ùaW={ÛîÇ¡ìØíc?”ûÞå£ZÈ0ái†£Ò„ŽB@§Y 9»ù°üDnF¢Ìœ‡Á/ïþùvyóËú)‹NñO-¤¦çOcsÒç`¹«z¶n‹ã¾l¶.û¢«VeÏ få\Æ\H¥‚ ð†] ÉQ ¨'%2‡ò+Æ®ö7>_ÄiÌü,áÙ” ’:S£_&Ÿa!_a*cÏ€åƒ+×lWv%Ëñ¿?®~+‹‚)vy³Å§Ë:•`O»¯ˆÇa Hp¥…´Ú—Üb=%L§/”žò¥8K"z. óñ7Ë«B %×#\Ï"лN0Š^˜‚ó+‰¥I•5a3óTÉ×2E R¬?”Ûå=kZvèZ[ºa¯%b¥¶2í©‘ÙHú…}êsд͢`"ïÖÔf„lšŒåÌNsbA<ÑËö@å d–)níë˜'ÊÇú¡vè צX|¸’ËÐæïSë®O¦3j÷:=â3ï6¬ú²Æ5º¦ÚØ&MePÜûp.C¢ÍÓ´j"C.³Ð’Š%eSTæ¹…ÇZÄkwž çyÓ´[•l_}±%§dYÖq¾»ƒP¹c),ɳ$Ë<à 2qY2ìmâlXÎzÀV—®ÞJÚ²ÌSÈAˆßFœ¿”c±déh²‹ã¯êò £ú¹(yÔòþPÕ˜满mk¢^FÑ"TÂÖy*/Âë«ÿ¡¤è+êî¿#[*µ­rƒñ#@Fïæ{#R4/^kp4G8ÖUŽ’ÆSàÕ(K¤/ •ºQvl]¹¤º X³bJ&¥9ÓbKÛì„á¶£TŽy¤—ãˆòxìËͱ®MB™Mž›&* ŒÛŒj0›Ú»•†éH*O¨-Fî_\Qš/^ÏâðµW1\œq ‡l¦æ³–‘¼rïsPõ&±¶‚Ñ>c]Ý›HÔËù;¦Hƒ˜ÿ¶Ø’ï1x8® vfÑþÙnضnWyÍ6ÇÆµñÅ:rg9¤òu¶¿ M-i»‘·ž!Ñ¥~BéØý¸‘-ÁGf”ŠIžÃ‚{ôD[QÑ•9iÌ–œŒ‘vµ‡3(ÍHøŽ:­§ŽÂ¦“jOÀ4=xyTE´×Ñð¡÷Íå™±æ^ö‡6ÏJØYÆÇ†Å›•ï-Í.§Fy0ÍÚ²ºmïiŸû–Ò#Òð¹¾MùêI/S¥? s$‰1,ˆ#ŸÐVÀÈ©ÌïmÖÁ½¹Ï½u*Ó³WôE®|ÍP£¡!’ϱÀ¤%ð@Ê:¦ ùN7å$Táhœj¯-}XLÓŒ§˜¶—ë²½ (7Z¬þü*Vúª=Ì"úTö5Ãס)³dz%|ª JQ¾€ÚK‡/#…KTv›1;ûa¹Žà›j<k­=¼NH×%í|?gp¼eש/’TðPhÓÿÛ¢pÍ®P‰ž”£ˆ.aÍ4eOÜWØÙ· p2â €‚öÆ‹òz°Ê–ÔQ ç=¤ÚÝÜU‹5=nÑZ¹-œJb·Y8†sËíELt‘£ׂ¶Cðëw^× Žz¼8y¨LE«Å-|1Ù¢õyJât¬'­lë]cKüJÐYS&ˆKP :¿ ˆÆ ¬`5êÕèX‚õô7è„%|\íµÅ]¾…Ð3âü4—4²ÒëõÙu8 ~4!ÅÖ…D«ëØ·SHØœÇ5"¨öUwxÙ–mì/‡„ô«mðæLo)ZÖ|=¯ó3ÌfÓG7?Ù˜>…õ6õ+yž½)1æº kêÁ=ØtŒž¶<+ß±ót\–»{œ}<ƒk¡|ùZ™Ks;A7p-H»cæ‚â4óAþhËל‰‰ÄÓi÷Þ”®3ÝÆŽõ9ò{lððÌÆtî¶$äIzVÚu«Ýc½PÓS/롯ʺm¶Ø•ykÅ4pTt¡Ú˯©N.ønêÞtE{¾áãåÁö Äi·ÜXEÉ ¢û Þg:ó…ù–]sv’¤ãšs-iì}öÜHOŽ|õ<åoén žek{‚'Õó|ŽH’—ùZq1fZ˜;AŠî5â†wqü*q‹kÒ&©æÇá9o?Ø´DÞUt÷3©òМº‰2ž„BÚÂ+ÏºÓóÅ*Ïc‹=MHý†…’ýœwà'%D|~Q­A’þÉ…4ûÿûåìø÷¾@ÃBendstream endobj 6 0 obj 2548 endobj 17 0 obj <> stream xœíYÛnÛH}×W4übjcõ°›×ž·ŒÙÉbn›hìAQ-‰kŠäðÇûõ[UÝMR¶2™ÁbXˆm¹»ªëvêTù7æsÁ|üg¿æÇÅWï¶ï>Û/~[ú%³_ò#ûf½.¼•\-×ÿQp|%}P’°U˜²õv‘ Ç…'|ÎÞë¼/ê FaˆòàŒÇ·zƒŸŠ˜'Jͧ>ž »Ãþ¾jt•uÇŠŽe쇷?¿gš®øð”4ž®uŸz]u ‹åuÕgEUT{æ´¨”‹Q o† É^•Å<ÉôXñ`:©õh¤<’‘ý¼êÛ¶Õ]ÞЄÇV>—äŽ ˆx˜Dl^ÄÓ»b”q%|aßî•zUj{UzÎJÙßÔæmô+ÅeªÒÐ]íG™)÷ãI&x­ã$3ôy’úžAañÑK·Þú Ù®.Ëz)#î‹Hy詬լª{–m««¾|búXô½Þòå¯ë¿AˆñVÒ`ñ,À6$Fù^úF¸ü˜åEµ«ÙYÞÖ ¿mÞÅøþžêè¥bùg—uξ¯s£«,º¾û¢µgTFe×·  _ѹ¹øC¿z—2̘Ýb“·%¥O@ú¨âŸ>¢ê æÒEÛª×íŠÍ÷ÃÄûXèGVïпKr•¦©7:Úª36ú<}Vë++Úš.à¶ å4› Ì }¸cË/0gn=ÍœüX€Nƒ\±€íÊÌ)§RVP-.ÝëQ‰â¶%Oí#ÚŽ³¦è#xIÀ“Pôq*U@š—/ôÀåøkvЭ¦A7K¡¦ƒtŽWôØœºëðnVBÄŠ-~›g%QËvIrEµ&£€+Wðo§ü+–U[výêiçJˆ³‹­ÞQ\Cîð‹Q©°Ž3)‹JŸ„tóöMGÏ×Y~`ݰiÚzßfG¾\E!øTI‡TeP:`i÷tÜÔeGw«Ú0Ny„£Åtå"Š/G#Þ¾{ûX{g|_Kó¾ëë¯òœîA¦­nÞ|³„§©@y¿üõk+Mß›Çë~ª²zz‡Î~\+„—u˜'oT1׆oFƾtãÀ²˜½n!Å+ŽôW¡Ÿˆyýçtœ‚ö•Yþ€ÞYíñŠº\:_¨† |(ª¿ëkv¨-p†±Á‰„+éD=f—spÁ„œx>h.WÝ¡Ê-Û`Ì{Ý6­Y„$Jýxf–ˆM0ð"ÚÕê®G‹N»"X¾¥šÊª% ¸ï'÷©'*…ѨÞ¸T?ÀO=ˆÃ+]}DÑYWWwË+¬HjŒ¾ã{ìd–$R WuµÚÝ•‚P7è+?ÿ6½fY®lÚ2݇A¡º\ÈŠK¸@+KW_f9*;åvУ¡;öîGͶ‚§@‡]rÁM²(pd0–`ÊÃPMÖpö†xAy)”}ðÌP9rðÄvCeöjÐ2ô€"Ógwº¿¨l¯èú¬Ê5Âh=ìwKôÊÑôN”¹. x­8§ÔÁêYZ¶ÒÑzǼ„m¤çð"‡±!\ã»é4:Utöl»®?I†GæíC“Æ€eÈoÑ'FX¾H|û‘ãÕåäpsÄ:|£m£öã‘„Êï¼àüŽÉV} >ß`uöµ ¯‚ˆš€È{œØ #«7ì }`¶–f?<c‰?î&÷]™»P/ÞyT2e ˆQí‡l¯»»¥áÿ)t¼ÿw”¸óÅ5|U2‚Vz„ðB”cß¿`¯á‡¦îºbSšþM¬ÈqWã„ÀÀGr3¹ù0Ãç£e»€­ˆÉÚó½ 3ÞQ³(óUNÚê>ûCÀD° ÀæŠ= êŸy9ÀÀ…|i24áéh|hŠñÖë®Øê—Ëe]]ÉtÈ…HÜXF›¡éWéôø@D%†%–F`À}5-G¶6Ímhÿ˜É·ÞAì‰0öžLqi‚XcÍæ`¬Ì‘EíÚúHÏr¨ŒÕëb‘šœ¦d“!H(ý±”¬øÏp¬Ñø¶ŸsTÃD.Æ<–ÈÄ>p¼Lý W•i DCØy¢AµŠp„ʵ]¢œˆMk xdüRú( ±"ðæ˜Ïg›=ÒÆgÍÞ 6Œþ<|ibNãŸkö³&/|Ôòòù&ñ 1³U€úÏ6y˜ÆEÂgz» }Æ­CKçŸý÷{;ÕCBü”ÀÓvzj}— p´p¥qi½è{`Q‚3V ¦£6þ³Nˆ®2¡-þ#üßi„4Â×0Ú¡«Qc˜“t\iXÖ·Ú_AWX§¸9¢ü¥wË ö»3-[ÌE2vÂ$Ü5{>'ÏZêÕÉ6Q&§eâf8Ù º!°¿™;y¾òpÚÇgC¹6ðÕ⾬7Yi6…³ÅSmàùâI²¨sðµYs&¸+Mç .çlá’¡¿î–Fð´[²×Ü2’Ëiyº<…O]mLÉÙØ½O@Ô£C³# ZÀç'á3´ªb ö´G*òk¢MQš8 ý $d0_â›qyÉÜb,`À Ó/|ɧh'¾åào{ kèzD{üÿVÈàWJþ,ÏuÓÓæ:Âsñv¦ŽBlÍÙ×QVŒÝ§Y½ã[¡ÊŒfº=íc†õÙMÁqz0Tƒ/Ž:«Læ1u“uE>m|ZMÐIƒoˆé;U‡H-vBFÙ§ÍfõìâˆRÞ8#Êåôɺ½˜âÔ½Ç Åë¿€+ö‘6Ö~¨¼¬-ê¡£E¿%MRzŸŒ§lJ„ͦǼ‰ÝæØm—1*¬JÆõN¦¶¿u”.MÆ—/i! dœz™ÝáRÆÀo‰.¯ö—Ì´1»-·bç Á[϶z\†8bØ´ÇÌB¼L×ç«aI­+ÍD\Bô¹¥šjÖØ?¼žAq)ƒ“š}÷­]4òÎ/ë5„1ÓOf›$ÓzôÆô<ƒP•dZFÍ´F3žt‹Ýü‚Ÿ.Šïwˆ¢Ô_³öa\¾€{ß÷í=þéçþǟޯ߽ý™^mYÅ¡ÍÓÈ9¬1f8Å…I:ÎÍ00³Vsûα—Æ@'FØc f£ó̱´ù_ë­ÒmM~l‰ÌtCì‹ØÆµ1»~õŠÞþz{ºXYÝ®ô§Ïì wÔfuQÀRö®Å¹£c´Ri3g·q1§"r÷_œ-¦ÂÏq7æ2Z—;Ó¢Þ·6¸±Hã‚áôò…¨CÐ '¥çÐÈŽ‡ÇOnEcSÓfmš²0·1.·ðpÙQ±»FYâ‘ðxæÊÙÌ•â¹+ †œf²Ú1òß1jòßqèzö> stream xœ­YÛnÛÊ}÷W übªˆXÎ…·¾¥9ç .Ú¢ Œ¦@R”4–ÙP¤IÙq¾¾kϤ,7§§…l‰Ã™}Y{¯µÇ?³$æ,¡÷{{¸úíûœí‡«„í¯~¾âæ!s¿¶öû»+§ìn‹u\Ѓ»û+û.g"Ïã$ÉX®»;\Ek¹^Ýý [™åà X½Ig9[§ø¸»’ìîé*’±b?>Òj©â¢PØÏzö1ªšS5Öíž5Ýt-Ó_ýŠqÂÓ4ÒÀï†Õ?ïþ8·jívZóÂìçya÷ûð [6>h¶Ó›/ã²LDtÚïuÏ´ÙeÄÂ8Yä1—Î˜è± Þ”1/JoåLjìÓÃ̼WvWØéÌ{Ãê‘í:,:V·L°a¬özˆÙmkÿd]«iÑPŽÍ3vë¾ ì¾ë­IeK! ¸#f¡!/ƾ^ œW(=ÖUsn}?ÙÁªv‡Wt5ˆA7hVÁ¤£ÞÒ›Ûj€Eæ@ŠÚŸ®xœqNGÝýæct{o¢vîf:ÛžÕk»q²)/ŒMÆ{ÝŽºœ³ã“9F¨$–ÜRÅÜuжÈâ81ƒ-ðÇ­´ë &³ŠvÝ~ac«ð^È Àvž'…6ƒä{™›—×Q¢ôAô×Ùûbö¾÷?6ïûgz"uÐs!¬ŽÇ¦vQ¬Éz)Öø2û~ ½Ðuo¾€¿úq%R”@ΩB°ðSTívd ôMã1XæxVX;Eœ[KìŸV±«:…ª.Ý¢H›Ð¯•À—YæGøUîQ×ö¬È!¢}=˜Ün«–m4˃á<øvì»}_XÕ4çe&d'ßMãM?0XîQĦlBP~>UíXµFÅ¡Ò*ë‹PE,¨é¸êÁ¾Î—jõá8r¶U³=5„êl·g¶yfcõ…šiõ½‰}"Tt¯{Ýn‘¢{Ôt¦Ìk>2eê"ã“!y,Sg2b– öT#2Tãä¨nk‹Ãi §PVç@;a¥ï1W…ï0s úF`ݤœÔ-ÊÔ¶Fp´©*—¼4])±Çž ‰äèCeQx\(ZL¦ÏXÑuå‰éÌ64=‹;¤Thz˳—ìb §¥Ç—³ÝPÎR Ú6úªç¬>L/CCd‰«èó[z€ 9÷ß¡ÎKiݹû|n­?oˆfÑ$ûÚj%*ä“áJô¢(}ÔíŽhÉu€õÄÖÿÐ=@ÈX _Õ ÿ“¸°VE=0åñL6Þ¶ŽE  ºþ`àcCäÖ­…M!ÕÌ-µãÊÀ0Mc©”Üm;ŒýikꓞÎkį B$K-ƒ¢ÙÆSnûìÈx·ç‡·S”A13£÷?±¿ £‰Ð Ô™Cãí´«ìº¶†¢/Nv]ghÐ{wû#÷‘`ÆÁÐÚ,@nà#Ú³eI…‰<‡PYüz¡NÓÔC¨žW“Ì”×=£K=Þê,õ¡ÝÕ3{zÐQOHê-’ˆ8¹#ÎêÔXmæÚ*EÅø¾íšÓ¡…û½SÎ"wòÀ{nEwÙešJô¾rç@Va¨ BQpóVÁs±pÿ‚8íŸMØÁ¤Õ’úˆ,µ_¸SIM 20Ä(˜†~G¬'á³y¦ùg¤ÁÆ$ŸT1´I Ñoa¢ÊˆF,£¼`„ºpÁ£Ö’ªˆô µ›gž!™BÌdÛ$Aí{ôZ™ð)èVÚÈÃ2²Â‡»(‚N…vðýxê[Ô3ÄPSo¼‚h#-T[ª4]ÐxÑ»CóU[ýie³Â:Ð/·IÖ‰ Ûœb%{n&ñîJ2Zw«ˆ¸-ÁB-1í»n‡ÎÖÕ€aê`µ­›Ç KJá¹0N \)uízþ õÖOu»ë¬¾(Ÿ Ü1ƒê&6Küçým]b¸¦ã\‹òN0Ó9PBI¦–Ô~Ú‡í ?z'$i'+h?í-ç¼ z¿] ú¤,C«.l P3x ° ªàSt:"³ý‰Õ}ý¤€LÖvÊ¢AàÙía&94—¸L² Í¡¤$—XîÍ@šZ—i–èQt$¥.Úy~(Œ»¾†=ÔG¿]›_‡±füšzŽÎìš>÷h¥”9£mÛÓa£ûseF2ñSäD§à~qè·è…AŠù›P`h6^ÈQ:uÚî¼,JÑ"7º©—ƒ4¨2äÌá]ú63#sE¥\ †Æäÿ4¨ Ìñj& }_ÁM*–R½ÀÒP$Š2¨–3РÆ-ÿÌÊ€Û;&Â.úÉÜÝ$sQ š®)vHÿ$/®¹ë«DIèF‰0–”ÖŽÆû žüî¥üu»jO¥Õ¿~ ¸޶Š/G ¦†.âÛƒ±­bºùvㆼš¬iæ$¼C{8è] x7f4®0ÒÈ¢wŸ½ùÌE1‡âÚŸè%éÞ00¾“IìÒÁÂƶÛ‹`[r„ÝÛLÊ3^µ»Þ("û6ò Ép‘ÿeB*–Ô F7ê ´1ù‚2Á/õJP‰Dw·w‹– Qùyáp]r™YïÈR^d“wbéÝ®«—ÞñI;/½¿Ì;±pkœ©cåÜÝO™¶âsihÜ1<Ï'ã§…šåÑp'Ðkw³nöwžpŒ7æ4„&”üo”ÌË…;Òçb®0sC¯çÈ•ea¬,]Û’“¬mOSÁ›%s;ÅE¯ Ø´yĬ$Æ{ÄTÿù2Ín÷¨(©›yUÞ¸¤çè=~üHcáz­›‘•ï†ÅTLǸ‹°°û¢Ü{ãn'¶Íi笱Wa€°L&m§”cèsïÝöêusOl±NKq~kÄÕl²zsÁ[ »ì 7z}Pe’ÎC½ 8ÉS?"´ÂˆJiv—X®µWÂ]µC¸ø²½ëØ¡»nMê¥1ÜŠ&eq…Y–þœ§jNH" T1óý†Éå\ÖãÖL”Ïz$†ï¢Œv8H³w¨£¨vô:çÈ®·œr(œåšnÆëÞl ÃÍ=êó±.p›¿¦ôNG ¹o+=/ò`@&,µyæÁYfüÿABèòÏÝ`"‘3†©"w ç¯Xt:¼pÖ¶;õƒ» Ý}é¨K{‰g÷Ÿ¤Å\5bºµtá I¹pí©½÷ƒ²…÷ÐAyߘqßAîÜÇjño 4!úÞâP¤EœËPRö c”ú»SßÃvŒøt› 2È‘KŸ¹^Ûÿx˜Ô™–nÇ×1Ò¸”ç“ä2*Mw°i rö×}ðÅØïÉx9J©¾Gô°)'‘×/ÙÊN‚üÒüû_Ñ»i(nŸï°»ø…ì.ÿü÷?‘{ˆÈÇWiÞßl½Nêg‰ŠUrÑ«_§Yþ3­óò p¯pú¹íßãt?j8&OÝû›"#lÒÅF˜Hò•e¸œà&† é ƒw®úíI’Î&Z^äqæWºÿ%ÿxwõ7üü»_ëendstream endobj 23 0 obj 3036 endobj 27 0 obj <> stream xœåYÛŽÛÈ}Ÿ¯hÌËPY«ÍnÞ'k;ë »qlÀ Jji˜¥H-IÍÅ_ŸS}#¥™µÈ>ü0cQì®>uêÔ©ž_YÈ éŸý¹9\½þ˜±}²ýÕ¯WB?döÇæÀþ¼¸’Bª_\“ ¸ñTä.uiæå vŠõ¿TÇ#X¹ &òÞ¶ÛåÌP+NyaIüÔ¶›ê&ùsè¤b¸+fš uƨ œ0TÁ©¬kj4(HÐï?|:vmÆ#­*ªìêJu8HÛà[ºJÏôRt°ª©†ª¬Ùæ®ì°hŸ»i¯ÖG«:nÄ ZÙB†Ÿu.óU].e‘=Sm_d(yd[lÄs½îgŸ4°ÆáˆŒÇ"”žh¤¼úäAÓé˜4™¥àÂË*—‚žtt`ŠTw$¶:vŠÊ*¨W"â79—1:L åæ׫c-IÅé´æC;:®ˆ‡…<ÂÀ¥a¨Më¤OhíK¢0s«Ý«q5hð9€=ÛYg«Ø€çÚàY§ýjוõ¬Ñ (”ÌRÇŽæ&®x ´˜´¬Ú‚(•Qp²>•Î×A•H à|cF«öòü|;Æ›ð8ué>¾“ä^ûòiäAOH’á%AAÁÈÈ«l,Œ ¸#¤ êBWXAÊãç8A6óÂ?è aë'ª_74àôín˜ÈOG·YÍy•¤)E(¾EÝF÷,z8±=Bbi¸ž|t= gj¿é]u䶃F¾_Û‡3öÐÒ·vˆêqPM¯Ý2 ÕàÈAŒŸÃ6êH&÷71³"›øZ§0‘¶îæ†A«j”a4¢«¾ñþlÓ»©x´5-1 ø¹Ä3£#7¾ºP-ÏÁºþ®5‰—EðÐ>™}¨3Ñ>@À(~<²7Â49$gnNBãŒâT\ìkf$£ü4?ý;äaÕ0¦Ecq‰¹L¸£.M÷/îÒÛö{Uî5>å§¿ÖBOË}U‰=ìi€•B®tm²êhÁ Þš=J닽³²» ”1镞bý[殈Ǵ2êöy¼ñy:#ÃúžN‰®{³Â h _&¯+—*Î~Ðò=¹?¤&;][ˆi{¸wãL—é:t†©ÈÆ·ï\‡~^UOgÒŒQ7?«aÀ‰ ޤ2×rh e?¡­§ß³‘Dà+¨…9$vRœŽ\_4á™ âçÕÂ/ÕROÔËõö/cˆà¢1Xiu*À¾4´%ì> stream xœÝXÛ’ÛÆ}çWLü"0&G˜ÁÝo«Õ*%×Fvºœ*mŠCÐ(jýõ9=€¤ìȯŽT’VÀÌt÷éîÓgð ó¹`>ý¶ÿ‡ÙË÷ Ûõ3Ÿíf¿Ì„~Éì?ŽZÍ$تÀ:!éÅj;3{“IÂ}?fI²Õaæ-£å|õ¥—§ °z)ý„Ç [Føo9 Øê<ó"³×´Xf\¤!ŽÃ«ÞÏë»yq_„‘·Zòb]5Ûù¿WßÏ’”NM}EQf–{­?šË|ûì³~@/ü]Š,ãIÈ–"¥5¾öàîxÌ;Õ õ3kúë4O«ã×RpI p?°‡ÿ|7c_Úï߈kÚázoò0ðÅ×7Kn<!iʃ”-ådÉ×!ë;V˜ñÀdzMœéýźhÛ®ì™O…·%)3ôg)ý$=‹x$ƒkTVëM[>¯7j‡ 42Ñ-2QÈóÏŽLö‘I¢KdTS\âÿ\BÂ%æL튞VèšWûõ¶ËŠ=yMÛ,û]õ4ÇÏ´þGêó š¾j›þi®Ý¹Þ2æÒm±Âþ‰º¸L3—Á³T’åÞhàÉË‘•wu¥:¦æBw{ìÁø¢ÕгÍ3+•aJ'p@Nç I~ª–³^|e b*ÙÞ¶íX•ÎÚ±íûjCùöª3è'1C‰tUùÜBãé±Îì?;ç}UìYÕ³†~fU‰b¨Š¼fCËx©6s‘Á§(ôN;kµA»s¸ËEÛÏëX6£ÈfmiîaÀE‚O=b¡öª>VÆvéö:¯{ب»ÿö[¤÷¹PG:¦7)=° cé•*rœÎòíìëªùˆãa‚gøÓ·5TÕ³_U×.á Ùða!£j·æG‡¶õ}¡Ÿv*/ñ‹9úh]ýЖœò<d™ŒS/ï¶æ^P=Ðí`HgE¥^n±¥VÍnس/€NS} Ô°‡GÕ@€ÝøeÝ1Lý"µ?®M»û°®J8 „¡ë@ÿ–ÜkG ÜÏ ø«Éy÷› !PÓ±·zx=-hhÒ>=%Ò Íïf½úí&"ƒ¦è‹ÓojµÐ•eâî E±C~<"[Uƒ²<¨CÛ=S¾º`B:¹©ø,åÉEÁ‹0±å§4ÇÛQh™¹Eg1úêfá+™ò(Ž¿B`ˆÁXÙ§ú­eó¶K(²È«T]š¬–U? 0OU¿§Â#_ nRÆÜ—±‹Ar?µ¹Øví~óúÏ—‰ŸòLZ©új×Pa¹²‹˜hʹà i© bI~È?¡ÒH“ª0¡ªa UðT¸P¥­Ï[•l£ð*×›n dzÓÍ—Y þÓÜ ¯j*[dÚé»}ÅÓœl@t¦Q5ƒ±½tÇU~xØ&/>Rpô”M†ÚÔzµ©“éxŸ‰%Å·(_j]AÉÔ¹ýeA6Ñß\dóÝ"áÄø‰ð¶½Ò£Täª`<Èf Gh.ˆ$Áºø ¹é~ÆP "Ç1}ÕŠÊÀY‰2c¥À3ä@ &ž£“'/‘#¬¡áL©Z°A:‘nöˆ 6`€§^/ÍëW‡ -Ô] ¥™÷®”)eJ¸)]s”K ÖBr5ï „Òt$ÐE ±þ¨ t RJ?UÛgíí'³1‚쉦±ÙXŸ4p6¢œÔñÖNq™›òå¸ãÔnÜš_èý±¤!¬|×Õ“…^M’pµOp–ûOsB³=íön¸_ɇ¥ŒÄãó>ýÝŒ;­AL ó¦i©F}2’ j¨h»^aB÷9ÇX¸˜2½]CSg•¦K¨+k<¥ºvÇÞÎ¥sóJˆÆ Áü´£ z.QPYÈãxd‰ýí@±¯ÇyÄåò,Ö hø©rèê`ñÚc”É‚+ÌFª¾m[×í\†FœiÛ»ŸY±Ï»¼@ÿ™zæilˆ,Œ5ÿùE*Rpªó½sZšÖÇcUÝû³S't§$‡¨hßÇ$ŸÛ‰"¯k= ~&ÚœMÄ6í©)óî™vÅf |ÂõzÔÁüÍt"{¸¹íÄÔ Ä4uÎVáü6°ýhyªÜ* ¬zWYvªw³Ã´²ž¤·Rl½~ø×ýë·?¼[¯æ™Dõ‰Ì»{õø°^/®ÃÅš”ÓŽœ)ó!×T§ßc6ýo` ¿øâö|ÿfžRá§¡w·þÛ»ŸÖˆ¿lul~xçuŸÄ\]‚˜[A)k¶Gk²é[F®/ßÞgY~ù9ÙÌäTÏiLº–zWSPòxRY[â+‚ Æúø]vøà¡ÇSï4VyW쫇&“¶Îr…!$0z ÒNýsoÔ êÚ÷©¡X¨5ª–Dñ«B& ²i,J{Ý®Ûö£)ßc§Ž½Lœnû˜ÚøTµ'ÌîjBF-eiwÝèÒ]Ó¯I¬¿Ñ-(•cÛõSØ8q7þ¢ž|úÔfŸPŠ•H5¼Ê¨§Å þÒúÎRgíæS…ËWÄ®Y—D´½ŒÝ÷ÖÆÓ˜¤çM&ìb—‰»«>H¦ “p²Uu•Òä\ѼÍD½À~o ¢I¢X\øg  I‹¿cµkJë˜ã 9Î%º4H#¯0ëè3ç¥&‚iõ(•tò90>k[û :êXŒóGZg|˜VV;q‰©|{›/jñ“ìfÜ8ª[]_œõí’ê‰nLy …`Ȳ;¢Ûˆãó=A€m ½#÷eÃØ_ ý•iöÚ÷4 "½ã/OsnýÎôw³edà1j¿Ð›qàÆþ'q)$"'Dº`P§1À¤o¾vÚDšðØ­´óV³à÷÷mendstream endobj 33 0 obj 2476 endobj 37 0 obj <> stream xœ½Y]Û¸}Ÿ_Á·h›+Rß}Ëb7‹)v±mb42Å@–i[YòJr&³¿¾çò’’<ù@±E‹ež©[âuH¯ßçþVåØ\E˱îÚAt{1øáö_›¿Þ¬•¤S«›"–E’¸¯ƒw¯& T!µŽr÷âÍkñ-†³©hÁZ%‰ aÐZ_¥ÄhNç¦ ¯’aN[¥¹L±Øî„‡‰]½y%~šÓ™Ôi¬Üa8¦iêö0ÐûEàÖE" •ŠµÊ­¯2Vn/ë©í~‰Œrä•W‰ŒÓPæ•°gb|¤¥Çجå©Læå]9ï£e”$Þàqìë-½S)¶/|4/£DÝ.6MéÛ¨©šuKãÂÈçÂ-‡wåÓ Ù=K•¦Þ«‡uapùZìújޭбkáI1ã]|ªƧ³y8—}y÷AS£Ù‘Õ¯ëÃ¥çDêLË iX+Í›$!§\­Ä¹<‘Ýߊzà âkkl¡dÇÅcí4À½*’¾ívOØ»®ºœL;‰ÁT„yÉHfl"£ƒp&Þí ¨óû[)Þq’lÞu±Ì£9:Ó-¶”’ÅdáZKÍ›”…™½HáE¨®j²Üug -ÙêŽHE!ê4‹l€leú……LþT€¤³6¢å¨”aæk&øáÝÒÈh÷³ü€ârïÀrüGKE¾ò/A@Q¦96Íåë_Ñ•y!3ʇKÜÿÑ ÔyøÜ‰?‡@aaæÌ³¼(Ê\;ó"YÀR:èW€ÓZæyX|pëᎳ¹Dÿw˜{/TT¨âôYtn÷Xúýs£Ždy0âÿ:õ.÷s3Q`3 †n©ºC[ÿaàL9ZªcWW Xïe 0µ¦Æ«^Thy´vlžìâ¦kxÞv=GãØõ”ÆÛ¤DE$u;ç7ÇÚvÄ5Fœ€W·ÓÆÕ‚/=A&xz\Fnæ¹óƒ[QVU½ƒu’{ÜÔíSÂvzÖYµkÍØçáÝÃë_ßüòÀ½^…I`öån‡ß3Y‘`ëþ2 ç6 ËNê6š:i¦bFÌ[ÜL¢S®Ä+nmšeÔÑÄÁŽºóJìÌPá5RÀªB!†Q41>[ç‚ù Ÿƒ¾ª¤¯J¹Y+š$ÙÄÞSeÙƒÎÖ²ýЦ;›y0ÂåJç¹Ì’Ø' ý'ÏØ+›qÂ*•‚{ÌIÄ5<–>„Qp0#pTë;ÉÛu ý[,&,Aá1@UŠpP~¸-ìDéÀ¬ÄÖTåe0´q)Tº­Çõ¹«­R£øÄhàiê lÍsϦÞE…+Þ…¢Åã-ø,Tyt—f'N¦lçZ˜ƒQÙ·m7‚HQMÁ§Ê >Ðùaòöx¬«£8Áv²*Š–ù°GÈ€­7Šõ³©Oµ­¯SwiGkµÿÆYIU0K"ÀƒiËLQe:ç3-"çØçùû¾;á<ªìljPËZ#xÔ!y•7ÛCm{Ðà3äÎ…uµPixi_–íÎÅæ>`òîú'´œ­/võðá¥S<(p‘¸)[® Œz¤$ìoAgBLÝádN8ÀZšðç¤ð‰'äÛÙRŽò˜Ncè×_îþö–BiJŸp€à†Ëýp*Ñ1‡Îp\-—1>ƒ±N~êŒIxŽg5”ç+Y›fzÒŠÚÖOÐwÛÆœÄÜIÆ|÷ö§;Ë[dN¸XOj<Ò SÅ«ïïË΋ 9o|£¤ê$b´¦Æhšá5›Â25 Æò‰¼ÇzröÒ`–i PdsÚrnïƒËPs¶Óe,ëf †¼Nr°xž¯Zn”iü™íե﹕KßÑxBÐ4Üx[Áj®9«,u}Tx%L6%ž×tЏöF;[A Ä„ E‰sÿq¼ŽöÏÆQ ²mv©ªît®Ax캆sÂì®’"¸Ô i—‘xîXZäˆsß]; A…Êw~4‹&È=pêN` SI€¯pF¦lì^¡›‚âØƒ‡òƒ jÎ} @TàÒ¡£šrJ¥ì)UÖMâ<Ÿ[WêXeãÍÞÓŠª)ûzQ“¬8¯`Vó ßÜ÷¢¯ ŠtˆâSÞ¼Žx`,ZîÞÜýSXÎßckMçeéóæ›Hy°T+™Š$Øè5h]lN 1Éàªçê€4ÁÏ“&ˆ„kÖ·/nRÞž‚)wfË®g:¸NeU·{&Mr.Kˆýê®¶ÙiËÝ";š§WÎï·]p88ú]Ê •¡îâIO(3×wTáæ4ˆß/(|ì~©l3€7/|ô÷õ}šóCå'Ý 5±¢ôLkú²YŒµ•´ï¨Ð¿S_t¼ve_‰m0æ¬|ïÙQ: ÎÁ^¶Ö°§Á¤‚|"nþ`¨Òx•»{@`»þĬBYÚVÃæ’T(Õ¿¼´5ç“¶J3/o•›Çßvèñ/ìüɘr_“É„a»¬ù$œt:¡ýY\Âh¾Ôùf\É}dÈñÍtt‚öO‚|aI‘Ý$8F{A.ÔR=¤1õÌÇInõÄ5YbÝ“nÊcèª=V4õýÞÖkšÛ~Oá´)‹ 3 Î~¦DgñÔs Cíèe©žvœ8%L9<¹ôPm¼@à«Ö`2Æ«…7•sO\ÚørD©1~Ô;L=Ñx¿‡¾_p›ú*¦£(á(íå L¾<«> ³§öš®‡Ú¥Óq.ÐM:Æ“n‘GŸÑnжËf^äÓWÔijNÐ5&W•ys“øR³¹ñÂ\͹kwƒxÄœ%^Bx¼œÜDa|=ƒ³[6TÓ¼eYMYVS”KM]ņ’žH?I^L·‘å°t2ÿË LÛøáP˜OéŸ]$¦M¢§[‘÷Áœ½•¢Ì€fð ½=²tÅÖãíe(!†(”N^£;}:—Ð-+hj?ÅÒöU Á9|k¿nŒo©ÜÜ#têøq–¯|á_4‹½Ku|¿uD7h÷ÈÝu µ8¡ÈkÔ}“‚üý¡«EJ?àÇÎ¥ÕÊÎÔs¦w[LÝW%®ýN$Máõ ¶»Ž^ð´ßÀâ2va\¸ØÝKŒêpQ§L¶1†$³xÆv«Ëó¹©+ÞJæÐ—'PŠ2îÅ¢¾Ð|Ó,š½Û"l>ßKĠ㩊ýQ¬ÿ"ܬ͚›»Ý¹(ð–YZ(ÎÔü9'‰ÃæãD±óü5͇É79pÕêÙyõ8ýi@£‚x˜ŒOyœ¶ÃX4×oIܶV&•-_-)Èé<Ξ2Á]Š;ÛwÐ-ò(\œc—=ó‹rm“)FñœU ÜùbÎ S7²O–QHë¦!¶…ѬI\C‚ÇDöß.ÿL©Óíùœäˆš”:IæÌ_ÙD>Q$ŽÓd§“Œw–t‹So¤`ZcÆ+VRÄRÏ_ç_HØ:*B;R]Q(ví 0‘Û9ýѵÂo¨Ãø+êÐÕ}*IÿÜu.gJý|o”è€îFÎó¯áŸ3o:1A’º{‹Ëê(”þÉròÆ #Ö¡n[ÐóÚ_À컦é0&°H2¶öÂÁ´‡ñH£ZQ¡²i4À>âûK=±–ÏW!ó2Ï•HG7š%+L`4ØÅ¶×¾lV°Óµ$ ‚ÜSˆà楛(èše`ö§ë‰Ó"H¬éý¥±31ºáÄb…­_ÑDgINvà¯nûÒ‰Æ›ŽŒbn^wñÉÃÄÇÇ«Ó+nÓ,É0ëDKЍqA8Õ‡£µ+¤Û‘ïgkš9œ¶3G¹§Á­ûþv®"=ép ( ±,Iù®‰„Ž¿-ÊЦË"íT04(ÜE€×ÝžïµÜºkåg¿²A³óîGkµÚ²©]BùÆ„ \2Ý.f³ çú»€÷»%â1q/v—Ó™8`zh=xÎæ»pÖdѦö˜ }ýwÕ¾»P ç&‰N, KǘS†í¤”Ø /FÖTÍ¥’ç®Tîì—¥ì.@W/†#Pµó;Ý»'´JŒ0WÏW⇷¿:mgG&3H•q"I Õ×—Åã@ú™Í¥Ñž³¨‚ÞXe#’¡»¡ ½ QWk©¯ JVóð/tA)t&‹K•c¸ñ×î/Ú?nnþŽÿ hsEendstream endobj 38 0 obj 3280 endobj 42 0 obj <> stream xœXÛ’Û6}×W`gLm$„ï“ØÙrÊŽ³ŽªòàÙRQ$¤¡M‘ AÍ%_¿§q¡¨™JeËå›$€¾œ>}° Ò÷»:.¾ÿœ±ƒ^„ì°øc!ÌKæ~UGöÃf!yÂ6¾’^lö »V0™e< S–Å1ÛÁ:[/7_±>_Ë0ãiÆÖqÎ6õ"8 ý®UGV÷J³®Y94ZqúþûÏ9ÃÞØXâç‡EÄ6‹ ñ¿©jlúnùf‘ E§b¯Þ k~;;(¶YF1…,‚ç“bïºqhpÐiXŠŒE&süò¿›Ÿçž¬Ý¾ka¬ô#ùφˆZYƒÔ¥Œ(›¾CÛæOdÑŸ^«ª-{¶­¼\ò,Ž¦Ê“‰ã.…pêÈ"ÔWÓŸQ}ûÂF&fIâ«ï Biˆ^Ð[÷n,/ÕrÓæ…û®¥8ÛÜ7š¾ŒSF h”a¸J@9ÓÊÚ¦‘iÔ;4æûÎ'8FÈabПÔ?®›à:Ê@>l-M´"›ÒŒgpAa yÌ#|öOc˜‹Pp ÃæÀ 0no[PŒ‹oô¢¡¯ýz‡Ô¿ìb_‚í§_·eZ¼ïÏmM1}»ŒB$žŸZ$ó.8•èÇ"QßðÀ?G„¼üf uÁ‘àŽ$òüu:¬à™( ß2©Ñõè"€?ðÑw†Ôhw×yf1“‰äè¥ó !f9û¥7ØFCIcqUéU jš<¸©HŠ€ˆ !¦Úüñ»ïÌ›ŠíÏ]¥_·ßtªn™¸dmf}Øó¸¡íä¥é¦!¡›cŽê¸Hés:V–þl÷9,±]·¾~ì—X¶F>ÿ6ÿúÜ5KVª¬yEMåPïXÌE¾2Ä£ -2 žJâ  ®™ÉZ¿C}>ØÐà}i[þ Z½VlûØè koà§4¯ãŽÐ1ÄÔQØÜ. Cü $‘Û¢ö"IdP¶gåë. Y¿·‡ìæñY l"Ž/H*‰VB`uuóÄÄÊ`ÖÒ#Y „˜>'Ng½Æ%jh+¥é<ñË•è n1‘-~Ù‚ÖÞ®(…Cm…TÉT¢_PÍ’J¾»5£ð*¨#4 e®°ˆƒóH ¸êIT¼Æmá6Ÿp[ 8zaÞ<^±›[»)lÊ!óóbFEX˜WÇÜà”l1ºgu£«³Ö®”n|€n Ýš °|ÖN­–ø›Åfñ“?Îõ ô¸Ì†Êo£9{o¨6‰xž¥žöH½Ùp43ñ@©7š©!Ù$\ÚI$Q!RÏ%+ïCÕ;‚¶Œnû꛵kå¬&SM9C@‰õ&²Q Èó‹ V„=-»gÛþ ¹’4¾nNBS%²›·–ì“•…nr¹EZ)£îŸYw6Õ^X_”û?Žh›1ãšWÔ8¡L»oD¥oœ_,mA=ªÃÓkž³+&¸â -Ár$ºš“çL£¥sFZø¶íN0Í;Žy>k·'òÇ62 ?;˜‰à@Mz`?”NÞÖõÍ”!7$gÛæpO¢•‰tüV³,»™eš‡ÅDÓdG13è#¼»Q1ïµ"xÐÒ”æV*jâf]Ð zäìV»~‚*w.ÒÖwz*!Ä}è]?y÷t2.ƒ²#*Ý·})s2Y¹ •ž%>P«f'hÃa¸ÉŠr‰Ä$^aÜXl1Ú)„<+0JåþV‡JôÚü…xw8ƒ†‡]NOƒúë/‰?¿ÎÙÇ÷¿þtÅSrËW”d™ˆîÿa°A®®@9o ´óv_«W¸t‹.Á©ï¾Àˆïkbš'¨Úßš±¡inÆNê%$^ßLøBŸw§¡? åÚßõ;2Æò"Wnÿm¨‡“–72o¦xõL/G…/`Ç(dR“æ4òÜ6˜it!:0»Ö'¡Å4 œ$* r)¦¶ '‡…ÓþçÃv”ÒWT—f(®•ã1[´;e‹À~m>¢zÐÃODænBJ8êüØü9)$ÝTH½+8g7ô¾¼óPìѤØ_Jæð•`¶,IQá€_ ¾ˆÊÇÑèZO@”¯å°ýûöÇŸ–9¥?ƒ[ «²¶b#OÌ [>Bú$ê¿As¸õ;7¿f¢±L¦×ðs·"- ü ’๣i_uþ·+aÄ7GA‹%#M§)15»ÈO{Þpv­>H‰“«À¡˜bîUgóä·¹®|}0üÍÒ Z".²håîà“»?C»¶ª;Œ÷ÔlÌÜt{2C?Øb‚³i¼Þ¡åÚÛýjçô™Ö4OÒµqøIS[‚¼þrÆÕ …M†ÉÅ‚´RÆf·íû’‡¹¸‚â<­™àqœe“Šü©Ÿpt 4]à ûÙ˜"ÒÐ_!¹žÇ3ôÁYcþ³mu†úè¨K©c3Žt!a"õ+Í2Fz ”ñœ0!Pˆ0mGs#Z£ Áà±3óësQà®<ÖxœdN×ilížÎw³ëA\if÷Ô ‘`Ë a˜Ìcuæïœü…ï»Íâ?øó?$»Ëendstream endobj 43 0 obj 2621 endobj 47 0 obj <> stream xœåXÛ’ã¶}×Wà-”=Bˆ oyÛdíÔ¤l'¶åòÃLJEQ†ŠÔ‚äj'_ŸÓ)RÚïTå)q©j.Ðè>}útSXÈ é3ü.Ž‹?þ”°C»Ùaña!Ü"~GöçõBòˆ­ ì’Öû…?+˜L†1K´fëã"X¥«åú_0å¶§ °{%Ã„Ç [Eøw·Pl}^)×ì=m–©†9,¿nÞ¹g¤JýÃØí_o¾¿ÿÇÏ›ªiN›­9”5 ?É0”´}…hn]\Eš'a’²•HéogÙÇ"B®E(‡[íþâ5œ‰Cû…n~ú®·†õ­á쇦cEo­©»ê…™cÙufÇ—«( ƒw]gËíR†<:Æ)Ãö=²¼Þ±¢©;œa5Îï±%(ë¼*ÿMgÿ¹þÛ+‘ñ( [)=+z#X#N]^VŸ¥~'`Åo‹¬LÔ2§²js¼ôï¯äs¼`YD×EWÅ××Ö™Rð,£lªj³Ï‹®±ºèUèD$¸HâÿèÒ7B×6ûîœÈ ųXÏÕÍlNåÉTem6;sêž<ˆñë jÅ…þß埼êÙëÏ[AY?糩ó£ñx%tâ7Ê4ä*òQ¯Ÿ ³}eZŠ‚óúkö—¯¿fd®e9@¡xN¹íX³gÐjÛ!âÜî\à´iW"dͳ4ÒÁÞvΤ{y°†Ç:TÔ }ƶeS·.ÍÃÂJHïj–yjàr\Ì*hÊ£J¹LD6"U^,OE6.€FÝSÙ2CëJñ%;äÖÁ'dŽ|¸sÍ"h¬K~˶3a|zD¬x"oÒò(ºt— Š×Ö‡–KœwàšÇÕE!ã„§‰žBUCbkмªp>ïü¥xEÙoE˜?üÝ×@JÖŠE”‘ÌŒþ®»9H‰JF“ˆnôý¸ô™­ÚfÁÇ®a7I_uƒbÈ^%çù©iÍ@éJt¥Â”‡®€ÁÇ|^¥i6Ö«Ò ê]„ÝÌY2ìI1î¿\FC_£äóg—~L`‘•‘ðu¦CÔŸ‰û>o×0tBp„ x–L\´Å¡•w jÂæåá©Ã“³ã¸Ì pC’'þ²UÃÙ}7TºJo½ èpù”·-x ¶/.@ƒ¯3¾x×É×Ù.¡)ˆ^ýá`,Ò×5.ŒªÜúH˜múÂÚÒÊÁÔÆæ/_åxr²¦¥êŽ‘E¹0QÞ"I£]BH²,”Á­¢‘Ž}wÑ1¨Îûå*ú‚Ž)5§ à+wƒ‚¥· †Ðç &y¬ û6 AÓªqê“É$8CµÚ¶?ºö)?ÈÓR¤J𸙉ۧ¦„^[ýδt´®^‘Ž—‡¾éÁslì‹ ÁhÇY•h.Çzâïƒ c¥âJecuØfŽæqé“—%<ŠÇÜ¡CÅ^ÖüÍ'èÞ¼¬áÝn‡l´wž¾Þyotæ|[1›×ÏnÕT†c-Ú Qç¹vP¥Ãtd`{±;×l×[Ý{6lš7Œ=´^ÝeœQ«0KA ÇÊéeGeaòâ *ôòIwJ‡×¥_ Œ™ûèU˜kº„Š\NEþÔÛ¥Ò!E¼tÎŒVó(é$U0¸?÷”fZ\ȶž÷ ”F<µƒw$Póð’°‡`Óö[@ ¹ê^Nðû¢ #ôyª —Rð&¾à…)NyRTä5uLÉš¡ª@E¸Šü^ 2Bk®²+\ÂÏ0 j‚?¯ØîL0ïD#–tó(){>ÌÆÅëÝéá¦ÚÎËÌU´ rÇ;xJW?èY$Ü ƒœ©UN½¥Æì+ÔE½ßÿ:AsèÕèÈM>€@Š/äCr§žˆ×‰¹*X§qMá+bP|l˜Øó$•Á/­Ï-Rô'Û°„KH+~rÁLW L]h`_D¾!£@ëš ©Ïw^Òô àïçù‘c:˜.ÍŸˆ DT­Á<‰Öj›£;áâ<êÛù…J×N¸t*t†äV;¯Úý<‹¥(z}&/ "È·D>ç8|éè2Ý€üè©û™(Ô<™ýˆ4çGâáI¿À|7ì.W(ÑûoÐüKRŠ!oíUâ†ÂŠQlpéRX2ö(?5ÕŽZóõS½i$#7~3lãôqïÇ÷D EÕŽHóÞ9¥8"ÿ 6¹µù‹g)+uCi/÷#xžE¨â$AX¯g"M¹‰ÄÛf¢75·<¤ÿêþ¸EãÆšfÛ—ŽŠ]„Ac!œ[өǾ”Uófþ©l}¿©ü$•ŸNU醋ëüAâÞ׸m pìný¸wiIk0pXPpŒíî0óø¢hò¨¡p°¹úJßQ‡^ŠÈÏ!˜B¾Jc®*+[ëžôš9 úiÒR ¹ÙLỂTý2Øøwµâ)·xeTÎï!vbÊÏð""Ý‹n°¥Ò4¶¼’p™Ò«Ô\Á‡®5|7›º‘æIûN^*»¾èZÜB:[Ïl¡?'÷^ÚypjŠ8ß9çi˜š îk¼àQŠ+÷bÓÔ>ãÖÓ†¨zAÀx¢\ª€Ç‡1}ëñQL>цa6éC‡ú>·¨üñËñå<¥I|Ø9|_úÍzñ#>ÿq¿Ònendstream endobj 48 0 obj 2018 endobj 52 0 obj <> stream xœ­XïsÛ¸ý®¿ßLÝX(Áß¼o9禓Nïzí)“vÇQ”ÅF"’ŠÏýëû @”lÇi§“™XÁÅb÷íÛ·ø"B©DHÿìßj?ûÓ?rñ0ÌBñ0û2Sæ¡°ª½øi9‹d*–Ö©ˆ,73~W‰(Ïef"O±ÜÏ‚E¹˜/ÿSfy!ðV/¢0—Y.)¾®g±X>΂B*%ÞÓê8•ªH`Ï‚O÷ïè·(•iüc\š7–÷¿|øí÷{½Æ^Wã}«÷µÿˆÂ°¤W&î-²Pæa^ˆ…*È@(Ë(!·ÁrÛ Bc߬檔e—Áq¬E×îž„>jÝ¢i…†oÿ\þe¦âBÊy÷î~I[-B™ÐU.ý“?ûƒ«D†qi}§­SÞú¾iwM[¯ï‡ãªïŽ#>‹÷~–óEZ"Ä*…sµø:Ò@ïŽpi#Ɖ·Qh¥"дÒx¸Py(£4Áa#Þ1Çæ°OÛº~31–ýX™`'…sº99Í+Bg!7ŒÃ´¡óW·k8…¿6 ¢ë›„«á µö¢êö‡f§Ç¦kűmÆkz§·¾únµ«÷â±·&˜I!“$SÎ%“Œý?GlúÀéèë L´U}-†Œ]¿®)ìW³§&lµ¨úšÀwÿî@.ÛC_¯›jÔðûA›ÿ•býz1vÆÒd¶¸<˜yxZm> xIίf=4©!£¿;¯ˆ½~«Züú·Ó œÛ;ÀÚVBïvlFY*C‡F2͵ôHq­º¾¯‘‘3ç±Éºkù”H¡‰·3âñ’f\`C‡‚úÜàœpæ Çj Ç®ÍÁ9䵿JçJæ©+€¯5ã,$cÕ¬”QQúªn¦@ÃeÔœa:yÓnº~Ï'ßôÝ^߇æƒ8hM!d`e\RY:‰ý‘¸à8–xihö”÷AC=˜Í±—Mñº¦›åqp|x¨ûyšò7.³P2 -¸5uJë DŠ×‹ýq‘Y„1cù6/É !OíO/’ÏXhbªy&üFM‰ ræÔ@Þpzªî¸[S]ÕseòøÈZ =ˆMG•%jš 0tIŸ–ÛàÃðˆ,z>¡©˜E¶«€¢ó7ºJ@=~èõž9q¥§Ó¶p‡w)e°§”B¢ýy¦‰µÀ껎cÆtH`ÿ†%î×d¸Xt›oaÍ‹©G%Øesl+SéwA[Sä.ú ¨@:ZëQßÍéŒäË]à’§Ѐzó†¨\êÃxW¢•·sD ñ̓§GâÜ)b݃L9¬`ÑÌò6¨7¢Ò-8TWÛka›.5$}‡fmZ3¶l†sä[Sî˜ú0Ewé“t3ùÐ!›ƒþQ uíñOâû¼$ïæ#*c“ß“ñ—Jû…ì_¤‰"|0­mõõ§±T¾˜ ÷c®d‘.a˜\ñ‰3,pÅ‚”Þÿ§ÆØË‰\{©Ô‚Ãs¢>U§®tþ¯êiä†wóq±ë*½³0ãZcÍhíÅ–'¿w¶Øžçú6°¤ð¸í†‹À^h»ézDnh­¨º›wsög"ø)qr&ö£ïûI4ûÕ*À†ƒµ¾~Cë+§¯h}rš$´“ùFóqi¶™ö5ÛÓPd*‹Ù12Ì]cÉ¢ª×Gµöu£Z˜†“&JŽe—5fCîZ‰<)–¾G¦À ­”/Ÿàë©O–Ÿ×U¶®^”Å–ŸžIZŽ) å:¹iöt˜ j§Œ”ÊÜÏSy¹×âÊÙºòÆöµnYi¹_· j— ~>÷ êÖ5MA9f03&mDíËj/é«aÅ1‚fH£7´Dð4pÙB(uâ’ Fƒ^}\™FŽÒVÞl¤ ›ÙDF65†¬«yj›Íp¨«Fïš×ë+±z¢ñË´Ó0òš/“9['…ÁÉ g8ð#º3µ“e¼xz]LžÜÐ]r¸JqžüùÇ3/<^(Í$‰²ïVš77÷-1ØŽ\«Ó”ûrû£åèº÷ WŸxv½€ÃÎ/<ÂgCÇmÐ ûñÙjû±~FWµîøeÅÿeâ¶s ÌX«7o'ò°°Ärª`¼ðá§Òà™œJó£ñ¬'Å¥ŸÚí æ7w‹u˜dž€s~‰QBøzT½Ö o§’Ó][äØSÅÔ„HC›~nÒÈ—”ëTq®—ó˜$sRý±6Ó›0œ )e]Îp“Mɨk°N?F%žô6_3ðزêÖOóÌbsÎ395Οž0Á¡—*-}ܘtGfÝÇÃõd&tãfvô@±ëºÏ,ÝžùBr´êtÍÐhh ëý"7L¨§i²˜¤¡1ÇËyTån¾Ä¿7ÌÏcñò(k4íPb%ûùÐa›ÁŒ¾[dm"÷CçRéý‡"ëÑ>¾`øÁ[W~,Æî ŒTï®LÞñµ‚që²È"³ƒ¯­ȼz»´R5--ºöZ×÷«§Ñ^üUoŠ,··o7tDÑBô6e(Lp2ò\4i¢ÿoõò ïõÓ|gY.Óàã`&o òp¹Œ }ð?:Q=V²î®aàs'@dî¯ÙÎZûÂ>sÌùZs½ÆL }£‹nÃÅœ`PMÓ×»Òcß;‹iŒÆ´Â’Ø>‹N»”¶ÔÌ:N!"s EkfZ-LÄ1ù¶P‹ê¿(3 Âh‡á²·”ªmU粌¢³ªª­&yIÑ7±æ$ðG“nÄÎ[UœùVeùÞÍþg×LëIï¢;] <œ¶¥D¡=Rhpu$ïÎÅ•ÏBá{–hˆ¦;`M¯ÐÔigZÀ¿"×"VâÝCû¯éÄ€*r$Ò®´ç?/gÇ¿ÿyòœ÷endstream endobj 53 0 obj 2364 endobj 57 0 obj <> stream xœµY]oÛÈ}÷¯,P˜ÊJÎðÛ@RgH±Ûm»jó`/ Z[ÜH¢–¤,«¿¾çÞ™!);i¶( v¤áÌÜsÏ=—ùM„R‰~ÜßÕöâíß3ñØ]„âñâ· Å‹ÂýYmÅŸ–Z&b¹ÂsJÓÂòáÂîUBg±LÂTdq,–Û‹›`¡f:.dQDA¸˜ý²ü3Žå­¹Àfì\è0‘*‹«‹H,A.U"ÞÏ–¿^DXÌcœµàãÝ;úN'2ÑQn¿LïXÞýøá¯?ßu}[WæÎlÌV„Ï: +Ú01t‘†2 ³\,TNÛ•L³„N¸ ®[Sö¦M+ŠPì›z×›V”»J”]wØb­[—{#ʶ-Oœ-Ò4“Ið+õNôk#ÈŠ}ÛˆLjqà7ÂjúÕíL¬ší¾Þ˜û( ±Žeæ|Ø­E(5ÇuáÖŠC<•´Ìq+ÂÇCËà»mÙ×Íîv&]šQ&Ú§&¸]×sqýí·sñe\ObÛtý$xì€.bäeX5»¾Þdðy4–t=Î*ÛJTÇ„EžDIP¶Ö¢´ÆÚƒHTu‡ÃVd0ëÆp«î(k­ v‰Í@IjÝ #Ôˆ0`Ÿº;ßv}ù<=õJ|:/᪠pæä_çâØL¡Ôд۪—N€\d%Øž¦gÁ .'v)Žu¿fSËûŽË¢À:ûÂF0q¬þWQÔügĆÆôëÉZ•áRÔ ´”)Uë¹ZÁ»oÆ‹bæIá¥s§?³(àbùäËK&‡Uz¼vÿ„ü°´åÁCOU§]¹­WˆØi1 ›µ™”à¶Œlˆ"sä“(?xÛ3W8Je¾Üvg!Â#j´<ãÝÿ [;›œ‡Ãfc³™gõÍ€JŒ¸ êm_8BÛj:<>úˆzqÞfCõá´' ‚÷g2W“ý–@P"ÓÒE¤,2Ó 8»CÓ7$ë6õ'ç³U¥ªÈeXx5×S¢Ki¯3w!ÈAØž«<ÁX±ôŒ‚QsWH/,¬Ïìß ÕÀžÝ'f_:•š =—6d^>Vüð¶d¦à(j4hyjAÃt49½ìÏbƒ[*³j*{1uj4I25Ò…Œ‹üë -™zc{ið®çãš#úÞºúYpý¼õc=ûÞÆOË4ü²¡rëþòŽO%ø`¾Ÿúamý¿ º†9I3Ke˜y¨ÛÄ@ãT©sºAñ¬¾££ggÔ8µ–¨_ë…øé T -§•»Ñq>.¥È…q<ÕæHÄ5àÅÎfñ…´`Ý!úÏ¢ÂúÔ9u;ŠMw‰'˜ïè[€›Êß6Hæ;j”ø”γˆÍÈÆ8t°JÆ¢t%Yo€¶ãä(O`4Õ´F†*pc,6LW®ÁBhÒılÔO;ˆSêÇgÍoR¹®tÊSµaT8AGWtt¥eÁÑâÁs‚`ö†DµÆ<Í„0Ô1.¬·´¶¡šnÎÔdóó¢«ÿe>§cáKó¡;7¸¥¥éƒ Û(—yêÒü0†Ðî³ßwÄ…¤ 1hé@»ij+Î₵5Û¦õI§UH&<— ByÞ嘘òÜ+¿!®œœö°[ôõ…Ú¥Œ‘«<;X%ZFÊ÷Ïw`ð΋¡é2ÛLöñ´öÄöõº2]çú>zQ¢Ï ‘³s´Í­iÈÚsÓN#—Gဿ°Ctöe 0˜ rÎ:J1'¸å˜ÃÉï-º)“b¹áL!Ä`cyZ¦#;\É…«è­O¨ŸI†E¼œAá\ }ööG‡â»çr»ß°ÍR²Å[P×b†~°°L9œÐÝ:¼ÝÎha¦ ªFÔâBÍuˆ/§v}fs};ûC¹ç¿8ãsŽTvȜƴSä"÷RÓ;ñJã5ºÃâºé<ÓcmzñÉê`*„>¥™ç;Ò"î%¨`…©½X³tpÊžå+hLûÊ î4ðF=mbz¬ìƒ´3ó©sÛD}x¨Õjúbůw;¡Ã1—ƒ.rèq ƒI°l?YÎ'Yã»2=oæ©8Ì@üç“wøzŒb¥ÈNЛ˜\é“+iÙ•šã9²} F%¹L¡ÿ•ºEoßB4¢¬*2˜Ó;õ\÷üÚ‚|±lÍ$"®€ ù|°óæiösáᤜ”d8 ©žØj…ucHoÝ)Ò0hŽTq¶9.&û?{›v·i Ý(dü·W»öТ» VәˋcÐÙ\@±þX¶˜üt&“þ¨rqž4^ÿÇÄwË‹¿áçß·ôÊùendstream endobj 58 0 obj 2630 endobj 62 0 obj <> stream xœ­XMÛȽϯèK0Ô®D³Ùü´OŽ7A6H6ÉB@3Æ€"[#Ú©eS–…Eþ{^Uw“{äÌafØìú|õªŠ¿ˆ(”"¢÷»>Þ½ú9Ïæ.Ïw¿ÜI>îW}¿ßÞÅa*¶5Þ“1l÷wö®qž„i”‰#:9E¦™òŽÇ¡w/µÓã*\mÀMoáÐZçÑhaÃw<8ZOgý®6¶´pÙ'ŽTû~®–„€”вð×ã`ÌMi@K3œ´ødó@×Ó0Šå½­–{ú–8/$Ð;á(¢¥º9‚r8k±ãB$iç ÊBl‡˜p ŠÓh‰'6cþ3 =¸W÷¡Mªç/ˆ|Z2 l¿{þÞ 1Õ¾Ì%Ñ‚8T7„ ãø!PJw@ºç±¶=¬˜ãƒwCoô/gä¡»®îa—ŒrRX+ù`½ÔjdäÒ“=k?Mt¤‡aíYÓ³(¢ÙÖ¨=WÀhsí«c[36k´êIàLg¨åkf,Fyâ¸Ø€Só"c€lg:ÍAs%´ý´dwJI4ãÊ)±üÌOqª¬ô4´¾É’Í]šYž ˱Ð, Í‘íÔ ¸L·â".‚Û3{¥a‘ª9”y‘¸ÂÐ]#mãv6Õ³æ"¸Å\Bª<æÞ¡³Žg”ù¨}Á!{HÍ$) ±DË骴*‡=fÛ ÷FOèÆS}Ó!¡ ¢©¦ÊeÈV>ÉÌÂIbñn-Þ}ÿ=šež¯Ù〈Ýd·ú©íÏš4ì(G¦FãÑs¬ÌÅ|e¥¢ð–‚”–a†2±êã°t/¢¾Cñ–3 dXÎÝrEÐÞF?U`“W•1ç£n6æPô«Ó iKÙ?ð”É0™[Ø?ŸÞÚ‡h„‹x;˜lŸfŽg)†z’O ûˆ •Ix£´XšÛ'}ÓKcðpòb´ZXff˜DÎ 3× qi†ZšóÄ®2šjžñáåndaãFªIøóa0œˆCå;¾µƒo2·´"¾sÅnAz–Ò³Ù"Vƒ½zT?%™nŸÑ¢g:N2¦c=ƒúó¤{ß ÁöMgáZ톗öP_Nâ¯Í9ý7slç0ÔsbgÁÙf稧ÃЫGÇÜôÞ<çNº¦m0R6ì‘î…Lž*x„KÑVs[ùi˜%~„;Þùá‰çÖ°RXºA¦/‡f¯2åx¹FÈt¿ô¡¤tœPCÀØÖÖ™ª0+óe•¥ ¦ q¨êÃkN‹+-³ñž h\wYq_Î ˜÷qî}{e;ìÙy 1é5hÞ`Šº¥É[ØÑHÁ†xŽEu¥XdÖj+ùô |» õùúvz¢z| Žˆ” (¾˜-\¨¢¼¤PmZsÀŒí€Çî d”ùŽ’×̦ͮGo:rõ„nñ â‘bÞ}bñ–ze©&y¹økZ0)’!U fm„ùh' L½¨§rΗ h·ü«0W:3¾Z„¼JW¸ÁÃOä_‹Ÿ´F›µTz[D .lÒ( 4¸—Þyÿ¥GÞõñÅA‚.3Aöˆ‡£ÿÙ¡c¾µÌ9¶%€Ó8ƒ_Þ^i±)WØ k’ݧ`a(~ÐSÕv¼8¤ …¼˜[lé^ëô~"ò·ôh´&¢m°–«­c¾¦¸Îø\Z¢ç,øô±¶f·¼_/ØóüÍbÿ-ªÆîêÆìFÅ—ðžC™HKNŒ«l;z4~[¨Á¦Äï5–šŠyS[ßPfäÇ~ì# „ù;AÛ·Äâ€næ°õÇsס¬8Üâ4¿„Ñ*%sÊ"p-Q8ûx`™SêÛ<ùõÅš™.mñ·V̶ßQg{#^½s»vcM*– Ýpa—Ér±ƒCA€°úéî©Óý†WL垺™ƒ¨Ð õk‰:áOÓøÄSÃò¨?Ÿšöh^«7xdGrç#=~2âW<_¼aÝŽµÑ‚b-˜søyzÃa°Ï!èéHr]ê6‹œ5·PT>,Gó¿cg©PáÆe>SË¥±»ZSÉÊæ|<=òqåfö;ÀÜ¢ÿ-`$lih:þfc+ÿBß,ŽX´höØÙ9iÒfr‹pF7QÈ t°TJ4sï—¼E÷)\ ,&­F0|EéíË‚ràÝúú{è¶wÿÀÏ¿™\Ü$endstream endobj 63 0 obj 2458 endobj 67 0 obj <> stream xœíXmoÛ6þî_Á"6GRÔèÐa/X÷j ’B¥%ÚÖ"‹®HÅÍ~ýޤ$ÛYºYRtEáNÄãÝsÏ=w¤õL±Ÿþ»ØN¾þ=Ak=!h=y3¡nõ_Å}³˜0¡Ev”Ù…Åjâ÷RÄŽ#£„s´ØN.ƒ92žá, 6Ÿ¾Züna뜑ÓÍyŠ%Ø}/¦ÌRNƒ›ªY£Õøo%ë5b+5ÚWfƒÎ°sÓc à' !¶órVùh)sˆFSœf„y«`#;TééâÏÉœ2ŽFüá–eîŠ h­T‰ªRŠUªYÕUaz(f#­ »ñ§IÐi‰ÔÊâ;Ð…'i–Þ¯<ÀcS:À» –o‘œÒeÁ[#›R:€Ÿúq™ÛÏÅYxöÕ í§”`B’0P¾”hkIBW²õaÓÔgÓG¾ ŒrÛÕ^{Bª•ÿ*(:mW«{¿6ÕœTŽ'8ã=4SŒÐ2œÐ,Š%Z‰ÄRuÈ®ôÌW,Jp¬Tk+¶J´­ñV3ë.Xv‡zd8®Æ€)Ž)¡ñÀ…ª¯OP·×–[å3ÛWu bhJ›ªÙ(-=5 0nK8`j-î¢j‹n«h +Þl@S3¨ŸP`Ñˤ?íl(ZˆÉðpØ ÔJQ£]«–µÜöüã«)v„Ç:ùY 0©`CÕ€ÌGéxŠñRh‰gCU#{&©cr¯¢GÂ@±YÖc±zÙˆÁÔe=‡h±Ÿ7ÿHšlâщ*yZƒþ©óÊCœƒðˆó¶‡T*^{Я!#cº@wÛç V–áu{Š1%8›ó£8‰1 í-ÜzQÈÆÌHn)Šëù›Î²ú[Ôi× >wC.Kƒ•¹#¬˜Ä°£õÅÅ1wáa!_½yô¼Ï¿;l☌c)ÈEÛŠÛÜbíw»ó8Ä”5Û»£>wãùx¼ò!™EîO؉{–`žðAîÁ­£ö<¥Ñ³GóÊÈ¥,jÑBÍaÝJ}Ы©‹Ÿz+BÅ8¡'Pž´dº[¶¢YˇWíÒ2¹»cr‘×^ù Ž…è„½ls˜Z Vr‡Çž¹–¯Ûíî8~·Ìq}â¨ÙÊí®¦OE¨¬óZ6ŸúÉ0b.…=%03 F¼ð8އk޳¾Èù5‡ß2Ú ÝBSfoE÷Ö4Œ?›šÂxPÅ””Ó'™äAÎï¤ËÊäjåS¿™G3pç9Ziiî„‚Z3öÐ<ÜÛÐ.ú Ÿ¿WøQøÙgÚ\Ôõñÿ«øéñâOøç#þ\úÿ¯Êï[aìö¶î9¼Þs¯Y·7ôo|‡âýB!f(¤è¥h‹ b„DG^hYôóÏW¶ß.&¿ÁçovºMNendstream endobj 68 0 obj 1274 endobj 72 0 obj <> stream xœíYÛŠÛ0}÷WèÑF«ÑÍ„À–-…BéÃ>ìã[R—ØÞµnÓ¯¯|ɵ4$©Yü`ðhÎHsÎHüŒDª§}‰qóÕBÓ hj<PQû ôÖ1(È ô8 •Á™/ jq,ˆDçÈIŒsÊVŠ™l8øæ|0†³Ê{R`°ÐÛÈ óî~àüÐAµ $f’P¨ ¦{; XÙÜt\?.ÝlR#qíÕ0jU“z1ÌI•ˆVX«H’bJ CC=ß}¡ªHÚ€u¼ö£-nºˆG;è:2·ŽD_ƒ‡^é¹I”øQîβÀ+ã,EwÇÒnÆ“zô½ûé³diQˆ×s›bË),QGlüOÚ¬?ÚOç‰ÆIñªý}û¾êTüìŠÄo¿ÕñWBÕ £WõïQ?éVü×tíyPþŠõFþYO]ß+®]þ§óJÉ!^%@¿x­Š«^A\¯{ïj´â•‘ËñZ”ù<(çyTg«3~q˜ésËOCÜå ÍÆ,·Q·‹†÷g3œù½¯–Û à½á³.?½T²öúUnE¢°èÃ[W)eoÖ»­›ô¾h÷6dõ g_ðæâå¹·èút‹“â|'ÛŠ×Ý›Ài¼®h‚™—7l.¢âÑ„ÇÁásS]pŸ-æ~î¥Óî$;]ã,«;Fª°%¶²ñ¢¥ígó4Üi¹l2w$}ó§§àUn™¬ÇäõºÚÿºw¥–î?a«°Qe:}oôÑ˃ïºE blQ\»þ¿ÿ7¼sŒ/úùT{ÅÊendstream endobj 73 0 obj 695 endobj 77 0 obj <> stream xœíYÑjÛ0}÷Wèѳ¦+É–¥ÐÑR:èÖu†2Úa[Í<§µ•îë'ËvÒx] Mâ†Pòˆ¤#霣{u•[D0 R}šïxb}8hTX¬[ L#j¾â úX»(ˆu? UCpmÕcQÁ±K<$8GÁĺ´P.±”ÌæÎàGðIÃê¡%.î£ ©ï,{îï!Oúûƒà—å̪¾žnõÕøº§}xQµð0[4„A3ˆ›6½Ÿ@Óvp¼Ä1aÒoe>‹ËY®ÂòþF=œÖñ®á½Ë§g>¨0@ûow„Y4Q'Ó…—à©À\ö"xFðá}©Â"ý£çÝ[FË4±‚ˆþˆ¨ÉPå#tjmtjÐJ}´Ç‰»¿6ÔÅŠ“¨ŒBÂñ4ŽÊtš¡ÃzÇ^ÃY­éEøå,Œ§YQˆ˜µ€O1¸+JÉÎ(НÇI±In“¤üYIßI“tR¬/êÍ5õ|Ø&M}JÔ*¥ ··szi‡¿Ôµ£<†ceRîºÅ­UðaÁ’-З©÷]LÝfœ!ýz˜›Èß\B¸Á“²é1rSì³9]FíRAÏópY-U/KŸë•Ey™^F™¯ýЂë}×kOã4£{U\Ùp50J“Œw\!ß\ñª® þºÂëíúûæŠÇ]Á·Ð¢Ç»{”çÑýÆ ¢ 8‚ÎS¸ŠÇQ^[b‰Û'ë"ŸõXpΆy”V¨7;FO˨ÄÂ]bãN_c†ÓY– ½îýÃá^ÍÞ‹¤$ Ù±/+p¹%OOξUÕyšh³Ìcâÿd4GDövDÖ8;:VÖ ëˆÁ&ÝZ?+]¿°®Òf¾qšuaWQ¯[œŸ×Çm`þ¾\`)V,:FÛœ\Œ˜—¶Ç5(#˜Áj´DåªVß¡ð0áÌ=Úãݨ¹ÑPU½±löYìäspt|tòMȧ²xš¤Ù¨‘Oê,¼8¿æì…E:ÊT²|†„VsmosOÆ.£+íñͳ?]ýÝÖÕ^W;¨ë»W=¯³l+N¬Ûã;]Êv,Í<°”ètR¶Ø¿a1)m“|M¨ÞÛ{ÄFyüQBÜ( ó)¸­¼ÿþMtX_õç/V .endstream endobj 78 0 obj 872 endobj 82 0 obj <> stream xœ•XYo#7~ׯàæeZ‰n’}ÚX“M˜Eä0ö@ $JêMJ7eÙ»Øÿ¾UEö!9Ç.ü [,ÖùUÕGÿÊB.Xˆ?þs[Íî~JÙ¡›…ì0ûu&èùmžZÍ$Ùj rBâÁj?sw“iÄã0ai±U5{ –b.£œç¹ âåüóê³eÈÞ^Š$æ"eË(c«Ý,øúÓ|õO0 G"á* %hăõ<‚ ѧȃË,X­M½mvE}`_£T–ó$Ë3'õ|‚»Bˆ`õÍú\wÅ¡6»DÊE–ÈÿíCè=ؼZ³îŠ–¡ÐÝOCuûÙ2Iy”†Š-UD7èBÆ%ø~4(‡< Uî’¾Ç`ל {ž :J³µMË:Ûž·öÜ’÷äº#®ÂÈûq ŽÇýwVe‡ßKžfê¦bþd»Ëÿ‡© ´-¼[\fʹæ=‹ œ±ðž³GÃöMY6Pjžgq\° ó^/ØSŸxAØiÈA‰wõÙ ¶s0—g>.ï8dmË_pö}cQ0<Îâüº,3sK“ 0å®cº5¬Ù³sg˜m˜f;³!o„Lx¦úžÓRU@£D_¤äRäÞNÀ?ö¹¤Cƒì#°Õ˜=ÅU$åè¤ô+ÛP˜Ëj«TÖ£Î×ݵeucFá"È"á#¸ðewlÈmß~"„4ôH¿œç’Д§bh¹ÚÒrKaX¡è/`šòí.„4%n÷ì)èŠzk?|æŠÚšÖtÓ‡É#ç Î”²îiÎ]q…J ;C7=B¹Ì=5|ñílõþ1øÞ˜¨ h²¦¦ra]ÀˆÑÛ#.Ñ8§ÀÞàC½c5^ó¿ÔÍü]Ÿ‚$áBõ1—Ë´{sÕÏàX€f ¥5Ô+S’m ¸½<¤²dЇ T»w/€$`<‰8Jä1¦Ïà³;§øÎg‡}/M¢Áø rhj«m‘CÄ=^û–}O¹$„©rÕ÷YøhYw>¡ŽÎt¬h[SÐ-%)0zÓ1ÏzÒRbl)À„Ï?…_,k×UCob&r1É„yùíö„ŽÛZÈg¥-$#)õks¶€V™ªi_P®Ýú€1¬:wöz,{ÅÿƒÍª¨ËÛeŽ8—IFàtLú‚›Ì™º\.(Z2}cñ1Ø6Õ©(Q5Ô«Ÿ¸Áß8sù¨ŒâøK|_mƱ’œýÛ—…f µé¹™Ä4,©bÇÞotgæËÔ·ðÝ;5ÔtÔqÚêÞå±»z“{D˜¤Ù4Ú*Á¦\—¦~` >öH}Vš PˆEÂÕÕ}‰W¥ýŠÄˆ™îºf{/À)AÓ$§*£kGWÞÈŸl»<w0ñgwÖ \º—x! Ã?‘ÖëmSÛâ@bgùkáú\­wEÕÝ3Eá‡PÁöÌRßW²öõd@÷ÎÜ+‰ÂÏC;ëòl~Ϧ-kª›»âÇVƒåürê˜tD B—+<€#Ùt½8¡1$_NjGhìi;þ‡¿…Q€0x 6&Èè $ˆËõ¦Þy ÜÀ¤ÜLÌÁžˆâó<ܹm’EÁ]Ù÷¬80d…zãh&ÓWð<ö&€xÓœk¢ËDñ$£˜’y`ŽÃ¥žß½X†é¥óŒ'ã2³´ŒÍ·«uêôBôëŠÊÿ6©ñ§±ó˜~vèâ ~MòÚ};R»xè;Ì¡î'GS±T^?r."ß}üáç5ôÚ¹2;G"à ጌl- y¦[óœa…“j_êÃ5hX õõ\Å|4ö÷x,·]w° lÀ @r ÛV¿vüj9 cîÕý½™dhD4ã -Á ÷¢«SéXÁRä1Ðõ¬ýÈ{ Z˜&ÕQ6˜\L×Z¤Æ^^žñ4š;L¤×Ô‘f·`ˆt¯ð4CåÊ5pÿT¸FüªLY  ô2Ã*:z D=NÔø »è¹ºŸd"¨ÍHH%¾°¢ñ•w1ú—SYl Ë€ëô£×–À…å·>=ŽrÚú æ¹|œ—OFm‰ÓlÄé„Ý_xr· Ó]ïux08~B\ŽZÊ–¡'ò]ïZ‰œÉSÞÌF7Tm;‘å©mœøã¹€¤S\¶%MxP–qÇüÜPá·Pœ_Às`„šZä!M³‡í§H_€ÞüY›˜zÖ?2‚¸TЙ}›,ì€ñ ¹s8T‰±Ÿ³Wq Ï¥uÏŽ ±s ^×`G@¯ëÆ yzãÇð¢—ÙdøFKy C`Db²Å¸É “sÁàñùnTÊ0Œ§C&‹¹=oÿ¹ðÍjö#üü½àn endstream endobj 83 0 obj 1909 endobj 87 0 obj <> stream xœXËrÛÊÝó+f'Ð&G˜ÁÛ*WÊ‘¬”RÎMb+ñÂÊ@ 7 @ãaJqùßszHùVn¥¼°¤º{NŸî>¯Ì傹ôÏüŸí—#¶ë.Û-¾.„:dæ¿lÏþx¿<`÷ž’î· ý®`2òyà†,ò}v¿_|qÖb)ý„'‰ç„ëå¿îÿ ³xu-Ý€‹ˆ­ý˜Ýç —Ç’ÝñüÐ-ëª2+ئ꜕5ë Ö5C›K¾\±àI8w5ËšºoÓ®_Ñ3mÁÊŽÕ +”éùÜ‹•¶/rà<`»ìÙp8À‘vÑhå¡oÙƒSöéÃ’¥m›>Ã+,ïEÀÚÜW&ƒ:Ú¼Ø.…Ë]7Jœt¨zù±¬*†›(³ÙжEÝ_Nʾ "#'­]ßwЬoZBDÝxX8*—‹5r©”ð(Ð8ßÔ-Lâ.ã$öÍQ­ŽTZ„àNôÁ—¬¶ø:]߭ؾÊÍ–µÀ WyzTYZ³=2ôØ,eÀ]á‡Î‘M5¬„@†±ÂHÇ{ù1fåv±ö(û qA¹õTžÎ>”:2_pϳAàËz«œ¹±pšvŸö%’˜ßOàÉRD@(Rñ·¥ çëJzJyBÞƒ×ÖÍZ(J:7Ÿ'XÀÕЕ–KÂ:Šwo‘”‚H׫{JpAÄÂÓÛi]Ö;BŒ~í‹vÏ.–eߕ޿4ëzä~Š\¹A'!œ_šV[.'Ãn+龃ä!Å‘-_„ ·f§¶˜Ä¾O³G¦pI+ÌÞœa §•Øœ¶¥êH âõêúõë3š *7ÝdG×鮨‹VWÅ9At\”¾&7÷Är•]e 4ÈIw,Ÿ§·ó$ˆqF:ÞŠ=¿õ¯(¶þ8C„Ø8Þ1çsß›ìe:[]ºg¯h;‘ŒYsn5ž¹”¡iwSOG\/} Çhª')x(¥gK*¢w*·oØý#µ‘CÚ¼tµYe'”ÆÕæ*ƒÖøž_ý€6#üóR+LÅoe> KÝ,ðu‘ïØ!›‰¹¦ú1”O5Àl×C×;vÇG4þ‡„ úvÞ°ï?Øô·sR­×uÍWôÂüJ©¢ÍlXëä!mƒz®'üéÜ”êï05Ýæayš&Êgi@=%Á‹48íí<ɱ7ý ô]uͬ´X%AÝT‰–b¬´§C[tÅÝüeÑ~Cp?‘Î\­²Š‹Óò0Å ýcŠ5=‘dkpFú¨GËòßÔaªNH‚æÿ p²OÍD8ª¸­€€¨í‡×>>´<(Ý¢„FN-ÅkÎ6Ï™ýùo5Ö“º?ÅÜó-ãWåÒ£B뺴›Qž’šÙcÞ=NeÆ;Ù =î[í3… ˜±‡45m Š2k/ŠgcTð0zfôÅ5'dA‰oœ‰z ð±y‰—b e6—.ñôšR^y±Qw÷yìŽUfö¶Ý®À2¢ š©§:­&A˜D¡³ÖOŒxp´4aÈÏ Â¬ºòô"IF’hǸkìTJDÌýPÚA¿íçW’ñËÀ¯fœ¥[ª[aºË3UüHS™ øÂóEpdÕQ FhƒªHõ:€úùF失uv¹óMˆöŸipKvKM®Þ¡÷‡> %'ÛúÚmI‚ûDÜëQ!ßZL#ÜÚÀ¾¥ ¹nêÒ¥}Cêу|õ*Æõö`øzÎ÷ËiZë(¦^ýÖ9A‚½ºT)Uû Eb—ŠªÁÄܰ·,½b—¯^¨'i^TA=]Mq`n^Küéß=ˆè)®«ËÙè#½1¶Žß²g“üpR=G˜{Zz š F—š/)ØÚâ×"£¹¢>9åEJ·{4½Âu¯Hç·WàP"5k‚ÂHqƒà¬ ÕE†k§­Zôíç§ób*g›£ú0õê|Ö½)èr\çmpë³5^Æ‚~ú[üé&€N ¥âO,1räLùª˜ÆÙ|^û!Bf‘@ÁB˜Ó•6Åø‰lG±7óo“šŸïÌ]AÒÐNjš /Ð:íÛ'Ôâè<üE©»’Òwb¦ó”f”vßgÆW§¦õÔ3©°®ìzšûUA/“i=¥¸å²—X.ÿܱN˜ñŽ-@«Ðˆ^Ólvc›¸ÓE ”£B=·; xŸŽ‘žU¨YÿRõÉÃLצ5­š_øãjç=+¢ýblMßÄOô±N4ÖŠy‚ý%m!é¤ëóV#)öúýýâïø÷_ï Pxendstream endobj 88 0 obj 2492 endobj 92 0 obj <> stream xœ­YM“Û6½ëWàfjKBð;·I¼Îz7®dm¹roMQ"%1¦H…¤,Ï¿ß× ¤äI[[.{lúãõë×ð—JøôËþÜß½OÄ¡_øâ°øc¡ø¥°?v'ñÃf¡e$6;¬Sš^lö ó­: eäÇ" C±9-½µZê0“YxÉzùŸÍ?ôã>_k?’*ë0›báåýró;NÅ+¥d…´)^ø2¢® ¯ju).}Ù‰~ȇòT6ƒÈ›Bä¢+‡K׈OÞp,»Rœòg±-EÓŠs×ÖíAìÚÿ,Ë¢,DÕàƒºÌ÷bivCÕ6Ÿ–’ÎK“騀}ÛˆáXõb—÷åŠÖ­ƒ4€J¬^¦-}´Çc1޾.•/}¥µk†– ê/x{=V»#­Áb±_*„'MR¯êúAôí¥Û•âÜö&Ú½ñ—ì_á-Ó]j>c ÷Êþr*ñ8è‡xíKÍaÄŸ?/¼}µ|eâÉLù*¶²sth^ئ§-ÝaõøÁZqŽ” ýÈ8úv ŽñÃM_õCOö¢íÄ©…£wÎô+Ñ6xzl/5rÖßn‘ùúå@T=»ÆFoþöè¹£m‚ ´M_–bŠ®¦„±Ù”½s1RŒb•i‰@qH¼¯¥Ã`&uš¥¡}±» ùQw¡ùî}*(¾{Â1â0!-5˜Éd >ö,­€– KgaôŠrkN´w9<í»ÁxÛÀàÈ`¦íN9;ˆ,›§~¬Pý+d¢t攫vnV™ëñp›B_a8‰¯Æ3(\u…üTÍ~<{ÅOÉTx¡Êym,œõ³Q+ á¶í/5U\Qewª„d–?›9aò23ÖÛjÑ@öqôÉ û'B¶Ëd&“Ȧë çQË8H¾Í%‚䈥‹GŸTóq„ɺyo °6`¹;l®Ä›Ê¢i¦nwùX¼3HÞŦ3FÉD$i9"iUEhˆ2ïk~¢ÜŒé H¥‰ G‡éÃø/ÒüŽ À cÖyÓ6Õ.¯Å^ÿ`Yà“·Û/ ™‘s}Z2-œ à«0²;›#c³·-÷&Hæòmx8‘T;È‘r#‹Mc" !Z–~Ä#@B£Ä"ðÑË«e€‚zýed‡ÝBk©•]ä»Ç ³&xsž ;îä„D±Ôú}Û çæœ‚¤ü Q‰{n2¤AzªSUç]ý àj‰³_±ŒR_~­ª¥ÎÐUèí‡É/•H)W!}KXÃä¶#ób?›…‰¶ó3¯ïfQ¢ Öz\TörǽÑá˜ο;ç÷[§ëê³CMYsÃëJjOܤ r²PêrLp]´ Úý$ð¾VƒØ'Ÿ¥¥³‘k‰bvŠ×¨…W‹ü«ƒ[~½ Å})~Ù‹0w‰ø4=˜ý«aÞHyÖþoHsÜÑ‘&ZˆÙ÷Çöt¢^ÃTI¥È4fæ@´¸þ‚æÂ(¶_¹)ŠíJ\«ºF[,ª&ï*çÊ'êPu¬ ¡z9â…àqK-àÃéRÕ½Çq<Ú,ƒÙÖlbcª¤A›g4Rh„“ûþ{Q´ÄÃ-©•kÕ³˜(п©þ™ [&äž¾D¼]Ž=özÅ¥àJc8NôÍ™ýPž_Án ¡5RÉ,½aóü|.óŽN9æ¼hdð0•qœe®Åðê/nߦ_Ç2IÇ6äµ¥Ý@GV8f®Ózû½#ú4á”Wî£o ãRjŽÈº! Gïñ’rûîÊ3C”JbwJ¥ŠŠnŒH3²°z±2 uòRÿž1TyU£,óm{«ZtœÑßæÝîÕbzLˆ&3£kêw3­J¤x¥ÊM£ "ðõ7ècC/um¼ c´Ô ±‰uóž(< y³±&ß Úìk+ߪw µ<ç"`¥€=ΚŽÑ–ˆ‹’o¹™dQ02¨–¾]ǰÞ±ÍÁw*ÂxŒÛ2†Ú«ÙÚSþ™V؃ŸÙ„½r˜,IºÎô—¾Íf—WË(40µÓ•u™ù,Ž&Ý:œPå]Ë›ZQ$:}}gè ½®ZØ2Ì´·Ï§°ýLúÁlŒÑúŽ“iìiihʉÀL eà£¬Ž¨s€×<› +b¦L–ë(¤ÖœPZZÓgzümÞ»ñÅŽ-æ+IüŽV•²ÏFö=ÆdÅéXvi˜ó»ü|de34 jÓHË5­1ö$Z(ûSOþ€éúêt¦ T‡c߃$Îm7—tlò¶$}S–kk¨WÎ ̺<“Ù•çŠ²Š™á‚l/C•¬Mxð‘3qW–åÐ&Gàè6¢D&Éþ^s;rOОŽÂäËãò¨¼çsô¸Öé4÷@P‹5LýHvš&ÙÜ›k#~¸z³Ï¬ÛÚ•Ž…ƒÀìöñŒhwí倎:ÐȤ½{ûë¤ b­Îh•Ó$iR»-I6Ÿªa óI‹×Z?ÁÄn[–÷ÛÓ›_Þ¿{â7k40–M([jx¤MK{؈‡)D Wqd¤Ñªj¥WT!gÓ0‚Švª/ïõoÓ^± bßɯ§‡¥BèoóD9<}adazóhIÇs­/$ðo_·%ðmcÍx+c5¶Tïá§É‚¥ïþT6˜ÆAOƅԜƛCÒ“³`$2ÕʉL~1»ïèöÅåtæ>à]°œm‡Çün‡YšŽN†ÖI4þn|íΛQæ…¹œ!¤Á‘ i삳h`Z\Àœ%:XúD(¹`NÈ?y˜vIzðÔ»'¬âÚa²ú|õ…çï,‰9 ÔÚwm×±¦¸íÑ©bKLìÞ´f–Éí&OGß]9/Ä(r÷9ȵŸãPÊ4ú»#/‚ `&…J¼Úv˜€½WC‘2NfwVQl%í¹«°Ø>¿ h‰˜sѸKß6tæÑÈC>“ÁŒ^†ê†•"ÌnŸdjΧ4™ÃJù‘K³oׇR| 5Êþ1ÎFÄ¿açÝ çlÄúiÚA\»Š“kT¯›GM¹ÖŠÓ‰Ô¿ÌýU“¿¾Œ3s(åõ7¶.\åÏ Š–ïPlÉ\³Mª"Åœ«‘ÇeÕ‰ö2œ/èjç Ö;Øã÷ð Må ŸÒì¢î-Ê›ÑM“R¤=uèLi–¹”–sªËt¬ï,eŒ„3”¯mAý5«$ê€H œàø†Ž½EgD锆hç{àOåÒ›[à×¶ª|G?ÿÞ€vf ¥Ø8Ø*в;[èjÁúi¯EI°ÄäæúªY¢‡£}LOÜqŒTF« ¹…Ú1PG– ça&È€öÝÜÈ$šJ/ÅCSØúÒIàtÕ¸5&Ú¯yï7V(À8Œ§oæÁ¶Îñ-ÌŽ¤ä-Åš;=˜¦³hì(ÿhÍ¥g–’ò½%Ö˜›¢Õ7c¿»8Ð'ÖŒn5ï%h˜JüH"Ï0$:DyFÅ`ßøîvQË@¬]W¢˜SWäÈÙ3w¦°&pÖ@Ëëðf.´a™"r¹i:mUºŸ©ªîW/‘G† #m6–ëCc©Ñwcµ÷L’î Ê\ÇRrÛ•fÎY$%Âôî‚f›ï>So—\—ùPm«ºž¹ër¹¶ÛßÑ{‚oqÙ¡™@œÖUÙ-£ÈÜ¿K;&ÇVÛóýao»AFݤi*]‰@‰wy·; íûÑüF Ü,üÒÿ8ý}³ø7~ý~T3endstream endobj 93 0 obj 2852 endobj 97 0 obj <> stream xœMN½ Â0Þï)nlÁžwפIWÁEpP²‰ƒD­ZÁç7i«È Ü÷; “ ç[0ö°>:ì^ÀØÁ2‘¸@ìq@ÉbˆI'š‰p‡Ù+¨Îå1z8•”jZjÛºðUy»û³J¶VÊ–Äaå´Æp…b¼•á™:ÜTâIx—Ò3÷–ÌMRgÅü&ñ+¬÷—1>P™í„x%ní<É21·ßIÛ‡tÿ7ìendstream endobj 98 0 obj 176 endobj 102 0 obj <> stream xœÍYÙrã6}×W *„ óæöÒãTbgÜìéT¹S,Š‚dN(RMR^æës±P¢–dÚщýà*n>ç®ç^|A¡ÈÓ¿îo¶}w'Ñ¢yh1ú2¢æ&r²%zÔ!JQ<Ù—(b\A9aˆâåŸßÞÄ—7ñ‡qüŸÑ„†’0¡ g(žî1%ãIx$ò"|}ßýˆDñíÅÇóøúöfüKüýˆR¾ /„„q?0yÓD-z€1¡‘âi÷˜õà‹½»ŽÑ…A<¡ÄŠÙˆGÄ÷YháãOgúCž¾A%ñ<¹wWúãDˆ¿˜kŸ¯Ç:¾÷ØïQýgeH2"¹¦â{[2Gåi¹åiÞÆ`x= æe9­ ”—óª^¦m^•(oZæm«fúU*úƒY¡#Iýé ˜Ûñ£ã‰Œ8 8Ç·cÊÁ?Ī~ÌÕ].IQ ï?Uc@І>žçæ9Cݸ²#aÉ÷÷Ø q9¬Ïséçi޳‹aŸ°-ñ Õª¬ÍËúv¾. ç¬æ[ôOŸÇ6%üMb´ƒmþ¡C x}sÕƒÄ2–f|ñizP…¤`}ûŸÝ]¡´œ¡¦­óÕgL< Â¥¾}Îuä RŽø$Øúäò" ª"¥8-Ö©ñNQe.’Æî…ÅÏ«Z5 \k¬—$ß$ßp´õåì( SLÂ=&qü Ð|Zïæ’`$pÎ[[çAõôdW4;ªÕJ?UFŒ½‘¿:~Ò7دýA¯ ^ÕéR¡ëm†ÿ=Ú–a´ïš _ì®Ë¼ÍÓàCf¬³vBZòm2ý÷°;ûè{ël½Xª²µ!¢S²#/ÑLMÇÌ#õ$^/’¹v%eëþPÍ¥‹—ã°ûùp~}‰Vu•é¤ÌÓ´Q3ÒCBÿ°9x'p‡Cè>vˆm^]üo„õOjS¸vöZt£±£pƒrÇfsëxá\3Ê|¸jèÐ2ïH  YmBõC›f¿¢Ÿª¼lUj•YŒ S ApA-wZ?ªmAô£[ÍQ¿ y]-7Aî ¶äž ^œšoÇÔ–©)‡˜×;rÓÕâ8g¬A³§1Õ $Çi=×íLë®?·ª4Í ”‡½HYÊšväA§N˜¥Ú§§wuGb}ëf O¿FHèßÂÂIì^ÙnG£®Ù½ß¾Qî%ýuà‘Ø“éTÈ{¨gþ? |Š!ºâ†6íqfoÂÙŽ–öº4)iÕrU¤­²Ü ->(=9÷ ñ¨W„€ûW©Ï?Íé$2Ô³"mš=Þ¾õ¹ž´ðùïEzðzæfÞ¥P±uü˜k"4ÒÆI3OJ(Y b] 0wxjÝÔ1b¬G‡ŸœN%z¬µtll °áÉéô\$HßCâÔ”–iŸ’? ‡øÉ“Ðñ;ŒÖCYUÕ3rÆŠäŽwê}ÆO°›Cák)ÝkNzd1`0­f/ÉÔvyž¨ð¢}š ¿†·¶Hœ–݆œÜ‰¾èÔÑgÈ*Ù 1¸³fK½Õ5âÏ袬ýRVå¤YäŸÇVËèY^D_¥eàÙ“k™£‘逋þ\J’ƒí )Þ`›ð øÏ>úÞ\¸3¨'‹£¿…Cî@ti#^/( $œ_¥—@Ÿ%ïo>&Oy9«ÆLÇcø)iÒýÙ•S7[@²zòÅæŸ0ø¢èB?3³Ÿ„—BŠF'~dt“¼Zi3IZÛ*©ÍÝIc}V¡Kd“4ùµ˜bfÈ’ðL ‡\ÂvΣíÊz÷6^“äòçóËŸô™èÅH‚¡Ägï~¸L7†›ñ¨ íPvÙÕßwÉþQž`Wµ²éÕ jŽÚµöAa6¥´;âøƒ³ôo†š•ÊôÐÇ—NH8_ø‹1Ù/€Íw¹d<´¨ÐïVËDŸséíò{Ôl3‰‘@º&…Wª(òraî!hÿ zÓÔÑõ£^·–ÿÏ wu{÷cR«y’Îfµ9¼ÐK$?6(0¡‡Å_îlZ”™Ñª½ 5kÄ,¤u·Âý…ªÝú€ ¶óÜÄw~9X•Å `Ô{·B¡ì¡Ê3et~Λ¶Ûi õô± ¿ÝÛ.×E›¯/ع®ô”·¨Ñ¨Ü,¦˜…z(™w¸ë–ý³”.0„^?Tկ뚂©! UÓèuç´PK§¾†P ÒµÂ*?„Ê õЇõ´NË….E¡^—E>~Y)tY¶u®ö`ŸT#éV~þVq +Ì è\o,©4H9îʨ>`HË6wMc´8Źk?¶Wâ…2MôY[ÿH*ꤾ¡Û:èo[/%¨Z©:m«Z7-SÛÝAî@Ùèh…„³äÙ„Ûù$×W/ãÑ¿à÷7ÆhLÄendstream endobj 103 0 obj 1860 endobj 107 0 obj <> stream xœÍ™YsÛ6Çßõ)ðHNÆ(ð«“^Ieòép(”ÙP¤BR±ÓOßÅÁKVšÊ¦2µl“„¸?ì‹Å'äa‚<õ±¿ÓÝê‡?"´mWÚ®>­ˆ¾‰ì¯t‡ž®áB!h¯Ì ‚xˆ9  9GëÝêƒaî^E"À~8¿Õ(-eÒ v/Ó"w©‡=ON‘&]QW¨Îѳ'OPÛÁ¿)ÊUÚº®ZQ"0 àëlÅÕ_ëÛ•ƒûƒ"wý×êÊ~ùaêë=õÝÊl1šýkÑ‚ÁeYT[eâs— ,8§ÎûøÚ%ÄÃB0g§uÕvñg—úp—R')R›ODtó0ìK,†" ž{EG„.ùh&G`Aº (>7V}pdv+,æT×ú9O=DÁŸÜ÷ÍSvnº®)6.QSá:‰^TiÁìo ŠÃ0 /Å{<¢xàVØD_ö0cš@ÝÕ¦8Ïß«;š‹€ƒEHzúøõ›xÓH—Ø#~èlï4IÈÀz&ìðå ¾‰F‰ñ©˜L?Çî÷Atžp~}õæ-JŒC¨§|a]p‰xy0'Jr½‡8~ˆƒú@£hŠ:Î3\†{ßÕGƒsØ„‰žËd½?{éF ®ƒê® Y’A œ¤Je\Ö)„èÉL" ÀúrlŸ=oÂÅÎårâµiCÝ$˜›fœëÇA˜|ß2)XÁ˜)(ëzؾǵV¤ÔÖš‹ zÈ¡GJõ—Pª‚‰7F­ÂÃ\0ól€ Ƕ¨€¦]k(ä€ê‰Kù˜Ÿðq°e—å UÝ÷;Â,:SX-¬æ  Ñâ°=& ñÔá r_”õvp(W•¦ª…¦ŒZ>‘}Âùò Ù\´Ñb¢=TM]–qnýBµù3I»º1´ZFË"?ZÔ£='ó&pò%8Û:ïn5_$Æz¨ͤ‘ñ¾€Ú¯¨dœÉ}wcPµ‹0ó¨szÀ š;RœŸ{¯MºÄ”{Mea0«wkQ}L¶2®’4(Z-D„8âl¯õ4PMÎ}o £ P µOfQô‹‰uðB(_‡›åÏó+ΓhAS-ÙÄ×ÄYÂ8‹,Hˆ„u—?%:»œ9IÄñ (-k£º)†™è1ñÍtPLíÌ#T°yÙ2ÖŒ?6ÚŸê˜K´¹ªÒ™E¯óÓjæ³æ¿Otߤ'GÁë‹{Ålôý\Õæ’ùÎm…žìÑçÿ‹s¡C7ö…Ò ':Ù…ºüb½ú>ÿC»endstream endobj 108 0 obj 1624 endobj 112 0 obj <> stream xœ…T]sÓ0|÷¯¸á›©UdËÒcù(f õ3-Ž­$†Ä¶ÓÀ¿ç$ÛM˜´ã´§ÛÛÛ]ù'p†ÀÝgz–ûàz™Á¦8l‚Ÿú"Lr/s: %äë`ìA@L) ÊdLQe„ïàͯÁ6}Ý6= -¼ŽòïAŒ,U— d†;„¼ Â/7®È]Ap¦…cá>\ÞÂç9g1´CÁxô-GLˆ G%FT,ÃbêOÇÖ»zW—tümaÊ8×iX¶uÙëv8¶ƒ»ßý`÷ý:´™N¤†Xšêæå]¾¼‰$Ñà†¯ò¹CL1ÒP?µ– †ü„ù¶î¡jËãÞ6T¶/»zeI‘­§Òõ™æÄÎ:-D*˜Jõ(ƒC3í/EijYV)œzªDÿ++fD=5ST]4ë¶Ûy¢¯Rw2–ÊY` v.ÓáÛöŒ‚,Iq2‡³$ŽÕ}耞ÁCøaÂŒAyaãPƒ­àÝq÷DvhŒ|ˆ˜×æJé¡ r"øúËy¦b*S3Ñ+q³¼•PuÅzM“ÛnúÄÁy9î±è¼s‡Í•Ýù…˼YÆL¢æ¤žNgbšÒžÌAÝÚÎBq8™ÅjgY§.µ\ø»p½X.¾BI¹«w$ Ø}=Ðð ÌÞ ž2¡Å¼sWBЧzØRT|²¥:ãIXIü4ÝÊ}"%Kd:ºµ,(9ŧh Ø þ«…UÑÛ§ ú|Íaõeë­Õú"‚' ‡®õÓd¢I®t¤èF)/ìc]¹nÒ··‡¢£xæÓsÂæ©ÌUÝ÷£1ù‹{º?vZÓËás96JO¿ýqõÝ–ƒã^Òr;Já`‡]ß^\ÀM —ÖT…§V‘ð/7=t¶?Ù@ÝÐOÙv®Nô."Á‹n Ǿ˜g„ž?eF3‘¡Î&+ñl¥t'ÆÓûâ $‡¢+·>¦~}m˜tM”d“>u]»Ò›<øDŸ?Ï}Rendstream endobj 113 0 obj 796 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 21 0 obj <> /Contents 22 0 R >> endobj 26 0 obj <> /Contents 27 0 R >> endobj 31 0 obj <> /Contents 32 0 R >> endobj 36 0 obj <> /Contents 37 0 R >> endobj 41 0 obj <> /Contents 42 0 R >> endobj 46 0 obj <> /Contents 47 0 R >> endobj 51 0 obj <> /Contents 52 0 R >> endobj 56 0 obj <> /Contents 57 0 R >> endobj 61 0 obj <> /Contents 62 0 R >> endobj 66 0 obj <> /Contents 67 0 R >> endobj 71 0 obj <> /Contents 72 0 R >> endobj 76 0 obj <> /Contents 77 0 R >> endobj 81 0 obj <> /Contents 82 0 R >> endobj 86 0 obj <> /Contents 87 0 R >> endobj 91 0 obj <> /Contents 92 0 R >> endobj 96 0 obj <> /Contents 97 0 R >> endobj 101 0 obj <> /Contents 102 0 R >> endobj 106 0 obj <> /Contents 107 0 R >> endobj 111 0 obj <> /Contents 112 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 21 0 R 26 0 R 31 0 R 36 0 R 41 0 R 46 0 R 51 0 R 56 0 R 61 0 R 66 0 R 71 0 R 76 0 R 81 0 R 86 0 R 91 0 R 96 0 R 101 0 R 106 0 R 111 0 R ] /Count 21 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 19 0 obj <> endobj 20 0 obj <> endobj 24 0 obj <> endobj 25 0 obj <> endobj 29 0 obj <> endobj 30 0 obj <> endobj 34 0 obj <> endobj 35 0 obj <> endobj 39 0 obj <> endobj 40 0 obj <> endobj 44 0 obj <> endobj 45 0 obj <> endobj 49 0 obj <> endobj 50 0 obj <> endobj 54 0 obj <> endobj 55 0 obj <> endobj 59 0 obj <> endobj 60 0 obj <> endobj 64 0 obj <> endobj 65 0 obj <> endobj 69 0 obj <> endobj 70 0 obj <> endobj 74 0 obj <> endobj 75 0 obj <> endobj 79 0 obj <> endobj 80 0 obj <> endobj 84 0 obj <> endobj 85 0 obj <> endobj 89 0 obj <> endobj 90 0 obj <> endobj 94 0 obj <> endobj 95 0 obj <> endobj 99 0 obj <> endobj 100 0 obj <> endobj 104 0 obj <> endobj 105 0 obj <> endobj 109 0 obj <> endobj 110 0 obj <> endobj 114 0 obj <> endobj 115 0 obj <> endobj 12 0 obj <> endobj 119 0 obj <> endobj 10 0 obj <> endobj 8 0 obj <> endobj 120 0 obj <> endobj 13 0 obj <> endobj 116 0 obj <>stream xœyiXS×ÚöŽ!{蝹* &hmëÐZÇjÕÖ:㈠ (Ê<Ï!d„$¬$@0Ï3â„ÎÖZµµµv:v8§åØÓµ9‹žë[Á~§ß÷¾çz¼üÈf﬽žç¹Ÿû¾Ÿ‹pG°X¬‰~Ññá© |ãC\×o3ÓYÌŒqÌkl/”ðÏ•#±F0‘Ù`¢[åŒ7·LedSà­W`ÆdÂÅZ±#À6oŸOÀ[ó翳11)+%:2*mæÒÅK–Í ËšùÇ™›ÂS£#fÎÁ2Âã“âÃÒvELJ¥§Î{ïLŸðÈô¸Ð”ÿ÷o®ö¿[Ÿ ˆ€õ ÷oLڔ앲9uKÚÖômÛ3CwˆÂ¼³Žìݾ;bOd”O´oŒ_ì¾8ÿø€ C^œ½d©ôÝeËß›¹bÖÊ×W½ñþ›Ì^ýáÜ5óÖ¾õvÐüwÄëÄnbñ±‡xŸx“ØKÌ&|ˆ9„/1—ð#æûˆ·âm"€˜OˆwˆýÄFbq€ØD,$‚/b±™XLl!–[‰mÄ»Ävb±ƒXNxï;‰Ä.b%1‰x…XGL&ÖSˆƒÄTÂ&^%¸„1`ñ’ÛKöñ«ÇMØ7a`¢ÛDõÄÏ_Þõ²n=)fÒÕW¼^©žì>ù›)ASîO]4õwo÷’Wç¼Zòêî|î#p,Rfsÿš2íØ´aÞžƒ?‡Æì¹Ãs—§ØóÂôµÓUÓ‡g„Ì(ymÉkFA¦À*èüU8^¸[x}æä™?Ìš6kõ,ɬ&hœ4œ0°—™ådø;¸ÁFeqÔ=d`nð2IttT¾Í‘giù"xÀAeÚmÆÒÂá|‰ídï|[’)Hù Eœë¯£EÐLÊ`1R°Ò¨3‰ÉN†{žõÙ¸é »ÂFÙÉýÆìÐAÃ6êäñ*[+ OÕÄm¢pJ»]ž} Ÿ–À£vê@¡Â¦;EÃ,êû ëʼnwl<¢T†Q´"@ÂS&£EotƒEr@ˆô”nB¶?Ÿ‹hdÇ{äm.Ê‘ç´e*$ʬøHÄA^è¥]OS*>pÚÍ­ú=Ï΋¨ù’¿"!d¡e<´í[:K“˜‡#—:¨=b3¨v{mçœçñ~@3ÛËc„²²•Ѻ< ÐÉ] 8í ü‹$҇¬çÁ9pû‡NÛõþ¤‘E “vN…œa¨~RÓÜŸ•Lã>ÑX•úuôèJ·N&_•ùŠzîTv¶u´8ƒ“ _ÜÛ_ŸdÛ^6XRY\SI»ÿR[eï8æ Ý– ¡uÔJÂèîO`@Ý!¡ÝŸ]L«Ûé öe=’›–» Ф–!ìqƒbJ_UPT®ï×óÜlãÀ¥ž`u`è|«¥l`–6°¿…¥ß²¡‘9ÌEÓ–ÌG4ãÙ\8NýñW(„¼EߣW…²Dî“KóÑkˆ ÞºîhDMO†0q0û6ø„þaàêÁ¿ o ³G|]ÅH‘ƒºò\ ”yr¥½2xhLQ”©Ë•¥æC(V=í@­"ꤶTú3š§!?Ú@éÞÍÉYœ‡ósÉA-5Ȭº4ô§à<˜qå뺪3c9–ö3ïaað±G&€›Ó9¤:#[ž r€Ä() Ô†}Q2?1?›²è‹pôt›IyP8E…ršv?2Íܦ ÷N­E/ ÜѸë6ôéhKs'óe'ëù0CB»Ìv’¿¶^½pãRç7à'ðmÂCßó[>F¬ô Qµˆ|¤2çþ¹ rù: }˜ëÜæb󱯮gGŸ<Ü×»  ña+Þ?˜°W¾ ÐGä@.„\a¦4°jžÂì'l8Ê|È ®‹·Á O}±Ñl4åæÒï‡Î×ì"¼¾oV¶W-†ŠRjŸMeÒöÑÌ÷”BÏÙ€¾à‚Ô<™2'=+Fâ@Rq¦#¶)ã:øˆ†ãÏÞýòjsÌ6Á$b‚ºÜ -]¬¿ ³™ïá‡ÜD2hVp zCG'‘ouzÐMCRO´%ò’Ut5”¤‘ò÷¥òZ-„)¤¾©  Ðp:΋Ö)-[J×’ùð Îhƒˆ¼«±É ]™Ðn”I7bp1Ô$ø“ÖJ'ëþv¡TÙÉ­†ìRí%¦S-ÇN7Y4J«À.±iJ]c/ohÍpF‡&¦oÜ/ü ¥1ø¦GJ}³p9K1CÙ]kÉ"#¥ P«½2gÿ¿Ra6o™R¬KWá-ÏÛ²ÑØ §áŒÿaË^”î=¥b­÷C«ƒZk”–êîÒ0Φ>וImïãñ•Ur'³¼zꙫpÕíiH·àGÜ<øGAjr5ùj Jƒ¢0ÍœV˜ èÕ>}[Ž|$ŠiÏ,OqüØÄÀÍQ]Ãi‚l´¸„4pDîV`ÓV» ©®¯ËsNxmèöéÔÖÝBD\O,—Ô€z~osýÀŦ˜%Õ.ŒJ{˜ßzX-dfþÄÙã"sùPcÎ5¬¥Ñ{Tìî¤ hÅ\HÂ]ß7|×JÐwêZý-pœuE6%”%×É\ÉI'Õ™Y²  ÙÆ,S°ý 9c/“É\tø­úuöonþ)Ž_8¹½§†!”áŠÕv±€ž›•ƒÌÄÖm ]3ãÏi²XkÔö®ˆN+TjWJòõZ£–>‹Î‘+š_:ÕU3Ø*YÓ“³sÒ?BRM»¡^hçÉ~Øádý6 / ³°ÙA®+’Ûtwh/ \£Ň®5;¨?î0{(ýÝââ&LrÍ"êºX©_O#t³Ù¸3Vé±U\Ý7ÄLu²>y7?ÁÐ9ÍÕ *³î DKÅÔÕ|›ì§‘œ‰©T‘”'ôÑØ¶cBøÍ‘R'0§êƒhTH­>x·³»¬¾^Ð×ÇYIhO;;¬gJùcðcnjإاä*ƒ´T{ϵsç%¶/Œx§EÔ—*×Z¹bE¾kR'³ÚÉb’qr‘PB¶äÛ•@”Zežr²ñfC‹º4¿Xø Âjj7Òv(¡º´&åÀ›p"êáÔF•1ÿ¨ŒC^ÖŠ€©ÄÞ _…÷x·ŠLMF°¥]Ì¿ð7áþ!]ÒÒ#"«­cÙ:BË3’¥js­J lÏ.KtRzZRhoü$®ÜS„ ‰Ã°X¹Ü¾…7,¡ÚTÅ* uª"i Já­€iâ@ TYM'Lx»!ª3Ï&wúJ-)EâÅ(ˆ7–æk‹A1TZÍíø©­ªZkVVÂéèž-Î,+…Àl³ÕcþWñ¾C {¸Ac|(´”õ@ü¯â˜±Ð‰_AMbö(/ú 1¼š©¾€óãÆevÝ䊥rÐiªÒ~!  À ¦QR“ÞqرÐ ÖðNsdÖÔT:« t…:“PkÑ™‰®o©ê9UŸ°O°‹B veåOÏ”FƒÜÃÞý!Wú{+¯ÜKü +2{§·J[{¾…avŽ×(2ä)Ò¤Ü @G%¶õ (ýåþ.øRïŸ. NÆX‚]Ìå|söô´x¿@ä…–ó`(¥ÿ´Ø•dêÄXÖXå† /°¬xÑíjM¡Üª»GÃÝT]å?^°æìfÊ™:A§ 0樆T€^Z¼ø'$…Fô{nÝ(3ß*ä;+U.ù®›=à!;2ËâúÑ«0÷œè¨o´·øv´TB5i‹Õ@ äòô”8Zž%Ë̵ñ$Õ9%ÚQ³ª 뮽¤¨IkwDb¡š@™¬ùà÷èM"Ѫø0¥*&Ÿ/³íT‚¢°ÄTTRZ)|_ùÍ,P4@…m */F;Ö¡-Ì„k¬ŸÀ̯ÙpÁȇ\!Lš”$ã'är²©"½˜ÝcÉ Ž–QqObCÞ0߀“×>›»koÔþL¿[÷‰ŽÁ†Z¥¨RÐWµl¤;hǪ€àªº1Mìf~vºÔžp¡¿ý? Y;unà¤_?œŒ¸yôVr!ר렙xÊp·¤äaÁ˜}IxÂ\Á èêØé¸cËr²ótê|•ðmÔˆ(X¤.Í+uA»Ânê3àô„I©º¼r…Y I¤ãÙ’ôºBeÃþ² Ùi»Äq’” ‘³h–,SVA6 SE¢”˜æ”¾[çáìóBlgÞ)i±×ù.¨ßa8¬Úlæu¸˜ä™êèEÞŸAêùùÛ;J”áÅ¢tsB…¸ ðë*Õ¼N¬8˜&Ü’¸|@#}¼§¬¹CP_íhhºDOúçË”ÕÏT`úÜ•§ %P6cà "òó<«Â€ùëmJ;K&^å¤c²@R©ý;ÍÌ¥`Áè N) -ÌmÎèþ1à®þCn7ÈJµcTn¸c+¹[ˆ3¹41žM,æ=8›Uµ@*ŸŸÏGV1oqìèg*çTæOJíW 4È1úG¼ì1–%ÏVýS˜‰i]>Ä•éÔ ·]Žu@È\Ǧâ`v´b›Ë#šõ…ÀèN‹2LˆSá-IV—ù¢âÙæuôê½e}¡Ëy¢M¸ƒ*ȇs9hþe.P©äJ…83Y™èû>ƒ“¡Û©{÷Ï<è/Ľ¬p渒5Õ•¬wû§¹‹F\é’‹ÈÏ4%bã,}Kr­‘} 4·ç =ºó?fmå"+œ·r¦š4>/)dråFù1LhT‹y®ä­=œ°ø€Ã ³ºT-Ú«4¼BæÞP6¦´Äwª ûÁÁ¬ðèƒaI›À* î,‡ÔŸ^‚Ä1zßáZ¶u^W@Mbɲ1ï`þÕÁjÃöb $Ùð÷‘•\ä‹f`S¼ eÑ9á÷7G¿Æp?œ˜à¿%<õ»$ôþxEÇ|@Gº €¬ŽØsš4ì‘oÎÈI§¤¥EEgùƒC ¸"²9p æÙ`¸á§c'èî¾SUçýÂ*¾ÞCXǦ⪫‹^Á®â’£©«ªD™P!(K¶)˱O¬¨¨î©Ûíœ,LÎÔ}@¯Šý}Dj×)›\co‰ZeTXÁ§4üN¢^8ÅÊxº“õó0ÌvÙ{Lµ÷r-9ú?¨T•³Võ‘«±D»¨t;U§-×ÕGàlq_Íå–Ž+à&8&íJj<Ò¿¬a†J96Y›¸õ&S=œ~õà›oïÙ¨L©Þ&£ƒ‹ðZ-Œé.l`5܆ÙêØL Ããv¯¡2€Ô˜iJ7ó’‹ ±¬.\¿i‘w]øG1ÂäÔŒL¹"?Ÿ‘®V`M·*Žen HŽ´ÿƒ?}XwlPÐÕ\ÞºÀÕƒ½ë ·ˆ·ÏjeÀÙÚ^oîÈwh  ôØ›ë[ìíà4hÔTK[h¤õä¶©ªÏúÛVYäÞµGg©OcµÅÞsRXŸq/5´4׉ãËŽ(k08Bû&FÚvãGÁ yð8Ǻûî•mçî³hLºOhDývnÕžÐÔ݇ð"¥1FÉSrý²ùI.’.аï û̹‡…£±˜R5¹>*\ 8;µ·0תÅßWSÇšÊ{}ª6ÒKˆPÚM9  ~(ŠrÍúNf¸“5< e¸j#sÜpcfqB ƒE<è^{î4ø è“u&7†÷®¨[ˆ«Ò("ïåÿ»°9Êuj\ئ1´¹œý~ê‚æ +¸œ bžr¬æ8eèð‚ý¡‘"Á¡ä(õ|­Ëãâw O}8üÞ“iîãPi'·ª,®E •gD‹ü8Ì#6ƒM_ ø5c㉄ҮÏQnɧݿ„n#‹¹Iii‰ Ué MUUiU xò;+íHw2¨7Ú9õ“§PúË4÷w_Üi¤ûŒô<…\<] Äb3íÞZaŽ™ BÄ1 QqY¡ |Ðï ÝöÜ9:x¤6Ü"+Ì)ô¶ý‡6,ÙyNÚ/H#›P§Št÷vèm¥öéVPžçPá•$]½¹ÝÓ!ýõ£çŸû]G¼;Â×/†öƒóôùcWE¶ šcK“Ëöà ‡ŽÚ ÷Xø ÿÜÇâjŒ;SÃe¾.ú,ÔÛ vWØÕ1®í+X›Ÿ¢ÈT+¥¹R¬`J“¸2«ZjÁ¢•–%NíN;ßßSZ[/ìh©ºÑî¿ެýOÉÁc*óÓ14a?èà®*Ùp72æsžà*ÅUˆE×j¸†3z…T£5œ²²*Ë!e Ï擺å9Ê.*=þ‡¥Yèd}þ„mò€2;™©5bŸÔɇÞœ‰vhŒc>߬4ª†ÎÉQË" L°“!Æ8Gè´úóëáèV_v]‹íÏa)Õ­³æÈÉ‘Ieè54‰Ç¬¤ò Gå 9>~¼ ó%z‹Þuø`‘ G3(~þ&Źö3Œ“õ|þÞÏÙ版| ±gÞ¤Q5¶¨ÃÅñIA;âÖMà@MÒ‰¬U'¸FûcÓÌg®i¦CD=úcιA¡õWÁ5õiû­nAÍ1Ëx@ÃRÊð«µô±å€Y}®ô€ ;émTë.¸N ò ÙŠM¸ŠE”UoÓcÕR,=(M¦tû¤Òyô˜”¼ìdìtm3TDžÏ«P‚D­J’Ç£¹£lš¿‹¹—[ì|à,µ´ U_â:orˆ¨Sx6ê[ u£<; S˜¡ÖGVëIìRF¸$¼AÖÓ'ÐÛõë:fI±“úl«®‡†í0˜‹M¦Úê¾òv@÷WEaFˆ§´>J…¯‹×Óì”/–i¯Ó°jêk©8è‹I+…(’ÒîQ«öªñC‰v*Ù[¨°ƒn> £àø£—×ì LÞ»Ou1º~I²•;èO)•Á_­ðwÚ^œÖY²ƒ„¨ˆÒúʤ~X”þ¹éEþ¹Ò•ìtÎh* dª“”‰h ú ñà÷ªŠ|³¶€ŸS©v+¨©.>çJƒSD]Ôç´}кŠ7µ£7™‰ªŠ¼±ó¹ªÒ¢3ø­ˆ:£±gu.€ûFÛ\™ZÈ|—~À±“O¡ÝT Ùð¬cÐj9[ìÒGèÕ uìnXÌõ†ºkÔ$hT@6ë6d³á”Ÿ¹ñ))± µ)Íu5MÍÉuñ®3&Ä;Íbò{zT½¡Yê`3׃éf+‰²~ß̹…Ûý)ãõNp ªÝl˜éº¼ ì¦ÛÂÚkªÛZÒ*•N§h´: t®ºÈÜZß~¾ËõiÝÈÔ:VͰäG64áoûÐìˆÈ½¾áˆè%€Æµ"ú„ogÈ™Ô!pô•w´ï‚4€/Ó0t1œ…¦ ò“¹OŽcçŽÂCf._ò< £ÃqOñ ÒFæá­í¼Ç†Gk¸[ÊÒ›u÷i¸šÒ})ª]_qÏá¨Ó?q]ëïW5ß*£­š ŽÆh±ÛÚLé¼²R¶eÝU¤è½häEgvÅÀÉ€#‡‘ÉxÝè§l8Þ6ÚÉ5@lÕ¤™Ÿ¨\Úº˜ƒ›Ý^c±Ò"‰bãªõK׎î‚ûLõ=üî)›I„¯qe…{ªƒ:>Ê%áj¸é›gÝ÷ÁCþÏï?xÃ/ ýH„ 6Z+ÞT©áõüµ½å6 ¿¼à³bõ¡E+– Ñf´—#g<©ÿg2ŽÓcd ÷£ìê8ýZá¸Þs¤ÜËZ/%ëV¸®ukÓâ¶fÓ ÒÝjø 7SúÛµ7Û*²ju·ièEåC"¼½›ºï.O…Ÿ< ¿ƒu .€_p/jmuε´._°™~ÏwÇúÄLSM„Ï&1fl‰4#ª/ýöýGu½'…'zk‡ÀG`0{ ±9£Jd;ìÀÚvëDmç9ÏϽÏ/Ü"ŽÄ'âqe·=×sïxË5@ßì?¼#R•’,ŒÇ·¶¤¾H8œ{ùÛãã×<ÀšÂÄÁlîlfo‰>ÝËÙÛДû/àÃ$Úz‹T$TÁ]ÿüv2± s› ·1Ÿqa YŒz£¹ë^ŽI’™£N|N"Rê´¡Z¾º@knéVÉŽ 1¸ Ì¥çï^·:3ÛT/ˆ­I·¤:Q*O H½ÿÅú3g„ÇW^÷ÁÑÀÓ!ý>Õh|åXö·VÛ3Xð-›ñYÇE¤r¯hC "ÖìA$@ž`Yý»}û»BÎ¥^ÅÆxòÓ r7~†^ ÉT…{ ëá|è ¸¤ŽFa¨›ûÕ©˜9ÆÝåõî¾ïá¢3æ§]XYÖliw¹`#~c®“¹{Ÿb”$÷ ¹å¹½9J.èù0žDFŸqn0jäunÜœ_™‹4`ýp÷8ãŽÝ Jùƒ¢†è˜ÌøƒÉæµ¶uËž¢†x "x¦¸ñi©ñXv›Z«+›šRjƘBÚ02©aê…û^÷`âÇ~÷§¹?€} Åýù\[/¸E±éÒÄzëâ펄_ Ü¿A¬• ›=ßz¸’p⃛}½ü ëMîÝ€šHàKoÞ¾6pèéÊÞK'îN=à.Šè¡ã½×nõ…lÞ•|dK0¶–‰Cd6r†ƒ¥ì¾å2h¤«Di©¢¬4qé’Š·hžÇÿp•}Œ[«é/ìKé\èVrÞqëÔóûWpÀé4\µ¾„<Є¥sÐt4éÎû8¬¬÷¬ ­@ì™èd^‚#\™—£ÈIJ —FzmЧpÂŲ˕uÂrg­µÐ__ŽV _@9ð<ô<·ã‰?Öpç’NèÉùõüÛd æì%ãQ0ñÉæ±‹8×Åx?8ŽÌ@žDûýFÆ 8ÎÙ ã8Ðßw]4».X$À½ÜL×sžd%^“6fy¨ÇLÿØÅô3˜ÿNõ¹ý'úÇú?xï9ç±™™|.dSÑ ‡í+ŠékÑÞ”·*1'&9:)ó8 –EõD4&VI>9B£vjÞÿD꯴y—#Ž)žäÓËÚ¾¢îÙšm­ Ž^pt¨Ze•ɽI•hâÇ4ÔQO”ÇCËߣѶ…ÜD5à8ßÖöq)ÝŽ~â>Û[™v‚m‘J\ÆDíÌ~u=‡$ïžæ¾õ74‹ûq[ßep™>Õ™–-pÏ©ušLz}‘À=ÊP¨úéæ"unlbľaóëžôgÔµ/¢¹'sªš ­­¬FÕÖ4©S¯Ü‡)µ7îÃäºiîA_Ž,Á¸Fœ™è%4åÃww–µ· Ïžk} ҷ»· L±ÜîæÈŸ”-áAÂØ£ b †ˆÔº®s ;…õ= Í€…ßr’~GÅÞàH7¥:i÷¶/«’e…qÓ5 M@î^g}nôw¶· ϶|î€R­MSQ¡rä7‚>Pkê­Aϧx'I÷7¾ü…áe%@ Â$þi¡1{EtTjm‡Ðóå?¾€¯_-4è4E‚R™MÓ˜‹©é #ažqG£rŽšb£FÎs ]‚‡1’ƒ0g^oBÏ›,¦™ñàŽê·1zyº½øà’üŸ³à–nö?/îG­Ç¯àÌŸŽêŽJM‹Ž­u™Š\i/4`´+ë1‰‘8ëxÙû§¹ÌbXÎ1Q£‹açM ^B¡è rñ‘«•ObE=‰mÀúñ)‡6-‹š;æ^í|ûëÙ½Au郱¶2Þ×;’î¥~¤øü~-ù¢þJÃÕ¦Ž;C®CŽÜ_á¯NèÕĺuæ$pGÃ|¸’k½UÞÓ90p€ÒÊ–S% tÉ:Òª£Û÷Tc³¶Èkçʰ²Œ–Ú²²ÚRµMR.”•æ™…nh:yå¤ÿÖC2¿T?AâÑå]¿x«‹ãª2š[þ̓/€AOÙ]È‹{ïTSmçÀ'_µÿ àK¾ñÓ»Ãa'“«Zäټϼë£ÖÕlµ®sÀë²UI»’vÆElÜëÒŒ±EÔÌ>®>G¯Z¬N–ǪDyb  EebGe…£²(ߦ)ÈÚU] ›6Q¦üÊÜê̺X~m\¹¼{ŽR{UÄb-б¥”åòN58Lý¦î"[1¨£«¥eé±,1UŸšž&Wåñê¨zèÁqf—efJ$™ŠQQ† 8ª0Oˆ2*¼2³,¶#³FnÆ#Y¦T’‘âÊvªš”™UÅ KÉVÊ ÎËA2Q"«.³:Ê­……fS±¹  ³ÆeBÑâÚK-ëëûl882…[‹"¿#k—SÑz©]×A,£ô-Vk«Þ…OÌ’o² á&`7%nƒ‰(é&L‚‰7Q"LÚ†qhtQÁT¸“Àá/0 ü( Ü+cÿ$Ãÿ•þÜüð>» Mã¦ÀÈ‘K(2å)Õ¦+•è#éß—QºX…"û6i)ã_ ƒKÉ®ñ_Lè2Nœø¨`âËñ#u¯è endstream endobj 11 0 obj <> endobj 117 0 obj <>stream xœVyPS׿nÕj5íË¥­õ¹ïZmß«âR÷…U .YÀ„,ä’}ÏÉaO €@ˆ¬DAÜjëR[DŸS«ÖeœvÚñµï\zœyïbßÌëßoî?wΙûÝó}¿í0°ñã0ƒñfl¦/^¸5ÿ 3ula5“A½3ŽúKÈ:”2š>º–Iñ&a`R˜4Þ÷Î$Ñ480º¦@é[ØxãÃmñesâ¢÷Î?Á†Ü¼QæáŒüˆeK–®ˆH)ˆøïNÄF¾8ópNÄlúEÊäæ ù9ù»2…)qDt®ðPNÄ¿ÿóÒÿŠýå1 ‹ÌYŸ»!O$Þœ/9TÊψΌ‰#0ì=l7ö>¶›…Ea1X,6‹Ãâ±õX"¶ûÛŠ-Ƕa+°•ØNlÆÀÂéAaã±t 2J/Ç%Œû1dGÈíñ™ão3³Y«Šõkh|èO¸ ñ†å;Nœ:ñmèœLAà‡)Ôt?ƒúÒˉv=ª[ ©ËáGX¨ç•åoˆ«Õ¤ê¹$Üí MpëÝ Ô8K|m 3æ±ü(Ì®³ë€ž øJÝv#NB[è+.¬âÀy°â$ª`N¦,º>¾Ÿb Lƒ]öûaìN*¾Á‰Û¬Ö׊K<®šÒâLa²›Ýµ®ºÊyGÓ¶ïØ…–Ïâ} s,Žxļ‚ä’¡¶ #£Íh3áìŒùè%s˜Õ—•Ô¼~éÙÀ™N€W•h ÔÆ,½€8ˆÖ0ÙnÕ^‹J;ƒ_I¶žjð?ÿ–7ÖrzœFm€ØÞ_ÂØßë§Ãv\ ±ûpâ-Aç‚n↯¹¼%€³¿ ­jëšñbã âðPɺlª4€PhÄhÊ«]áQcŒgmð:ç è1ûõÝŠ†d‹#,r+š|HR¨(?]WÑã –õÒE‡¡STW^tà÷;2#£Å’ÅD¦§&1¥,=©5Ê€hR÷Á²Ô¢,€£,‹ö!1Z1„Á…/ÿÑóÛBQ¹ty”p à¢íÃp:œx¾y÷>qºÿràxâJöº…jFƒšò$ä<õWN½½ÎîW’ Ôˆ8ŒÂóWÉÖîÐîWª“m4cU…îSxê*}wüwˆUµ¹àp6\?†+îìÛ¸-){MÑü‹ÝmwÀuZž…I˜ÐK·m­9¢ÁæœUÉ;íNîx®¬ª®­NM×/öŸ±Ðgâ?õŸßœ>×úº{GÚÎ7óbà2»µ…ÇäxÐ[Ý”׿æçæ!R’S£ÈTåáð!(´8Ö«tÖõj®"´Îå²{^W¡-P@n&>B§h–sUþ‚ZjA½Ü? 2nõÞ cÛ;àlŽ -gzY%>—« ”j³Ÿ¦­ÀP_eñÍ|péìãÒž} ~y ðÖZû`0ýï¥ÓôÃß[°ŸZÇù˜xiwúáYF£Å¦7òÒ>Û™­é F 6`µ[ðÛ¬ (`ÕÙÌ=W›e-.­%›z[Ï/óTʼn;H’\±¸Â€ÝE<†™XcäJè£&ø5þi'Fà'wÃØêm8ñ[•*Úp 梲"jn÷à 3’‡æhD6âl߂݉ Ù3UúÒ*'pÚÄSøo‹#J™nŒ5p•¡]6JMn+=ЙĺÌtô^¸<Ò(xzuAû¡³0†ò„+Ü$8{‡ Zì««ùéÞØ©ú“üÔºi¾0áVû•Çqrs³³5:àêEÅþp]\K8KíG‰Á¾Ë`±h’ô9µÉ´â¸h!Ú†–oú<åÊ·=­ð­Ç„tUD8[žS®t­y:ÌCÛœ6kd€Є͑8ûTž8S‘3ó°$Ð{¾ó—“—‰®‹½-ÝcšØƒRüÔ?içŸÞREÍâ”;=ö2Ð jH\Sä Ê|@H¥<7=?W­’J4zݽѩñ–kÝj€K ɑڂàÚ æÂ$È ®Ã)› Š„ùd¡„ôhý*^¦X” õð'+Ñ{2ˆ‡þWÜ̲Ú,À ô¶tc¼ÖdSY”Ö±“i:(¢–|µ7CàËß8±{Ò$‰Î c¯¦2¨ Nù,¥Tg’P;¥œ=R"Ír f¾ùéܸªœKÛ ·Ù'÷ɽŠ*Ò£ëK¬8’ñu±Q‘î¼ñŽžÌ‘‰ÄÌjVq}Y©Ÿvù*s£®WÑdugŒmü?ØvÚoT˜mF«ž@¼W ­ö9nºOÞ2ØøñêX®¼¦5spü×\uæõè&š×f“Éd6*d:Í&k JC³»Ìåò¥ÍÀew;¼ ˜Û!jÊ’É …b^bvJÒ§h\ãÝÊs ïÈ?š¹kÓVôÁbÞEÈ·8â4R󪱛^/í·%´ßº ´ã¨Å‹3ÐTšû’µfR•€³NÃeUŸ· ^xøÅ¹6€WëH•MHEïú³R•ˆ d‰`àÛþëgN6¼¬DG…Ö$#¢B›fQ--a%ÙØw²õöÏ]LOÎ9¹ šÚX3*XõîN¬/›4 Ãþqß P endstream endobj 9 0 obj <> endobj 118 0 obj <>stream xœXyTSW·¿1æÞ«"UâÕÄ!ÁÖ«V[­Sçqĉ™0C aHÂÆœ0Ï˜Š " ‚ZlêPµu¨¿:|V;Zû}o_zxo½s¡}¯o­÷­õÖ[ünî¹'gïýûýöo_5t%‰FìWig¯V‡ù —oòDüÄ!ü$1¾¿÷¹Ix……ÄÈaèቜø÷FCçk E ‰nÜ]â²g§ûŒ™3g­QGê5ÁAÑÎïÌ}{¾³¯Þù;ÎkUÚàÀçiäŸXU˜:2\íî£uÞ©÷‰p~ü¯_ü÷Vÿ¿Í)ŠZ½*bßjõšÈµë4ëµ¢7ÆlŠóÙ¢óݪ÷ÛïïªÚà´3x×îÐ=a{ÃÝg¿å5÷íwæÍwóÂE‹ßX2ÝeÆLŠzÚN-¦Þ Ü¨)Ôj*5ÚEM§vS.Ôjµ—z“r§öQ«©YÔ~j 5›:@­¥Þ¢Rë¨9Ôzj.µz›ÚHm¢æQ›©ùÔ»ÔVjµZH¹R‹(Gê5j%5šr¢¤ÔŠ£ÆRã(%£äÔxj(5b©aÔpÊZCªD¾¤¾éE}CViψÿ}¨ûÐ.ÉBI·„§Õô]fÆüÊf{mXÛð‘Ã݇ÿ}Äüö<ΔT¼íøžãO¯y½ötÔ¢QŸŒž8ºÚ‰qZâT$]+½!}2fènŒvL7‘+åþ6ö½±mcOŽýr\À¸§²-²tY¯œ‘o—GCžc_²Âº“üz«¨oóB)•{`4Öò‡ejkúϨf''L“kÀËÎlÏ)C ¨¢ÈVÿAU‡ bèÖ¥åA(ÅÒ‚r2MS’‰ÕÀC¦?R¸õgIù ÈʽjuºJP€rœtßfãr Uæò™G{?\¼ÝCí žy€wi™®ôâ4³7‹{“·1ÍËÈj!ÃÆæ,è Vå••–²Ò‡õõ¶òÃŽWGîRâLƤ2$„d“ÅÉÌ@`}£HTkûq8OCßÈ,ÎD‘(6%îÐæä„8µ6äMxSf°æ rTW^Ü–Kþ1WšY;þYôeW¤6{ÂÜ%ÃkpTx€Ö°?ƒd!ÏθÆ•’,ÔÕ6?xÙþ¾ì%^P®+‰FÉrOÒ…RH"HžÛ™`sbÅÁ»x3´É¾ñph¨½_$w웃Žñ¿uú æÃ\XŒ°rœô#ËXx@Ã2ú$ÝºŽ feÐÑàªuU¬ô%°­§>ÿjÎ%¼T¯iè[Ùµ‰¹{Ù~“ãžhX›Á‚>åŽÒÒç¯ÎïÁCÞôÝ¿Ä+¾ºKÉ›‡¶UVt(¤/?9æ=ûõ5~-[éÈg'5óËšEv˜oÃt1äóá3ãu<¿ñb È`ì÷¯À&Ï|…9¥9Œ»\»/ÂoŹïp‹{Ÿ<´¦¦÷š’¤Xw¶oX‹è¬÷M…YœÛ¶Pí]DrH†mB[GôF\Hú½dÁï ‡žÓzU—¢Se j]ÉÚÁI'¦¥Æ¢4””SºÓv ì bñ!<ÏÆ>ئá©àÌíã ~IN}û€áC~ø%‚¥K Àeœ4 Îà­Üö܄ڜ;,LfβΠ$_ü.à¼ò»FïSJ«ï `+£4ù°ý9ŒÉÇh<$`«‘†-ãÏr¨¨ÄR^a­?\^Ø^Ûv<ŠtÛq¸=QçkýH~·V‹+ÇÂÂ` Á´øb%áM¢_ÖÐ×3k͇ØþTÆ+2f—rø/¸ÃÖò“wχ¬?®ht¯\ ÙqóC=ƒ=FoF¬§¡âŒR€E3­¢ß`ØÒ§äH‘rÝм7)yM«á¿f:À_¢¦Ã6Æ©#<ö$,Gìf}E§2¡Sþå˜eàYˆiÿ@L™YHdÚ+Jzaá¹`,·+ìàÑŸväÝ+[V§oFÎ…³6Î5/¥Ât…LoSgKqIzB™¢6²*­±'šÚ»ƒ[íWEm8¤”ÞùïÐ2§3Ë’Í>4õIMñN'©¬ey Ìò×0¬‰æ½ úíÌ;yºòœ‹,$1¿æœ¨$§¶Ã3 ­ÇtPÐtôÇ¡ßÿîj|ÐQE½¦,²r+k#'¿AN.Oj嵈Åbx_p05†ÉHÌÈ4  ”–›PZع›¶-ÜtÊ㥷òNx£…²þáQžë<Î<ŽU¨ñb;]V_XX‚ PqNiÖ‘äó)Gûìúµ¿ªêœ~Z¹áˆÚŽZÙ–&{{cCJl½¢.®L_åÅ:öÕêZúd-¢°za®¸/ :8üƒ†þ[VUjî.öuf_DÌÆ­>µ! ¯‹±8°p`dO§^Õù$€ö%˜¯€²µßT‚”ɽWV~¯ˆu„GÉŸÂï]¢» ÃeÞ‡› Ë4´ë»~ž›w³‘½ø!³¹ÓïÎ­Ž£_ŸRhÊâT I±H®N©îPÂ/ˆ4ÖÍ¿ÒmVÑ? –3Hú[W_a:Ïò:Æü~]õÇyDŸk˜ÛÙV„ä8à7pç¶pçïæffMbî>¡®¦ý † FR׿ۙµEú Óû,ÄCŽgröÅÖ¦ bHpq!éæ>sN7ÿìgøÖNÎ;7¹ÂÔÉB?öÐ2ç²Ë“Í^,ncBBâR"ë›h}_ ßa7-sÊX”&À­€™wÞý›Þã–ó—›™Î*[þÍ"VºïZé5òAÕ Чíܪü¸JÓ… .Ô[îæ’£¿Ò0Ÿd×ýɬ}úÄՙ䀯A­ü«ˆ×“”â™Zº3§<iQrv’Q·o–-/£Õ”Šä¨ª´Èž›‡ŠÌÅfÖ†ó´ÌáìÂì´<Ô=Ýâøœ¬†ù¼smWqqs‘ü€Á½ûÜ…½'héYeF UØò¤@cŒ!0¥3³VSwÃx •"KiA{ÙÙ eNf™Mµ›ÌÙ¹Æ<ã¼B¦½ø\w>³ •ÉQuiQS>Y¦Ñ2 ™ù›À¥¸ÌFÃh¸þ+¾.9LÃ~jÕ‰ââÆùs²Ã4pž“ÆIïðá7¸ÔÔììlS&’'¥W+¡’ùvE/vÄ’ûVúØ´§:šl­•™‹"­4»²u–6…ôù{¤«r5ƒGÐDy…Ç#oÖµÛóæ¥nëùeûêuçP'j¶´Ÿ"] »_â"Ãâ’µˆ mì¸|úô—uÊ4”l˜€ÃR;§1§ªðeÞQn°·Íþc1©Úi óEFa6)GB¦1, ‡ã„JTUÝÍ'÷Ÿi¡) É=Á°.cÀö1vØŒãjµi(EŽ I™!9™È€<ËS¡üŠ(âu6.¡ =?½ »€Nöœj[Ëš ä6¼TËœÍÌ3!=JLW‡fd$êcc› 5Y…±Ç’ëQ1ª¨(lý ™…YÖpƒ÷Ë""CÒ’Ôþê0]rZFJ¶>‡Hå2C,PªB–†SíÝyy…ÅE%5êÊØÒ¤ªYib±Q²!#TXœ1ÀŸcüÔ`‹U >,$»ºÏ™;c,I3û²ý¿•3_\ìöiK<ä þ Þåòï±ø@P‚ŸJ åx/{ñ®¦³ÖÒ‚ØkÍ›° +÷lñ‰l>;Ø|ú$VÑ?„*8AA‡,‹ õ Ø¥_†XW¡ÉðaLîÃÊŠoýªa>& Êì>˜ð¤”µDøB±Ï%þ‘Udb>úr)%'-M³ï–­mqï#„Š —Ê‹ìy³ì¯<2uϰø•é÷Æïׄj‘<ÍX\bF¹æ<¥¹À\€òÙ#ÑÖ UT”êPGè¥Ö#eõuŠºÃÖŽã/`?YV}º´´9%}.é/¼Îd1?D\€OT’/bçï~ _»Þk©2¦* &ò1﯎iGìéÛÉkÏÎçOÆS°òé ýðbóýËJÇß×¢õ§ù&˜#þ}¶[Q’Zšså]™Üû••`,`ð¡þ0|ˆ“àB }7³: ‘<©“«!y¹ ‡;³¤@g5Ýgù úŸIi(àÿ)é/drv’W èý–ù³M‹øE0ŸSÓÆð4}Bt‡6õ]AC?]ÒÐÏ0éøuImÿ¾ÁÎ&lèw‘ixéd.úXùÉ hë]hˆêžã›;9ϼ¤ tšåïâP-s3«4¼…ñî·x4d±3žŠ'}6ãZ,ç{”›™î {Á5¢³[¯K¤-øÀwÊHO6ÄEÇ¦Ä v¯æ Œ®ñÊå–f­ªR°KzkŽ+§ßºø5]Äôƒg§WëkMwY~CäWÿ)IÿˆF—**o–Ì…j˜{éÖX´–Å—ü+¿J‚5´U'žÝÉöG0&·šPÖ»°ýÌoñÓ`4ç{ \ïüQDMìqý1cKñ‚tÆß{BÛCO²î"1Zè‚§ái_Ï„Q_k~qS‰«`—5çPª ÎÅb6‘ù¯œ4ø#Þ–ŸÔ·ÃØOÇ*bK§ãéÄð‘OòçÞD%fbO¥)„ƒ!7ðHì}]±³˜Ù"ð‚°ëÀÂ0%éÚ¤”“»à`³èSÒ¸‰}l¶Ñës“ËL³pëq×|pd>¬¬o«)KOÎÌÎÈHU¤%f¥¢6¬AÛzÂn?qeÇ©ݵ^‘ŠØ £/z—Ýéu ?¢M^)ÉžYì ïýBzúX)&é~l§—•Krî³àÊÀsk~WõWÍ]WÑç,°³>Æï)ð };³21w Ûïʘ¶%Åxfe£Ôœ”LüçÜáêò–oZ¼0µ5Y­ÐÆ…¤¯E¬Àqßcü iÍNMO–Â$22Løbœt#Ë¿Î]Àcé‹—ºÐo±pÓ¬ òP›ZY¯©5ôè–Fúù£}È·F#š•žÜj ‰ò¿ãA08Á{{~¸£sr®b³y9±5É››ê:¾ËGU- 饫 G;¯GÉGÕM¬ôÓåý{¹‚=vG¹Ìó8ÜUWTÖtX)õ”OãzjUo½¥ ¡{âv¸+ ïÖ2Ýi…dí/úW3h~QiiéÀŠØ9 4)ÈX!îó²szd(H­ÄÐ.»Rk/oj8Òhé@gH9\®á-帛U™”»J(GΪ´Ô傯zfgˆÊ”åÜ%m¬‘?ü±|èþ-ü*̯Ê+,,µØûÝ ï×·$ú‡Æ*£âƒÓW˜ˆUlÐ0Çé*ÌÁÓþ?‡bœo¨Bí,?JˆµËXœö§‘O7z¦’Œ iØÃ𽃂|<[BººZ[ºº‚[½…T~ŒoÖYºÀ3`Ä8é"^Ç«9gŒ‘ézbh“ób‰X<¬ö-ôŸ€'.ZŽ¥ó{·ÂˆÊ[¡O|lQh¯|ý¯ånìçTŠÈI-ñŸ°¡ Š‹-¤“–e×§Ÿ‹?‘ÞE†—_¾§ž6Sâé÷–tÄØÑYùµÓí·ÏœÖ´)Zƒ,ÖͬÐíD¡àþˆ•XŸR–óåm ¼–ÕëQG°GèðôÿHgcɺFôvè|¶ßÆä¬HI](èn3—ÅVp·Š> R*´±húhfuVAv~v^ÊD©©ú”<‘ñkðv-sÌT¥7û@Æ/AfÒhcešzX ™Ã¶ïñøMa22ÊQrR†ZXa°1)(3/4h¨“ýò†šëŬ0[Ÿë£­¢Ÿ`<è÷íÞbDj臙u±hõ€8ºìZGLñºðx /•;h„îd”rÉ¢Ç šQwà#¯³A7ô÷Ð}ôI}ç‰3í Ÿ¡ç,ÜeÌW+-×K!"dí–0Md„¢«©ƒåŸâZ¦ÅT­3«BRécCBb´½ïuâfެ¡?ɲy0;9ÞKñ×2LΤëÎ*CUrt¸ª¬=·U˜«„—+O5Ìùô£}7”ôÿ #]OÇÿÍv­²¢Wx1rÿÏWEŸrtpL8Ô÷¡S™ UæS¾.Úé½eŸ"üzm+Ú‚<#UÛYé¹wG§3Ëÿ2”z Ciº ÎO®D'x[h©©(c¥_Yê,E5NVEo˜kö7$fÖ#8¼}`q¥¶¢´¾š¬Dl{•Öm`©Ÿ!1@0eiŒãÖ>¥Uô{°‰ÍúƒìªT† Ù‰YIx(þA†)xšÒš]ŽJåÈVUÒ•—K&ÎB!75Ì©kZ™öøLŽ?Â<•YS„JäèHyI¯à$z4ÌéŒÒ´êÔÿ³¬‰W> VôG váÿsEG}]+/à¬VÔYbèÆÑ,ÌBíyX&:ËÄd"˜Ëy¨TÛzζ·õœUµ^á7îˆø,üw§?c½àÞ M}ò&‘ Þ‰ðŽòúÖr›Ñ&/ß5¡»cf£Ed|AtDc¿'†Â½IÚ§¸ÝÀ!7ã²´È”ˆ„$2|ï×]†JÐ30«æÒ¹sÖmxºbÀc÷M$ u1ïjãÞ6ë-ˆ0ôV<ƒ °HÅ”äååç6–Ú‹*k/‹9¤ìçó’X½ ?bÀ§ƒœß´.ÀD1¯@NKG¬MɘbbñLAmßúâÁñ[è3ù¿­ø ‹öŒ RøûÇ«W²Mtóõ .Ôª« ,-V“!ÌK·;ôÀ¾åAÞÄÌe£ùù³àyþöWNÐÓV=NúíeÞʵÔr¸±×OúoÙ4+\Ï|ÑßÌJï4GÔx¿Få±]«+;¢ð?a C¬*R¼çjàw°”ôH¦õ$žŽ8®ŒµÇ—ùÕ°Òooœ¬=reü#×÷§º¬Ü?e÷`†`ˆù·­N`…©ø xcœô%±®Å¿î=Æm9v‹6ÌÚ>KŽ%`ÆS¢çSaÊuÓÒçØw,VÑ ‚ódÎ6~ħƒTÄû\L„Ëu[cVºã¡ËÝðP„å,^õŒs2Œzö3ÓÈÕŸc:4&Ë®8Ó¿ù ¦eq*>ÉÝ:¼ÏÃÉ´ñ¥µ©Êø–Ô{è9ºVx©¨ ¸°"¿ŠxÈÑ,0IÄGºõϧ½°Fb§«¯±õšXð£‰ín“|O ç;Ö7æˆSŒÄC€#A(±\hTÏa=<ävê´&B¨B^ìÔo7€”Ï¿‡ÇÞלo+¤÷~híè¸9þéÊ‹ØOxgýä{~vS€ÃOÜÂNÑE¶§­­çâ1ÏåÑ!^džYD«m¡h»1Äwkà…§–í¸*Ô`tþ£QÔ³HªæŠ› 8[oÛ?¿òëg…@ʪ9 ÁÎxôÛ.x~ï=´T6)¼ñ¬%Kñ”]ßD®YR˵U‘¥kÑZ™ší™c@i¦,“Á”™cÌÔg%"v[ôeB^¶ü¨`{8í¼ãï‰ø@hãæÓ50^òÓ½yô,§Ãq€Kþr1yõ´—8“ÏrýùÀ=üåâ'Z0Àœ°Š<*ìGô‡è ±ÃËD_ Z³äÓ¸3”|çy -àlO{{wÏ€þÀ#þÌûmñÀsÀÞ:ÿ1zÄÞñíÙ¾?$tÿÁ#ag ¹P‘gÎE¹ˆ-+N3¨‚}Vº ö-°ŠºA"†+}›¹m!êXßs<ðp„Ç¢9öùg—w¯éôûÉmbvžÐØcÏ„_KúÁ$ÊÊ_š®Z»ì W;Ø?öÕd£F¼”»ÖÒTwòô·Ïºa=Ó<9øÐã®wÇŒ+¬š¹hªó<º­r“V$MSoóÒDm÷#œ¸ER½ã qDOÄÄç°ÿ<ðǪ'„ŽþO°?¨æÑŽºZÞ§¼ªè–á ÑRààŠR‡‘õŸ€‰ª endstream endobj 121 0 obj <>stream 2020-12-26T09:14:24-08:00 2020-12-26T09:14:24-08:00 groff version 1.22.4 Untitled endstream endobj 2 0 obj <>endobj xref 0 122 0000000000 65535 f 0000049646 00000 n 0000073130 00000 n 0000049443 00000 n 0000046030 00000 n 0000000182 00000 n 0000002800 00000 n 0000049712 00000 n 0000052220 00000 n 0000064990 00000 n 0000051836 00000 n 0000061676 00000 n 0000051219 00000 n 0000052774 00000 n 0000049753 00000 n 0000049783 00000 n 0000046190 00000 n 0000002820 00000 n 0000005846 00000 n 0000049835 00000 n 0000049865 00000 n 0000046352 00000 n 0000005867 00000 n 0000008975 00000 n 0000049906 00000 n 0000049936 00000 n 0000046514 00000 n 0000008996 00000 n 0000012026 00000 n 0000049977 00000 n 0000050007 00000 n 0000046676 00000 n 0000012047 00000 n 0000014595 00000 n 0000050048 00000 n 0000050078 00000 n 0000046838 00000 n 0000014616 00000 n 0000017968 00000 n 0000050119 00000 n 0000050149 00000 n 0000047000 00000 n 0000017989 00000 n 0000020682 00000 n 0000050190 00000 n 0000050220 00000 n 0000047162 00000 n 0000020703 00000 n 0000022793 00000 n 0000050261 00000 n 0000050291 00000 n 0000047324 00000 n 0000022814 00000 n 0000025250 00000 n 0000050332 00000 n 0000050362 00000 n 0000047486 00000 n 0000025271 00000 n 0000027973 00000 n 0000050403 00000 n 0000050433 00000 n 0000047648 00000 n 0000027994 00000 n 0000030524 00000 n 0000050474 00000 n 0000050504 00000 n 0000047810 00000 n 0000030545 00000 n 0000031891 00000 n 0000050545 00000 n 0000050575 00000 n 0000047972 00000 n 0000031912 00000 n 0000032679 00000 n 0000050607 00000 n 0000050637 00000 n 0000048134 00000 n 0000032699 00000 n 0000033643 00000 n 0000050669 00000 n 0000050699 00000 n 0000048296 00000 n 0000033663 00000 n 0000035644 00000 n 0000050731 00000 n 0000050761 00000 n 0000048458 00000 n 0000035665 00000 n 0000038229 00000 n 0000050802 00000 n 0000050832 00000 n 0000048620 00000 n 0000038250 00000 n 0000041174 00000 n 0000050873 00000 n 0000050903 00000 n 0000048782 00000 n 0000041195 00000 n 0000041443 00000 n 0000050944 00000 n 0000050974 00000 n 0000048945 00000 n 0000041463 00000 n 0000043397 00000 n 0000051007 00000 n 0000051038 00000 n 0000049111 00000 n 0000043419 00000 n 0000045117 00000 n 0000051071 00000 n 0000051102 00000 n 0000049277 00000 n 0000045139 00000 n 0000046009 00000 n 0000051135 00000 n 0000051166 00000 n 0000053386 00000 n 0000061959 00000 n 0000065444 00000 n 0000051730 00000 n 0000052681 00000 n 0000071706 00000 n trailer << /Size 122 /Root 1 0 R /Info 2 0 R /ID [(x#,*`a\321=}I\036\022BS\353`)(x#,*`a\321=}I\036\022BS\353`)] >> startxref 73284 %%EOF libdwarf-20210528/libdwarf/dwarf_elfread.h0000664000175000017500000002056513763460527015251 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef READELFOBJ_H #define READELFOBJ_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Use this for .rel. too. */ struct generic_rela { Dwarf_Unsigned gr_offset; Dwarf_Unsigned gr_info; Dwarf_Unsigned gr_sym; /* From info */ Dwarf_Unsigned gr_type; /* From info */ Dwarf_Signed gr_addend; unsigned char gr_type2; /*MIPS64*/ unsigned char gr_type3; /*MIPS64*/ /* The following TRUE if .rela. and FALSE if .rel. if FALSE, gr_addend will be zero. */ int gr_is_rela; }; /* The following are generic to simplify handling Elf32 and Elf64. Some fields added where the two sizes have different extraction code. */ struct generic_ehdr { unsigned char ge_ident[EI_NIDENT]; Dwarf_Unsigned ge_type; Dwarf_Unsigned ge_machine; Dwarf_Unsigned ge_version; Dwarf_Unsigned ge_entry; Dwarf_Unsigned ge_phoff; Dwarf_Unsigned ge_shoff; Dwarf_Unsigned ge_flags; Dwarf_Unsigned ge_ehsize; Dwarf_Unsigned ge_phentsize; Dwarf_Unsigned ge_phnum; Dwarf_Unsigned ge_shentsize; Dwarf_Unsigned ge_shnum; Dwarf_Unsigned ge_shstrndx; }; struct generic_phdr { Dwarf_Unsigned gp_type; Dwarf_Unsigned gp_flags; Dwarf_Unsigned gp_offset; Dwarf_Unsigned gp_vaddr; Dwarf_Unsigned gp_paddr; Dwarf_Unsigned gp_filesz; Dwarf_Unsigned gp_memsz; Dwarf_Unsigned gp_align; }; struct generic_shdr { Dwarf_Unsigned gh_secnum; Dwarf_Unsigned gh_name; const char * gh_namestring; Dwarf_Unsigned gh_type; Dwarf_Unsigned gh_flags; Dwarf_Unsigned gh_addr; Dwarf_Unsigned gh_offset; Dwarf_Unsigned gh_size; Dwarf_Unsigned gh_link; /* Section index (in an SHT_REL or SHT_RELA section) of the target section from gh_link. Otherwise 0. */ Dwarf_Unsigned gh_reloc_target_secnum; Dwarf_Unsigned gh_info; Dwarf_Unsigned gh_addralign; Dwarf_Unsigned gh_entsize; /* Zero unless content read in. Malloc space of size gh_size, in bytes. For dwarf and strings mainly. free() this if not null*/ char * gh_content; /* If a .rel or .rela section this will point to generic relocation records if such have been loaded. free() this if not null. */ Dwarf_Unsigned gh_relcount; struct generic_rela * gh_rels; /* For SHT_GROUP based grouping, which group is this section in. 0 unknown, 1 DW_GROUP_NUMBER_BASE base DWARF, 2 DW_GROUPNUMBER_DWO dwo sections, 3+ are in an SHT_GROUP. GNU uses this. set with group number (3+) from SHT_GROUP and the flags should have SHF_GROUP set if in SHT_GROUP. Must only be in one group? */ Dwarf_Unsigned gh_section_group_number; /* Content of an SHT_GROUP section as an array of integers. [0] is the version, which can only be one(1) . */ Dwarf_Unsigned * gh_sht_group_array; /* Number of elements in the gh_sht_group_array. */ Dwarf_Unsigned gh_sht_group_array_count; /* TRUE if .debug_info .eh_frame etc. */ char gh_is_dwarf; }; struct generic_dynentry { Dwarf_Unsigned gd_tag; /* gd_val stands in for d_ptr and d_val union, the union adds nothing in practice since we expect ptrsize <= ulongest. */ Dwarf_Unsigned gd_val; Dwarf_Unsigned gd_dyn_file_offset; }; struct generic_symentry { Dwarf_Unsigned gs_name; Dwarf_Unsigned gs_value; Dwarf_Unsigned gs_size; Dwarf_Unsigned gs_info; Dwarf_Unsigned gs_other; Dwarf_Unsigned gs_shndx; /* derived */ Dwarf_Unsigned gs_bind; Dwarf_Unsigned gs_type; }; struct location { const char *g_name; Dwarf_Unsigned g_offset; Dwarf_Unsigned g_count; Dwarf_Unsigned g_entrysize; Dwarf_Unsigned g_totalsize; }; typedef struct elf_filedata_s { /* f_ident[0] == 'E' means it is elf and elf_filedata_s is the struct involved. Other means error/corruption of some kind. f_ident[1] is a version number. Only version 1 is defined. */ char f_ident[8]; char * f_path; /* non-null if known. Must be freed */ int f_fd; int f_machine; /* EM_* */ int f_destruct_close_fd; int f_is_64bit; unsigned f_endian; Dwarf_Unsigned f_filesize; /* Elf size, not DWARF. 32 or 64 */ Dwarf_Small f_offsetsize; Dwarf_Small f_pointersize; int f_ftype; Dwarf_Unsigned f_max_secdata_offset; Dwarf_Unsigned f_max_progdata_offset; void (*f_copy_word) (void *, const void *, unsigned long); struct location f_loc_ehdr; struct generic_ehdr* f_ehdr; struct location f_loc_shdr; struct generic_shdr* f_shdr; struct location f_loc_phdr; struct generic_phdr* f_phdr; char *f_elf_shstrings_data; /* section name strings */ /* length of currentsection. Might be zero..*/ Dwarf_Unsigned f_elf_shstrings_length; /* size of malloc-d space */ Dwarf_Unsigned f_elf_shstrings_max; /* This is the .dynamic section */ struct location f_loc_dynamic; struct generic_dynentry * f_dynamic; Dwarf_Unsigned f_dynamic_sect_index; /* .dynsym, .dynstr */ struct location f_loc_dynsym; struct generic_symentry* f_dynsym; char *f_dynsym_sect_strings; Dwarf_Unsigned f_dynsym_sect_strings_max; Dwarf_Unsigned f_dynsym_sect_strings_sect_index; Dwarf_Unsigned f_dynsym_sect_index; /* .symtab .strtab */ struct location f_loc_symtab; struct generic_symentry* f_symtab; char * f_symtab_sect_strings; Dwarf_Unsigned f_symtab_sect_strings_max; Dwarf_Unsigned f_symtab_sect_strings_sect_index; Dwarf_Unsigned f_symtab_sect_index; /* Starts at 3. 0,1,2 used specially. */ Dwarf_Unsigned f_sg_next_group_number; /* Both the following will be zero unless there are explicit Elf groups. */ Dwarf_Unsigned f_sht_group_type_section_count; Dwarf_Unsigned f_shf_group_flag_section_count; Dwarf_Unsigned f_dwo_group_section_count; } dwarf_elf_object_access_internals_t; int dwarf_construct_elf_access(int fd, const char *path, dwarf_elf_object_access_internals_t **ep,int *errcode); int dwarf_destruct_elf_access( dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_header( dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_sectheaders( dwarf_elf_object_access_internals_t* ep,int *errcode); int _dwarf_load_elf_symtab_symbols( dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode); /* These two enums used for type safety in passing values. */ enum RelocRela { RelocIsRela = 1, RelocIsRel = 2 }; enum RelocOffsetSize { RelocOffset32 = 4, RelocOffset64 = 8 }; int _dwarf_load_elf_relx(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum,enum RelocRela,int *errcode); #ifndef EI_NIDENT #define EI_NIDENT 16 #endif /* EI_NIDENT */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* READELFOBJ_H */ libdwarf-20210528/libdwarf/dwarf_rnglists.h0000664000175000017500000001245313733470513015502 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_RNGLISTS_H #define DWARF_RNGLISTS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Rangelists header for a CU. The type is never visible to libdwarf callers */ struct Dwarf_Rnglists_Context_s { Dwarf_Debug rc_dbg; Dwarf_Unsigned rc_index; /* An index assigned by libdwarf to each rnglists context. Starting with zero at the zero offset in .debug_rnglists. */ /* Offset of the .debug_rnglists header involved. */ Dwarf_Unsigned rc_header_offset; Dwarf_Unsigned rc_length; /* Many places in in libdwarf this is called length_size. */ Dwarf_Small rc_offset_size; /* rc_extension_size is zero unless this is standard DWARF3 and later 64bit dwarf using the extension mechanism. 64bit DWARF3 and later: rc_extension_size is 4. 64bit DWARF2 MIPS/IRIX: rc_extension_size is zero. 32bit DWARF: rc_extension_size is zero. */ Dwarf_Small rc_extension_size; unsigned rc_version; /* 5 */ Dwarf_Small rc_address_size; Dwarf_Small rc_segment_selector_size; Dwarf_Unsigned rc_offset_entry_count; /* offset in the section of the offset entries */ Dwarf_Unsigned rc_offsets_off_in_sect; /* Do not free. Points into section memory */ Dwarf_Small * rc_offsets_array; /* Offset in the .debug_rnglists section of the first rangelist in the set of rangelists for the CU. */ Dwarf_Unsigned rc_first_rnglist_offset; Dwarf_Unsigned rc_past_last_rnglist_offset; /* pointer to 1st byte of rangelist header*/ Dwarf_Small * rc_rnglists_header; /* pointer to first byte of the rnglist data for rnglist involved. Do not free. */ Dwarf_Small *rc_startaddr; /* pointer one past end of the rnglist data. */ Dwarf_Small *rc_endaddr; }; typedef struct Dwarf_Rnglists_Entry_s *Dwarf_Rnglists_Entry; struct Dwarf_Rnglists_Entry_s { unsigned rle_entrylen; unsigned rle_code; /* Failed means .debug_addr section needed but missing. (possibly tied file needed) */ Dwarf_Bool rle_index_failed; Dwarf_Unsigned rle_raw1; Dwarf_Unsigned rle_raw2; /* Cooked means the raw values from the .debug_rnglists section translated to DIE-specific addresses. */ Dwarf_Unsigned rle_cooked1; Dwarf_Unsigned rle_cooked2; Dwarf_Rnglists_Entry rle_next; }; struct Dwarf_Rnglists_Head_s { Dwarf_Rnglists_Entry *rh_rnglists; /* rh_last and rh_first used during build-up. Zero when array rh_rnglists built. */ Dwarf_Rnglists_Entry rh_first; Dwarf_Rnglists_Entry rh_last; Dwarf_Unsigned rh_count; Dwarf_Unsigned rh_bytes_total; /* A global Rnglists Context, */ Dwarf_CU_Context rh_context; Dwarf_Debug rh_dbg; Dwarf_Rnglists_Context rh_localcontext; Dwarf_Unsigned rh_version; Dwarf_Unsigned rh_index; Dwarf_Unsigned rh_offset_size; Dwarf_Unsigned rh_address_size; unsigned rh_segment_selector_size; /* DW_AT_rnglists_base */ Dwarf_Bool rh_at_rnglists_base_present; Dwarf_Unsigned rh_at_rnglists_base; /* DW_AT_low_pc of CU or zero if none. */ Dwarf_Bool rh_cu_base_address_present; Dwarf_Unsigned rh_cu_base_address; /* DW_AT_addr_base, so we can use .debug_addr if such is needed. */ Dwarf_Bool rh_cu_addr_base_present; Dwarf_Unsigned rh_cu_addr_base; Dwarf_Small * rh_rlepointer; Dwarf_Unsigned rh_rlearea_offset; Dwarf_Small * rh_end_data_area; }; int _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, Dwarf_Small *end_data, Dwarf_Unsigned offset, Dwarf_Rnglists_Context buildhere, Dwarf_Unsigned *next_offset, Dwarf_Error *error); void _dwarf_rnglists_head_destructor(void *m); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_RNGLISTS_H */ libdwarf-20210528/libdwarf/dwarf_find_sigref.c0000664000175000017500000001305414012617207016077 00000000000000/* Copyright (C) 2021 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include /* for debugging only. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef HAVE_STDLIB_H #include /* For uintptr_t */ #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 static int _dwarf_find_CU_Context_given_sig(Dwarf_Debug dbg, Dwarf_Sig8 *sig_in, Dwarf_CU_Context *cu_context_out, Dwarf_Bool *is_info_out, Dwarf_Error *error) { Dwarf_CU_Context cu_context = 0; Dwarf_Bool is_info = FALSE; int loopcount = 0; int lres = 0; Dwarf_Debug_InfoTypes dis = 0; struct Dwarf_Section_s *secdp = 0; /* Loop once with is_info, once with !is_info. Then stop. */ for ( ; loopcount < 2; ++loopcount) { Dwarf_CU_Context prev_cu_context = 0; Dwarf_Unsigned section_size = 0; Dwarf_Unsigned new_cu_offset = 0; is_info = !is_info; if (is_info) { dis = &dbg->de_info_reading; secdp = &dbg->de_debug_info; } else { dis = &dbg->de_types_reading; secdp = &dbg->de_debug_types; } lres = _dwarf_load_die_containing_section(dbg,is_info,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY ) { continue; } /* Lets see if we already have the CU we need. */ for (cu_context = dis->de_cu_context_list; cu_context; cu_context = cu_context->cc_next) { prev_cu_context = cu_context; if (memcmp(sig_in,&cu_context->cc_signature, sizeof(Dwarf_Sig8))) { continue; } if (cu_context->cc_unit_type == DW_UT_split_type|| cu_context->cc_unit_type == DW_UT_type) { *cu_context_out = cu_context; *is_info_out = cu_context->cc_is_info; return DW_DLV_OK; } } if (prev_cu_context) { Dwarf_CU_Context lcu_context = prev_cu_context; new_cu_offset = _dwarf_calculate_next_cu_context_offset( lcu_context); } else { new_cu_offset = 0; } section_size = secdp->dss_size; for ( ; new_cu_offset < section_size; new_cu_offset = _dwarf_calculate_next_cu_context_offset( cu_context)) { #if 0 lres = _dwarf_load_die_containing_section(dbg, is_info,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { continue; } #endif lres = _dwarf_create_a_new_cu_context_record_on_list( dbg, dis,is_info,section_size,new_cu_offset, &cu_context,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { break; } if (memcmp(sig_in,&cu_context->cc_signature, sizeof(Dwarf_Sig8))) { continue; } if (cu_context->cc_unit_type == DW_UT_split_type|| cu_context->cc_unit_type == DW_UT_type) { *cu_context_out = cu_context; *is_info_out = cu_context->cc_is_info; return DW_DLV_OK; } } } /* Loop-end. */ /* Not found */ return DW_DLV_NO_ENTRY; } /* We will search to find a CU with the indicated signature The attribute leading us here is often We are looking for a DW_UT_split_type or DW_UT_type CU. DW_AT_type and if DWARF4 that means our first look is to !is_info */ int dwarf_find_die_given_sig8(Dwarf_Debug dbg, Dwarf_Sig8 *ref, Dwarf_Die *die_out, Dwarf_Bool *is_info, Dwarf_Error *error) { int res = 0; Dwarf_Die ndi = 0; Dwarf_CU_Context context = 0; Dwarf_Bool result_is_info = FALSE; Dwarf_Unsigned dieoffset = 0; res =_dwarf_find_CU_Context_given_sig(dbg, ref, &context, &result_is_info,error); if (res != DW_DLV_OK) { return res; } dieoffset = context->cc_debug_offset + context->cc_signature_offset; res = dwarf_offdie_b(dbg,dieoffset,result_is_info, &ndi,error); if (res == DW_DLV_OK) { *die_out = ndi; *is_info = result_is_info; } return res; } libdwarf-20210528/libdwarf/dwarf_query.c0000664000175000017500000016627014053207172014777 00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. Portions Copyright 2020 Google All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_die_deliv.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned * return_val, Dwarf_Error * error); int dwarf_get_offset_size(Dwarf_Debug dbg, Dwarf_Half * offset_size, Dwarf_Error * error) { if (dbg == 0) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } *offset_size = dbg->de_length_size; return DW_DLV_OK; } #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif /* This is normally reliable. But not always. If different compilation units have different address sizes this may not give the correct value in all contexts. If the Elf offset size != address_size (for example if address_size = 4 but recorded in elf64 object) this may not give the correct value in all contexts. */ int dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half * ret_addr_size, Dwarf_Error * error) { Dwarf_Half address_size = 0; if (dbg == 0) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } address_size = dbg->de_pointer_size; *ret_addr_size = address_size; return DW_DLV_OK; } /* This will be correct in all contexts where the CU context of a DIE is known. */ int dwarf_get_die_address_size(Dwarf_Die die, Dwarf_Half * ret_addr_size, Dwarf_Error * error) { Dwarf_Half address_size = 0; CHECK_DIE(die, DW_DLV_ERROR); address_size = die->di_cu_context->cc_address_size; *ret_addr_size = address_size; return DW_DLV_OK; } int dwarf_dieoffset(Dwarf_Die die, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *ret_offset = (die->di_debug_ptr - dataptr); return DW_DLV_OK; } /* This function returns the offset of the die relative to the start of its compilation-unit rather than .debug_info. Returns DW_DLV_ERROR on error. */ int dwarf_die_CU_offset(Dwarf_Die die, Dwarf_Off * cu_off, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *cu_off = (die->di_debug_ptr - dataptr - cu_context->cc_debug_offset); return DW_DLV_OK; } /* A common function to get both offsets (local and global) It's unusual in that it sets both return offsets to zero on entry. Normally we only set any output-args (through their pointers) in case of success. */ int dwarf_die_offsets(Dwarf_Die die, Dwarf_Off *off, Dwarf_Off *cu_off, Dwarf_Error *error) { int res = 0; Dwarf_Off lcuoff = 0; Dwarf_Off loff = 0; res = dwarf_dieoffset(die,&loff,error); if (res == DW_DLV_OK) { res = dwarf_die_CU_offset(die,&lcuoff,error); } if (res == DW_DLV_OK) { /* Waiting till both succeed before returning any value at all to retain normal libdwarf call semantics. */ *off = loff; *cu_off = lcuoff; } else { *off = 0; *cu_off = 0; } return res; } /* This function returns the global offset (meaning the section offset) and length of the CU that this die is a part of. Used for correctness checking by dwarfdump. */ int dwarf_die_CU_offset_range(Dwarf_Die die, Dwarf_Off * cu_off, Dwarf_Off * cu_length, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; *cu_off = cu_context->cc_debug_offset; *cu_length = cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; return DW_DLV_OK; } int dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) { CHECK_DIE(die, DW_DLV_ERROR); *tag = die->di_abbrev_list->abl_tag; return DW_DLV_OK; } /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Off **offbuf, Dwarf_Unsigned *offcnt, Dwarf_Error * error) { Dwarf_Die die = 0; Dwarf_Die child = 0; Dwarf_Die sib_die = 0; Dwarf_Die cur_die = 0; Dwarf_Unsigned off_count = 0; int res = 0; /* Temporary counter. */ Dwarf_Unsigned i = 0; /* Points to contiguous block of Dwarf_Off's to be returned. */ Dwarf_Off *ret_offsets = 0; Dwarf_Chain_2 curr_chain = 0; Dwarf_Chain_2 prev_chain = 0; Dwarf_Chain_2 head_chain = 0; *offbuf = NULL; *offcnt = 0; /* Get DIE for offset */ res = dwarf_offdie_b(dbg,offset,is_info,&die,error); if (DW_DLV_OK != res) { return res; } /* Get first child for die */ res = dwarf_child(die,&child,error); if (DW_DLV_ERROR == res || DW_DLV_NO_ENTRY == res) { return res; } cur_die = child; for (;;) { if (DW_DLV_OK == res) { int dres = 0; Dwarf_Off cur_off = 0; /* Get Global offset for current die */ dres = dwarf_dieoffset(cur_die,&cur_off,error); if (dres == DW_DLV_OK) { /* Normal. use cur_off. */ } else if (dres == DW_DLV_ERROR) { /* Should be impossible unless... */ /* avoid leak. */ /* Just leave cur_off as zero. */ /* dwarf_dealloc(dbg,*error,DW_DLA_ERROR); */ /* *error = NULL; */ return DW_DLV_ERROR; } else { /* DW_DLV_NO_ENTRY */ /* Impossible, dwarf_dieoffset never returns this */ } /* Record offset in current entry chain */ curr_chain = (Dwarf_Chain_2)_dwarf_get_alloc( dbg,DW_DLA_CHAIN_2,1); if (curr_chain == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Put current offset on singly_linked list. */ curr_chain->ch_item = cur_off; ++off_count; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } /* Process any siblings entries if any */ sib_die = 0; res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,error); if (DW_DLV_ERROR == res) { return res; } if (DW_DLV_NO_ENTRY == res) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if (cur_die != die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } cur_die = sib_die; } /* Points to contiguous block of Dwarf_Off's. */ ret_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, off_count); if (ret_offsets == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Store offsets in contiguous block, and deallocate the chain. */ curr_chain = head_chain; for (i = 0; i < off_count; i++) { *(ret_offsets + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN_2); } *offbuf = ret_offsets; *offcnt = off_count; return DW_DLV_OK; } static void empty_local_attrlist(Dwarf_Debug dbg, Dwarf_Attribute attr) { Dwarf_Attribute cur = 0; Dwarf_Attribute next = 0; for (cur = attr; cur ; cur = next) { next = cur->ar_next; dwarf_dealloc(dbg,cur,DW_DLA_ATTR); } } /* Now we use *_wrapper here, We cannot leak memory. */ int dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute ** attrbuf, Dwarf_Signed * attrcnt, Dwarf_Error * error) { Dwarf_Unsigned attr_count = 0; Dwarf_Unsigned attr = 0; Dwarf_Unsigned attr_form = 0; Dwarf_Unsigned i = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Abbrev_List abbrev_list = 0; Dwarf_Attribute head_attr = NULL; Dwarf_Attribute curr_attr = NULL; Dwarf_Attribute *attr_ptr = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Byte_Ptr die_info_end = 0; int lres = 0; Dwarf_CU_Context context = 0; Dwarf_Unsigned highest_code = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; die_info_end = _dwarf_calculate_info_section_end_ptr(context); lres = _dwarf_get_abbrev_for_code(context, die->di_abbrev_list->abl_code, &abbrev_list, &highest_code,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ABBREV_MISSING " "There is no abbrev present for code %u " "in this compilation unit. ", die->di_abbrev_list->abl_code); dwarfstring_append_printf_u(&m, "The highest known code " "in any compilation unit is %u .", highest_code); _dwarf_error_string(dbg, error, DW_DLE_ABBREV_MISSING, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context); info_ptr = die->di_debug_ptr; { /* SKIP_LEB128 */ Dwarf_Unsigned ignore_this = 0; Dwarf_Unsigned len = 0; lres = _dwarf_decode_u_leb128_chk(info_ptr, &len,&ignore_this,die_info_end); if (lres == DW_DLV_ERROR) { /* Stepped off the end SKIPping the leb */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DIE_BAD: In building an attrlist " "we run off the end of the DIE while skipping " " the DIE tag, seeing the leb length as 0x%u ", len); _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } info_ptr += len; } do { Dwarf_Signed implicit_const = 0; Dwarf_Attribute new_attr = 0; int res = 0; /* The DECODE have to be wrapped in functions to catch errors before return. */ /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2, dbg,error,abbrev_end); */ res = _dwarf_leb128_uword_wrapper(dbg, &abbrev_ptr,abbrev_end,&attr,error); if (res == DW_DLV_ERROR) { empty_local_attrlist(dbg,head_attr); return res; } if (attr > DW_AT_hi_user) { empty_local_attrlist(dbg,head_attr); _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2, dbg,error,abbrev_end); */ res = _dwarf_leb128_uword_wrapper(dbg, &abbrev_ptr,abbrev_end,&attr_form,error); if (res == DW_DLV_ERROR) { empty_local_attrlist(dbg,head_attr); return res; } if (!_dwarf_valid_form_we_know(attr_form,attr)) { empty_local_attrlist(dbg,head_attr); _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ res = _dwarf_leb128_sword_wrapper(dbg,&abbrev_ptr, abbrev_end, &implicit_const, error); if (res == DW_DLV_ERROR) { empty_local_attrlist(dbg,head_attr); return res; } /*DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_end); */ } if (!_dwarf_valid_form_we_know(attr_form,attr)) { empty_local_attrlist(dbg,head_attr); _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } if (attr != 0) { new_attr = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (new_attr == NULL) { empty_local_attrlist(dbg,head_attr); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form_direct = attr_form; new_attr->ar_attribute_form = attr_form; if (attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6 = 0; if (_dwarf_reference_outside_section(die, (Dwarf_Small*) info_ptr, ((Dwarf_Small*) info_ptr )+1)) { dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR); empty_local_attrlist(dbg,head_attr); _dwarf_error_string(dbg, error, DW_DLE_ATTR_OUTSIDE_SECTION, "DW_DLE_ATTR_OUTSIDE_SECTION: " " Reading Attriutes: " "For DW_FORM_indirect there is" " no room for the form. Corrupt Dwarf"); return DW_DLV_ERROR; } /* DECODE_LEB128_UWORD does info_ptr update DECODE_LEB128_UWORD_CK(info_ptr, utmp6, dbg,error,die_info_end); */ res = _dwarf_leb128_uword_wrapper(dbg, &info_ptr,die_info_end,&utmp6,error); attr_form = (Dwarf_Half) utmp6; new_attr->ar_attribute_form = attr_form; } /* Here the final address must be *inside* the section, as we will read from there, and read at least one byte, we think. We do not want info_ptr to point past end so we add 1 to the end-pointer. */ if ( attr_form != DW_FORM_implicit_const && _dwarf_reference_outside_section(die, (Dwarf_Small*) info_ptr, ((Dwarf_Small*) info_ptr )+1)) { dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR); empty_local_attrlist(dbg,head_attr); _dwarf_error_string(dbg, error, DW_DLE_ATTR_OUTSIDE_SECTION, "DW_DLE_ATTR_OUTSIDE_SECTION: " " Reading Attriutes: " "We have run off the end of the section. " "Corrupt Dwarf"); return DW_DLV_ERROR; } new_attr->ar_cu_context = die->di_cu_context; new_attr->ar_debug_ptr = info_ptr; new_attr->ar_die = die; new_attr->ar_dbg = dbg; if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. Do not increment info_ptr */ new_attr->ar_implicit_const = implicit_const; } else { Dwarf_Unsigned sov = 0; int vres = 0; vres = _dwarf_get_size_of_val(dbg, attr_form, die->di_cu_context->cc_version_stamp, die->di_cu_context->cc_address_size, info_ptr, die->di_cu_context->cc_length_size, &sov, die_info_end, error); if (vres!= DW_DLV_OK) { dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR); empty_local_attrlist(dbg,head_attr); return vres; } info_ptr += sov; } if (head_attr == NULL) head_attr = curr_attr = new_attr; else { curr_attr->ar_next = new_attr; curr_attr = new_attr; } attr_count++; } } while (attr || attr_form); if (!attr_count) { *attrbuf = NULL; *attrcnt = 0; return DW_DLV_NO_ENTRY; } attr_ptr = (Dwarf_Attribute *) _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); if (attr_ptr == NULL) { empty_local_attrlist(dbg,head_attr); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_attr = head_attr; for (i = 0; i < attr_count; i++) { *(attr_ptr + i) = curr_attr; curr_attr = curr_attr->ar_next; } *attrbuf = attr_ptr; *attrcnt = attr_count; return DW_DLV_OK; } /* This function takes a die, and an attr, and returns a pointer to the start of the value of that attr in the given die in the .debug_info section. The form is returned in *attr_form. If the attr_form is DW_FORM_implicit_const (known signed, so most callers) that is fine, but in that case we do not need to actually set the *ptr_to_value. Returns NULL on error, or if attr is not found. However, *attr_form is 0 on error, and positive otherwise. */ static int _dwarf_get_value_ptr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Half * attr_form, Dwarf_Byte_Ptr * ptr_to_value, Dwarf_Signed *implicit_const_out, Dwarf_Error *error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Abbrev_List abbrev_list; Dwarf_Half curr_attr = 0; Dwarf_Half curr_attr_form = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_CU_Context context = die->di_cu_context; Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Debug dbg = 0; int lres = 0; Dwarf_Unsigned highest_code = 0; if (!context) { _dwarf_error(NULL,error,DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } dbg = context->cc_dbg; die_info_end = _dwarf_calculate_info_section_end_ptr(context); lres = _dwarf_get_abbrev_for_code(context, die->di_abbrev_list->abl_code, &abbrev_list,&highest_code,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_CU_DIE_NO_ABBREV_LIST " "There is no abbrev present for code %u " "in this compilation unit. ", die->di_abbrev_list->abl_code); dwarfstring_append_printf_u(&m, "The highest known code " "in any compilation unit is %u.", highest_code); _dwarf_error_string(dbg, error, DW_DLE_CU_DIE_NO_ABBREV_LIST, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context); info_ptr = die->di_debug_ptr; /* This ensures and checks die_info_end >= info_ptr */ { /* SKIP_LEB128 */ Dwarf_Unsigned ignore_this = 0; Dwarf_Unsigned len = 0; lres = _dwarf_decode_u_leb128_chk(info_ptr, &len,&ignore_this,die_info_end); if (lres == DW_DLV_ERROR) { /* Stepped off the end SKIPping the leb */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DIE_BAD: In building an attrlist " "we run off the end of the DIE while skipping " " the DIE tag, seeing the leb length as 0x%u ", len); _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } info_ptr += len; } do { Dwarf_Unsigned formtmp3 = 0; Dwarf_Unsigned atmp3 = 0; Dwarf_Unsigned value_size=0; Dwarf_Signed implicit_const = 0; int res = 0; DECODE_LEB128_UWORD_CK(abbrev_ptr, atmp3,dbg, error,abbrev_end); if (atmp3 > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } curr_attr = (Dwarf_Half) atmp3; DECODE_LEB128_UWORD_CK(abbrev_ptr,formtmp3, dbg,error,abbrev_end); if (!_dwarf_valid_form_we_know(formtmp3,curr_attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } curr_attr_form = (Dwarf_Half) formtmp3; if (curr_attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; /* DECODE_LEB128_UWORD updates info_ptr */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg, error,die_info_end); curr_attr_form = (Dwarf_Half) utmp6; } if (curr_attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_end); } if (curr_attr == attr) { *attr_form = curr_attr_form; if (implicit_const_out) { *implicit_const_out = implicit_const; } *ptr_to_value = info_ptr; return DW_DLV_OK; } res = _dwarf_get_size_of_val(dbg, curr_attr_form, die->di_cu_context->cc_version_stamp, die->di_cu_context->cc_address_size, info_ptr, die->di_cu_context->cc_length_size, &value_size, die_info_end, error); if (res != DW_DLV_OK) { return res; } { Dwarf_Unsigned len = 0; /* ptrdiff_t is generated but not named */ len = (die_info_end >= info_ptr)? (die_info_end - info_ptr):0; if (value_size > len) { /* Something badly wrong. We point past end of debug_info or debug_types or a section is unreasonably sized or we are pointing to two different sections? */ _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD); return DW_DLV_ERROR; } } info_ptr+= value_size; } while (curr_attr != 0 || curr_attr_form != 0); return DW_DLV_NO_ENTRY; } int dwarf_die_text(Dwarf_Die die, Dwarf_Half attrnum, char **ret_name, Dwarf_Error * error) { Dwarf_Debug dbg = 0; int res = DW_DLV_ERROR; Dwarf_Attribute attr = 0; Dwarf_Error lerr = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_attr(die,attrnum,&attr,&lerr); dbg = die->di_cu_context->cc_dbg; if (res == DW_DLV_ERROR) { return DW_DLV_NO_ENTRY; } if (res == DW_DLV_NO_ENTRY) { return res; } res = dwarf_formstring(attr,ret_name,error); dwarf_dealloc(dbg,attr, DW_DLA_ATTR); attr = 0; return res; } int dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error) { return dwarf_die_text(die,DW_AT_name,ret_name,error); } int dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool * return_bool, Dwarf_Error * error) { Dwarf_Half attr_form = 0; Dwarf_Byte_Ptr info_ptr = 0; int res = 0; Dwarf_Signed implicit_const; CHECK_DIE(die, DW_DLV_ERROR); res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, &implicit_const,error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { *return_bool = false; return DW_DLV_OK; } *return_bool = (true); return DW_DLV_OK; } int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute * ret_attr, Dwarf_Error * error) { Dwarf_Half attr_form = 0; Dwarf_Attribute attrib = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Signed implicit_const = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, &implicit_const,error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (!attrib) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL allocating a single Dwarf_Attribute" " in function dwarf_attr()."); return DW_DLV_ERROR; } attrib->ar_attribute = attr; attrib->ar_attribute_form = attr_form; attrib->ar_attribute_form_direct = attr_form; attrib->ar_cu_context = die->di_cu_context; /* Only nonzero if DW_FORM_implicit_const */ attrib->ar_implicit_const = implicit_const; /* Only nonnull if not DW_FORM_implicit_const */ attrib->ar_debug_ptr = info_ptr; attrib->ar_die = die; attrib->ar_dbg = dbg; *ret_attr = attrib; return DW_DLV_OK; } /* A DWP (.dwp) package object never contains .debug_addr, only a normal .o or executable object. Error returned here is on dbg, not tieddbg. This looks for DW_AT_addr_base and if present adds it in appropriately. You should use _dwarf_look_in_local_and_tied_by_index() instead of this, in general. */ static int _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index_to_addr, Dwarf_Addr *addr_out, Dwarf_Error *error) { Dwarf_Unsigned address_base = 0; Dwarf_Unsigned addrindex = index_to_addr; Dwarf_Unsigned addr_offset = 0; Dwarf_Unsigned ret_addr = 0; int res = 0; Dwarf_Byte_Ptr sectionstart = 0; Dwarf_Byte_Ptr sectionend = 0; Dwarf_Unsigned sectionsize = 0; address_base = context->cc_addr_base; res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error); if (res != DW_DLV_OK) { /* Ignore the inner error, report something meaningful */ if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,*error, DW_DLA_ERROR); *error = 0; } _dwarf_error(dbg,error, DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION); return DW_DLV_ERROR; } /* DW_FORM_addrx has a base value from the CU die: DW_AT_addr_base. DW_OP_addrx and DW_OP_constx rely on DW_AT_addr_base too. */ /* DW_FORM_GNU_addr_index relies on DW_AT_GNU_addr_base which is in the CU die. */ sectionstart = dbg->de_debug_addr.dss_data; addr_offset = address_base + (addrindex * context->cc_address_size); /* The offsets table is a series of address-size entries but with a base. */ sectionsize = dbg->de_debug_addr.dss_size; sectionend = sectionstart + sectionsize; if (addr_offset > (sectionsize - context->cc_address_size)) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ATTR_FORM_SIZE_BAD: " "Extracting an address from .debug_addr fails" "as the offset is 0x%x ", addr_offset); dwarfstring_append_printf_u(&m, "but the object section is just 0x%x " "bytes long so there not enough space" " for an address.", sectionsize); _dwarf_error_string(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,ret_addr,Dwarf_Addr, sectionstart + addr_offset, context->cc_address_size, error,sectionend); *addr_out = ret_addr; return DW_DLV_OK; } int _dwarf_look_in_local_and_tied_by_index( Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *return_addr, Dwarf_Error *error) { int res2 = 0; res2 = _dwarf_extract_address_from_debug_addr(dbg, context, index, return_addr, error); if (res2 != DW_DLV_OK) { if (res2 == DW_DLV_ERROR && error && dwarf_errno(*error) == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION && dbg->de_tied_data.td_tied_object) { int res3 = 0; /* We do not want to leak error structs... */ dwarf_dealloc(dbg,*error,DW_DLA_ERROR); *error = 0; /* error is returned on dbg, not tieddbg. */ res3 = _dwarf_get_addr_from_tied(dbg, context,index,return_addr,error); return res3; } return res2; } return DW_DLV_OK; } /* The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr */ int dwarf_debug_addr_index_to_addr(Dwarf_Die die, Dwarf_Unsigned index, Dwarf_Addr *return_addr, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context context = 0; int res = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; /* error is returned on dbg, not tieddbg. */ res = _dwarf_look_in_local_and_tied_by_index(dbg, context, index, return_addr, error); return res; } /* ASSERT: attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_addrx */ int _dwarf_look_in_local_and_tied(Dwarf_Half attr_form, Dwarf_CU_Context context, Dwarf_Small *info_ptr, Dwarf_Addr *return_addr, Dwarf_Error *error) { int res2 = 0; Dwarf_Unsigned index_to_addr = 0; Dwarf_Debug dbg = 0; /* We get the index. It might apply here or in tied object. Checking that next. */ dbg = context->cc_dbg; res2 = _dwarf_get_addr_index_itself(attr_form, info_ptr,dbg,context, &index_to_addr,error); if (res2 != DW_DLV_OK) { return res2; } /* error is returned on dbg, not tieddbg. */ res2 = _dwarf_look_in_local_and_tied_by_index( dbg,context,index_to_addr,return_addr,error); return res2; } int dwarf_lowpc(Dwarf_Die die, Dwarf_Addr * return_addr, Dwarf_Error * error) { Dwarf_Addr ret_addr = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Debug dbg = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; int version = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; int res = 0; Dwarf_CU_Context context = die->di_cu_context; Dwarf_Small *die_info_end = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = context->cc_dbg; address_size = context->cc_address_size; offset_size = context->cc_length_size; res = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form,&info_ptr,0,error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } version = context->cc_version_stamp; class = dwarf_get_form_class(version,DW_AT_low_pc, offset_size,attr_form); if (class != DW_FORM_CLASS_ADDRESS) { /* Not the correct form for DW_AT_low_pc */ _dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS); return DW_DLV_ERROR; } if (attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_addrx) { /* error is returned on dbg, not tieddbg. */ res = _dwarf_look_in_local_and_tied( attr_form, context, info_ptr, return_addr, error); return res; } die_info_end = _dwarf_calculate_info_section_end_ptr(context); READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr, info_ptr, address_size, error,die_info_end); *return_addr = ret_addr; return DW_DLV_OK; } /* This works for DWARF2 and DWARF3 but fails for DWARF4 DW_AT_high_pc attributes of class constant. It is best to cease using this interface. */ int dwarf_highpc(Dwarf_Die die, Dwarf_Addr * return_addr, Dwarf_Error * error) { int res = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; Dwarf_Half form = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_highpc_b(die,return_addr,&form,&class,error); if (res != DW_DLV_OK) { return res; } if (form != DW_FORM_addr) { /* Not the correct form for DWARF2/3 DW_AT_high_pc */ Dwarf_Debug dbg = die->di_cu_context->cc_dbg; _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); return DW_DLV_ERROR; } return DW_DLV_OK; } /* If the giving 'die' contains the DW_AT_type attribute, it returns the offset referenced by the attribute. In case of DW_DLV_NO_ENTRY or DW_DLV_ERROR it sets offset zero. */ int dwarf_dietype_offset(Dwarf_Die die, Dwarf_Off *return_off, Dwarf_Error *error) { int res = 0; Dwarf_Off offset = 0; Dwarf_Attribute attr = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_attr(die,DW_AT_type,&attr,error); if (res == DW_DLV_OK) { res = dwarf_global_formref(attr,&offset,error); dwarf_dealloc(die->di_cu_context->cc_dbg,attr, DW_DLA_ATTR); } *return_off = offset; return res; } int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Debug tieddbg, Dwarf_CU_Context *tiedcontext_out, Dwarf_Error *error) { Dwarf_CU_Context tiedcontext = 0; int res = 0; if (!tieddbg) { return DW_DLV_NO_ENTRY; } if (!context->cc_signature_present) { return DW_DLV_NO_ENTRY; } res = _dwarf_search_for_signature(tieddbg, context->cc_signature, &tiedcontext, error); if ( res == DW_DLV_ERROR) { /* Associate the error with dbg, not tieddbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res == DW_DLV_NO_ENTRY) { return res; } if (!context->cc_low_pc_present) { context->cc_low_pc_present = tiedcontext->cc_low_pc_present; context-> cc_low_pc= tiedcontext->cc_low_pc; } if (!context->cc_addr_base_present) { context-> cc_addr_base_present = tiedcontext->cc_addr_base_present; context-> cc_addr_base= tiedcontext->cc_addr_base; } if (!context->cc_rnglists_base_present) { context-> cc_rnglists_base_present = tiedcontext->cc_rnglists_base_present; context-> cc_rnglists_base= tiedcontext->cc_rnglists_base; } if (!context->cc_loclists_base_present) { context-> cc_loclists_base_present = tiedcontext->cc_loclists_base_present; context-> cc_loclists_base= tiedcontext->cc_loclists_base; } if (!context->cc_str_offsets_base_present) { context-> cc_str_offsets_base_present = tiedcontext->cc_str_offsets_base_present; context-> cc_str_offsets_base= tiedcontext->cc_str_offsets_base; } /* GNU DW4 extension. */ if (!context-> cc_ranges_base_present) { context-> cc_ranges_base_present = tiedcontext->cc_ranges_base_present; context-> cc_ranges_base = tiedcontext->cc_ranges_base; } if (tiedcontext_out) { *tiedcontext_out = tiedcontext; } return DW_DLV_OK; } int _dwarf_get_string_base_attr_value(UNUSEDARG Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *sbase_out, UNUSEDARG Dwarf_Error *error) { if (context->cc_str_offsets_base_present) { *sbase_out = context->cc_str_offsets_base; return DW_DLV_OK; } *sbase_out = 0; return DW_DLV_OK; } /* Goes to the CU die and finds the DW_AT_GNU_addr_base (or DW_AT_addr_base ) and gets the value from that CU die and returns it through abase_out. If we cannot find the value it is a serious error in the DWARF. */ /* This works for all versions of DWARF. This is the preferred interface, cease using dwarf_highpc. The consumer has to check the return_form or return_class to decide if the value returned through return_value is an address or an address-offset. See DWARF4 section 2.17.2, "Contiguous Address Range". */ int dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr * return_value, Dwarf_Half * return_form, enum Dwarf_Form_Class * return_class, Dwarf_Error * error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Debug dbg = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; Dwarf_Half version = 0; Dwarf_Byte_Ptr die_info_end = 0; int res = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; address_size = die->di_cu_context->cc_address_size; res = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr,0,error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } die_info_end = _dwarf_calculate_info_section_end_ptr( die->di_cu_context); version = die->di_cu_context->cc_version_stamp; offset_size = die->di_cu_context->cc_length_size; class = dwarf_get_form_class(version,DW_AT_high_pc, offset_size,attr_form); if (class == DW_FORM_CLASS_ADDRESS) { Dwarf_Addr addr = 0; if (dwarf_addr_form_is_indexed(attr_form)) { Dwarf_Unsigned addr_out = 0; Dwarf_Unsigned index_to_addr = 0; int res2 = 0; Dwarf_CU_Context context = die->di_cu_context; /* index_to_addr we get here might apply to this dbg or to tieddbg. */ /* error is returned on dbg, not tied */ res2 = _dwarf_get_addr_index_itself(attr_form, info_ptr,dbg,context,&index_to_addr,error); if (res2 != DW_DLV_OK) { return res2; } res2= _dwarf_look_in_local_and_tied_by_index(dbg, context, index_to_addr, &addr_out, error); if (res2 != DW_DLV_OK) { return res2; } } READ_UNALIGNED_CK(dbg, addr, Dwarf_Addr, info_ptr, address_size, error,die_info_end); *return_value = addr; } else { int res3 = 0; Dwarf_Unsigned v = 0; res3 = _dwarf_die_attr_unsigned_constant(die,DW_AT_high_pc, &v,error); if (res3 != DW_DLV_OK) { Dwarf_Byte_Ptr info_ptr2 = 0; res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr2,0,error); if (res3 == DW_DLV_ERROR) { return res3; } if (res3 == DW_DLV_NO_ENTRY) { return res3; } if (attr_form == DW_FORM_sdata) { Dwarf_Signed sval = 0; /* DWARF4 defines the value as an unsigned offset in section 2.17.2. */ DECODE_LEB128_UWORD_CK(info_ptr2, sval, dbg,error,die_info_end); *return_value = (Dwarf_Unsigned)sval; } else { _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); return DW_DLV_ERROR; } } else { *return_value = v; } } /* Allow null args starting 22 April 2019. */ if (return_form) { *return_form = attr_form; } if (return_class) { *return_class = class; } return DW_DLV_OK; } /* The dbg and context here are a file with DW_FORM_addrx but missing .debug_addr. So go to the tied file and using the signature from the current context locate the target CU in the tied file Then get the address. */ int _dwarf_get_addr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *addr_out, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; int res = 0; Dwarf_Addr local_addr = 0; Dwarf_CU_Context tiedcontext = 0; if (!context->cc_signature_present) { _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP); return DW_DLV_ERROR; } tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE); return DW_DLV_ERROR; } if (!context->cc_addr_base_present) { /* Does not exist. */ return DW_DLV_NO_ENTRY; } res = _dwarf_search_for_signature(tieddbg, context->cc_signature, &tiedcontext, error); if (res == DW_DLV_ERROR) { /* Associate the error with dbg, not tieddbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res == DW_DLV_NO_ENTRY) { return res; } res = _dwarf_extract_address_from_debug_addr(tieddbg, tiedcontext, index, &local_addr, error); if ( res == DW_DLV_ERROR) { /* Associate the error with dbg, not tidedbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res == DW_DLV_NO_ENTRY) { return res; } *addr_out = local_addr; return DW_DLV_OK; } /* Takes a die, an attribute attr, and checks if attr occurs in die. Attr is required to be an attribute whose form is in the "constant" class. If attr occurs in die, the value is returned. It does not really allow for a signed constant, and DWARF does not always specify that only non-negative values are allowed.. Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as appropriate. Sets the value thru the pointer return_val. This function is meant to do all the processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, and dwarf_srclang. And it helps in dwarf_highpc_with_form(). */ static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned * return_val, Dwarf_Error * error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Unsigned ret_value = 0; Dwarf_Signed implicit_const_value = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Byte_Ptr die_info_end = 0; CHECK_DIE(die, DW_DLV_ERROR); die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context); dbg = die->di_cu_context->cc_dbg; res = _dwarf_get_value_ptr(die,attr,&attr_form, &info_ptr,&implicit_const_value,error); if (res != DW_DLV_OK) { return res; } switch (attr_form) { case DW_FORM_data1: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Small), error,die_info_end); *return_val = ret_value; return DW_DLV_OK; case DW_FORM_data2: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Shalf), error,die_info_end); *return_val = ret_value; return DW_DLV_OK; case DW_FORM_data4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, DWARF_32BIT_SIZE, error,die_info_end); *return_val = ret_value; return DW_DLV_OK; case DW_FORM_data8: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, DWARF_64BIT_SIZE, error,die_info_end); *return_val = ret_value; return DW_DLV_OK; case DW_FORM_udata: { Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_CK(info_ptr, v,dbg,error,die_info_end); *return_val = v; return DW_DLV_OK; } case DW_FORM_implicit_const: { if (implicit_const_value < (Dwarf_Signed)0) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_i(&m, "DW_DLE_NEGATIVE_SIZE " "An implicit const value of " "%d is inappropriate as a size", implicit_const_value); _dwarf_error_string(dbg, error, DW_DLE_NEGATIVE_SIZE, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } *return_val = implicit_const_value; return DW_DLV_OK; } default: _dwarf_error(dbg, error, DW_DLE_DIE_BAD); return DW_DLV_ERROR; } } /* Size Value >= 0 is not specified in DWARF5, but a negative value is surely not meaningful. */ int dwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, error); *ret_size = luns; return res; } /* Size Value >= 0 is not specified in DWARF5, but a negative value is not meaningful. */ int dwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns, error); *ret_size = luns; return res; } /* Size Value >= 0 required. DWARF5 sec5.7.6 */ int dwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns, error); *ret_size = luns; return res; } /* Refer section 3.1, page 21 in Dwarf Definition. Language codes are always non-negative and specified in the DWARF standard*/ int dwarf_srclang(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, error); *ret_size = luns; return res; } /* Refer section 5.4, page 37 in Dwarf Definition. array order values are always non-negative and specified in the DWARF standard*/ int dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns, error); *ret_size = luns; return res; } /* Return DW_DLV_OK if ok DW_DLV_ERROR if failure. If the die and the attr are not related the result is meaningless. */ int dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset /* return offset thru this ptr */, Dwarf_Error * error) { Dwarf_Off attroff = 0; Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; attroff = (attr->ar_debug_ptr - dataptr); *offset = attroff; return DW_DLV_OK; } int dwarf_die_abbrev_code(Dwarf_Die die) { return die->di_abbrev_code; } /* Returns a flag through ablhas_child. Non-zero if the DIE has children, zero if it does not. It has no Dwarf_Error arg! */ int dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child) { if (die->di_abbrev_list) { *ab_has_child = die->di_abbrev_list->abl_has_child; return DW_DLV_OK; } return DW_DLV_ERROR; } /* Helper function for finding form class. Only called for FORMs that might be offsets to one or another section. */ static enum Dwarf_Form_Class dw_get_special_offset(Dwarf_Half attrnum, Dwarf_Half dwversion) { switch (attrnum) { case DW_AT_stmt_list: return DW_FORM_CLASS_LINEPTR; case DW_AT_macro_info: /* DWARF2-DWARF4 */ return DW_FORM_CLASS_MACPTR; case DW_AT_start_scope: case DW_AT_ranges: { if (dwversion <= 4) { return DW_FORM_CLASS_RANGELISTPTR; } return DW_FORM_CLASS_RNGLIST; } case DW_AT_GNU_ranges_base: /* DWARF5-like */ case DW_AT_rnglists_base: /* DWARF5 */ return DW_FORM_CLASS_RNGLISTSPTR; case DW_AT_GNU_macros: /* DWARF5-like */ case DW_AT_macros: /* DWARF5 */ return DW_FORM_CLASS_MACROPTR; case DW_AT_loclists_base: /* DWARF5 */ return DW_FORM_CLASS_LOCLISTSPTR; case DW_AT_GNU_addr_base: /* DWARF55-like */ case DW_AT_addr_base: /* DWARF5 */ return DW_FORM_CLASS_ADDRPTR; case DW_AT_str_offsets_base: /* DWARF5 */ return DW_FORM_CLASS_STROFFSETSPTR; case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: case DW_AT_vtable_elem_location: { if (dwversion <= 4) { return DW_FORM_CLASS_LOCLIST; } return DW_FORM_CLASS_LOCLISTPTR; } case DW_AT_sibling: case DW_AT_byte_size : case DW_AT_bit_offset : case DW_AT_bit_size : case DW_AT_discr : case DW_AT_import : case DW_AT_common_reference: case DW_AT_containing_type: case DW_AT_default_value: case DW_AT_lower_bound: case DW_AT_bit_stride: case DW_AT_upper_bound: case DW_AT_abstract_origin: case DW_AT_base_types: case DW_AT_count: case DW_AT_friend: case DW_AT_namelist_item: case DW_AT_priority: case DW_AT_specification: case DW_AT_type: case DW_AT_allocated: case DW_AT_associated: case DW_AT_byte_stride: case DW_AT_extension: case DW_AT_trampoline: case DW_AT_small: case DW_AT_object_pointer: case DW_AT_signature: return DW_FORM_CLASS_REFERENCE; case DW_AT_MIPS_fde: /* SGI/IRIX extension */ return DW_FORM_CLASS_FRAMEPTR; } return DW_FORM_CLASS_UNKNOWN; } static int block_means_locexpr(Dwarf_Half attr) { switch(attr) { case DW_AT_bit_size: case DW_AT_byte_size: case DW_AT_call_data_location: case DW_AT_call_data_value: case DW_AT_call_value: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_GNU_call_site_target: case DW_AT_GNU_call_site_value: case DW_AT_location: case DW_AT_return_addr: case DW_AT_segment: case DW_AT_static_link: case DW_AT_string_length: case DW_AT_use_location: case DW_AT_vtable_elem_location: return TRUE; } return FALSE; } /* It takes 4 pieces of data (including the FORM) to accurately determine the form 'class' as documented in the DWARF spec. This is per DWARF4, but will work for DWARF2 or 3 as well. */ enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half dwversion, Dwarf_Half attrnum, Dwarf_Half offset_size, Dwarf_Half form) { switch (form) { case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS; case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data4: if (dwversion <= 3 && offset_size == 4) { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } return DW_FORM_CLASS_CONSTANT; case DW_FORM_data8: if (dwversion <= 3 && offset_size == 8) { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } return DW_FORM_CLASS_CONSTANT; case DW_FORM_sec_offset: { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } /* We do not know what this is. */ return DW_FORM_CLASS_UNKNOWN; break; case DW_FORM_string: return DW_FORM_CLASS_STRING; case DW_FORM_strp: return DW_FORM_CLASS_STRING; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: if (dwversion <= 3) { if (block_means_locexpr(attrnum)) { return DW_FORM_CLASS_EXPRLOC; } } return DW_FORM_CLASS_BLOCK; /* DWARF4 and DWARF5 */ case DW_FORM_exprloc: return DW_FORM_CLASS_EXPRLOC; case DW_FORM_data16: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT; case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT; case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT; case DW_FORM_ref_addr: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref1: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref2: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref4: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref8: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref_udata: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref_sig8: return DW_FORM_CLASS_REFERENCE; case DW_FORM_flag: return DW_FORM_CLASS_FLAG; case DW_FORM_flag_present: return DW_FORM_CLASS_FLAG; case DW_FORM_addrx: case DW_FORM_addrx1: case DW_FORM_addrx2: case DW_FORM_addrx3: case DW_FORM_addrx4: return DW_FORM_CLASS_ADDRESS; /* DWARF5 */ case DW_FORM_GNU_addr_index: return DW_FORM_CLASS_ADDRESS; case DW_FORM_strx: /* DWARF5 */ case DW_FORM_strx1: /* DWARF5 */ case DW_FORM_strx2: /* DWARF5 */ case DW_FORM_strx3: /* DWARF5 */ case DW_FORM_line_strp: /* DWARF5 */ case DW_FORM_strp_sup: /* DWARF5 */ case DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING; case DW_FORM_GNU_str_index: return DW_FORM_CLASS_STRING; case DW_FORM_rnglistx: return DW_FORM_CLASS_RNGLIST; /* DWARF5 */ case DW_FORM_loclistx: return DW_FORM_CLASS_LOCLIST; /* DWARF5 */ case DW_FORM_GNU_ref_alt: return DW_FORM_CLASS_REFERENCE; case DW_FORM_implicit_const: return DW_FORM_CLASS_CONSTANT; /* DWARF5 */ case DW_FORM_indirect: default: break; }; return DW_FORM_CLASS_UNKNOWN; } /* Given a DIE, figure out what the CU's DWARF version is and the size of an offset and return it through the *version pointer and return DW_DLV_OK. If we cannot find a CU, return DW_DLV_ERROR on error. In case of error no Dwarf_Debug was available, so setting a Dwarf_Error is somewhat futile. Never returns DW_DLV_NO_ENTRY. */ int dwarf_get_version_of_die(Dwarf_Die die, Dwarf_Half *version, Dwarf_Half *offset_size) { Dwarf_CU_Context cucontext = 0; if (!die) { return DW_DLV_ERROR; } cucontext = die->di_cu_context; if (!cucontext) { return DW_DLV_ERROR; } *version = cucontext->cc_version_stamp; *offset_size = cucontext->cc_length_size; return DW_DLV_OK; } Dwarf_Byte_Ptr _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context, Dwarf_Unsigned *section_len) { Dwarf_Debug dbg = 0; Dwarf_Small *dataptr = 0; struct Dwarf_Section_s *sec = 0; dbg = context->cc_dbg; sec = context->cc_is_info? &dbg->de_debug_info: &dbg->de_debug_types; dataptr = sec->dss_data; *section_len = sec->dss_size; return dataptr; } Dwarf_Byte_Ptr _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context) { Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr info_end = 0; Dwarf_Byte_Ptr info_start = 0; Dwarf_Off off2 = 0; Dwarf_Small *dataptr = 0; dbg = context->cc_dbg; dataptr = context->cc_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; off2 = context->cc_debug_offset; info_start = dataptr + off2; info_end = info_start + context->cc_length + context->cc_length_size + context->cc_extension_size; return info_end; } Dwarf_Byte_Ptr _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context) { Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Byte_Ptr abbrev_start = 0; struct Dwarf_Section_s *sec = 0; dbg = context->cc_dbg; sec = &dbg->de_debug_abbrev; abbrev_start = sec->dss_data; abbrev_end = abbrev_start + sec->dss_size; return abbrev_end; } /* New December 2020. Any Dwarf_Die will work. The values returned are about the CU itself, not a DIE. extension_size is set zero unless it offset_size is 64 and it is standard Dwarf, in which case extension_size is set to 4. If there is no signature *signature is set zero, offset_of_length is the section offset of the first byte of the compilation-unit length field. total_byte_length includes the length field and all the CU data. The offset of the first byte of the CU is therefore offset_of_lenth + offset_size + extension_size. is_info is always non-zero except if the section of the CU is DWARF4 .debug_types. */ int dwarf_cu_header_basics(Dwarf_Die die, Dwarf_Half *version, Dwarf_Bool *is_info, Dwarf_Bool *is_dwo, Dwarf_Half *offset_size, Dwarf_Half *address_size, Dwarf_Half *extension_size, Dwarf_Sig8 **signature, Dwarf_Off *offset_of_length, Dwarf_Unsigned *total_byte_length, Dwarf_Error *error) { Dwarf_CU_Context context = 0; CHECK_DIE(die, DW_DLV_ERROR); context= die->di_cu_context; if (version) { *version = context->cc_version_stamp; } if (is_info) { /* ASSERT: matches context->cc_is_info */ *is_info = die->di_is_info; } if (is_dwo) { *is_dwo = context->cc_is_dwo; } if (offset_size) { *offset_size = context->cc_length_size; } if (address_size) { *address_size = context->cc_address_size; } if (extension_size) { *extension_size = context->cc_extension_size; } if (signature) { if (context->cc_signature_present) { *signature = &context->cc_signature; } else { *signature = 0; } } if (offset_of_length) { *offset_of_length = context->cc_debug_offset; } if (total_byte_length) { *total_byte_length = context->cc_length + context->cc_length_size + context->cc_extension_size; } return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf.h0000664000175000017500000022257614053207641013562 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2007-2021 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Latest update 2021-02-23 with DW_AT_ghs_* entries. */ #ifndef __DWARF_H #define __DWARF_H #ifdef __cplusplus extern "C" { #endif /* dwarf.h DWARF debugging information values $Revision: 1.41 $ $Date: 2006/04/17 00:09:56 $ The comment "DWARF3" appears where there are new entries from DWARF3 as of 2004, "DWARF3f" where there are new entries as of the November 2005 public review document and other comments apply where extension entries appear. Extensions part of DWARF4 are marked DWARF4. A few extension names have omitted the 'vendor id' (See chapter 7, "Vendor Extensibility"). Please always use a 'vendor id' string in extension names. Vendors should use a vendor string in names and wherever possible avoid duplicating values used by other vendor extensions The DWARF1 comments indicate values unused in DWARF2 and later but used or reserved in DWARF1. */ #define DW_TAG_array_type 0x01 #define DW_TAG_class_type 0x02 #define DW_TAG_entry_point 0x03 #define DW_TAG_enumeration_type 0x04 #define DW_TAG_formal_parameter 0x05 /* TAG_global_subroutine 0x06 DWARF1 only */ /* TAG_global_variable 0x07 DWARF1 only */ #define DW_TAG_imported_declaration 0x08 /* reserved by DWARF1 0x09 DWARF1 only */ #define DW_TAG_label 0x0a #define DW_TAG_lexical_block 0x0b /* TAG_local_variable 0x0c DWARF1 only. */ #define DW_TAG_member 0x0d /* reserved by DWARF1 0x0e DWARF1 only */ #define DW_TAG_pointer_type 0x0f #define DW_TAG_reference_type 0x10 #define DW_TAG_compile_unit 0x11 #define DW_TAG_string_type 0x12 #define DW_TAG_structure_type 0x13 /* TAG_subroutine 0x14 DWARF1 only */ #define DW_TAG_subroutine_type 0x15 #define DW_TAG_typedef 0x16 #define DW_TAG_union_type 0x17 #define DW_TAG_unspecified_parameters 0x18 #define DW_TAG_variant 0x19 #define DW_TAG_common_block 0x1a #define DW_TAG_common_inclusion 0x1b #define DW_TAG_inheritance 0x1c #define DW_TAG_inlined_subroutine 0x1d #define DW_TAG_module 0x1e #define DW_TAG_ptr_to_member_type 0x1f #define DW_TAG_set_type 0x20 #define DW_TAG_subrange_type 0x21 #define DW_TAG_with_stmt 0x22 #define DW_TAG_access_declaration 0x23 #define DW_TAG_base_type 0x24 #define DW_TAG_catch_block 0x25 #define DW_TAG_const_type 0x26 #define DW_TAG_constant 0x27 #define DW_TAG_enumerator 0x28 #define DW_TAG_file_type 0x29 #define DW_TAG_friend 0x2a #define DW_TAG_namelist 0x2b /* Early releases of this header had the following misspelled with a trailing 's' */ #define DW_TAG_namelist_item 0x2c /* DWARF3/2 spelling */ #define DW_TAG_namelist_items 0x2c /*SGI misspelling/typo*/ #define DW_TAG_packed_type 0x2d #define DW_TAG_subprogram 0x2e /* The DWARF2 document had two spellings of the following two TAGs, DWARF3 specifies the longer spelling. */ #define DW_TAG_template_type_parameter 0x2f /* DWARF3/2 spelling*/ #define DW_TAG_template_type_param 0x2f /* DWARF2 spelling*/ #define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/ #define DW_TAG_template_value_param 0x30 /* DWARF2 spelling*/ #define DW_TAG_thrown_type 0x31 #define DW_TAG_try_block 0x32 #define DW_TAG_variant_part 0x33 #define DW_TAG_variable 0x34 #define DW_TAG_volatile_type 0x35 #define DW_TAG_dwarf_procedure 0x36 /* DWARF3 */ #define DW_TAG_restrict_type 0x37 /* DWARF3 */ #define DW_TAG_interface_type 0x38 /* DWARF3 */ #define DW_TAG_namespace 0x39 /* DWARF3 */ #define DW_TAG_imported_module 0x3a /* DWARF3 */ #define DW_TAG_unspecified_type 0x3b /* DWARF3 */ #define DW_TAG_partial_unit 0x3c /* DWARF3 */ #define DW_TAG_imported_unit 0x3d /* DWARF3 */ /* Do not use DW_TAG_mutable_type */ #define DW_TAG_mutable_type 0x3e /*Withdrawn from DWARF3 by DWARF3f*/ #define DW_TAG_condition 0x3f /* DWARF3f */ #define DW_TAG_shared_type 0x40 /* DWARF3f */ #define DW_TAG_type_unit 0x41 /* DWARF4 */ #define DW_TAG_rvalue_reference_type 0x42 /* DWARF4 */ #define DW_TAG_template_alias 0x43 /* DWARF4 */ #define DW_TAG_coarray_type 0x44 /* DWARF5 */ #define DW_TAG_generic_subrange 0x45 /* DWARF5 */ #define DW_TAG_dynamic_type 0x46 /* DWARF5 */ #define DW_TAG_atomic_type 0x47 /* DWARF5 */ #define DW_TAG_call_site 0x48 /* DWARF5 */ #define DW_TAG_call_site_parameter 0x49 /* DWARF5 */ #define DW_TAG_skeleton_unit 0x4a /* DWARF5 */ #define DW_TAG_immutable_type 0x4b /* DWARF5 */ #define DW_TAG_lo_user 0x4080 #define DW_TAG_MIPS_loop 0x4081 /* HP extensions: ftp://ftp.hp.com/pub/lang/tools/\ WDB/wdb-4.0.tar.gz */ #define DW_TAG_HP_array_descriptor 0x4090 /* HP */ /* GNU extensions. The first 3 missing the GNU_. */ #define DW_TAG_format_label 0x4101 /* GNU. Fortran. */ #define DW_TAG_function_template 0x4102 /* GNU. For C++ */ #define DW_TAG_class_template 0x4103 /* GNU. For C++ */ #define DW_TAG_GNU_BINCL 0x4104 /* GNU */ #define DW_TAG_GNU_EINCL 0x4105 /* GNU */ /* GNU extension. http://gcc.gnu.org/wiki/TemplateParmsDwarf */ #define DW_TAG_GNU_template_template_parameter 0x4106 /* GNU */ #define DW_TAG_GNU_template_template_param 0x4106 /* GNU */ #define DW_TAG_GNU_template_parameter_pack 0x4107 /* GNU */ #define DW_TAG_GNU_formal_parameter_pack 0x4108 /* GNU */ #define DW_TAG_GNU_call_site 0x4109 /* GNU */ #define DW_TAG_GNU_call_site_parameter 0x410a /* GNU */ /* ALTIUM extensions */ /* DSP-C/Starcore __circ qualifier */ #define DW_TAG_ALTIUM_circ_type 0x5101 /* ALTIUM */ /* Starcore __mwa_circ qualifier */ #define DW_TAG_ALTIUM_mwa_circ_type 0x5102 /* ALTIUM */ /* Starcore __rev_carry qualifier */ #define DW_TAG_ALTIUM_rev_carry_type 0x5103 /* ALTIUM */ /* M16 __rom qualifier */ #define DW_TAG_ALTIUM_rom 0x5111 /* ALTIUM */ /* The following 3 are extensions to support UPC */ #define DW_TAG_upc_shared_type 0x8765 /* UPC */ #define DW_TAG_upc_strict_type 0x8766 /* UPC */ #define DW_TAG_upc_relaxed_type 0x8767 /* UPC */ /* The following are SUN extensions */ #define DW_TAG_SUN_function_template 0x4201 /* SUN */ #define DW_TAG_SUN_class_template 0x4202 /* SUN */ #define DW_TAG_SUN_struct_template 0x4203 /* SUN */ #define DW_TAG_SUN_union_template 0x4204 /* SUN */ #define DW_TAG_SUN_indirect_inheritance 0x4205 /* SUN */ #define DW_TAG_SUN_codeflags 0x4206 /* SUN */ #define DW_TAG_SUN_memop_info 0x4207 /* SUN */ #define DW_TAG_SUN_omp_child_func 0x4208 /* SUN */ #define DW_TAG_SUN_rtti_descriptor 0x4209 /* SUN */ #define DW_TAG_SUN_dtor_info 0x420a /* SUN */ #define DW_TAG_SUN_dtor 0x420b /* SUN */ #define DW_TAG_SUN_f90_interface 0x420c /* SUN */ #define DW_TAG_SUN_fortran_vax_structure 0x420d /* SUN */ #define DW_TAG_SUN_hi 0x42ff /* SUN */ /* GHS C */ #define DW_TAG_ghs_namespace 0x8004 #define DW_TAG_ghs_using_namespace 0x8005 #define DW_TAG_ghs_using_declaration 0x8006 #define DW_TAG_ghs_template_templ_param 0x8007 /* PGI (STMicroelectronics) extensions. */ #define DW_TAG_PGI_kanji_type 0xa000 /* PGI */ #define DW_TAG_PGI_interface_block 0xa020 /* PGI */ #define DW_TAG_BORLAND_property 0xb000 #define DW_TAG_BORLAND_Delphi_string 0xb001 #define DW_TAG_BORLAND_Delphi_dynamic_array 0xb002 #define DW_TAG_BORLAND_Delphi_set 0xb003 #define DW_TAG_BORLAND_Delphi_variant 0xb004 #define DW_TAG_hi_user 0xffff /* The following two are non-standard. Use DW_CHILDREN_yes and DW_CHILDREN_no instead. These could probably be deleted, but someone might be using them, so they remain. */ #define DW_children_no 0 #define DW_children_yes 1 #define DW_FORM_addr 0x01 /* FORM_REF 0x02 DWARF1 only */ #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 #define DW_FORM_data2 0x05 #define DW_FORM_data4 0x06 #define DW_FORM_data8 0x07 #define DW_FORM_string 0x08 #define DW_FORM_block 0x09 #define DW_FORM_block1 0x0a #define DW_FORM_data1 0x0b #define DW_FORM_flag 0x0c #define DW_FORM_sdata 0x0d #define DW_FORM_strp 0x0e #define DW_FORM_udata 0x0f #define DW_FORM_ref_addr 0x10 #define DW_FORM_ref1 0x11 #define DW_FORM_ref2 0x12 #define DW_FORM_ref4 0x13 #define DW_FORM_ref8 0x14 #define DW_FORM_ref_udata 0x15 #define DW_FORM_indirect 0x16 #define DW_FORM_sec_offset 0x17 /* DWARF4 */ #define DW_FORM_exprloc 0x18 /* DWARF4 */ #define DW_FORM_flag_present 0x19 /* DWARF4 */ #define DW_FORM_strx 0x1a /* DWARF5 */ #define DW_FORM_addrx 0x1b /* DWARF5 */ #define DW_FORM_ref_sup4 0x1c /* DWARF5 */ #define DW_FORM_strp_sup 0x1d /* DWARF5 */ #define DW_FORM_data16 0x1e /* DWARF5 */ #define DW_FORM_line_strp 0x1f /* DWARF5 */ #define DW_FORM_ref_sig8 0x20 /* DWARF4 */ #define DW_FORM_implicit_const 0x21 /* DWARF5 */ #define DW_FORM_loclistx 0x22 /* DWARF5 */ #define DW_FORM_rnglistx 0x23 /* DWARF5 */ #define DW_FORM_ref_sup8 0x24 /* DWARF5 */ #define DW_FORM_strx1 0x25 /* DWARF5 */ #define DW_FORM_strx2 0x26 /* DWARF5 */ #define DW_FORM_strx3 0x27 /* DWARF5 */ #define DW_FORM_strx4 0x28 /* DWARF5 */ #define DW_FORM_addrx1 0x29 /* DWARF5 */ #define DW_FORM_addrx2 0x2a /* DWARF5 */ #define DW_FORM_addrx3 0x2b /* DWARF5 */ #define DW_FORM_addrx4 0x2c /* DWARF5 */ /* Extensions http://gcc.gnu.org/wiki/DebugFission. */ #define DW_FORM_GNU_addr_index 0x1f01 /* GNU, debug_info.dwo.*/ /* GNU, somewhat like DW_FORM_strp */ #define DW_FORM_GNU_str_index 0x1f02 #define DW_FORM_GNU_ref_alt 0x1f20 /* GNU, Offset in .debug_info. */ /* GNU extension. Offset in .debug_str of another object file. */ #define DW_FORM_GNU_strp_alt 0x1f21 #define DW_AT_sibling 0x01 #define DW_AT_location 0x02 #define DW_AT_name 0x03 /* reserved DWARF1 0x04, DWARF1 only */ /* AT_fund_type 0x05, DWARF1 only */ /* AT_mod_fund_type 0x06, DWARF1 only */ /* AT_user_def_type 0x07, DWARF1 only */ /* AT_mod_u_d_type 0x08, DWARF1 only */ #define DW_AT_ordering 0x09 #define DW_AT_subscr_data 0x0a #define DW_AT_byte_size 0x0b #define DW_AT_bit_offset 0x0c #define DW_AT_bit_size 0x0d /* reserved DWARF1 0x0d, DWARF1 only */ #define DW_AT_element_list 0x0f #define DW_AT_stmt_list 0x10 #define DW_AT_low_pc 0x11 #define DW_AT_high_pc 0x12 #define DW_AT_language 0x13 #define DW_AT_member 0x14 #define DW_AT_discr 0x15 #define DW_AT_discr_value 0x16 #define DW_AT_visibility 0x17 #define DW_AT_import 0x18 #define DW_AT_string_length 0x19 #define DW_AT_common_reference 0x1a #define DW_AT_comp_dir 0x1b #define DW_AT_const_value 0x1c #define DW_AT_containing_type 0x1d #define DW_AT_default_value 0x1e /* reserved 0x1f */ #define DW_AT_inline 0x20 #define DW_AT_is_optional 0x21 #define DW_AT_lower_bound 0x22 /* reserved 0x23 */ /* reserved 0x24 */ #define DW_AT_producer 0x25 /* reserved 0x26 */ #define DW_AT_prototyped 0x27 /* reserved 0x28 */ /* reserved 0x29 */ #define DW_AT_return_addr 0x2a /* reserved 0x2b */ #define DW_AT_start_scope 0x2c /* reserved 0x2d */ #define DW_AT_bit_stride 0x2e /* DWARF3 name */ #define DW_AT_stride_size 0x2e /* DWARF2 name */ #define DW_AT_upper_bound 0x2f /* AT_virtual 0x30, DWARF1 only */ #define DW_AT_abstract_origin 0x31 #define DW_AT_accessibility 0x32 #define DW_AT_address_class 0x33 #define DW_AT_artificial 0x34 #define DW_AT_base_types 0x35 #define DW_AT_calling_convention 0x36 #define DW_AT_count 0x37 #define DW_AT_data_member_location 0x38 #define DW_AT_decl_column 0x39 #define DW_AT_decl_file 0x3a #define DW_AT_decl_line 0x3b #define DW_AT_declaration 0x3c #define DW_AT_discr_list 0x3d /* DWARF2 */ #define DW_AT_encoding 0x3e #define DW_AT_external 0x3f #define DW_AT_frame_base 0x40 #define DW_AT_friend 0x41 #define DW_AT_identifier_case 0x42 #define DW_AT_macro_info 0x43 /* DWARF{234} not DWARF5 */ #define DW_AT_namelist_item 0x44 #define DW_AT_priority 0x45 #define DW_AT_segment 0x46 #define DW_AT_specification 0x47 #define DW_AT_static_link 0x48 #define DW_AT_type 0x49 #define DW_AT_use_location 0x4a #define DW_AT_variable_parameter 0x4b #define DW_AT_virtuality 0x4c #define DW_AT_vtable_elem_location 0x4d #define DW_AT_allocated 0x4e /* DWARF3 */ #define DW_AT_associated 0x4f /* DWARF3 */ #define DW_AT_data_location 0x50 /* DWARF3 */ #define DW_AT_byte_stride 0x51 /* DWARF3f */ #define DW_AT_stride 0x51 /* DWARF3 (do not use) */ #define DW_AT_entry_pc 0x52 /* DWARF3 */ #define DW_AT_use_UTF8 0x53 /* DWARF3 */ #define DW_AT_extension 0x54 /* DWARF3 */ #define DW_AT_ranges 0x55 /* DWARF3 */ #define DW_AT_trampoline 0x56 /* DWARF3 */ #define DW_AT_call_column 0x57 /* DWARF3 */ #define DW_AT_call_file 0x58 /* DWARF3 */ #define DW_AT_call_line 0x59 /* DWARF3 */ #define DW_AT_description 0x5a /* DWARF3 */ #define DW_AT_binary_scale 0x5b /* DWARF3f */ #define DW_AT_decimal_scale 0x5c /* DWARF3f */ #define DW_AT_small 0x5d /* DWARF3f */ #define DW_AT_decimal_sign 0x5e /* DWARF3f */ #define DW_AT_digit_count 0x5f /* DWARF3f */ #define DW_AT_picture_string 0x60 /* DWARF3f */ #define DW_AT_mutable 0x61 /* DWARF3f */ #define DW_AT_threads_scaled 0x62 /* DWARF3f */ #define DW_AT_explicit 0x63 /* DWARF3f */ #define DW_AT_object_pointer 0x64 /* DWARF3f */ #define DW_AT_endianity 0x65 /* DWARF3f */ #define DW_AT_elemental 0x66 /* DWARF3f */ #define DW_AT_pure 0x67 /* DWARF3f */ #define DW_AT_recursive 0x68 /* DWARF3f */ #define DW_AT_signature 0x69 /* DWARF4 */ #define DW_AT_main_subprogram 0x6a /* DWARF4 */ #define DW_AT_data_bit_offset 0x6b /* DWARF4 */ #define DW_AT_const_expr 0x6c /* DWARF4 */ #define DW_AT_enum_class 0x6d /* DWARF4 */ #define DW_AT_linkage_name 0x6e /* DWARF4 */ #define DW_AT_string_length_bit_size 0x6f /* DWARF5 */ #define DW_AT_string_length_byte_size 0x70 /* DWARF5 */ #define DW_AT_rank 0x71 /* DWARF5 */ #define DW_AT_str_offsets_base 0x72 /* DWARF5 */ #define DW_AT_addr_base 0x73 /* DWARF5 */ /* Use DW_AT_rnglists_base, DW_AT_ranges_base is obsolete as */ /* it was only used in some DWARF5 drafts, not the final DWARF5. */ #define DW_AT_rnglists_base 0x74 /* DWARF5 */ /* DW_AT_dwo_id, an experiment in some DWARF4+. Not DWARF5! */ #define DW_AT_dwo_id 0x75 /* DWARF4!*/ #define DW_AT_dwo_name 0x76 /* DWARF5 */ #define DW_AT_reference 0x77 /* DWARF5 */ #define DW_AT_rvalue_reference 0x78 /* DWARF5 */ #define DW_AT_macros 0x79 /* DWARF5 */ #define DW_AT_call_all_calls 0x7a /* DWARF5 */ #define DW_AT_call_all_source_calls 0x7b /* DWARF5 */ #define DW_AT_call_all_tail_calls 0x7c /* DWARF5 */ #define DW_AT_call_return_pc 0x7d /* DWARF5 */ #define DW_AT_call_value 0x7e /* DWARF5 */ #define DW_AT_call_origin 0x7f /* DWARF5 */ #define DW_AT_call_parameter 0x80 /* DWARF5 */ #define DW_AT_call_pc 0x81 /* DWARF5 */ #define DW_AT_call_tail_call 0x82 /* DWARF5 */ #define DW_AT_call_target 0x83 /* DWARF5 */ #define DW_AT_call_target_clobbered 0x84 /* DWARF5 */ #define DW_AT_call_data_location 0x85 /* DWARF5 */ #define DW_AT_call_data_value 0x86 /* DWARF5 */ #define DW_AT_noreturn 0x87 /* DWARF5 */ #define DW_AT_alignment 0x88 /* DWARF5 */ #define DW_AT_export_symbols 0x89 /* DWARF5 */ #define DW_AT_deleted 0x8a /* DWARF5 */ #define DW_AT_defaulted 0x8b /* DWARF5 */ #define DW_AT_loclists_base 0x8c /* DWARF5 */ /* GreenHills, ghs.com GHS C */ #define DW_AT_ghs_namespace_alias 0x806 #define DW_AT_ghs_using_namespace 0x807 #define DW_AT_ghs_using_declaration 0x808 /* In extensions, we attempt to include the vendor extension in the name even when the vendor leaves it out. */ /* HP extensions. */ #define DW_AT_HP_block_index 0x2000 /* HP */ /* 0x2000 Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_AT_lo_user 0x2000 #define DW_AT_MIPS_fde 0x2001 /* MIPS/SGI */ #define DW_AT_MIPS_loop_begin 0x2002 /* MIPS/SGI */ #define DW_AT_MIPS_tail_loop_begin 0x2003 /* MIPS/SGI */ #define DW_AT_MIPS_epilog_begin 0x2004 /* MIPS/SGI */ #define DW_AT_MIPS_loop_unroll_factor 0x2005 /* MIPS/SGI */ #define DW_AT_MIPS_software_pipeline_depth 0x2006 /* MIPS/SGI */ #define DW_AT_MIPS_linkage_name 0x2007 /* MIPS/SGI,GNU,and others.*/ #define DW_AT_MIPS_stride 0x2008 /* MIPS/SGI */ #define DW_AT_MIPS_abstract_name 0x2009 /* MIPS/SGI */ #define DW_AT_MIPS_clone_origin 0x200a /* MIPS/SGI */ #define DW_AT_MIPS_has_inlines 0x200b /* MIPS/SGI */ #define DW_AT_MIPS_stride_byte 0x200c /* MIPS/SGI */ #define DW_AT_MIPS_stride_elem 0x200d /* MIPS/SGI */ #define DW_AT_MIPS_ptr_dopetype 0x200e /* MIPS/SGI */ #define DW_AT_MIPS_allocatable_dopetype 0x200f /* MIPS/SGI */ #define DW_AT_MIPS_assumed_shape_dopetype 0x2010 /* MIPS/SGI */ #define DW_AT_MIPS_assumed_size 0x2011 /* MIPS/SGI */ /* HP extensions. */ #define DW_AT_HP_unmodifiable 0x2001 /* conflict: MIPS */ #define DW_AT_HP_prologue 0x2005 /* conflict: MIPS */ #define DW_AT_HP_epilogue 0x2008 /* conflict: MIPS */ #define DW_AT_HP_actuals_stmt_list 0x2010 /* conflict: MIPS */ #define DW_AT_HP_proc_per_section 0x2011 /* conflict: MIPS */ #define DW_AT_HP_raw_data_ptr 0x2012 /* HP */ #define DW_AT_HP_pass_by_reference 0x2013 /* HP */ #define DW_AT_HP_opt_level 0x2014 /* HP */ #define DW_AT_HP_prof_version_id 0x2015 /* HP */ #define DW_AT_HP_opt_flags 0x2016 /* HP */ #define DW_AT_HP_cold_region_low_pc 0x2017 /* HP */ #define DW_AT_HP_cold_region_high_pc 0x2018 /* HP */ #define DW_AT_HP_all_variables_modifiable 0x2019 /* HP */ #define DW_AT_HP_linkage_name 0x201a /* HP */ #define DW_AT_HP_prof_flags 0x201b /* HP */ #define DW_AT_HP_unit_name 0x201f #define DW_AT_HP_unit_size 0x2020 #define DW_AT_HP_widened_byte_size 0x2021 #define DW_AT_HP_definition_points 0x2022 #define DW_AT_HP_default_location 0x2023 #define DW_AT_HP_is_result_param 0x2029 #define DW_AT_CPQ_discontig_ranges 0x2001 /* COMPAQ/HP */ #define DW_AT_CPQ_semantic_events 0x2002 /* COMPAQ/HP */ #define DW_AT_CPQ_split_lifetimes_var 0x2003 /* COMPAQ/HP */ #define DW_AT_CPQ_split_lifetimes_rtn 0x2004 /* COMPAQ/HP */ #define DW_AT_CPQ_prologue_length 0x2005 /* COMPAQ/HP */ /* From GHS C GreenHills ghs.com */ #define DW_AT_ghs_mangled 0x2007 /* conflict MIPS */ #define DW_AT_ghs_rsm 0x2083 #define DW_AT_ghs_frsm 0x2085 #define DW_AT_ghs_frames 0x2086 #define DW_AT_ghs_rso 0x2087 #define DW_AT_ghs_subcpu 0x2092 #define DW_AT_ghs_lbrace_line 0x2093 #define DW_AT_INTEL_other_endian 0x2026 /* Intel, 1 if byte swapped.*/ /* GNU extensions. */ #define DW_AT_sf_names 0x2101 /* GNU */ #define DW_AT_src_info 0x2102 /* GNU */ #define DW_AT_mac_info 0x2103 /* GNU */ #define DW_AT_src_coords 0x2104 /* GNU */ #define DW_AT_body_begin 0x2105 /* GNU */ #define DW_AT_body_end 0x2106 /* GNU */ #define DW_AT_GNU_vector 0x2107 /* GNU */ /* Thread safety, see http://gcc.gnu.org/wiki/ThreadSafetyAnnotation . */ /* The values here are from gcc-4.6.2 include/dwarf2.h. The values are not given on the web page at all, nor on web pages it refers to. */ #define DW_AT_GNU_guarded_by 0x2108 /* GNU */ #define DW_AT_GNU_pt_guarded_by 0x2109 /* GNU */ #define DW_AT_GNU_guarded 0x210a /* GNU */ #define DW_AT_GNU_pt_guarded 0x210b /* GNU */ #define DW_AT_GNU_locks_excluded 0x210c /* GNU */ #define DW_AT_GNU_exclusive_locks_required 0x210d /* GNU */ #define DW_AT_GNU_shared_locks_required 0x210e /* GNU */ /* See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo */ #define DW_AT_GNU_odr_signature 0x210f /* GNU */ /* See See http://gcc.gnu.org/wiki/TemplateParmsDwarf */ /* The value here is from gcc-4.6.2 include/dwarf2.h. The value is not consistent with the web page as of December 2011. */ #define DW_AT_GNU_template_name 0x2110 /* GNU */ /* The GNU call site extension. See http://www.dwarfstd.org/ShowIssue.php?\ issue=100909.2&type=open . */ #define DW_AT_GNU_call_site_value 0x2111 /* GNU */ #define DW_AT_GNU_call_site_data_value 0x2112 /* GNU */ #define DW_AT_GNU_call_site_target 0x2113 /* GNU */ #define DW_AT_GNU_call_site_target_clobbered 0x2114 /* GNU */ #define DW_AT_GNU_tail_call 0x2115 /* GNU */ #define DW_AT_GNU_all_tail_call_sites 0x2116 /* GNU */ #define DW_AT_GNU_all_call_sites 0x2117 /* GNU */ #define DW_AT_GNU_all_source_call_sites 0x2118 /* GNU */ /* Section offset to .debug_macro section. */ #define DW_AT_GNU_macros 0x2119 /* GNU */ #define DW_AT_GNU_deleted 0x211a /* GNU */ /* The GNU DebugFission project: http://gcc.gnu.org/wiki/DebugFission */ #define DW_AT_GNU_dwo_name 0x2130 /* GNU */ #define DW_AT_GNU_dwo_id 0x2131 /* GNU */ #define DW_AT_GNU_ranges_base 0x2132 /* GNU */ #define DW_AT_GNU_addr_base 0x2133 /* GNU */ #define DW_AT_GNU_pubnames 0x2134 /* GNU */ #define DW_AT_GNU_pubtypes 0x2135 /* GNU */ /* To distinguish distinct basic blocks in a single source line. */ #define DW_AT_GNU_discriminator 0x2136 /* GNU */ #define DW_AT_GNU_locviews 0x2137 /* GNU */ #define DW_AT_GNU_entry_view 0x2138 /* GNU */ /* See https://gcc.gnu.org/wiki/DW_AT_GNU_bias */ #define DW_AT_GNU_bias 0x2305 /* Sun extensions */ #define DW_AT_SUN_template 0x2201 /* SUN */ #define DW_AT_VMS_rtnbeg_pd_address 0x2201 /* VMS */ #define DW_AT_SUN_alignment 0x2202 /* SUN */ #define DW_AT_SUN_vtable 0x2203 /* SUN */ #define DW_AT_SUN_count_guarantee 0x2204 /* SUN */ #define DW_AT_SUN_command_line 0x2205 /* SUN */ #define DW_AT_SUN_vbase 0x2206 /* SUN */ #define DW_AT_SUN_compile_options 0x2207 /* SUN */ #define DW_AT_SUN_language 0x2208 /* SUN */ #define DW_AT_SUN_browser_file 0x2209 /* SUN */ #define DW_AT_SUN_vtable_abi 0x2210 /* SUN */ #define DW_AT_SUN_func_offsets 0x2211 /* SUN */ #define DW_AT_SUN_cf_kind 0x2212 /* SUN */ #define DW_AT_SUN_vtable_index 0x2213 /* SUN */ #define DW_AT_SUN_omp_tpriv_addr 0x2214 /* SUN */ #define DW_AT_SUN_omp_child_func 0x2215 /* SUN */ #define DW_AT_SUN_func_offset 0x2216 /* SUN */ #define DW_AT_SUN_memop_type_ref 0x2217 /* SUN */ #define DW_AT_SUN_profile_id 0x2218 /* SUN */ #define DW_AT_SUN_memop_signature 0x2219 /* SUN */ #define DW_AT_SUN_obj_dir 0x2220 /* SUN */ #define DW_AT_SUN_obj_file 0x2221 /* SUN */ #define DW_AT_SUN_original_name 0x2222 /* SUN */ #define DW_AT_SUN_hwcprof_signature 0x2223 /* SUN */ #define DW_AT_SUN_amd64_parmdump 0x2224 /* SUN */ #define DW_AT_SUN_part_link_name 0x2225 /* SUN */ #define DW_AT_SUN_link_name 0x2226 /* SUN */ #define DW_AT_SUN_pass_with_const 0x2227 /* SUN */ #define DW_AT_SUN_return_with_const 0x2228 /* SUN */ #define DW_AT_SUN_import_by_name 0x2229 /* SUN */ #define DW_AT_SUN_f90_pointer 0x222a /* SUN */ #define DW_AT_SUN_pass_by_ref 0x222b /* SUN */ #define DW_AT_SUN_f90_allocatable 0x222c /* SUN */ #define DW_AT_SUN_f90_assumed_shape_array 0x222d /* SUN */ #define DW_AT_SUN_c_vla 0x222e /* SUN */ #define DW_AT_SUN_return_value_ptr 0x2230 /* SUN */ #define DW_AT_SUN_dtor_start 0x2231 /* SUN */ #define DW_AT_SUN_dtor_length 0x2232 /* SUN */ #define DW_AT_SUN_dtor_state_initial 0x2233 /* SUN */ #define DW_AT_SUN_dtor_state_final 0x2234 /* SUN */ #define DW_AT_SUN_dtor_state_deltas 0x2235 /* SUN */ #define DW_AT_SUN_import_by_lname 0x2236 /* SUN */ #define DW_AT_SUN_f90_use_only 0x2237 /* SUN */ #define DW_AT_SUN_namelist_spec 0x2238 /* SUN */ #define DW_AT_SUN_is_omp_child_func 0x2239 /* SUN */ #define DW_AT_SUN_fortran_main_alias 0x223a /* SUN */ #define DW_AT_SUN_fortran_based 0x223b /* SUN */ /* ALTIUM extension: ALTIUM Compliant location lists (flag) */ #define DW_AT_ALTIUM_loclist 0x2300 /* ALTIUM */ /* Ada GNAT gcc attributes. constant integer forms. */ /* See http://gcc.gnu.org/wiki/DW_AT_GNAT_descriptive_type . */ #define DW_AT_use_GNAT_descriptive_type 0x2301 #define DW_AT_GNAT_descriptive_type 0x2302 #define DW_AT_GNU_numerator 0x2303 /* GNU */ #define DW_AT_GNU_denominator 0x2304 /* GNU */ /* See https://gcc.gnu.org/wiki/DW_AT_GNU_bias */ #define DW_AT_GNU_bias 0x2305 /* GNU */ /* Go-specific type attributes Naming as lower-case go instead of GO is a small mistake by the Go language folks, it seems. This is the common spelling for these. */ #define DW_AT_go_kind 0x2900 #define DW_AT_go_key 0x2901 #define DW_AT_go_elem 0x2902 /* Attribute for DW_TAG_member of a struct type. Nonzero value indicates the struct field is an embedded field.*/ #define DW_AT_go_embedded_field 0x2903 #define DW_AT_go_runtime_type 0x2904 /* UPC extension. */ #define DW_AT_upc_threads_scaled 0x3210 /* UPC */ #define DW_AT_IBM_wsa_addr 0x393e #define DW_AT_IBM_home_location 0x393f #define DW_AT_IBM_alt_srcview 0x3940 /* PGI (STMicroelectronics) extensions. */ /* PGI. Block, constant, reference. This attribute is an ASTPLAB extension used to describe the array local base. */ #define DW_AT_PGI_lbase 0x3a00 /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the section offset, or the offset to the first element in the dimension. */ #define DW_AT_PGI_soffset 0x3a01 /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the linear stride or the distance between elements in the dimension. */ #define DW_AT_PGI_lstride 0x3a02 #define DW_AT_BORLAND_property_read 0x3b11 #define DW_AT_BORLAND_property_write 0x3b12 #define DW_AT_BORLAND_property_implements 0x3b13 #define DW_AT_BORLAND_property_index 0x3b14 #define DW_AT_BORLAND_property_default 0x3b15 #define DW_AT_BORLAND_Delphi_unit 0x3b20 #define DW_AT_BORLAND_Delphi_class 0x3b21 #define DW_AT_BORLAND_Delphi_record 0x3b22 #define DW_AT_BORLAND_Delphi_metaclass 0x3b23 #define DW_AT_BORLAND_Delphi_constructor 0x3b24 #define DW_AT_BORLAND_Delphi_destructor 0x3b25 #define DW_AT_BORLAND_Delphi_anonymous_method 0x3b26 #define DW_AT_BORLAND_Delphi_interface 0x3b27 #define DW_AT_BORLAND_Delphi_ABI 0x3b28 #define DW_AT_BORLAND_Delphi_frameptr 0x3b30 #define DW_AT_BORLAND_closure 0x3b31 #define DW_AT_LLVM_include_path 0x3e00 #define DW_AT_LLVM_config_macros 0x3e01 #define DW_AT_LLVM_sysroot 0x3e02 #define DW_AT_LLVM_tag_offset 0x3e03 /* LLVM intends to use 0x3e04 - 0x3e06 */ #define DW_AT_LLVM_apinotes 0x3e03 #define DW_AT_APPLE_optimized 0x3fe1 #define DW_AT_APPLE_flags 0x3fe2 #define DW_AT_APPLE_isa 0x3fe3 /* 0x3fe4 Also known as DW_AT_APPLE_closure, block preferred. */ #define DW_AT_APPLE_block 0x3fe4 /* The rest of APPLE here are in support of Objective C */ #define DW_AT_APPLE_major_runtime_vers 0x3fe5 #define DW_AT_APPLE_runtime_class 0x3fe6 #define DW_AT_APPLE_omit_frame_ptr 0x3fe7 #define DW_AT_APPLE_property_name 0x3fe8 #define DW_AT_APPLE_property_getter 0x3fe9 #define DW_AT_APPLE_property_setter 0x3fea #define DW_AT_APPLE_property_attribute 0x3feb #define DW_AT_APPLE_objc_complete_type 0x3fec #define DW_AT_APPLE_property 0x3fed #define DW_AT_APPLE_objc_direct 0x3fee #define DW_AT_APPLE_sdk 0x3fef #define DW_AT_hi_user 0x3fff /* OP values 0x01,0x02,0x04,0x05,0x07 are DWARF1 only */ #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 #define DW_OP_const1u 0x08 #define DW_OP_const1s 0x09 #define DW_OP_const2u 0x0a #define DW_OP_const2s 0x0b #define DW_OP_const4u 0x0c #define DW_OP_const4s 0x0d #define DW_OP_const8u 0x0e #define DW_OP_const8s 0x0f #define DW_OP_constu 0x10 #define DW_OP_consts 0x11 #define DW_OP_dup 0x12 #define DW_OP_drop 0x13 #define DW_OP_over 0x14 #define DW_OP_pick 0x15 #define DW_OP_swap 0x16 #define DW_OP_rot 0x17 #define DW_OP_xderef 0x18 #define DW_OP_abs 0x19 #define DW_OP_and 0x1a #define DW_OP_div 0x1b #define DW_OP_minus 0x1c #define DW_OP_mod 0x1d #define DW_OP_mul 0x1e #define DW_OP_neg 0x1f #define DW_OP_not 0x20 #define DW_OP_or 0x21 #define DW_OP_plus 0x22 #define DW_OP_plus_uconst 0x23 #define DW_OP_shl 0x24 #define DW_OP_shr 0x25 #define DW_OP_shra 0x26 #define DW_OP_xor 0x27 #define DW_OP_bra 0x28 #define DW_OP_eq 0x29 #define DW_OP_ge 0x2a #define DW_OP_gt 0x2b #define DW_OP_le 0x2c #define DW_OP_lt 0x2d #define DW_OP_ne 0x2e #define DW_OP_skip 0x2f #define DW_OP_lit0 0x30 #define DW_OP_lit1 0x31 #define DW_OP_lit2 0x32 #define DW_OP_lit3 0x33 #define DW_OP_lit4 0x34 #define DW_OP_lit5 0x35 #define DW_OP_lit6 0x36 #define DW_OP_lit7 0x37 #define DW_OP_lit8 0x38 #define DW_OP_lit9 0x39 #define DW_OP_lit10 0x3a #define DW_OP_lit11 0x3b #define DW_OP_lit12 0x3c #define DW_OP_lit13 0x3d #define DW_OP_lit14 0x3e #define DW_OP_lit15 0x3f #define DW_OP_lit16 0x40 #define DW_OP_lit17 0x41 #define DW_OP_lit18 0x42 #define DW_OP_lit19 0x43 #define DW_OP_lit20 0x44 #define DW_OP_lit21 0x45 #define DW_OP_lit22 0x46 #define DW_OP_lit23 0x47 #define DW_OP_lit24 0x48 #define DW_OP_lit25 0x49 #define DW_OP_lit26 0x4a #define DW_OP_lit27 0x4b #define DW_OP_lit28 0x4c #define DW_OP_lit29 0x4d #define DW_OP_lit30 0x4e #define DW_OP_lit31 0x4f #define DW_OP_reg0 0x50 #define DW_OP_reg1 0x51 #define DW_OP_reg2 0x52 #define DW_OP_reg3 0x53 #define DW_OP_reg4 0x54 #define DW_OP_reg5 0x55 #define DW_OP_reg6 0x56 #define DW_OP_reg7 0x57 #define DW_OP_reg8 0x58 #define DW_OP_reg9 0x59 #define DW_OP_reg10 0x5a #define DW_OP_reg11 0x5b #define DW_OP_reg12 0x5c #define DW_OP_reg13 0x5d #define DW_OP_reg14 0x5e #define DW_OP_reg15 0x5f #define DW_OP_reg16 0x60 #define DW_OP_reg17 0x61 #define DW_OP_reg18 0x62 #define DW_OP_reg19 0x63 #define DW_OP_reg20 0x64 #define DW_OP_reg21 0x65 #define DW_OP_reg22 0x66 #define DW_OP_reg23 0x67 #define DW_OP_reg24 0x68 #define DW_OP_reg25 0x69 #define DW_OP_reg26 0x6a #define DW_OP_reg27 0x6b #define DW_OP_reg28 0x6c #define DW_OP_reg29 0x6d #define DW_OP_reg30 0x6e #define DW_OP_reg31 0x6f #define DW_OP_breg0 0x70 #define DW_OP_breg1 0x71 #define DW_OP_breg2 0x72 #define DW_OP_breg3 0x73 #define DW_OP_breg4 0x74 #define DW_OP_breg5 0x75 #define DW_OP_breg6 0x76 #define DW_OP_breg7 0x77 #define DW_OP_breg8 0x78 #define DW_OP_breg9 0x79 #define DW_OP_breg10 0x7a #define DW_OP_breg11 0x7b #define DW_OP_breg12 0x7c #define DW_OP_breg13 0x7d #define DW_OP_breg14 0x7e #define DW_OP_breg15 0x7f #define DW_OP_breg16 0x80 #define DW_OP_breg17 0x81 #define DW_OP_breg18 0x82 #define DW_OP_breg19 0x83 #define DW_OP_breg20 0x84 #define DW_OP_breg21 0x85 #define DW_OP_breg22 0x86 #define DW_OP_breg23 0x87 #define DW_OP_breg24 0x88 #define DW_OP_breg25 0x89 #define DW_OP_breg26 0x8a #define DW_OP_breg27 0x8b #define DW_OP_breg28 0x8c #define DW_OP_breg29 0x8d #define DW_OP_breg30 0x8e #define DW_OP_breg31 0x8f #define DW_OP_regx 0x90 #define DW_OP_fbreg 0x91 #define DW_OP_bregx 0x92 #define DW_OP_piece 0x93 #define DW_OP_deref_size 0x94 #define DW_OP_xderef_size 0x95 #define DW_OP_nop 0x96 #define DW_OP_push_object_address 0x97 /* DWARF3 */ #define DW_OP_call2 0x98 /* DWARF3 */ #define DW_OP_call4 0x99 /* DWARF3 */ #define DW_OP_call_ref 0x9a /* DWARF3 */ #define DW_OP_form_tls_address 0x9b /* DWARF3f */ #define DW_OP_call_frame_cfa 0x9c /* DWARF3f */ #define DW_OP_bit_piece 0x9d /* DWARF3f */ #define DW_OP_implicit_value 0x9e /* DWARF4 */ #define DW_OP_stack_value 0x9f /* DWARF4 */ #define DW_OP_implicit_pointer 0xa0 /* DWARF5 */ #define DW_OP_addrx 0xa1 /* DWARF5 */ #define DW_OP_constx 0xa2 /* DWARF5 */ #define DW_OP_entry_value 0xa3 /* DWARF5 */ #define DW_OP_const_type 0xa4 /* DWARF5 */ #define DW_OP_regval_type 0xa5 /* DWARF5 */ #define DW_OP_deref_type 0xa6 /* DWARF5 */ #define DW_OP_xderef_type 0xa7 /* DWARF5 */ #define DW_OP_convert 0xa8 /* DWARF5 */ #define DW_OP_reinterpret 0xa9 /* DWARF5 */ #define DW_OP_GNU_push_tls_address 0xe0 /* GNU */ #define DW_OP_WASM_location 0xed #define DW_OP_WASM_location_int 0xee /* Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_OP_lo_user 0xe0 #define DW_OP_GNU_uninit 0xf0 /* GNU */ #define DW_OP_GNU_encoded_addr 0xf1 /* GNU */ #define DW_OP_GNU_implicit_pointer 0xf2 /* GNU */ #define DW_OP_GNU_entry_value 0xf3 /* GNU */ #define DW_OP_GNU_const_type 0xf4 /* GNU */ #define DW_OP_GNU_regval_type 0xf5 /* GNU */ #define DW_OP_GNU_deref_type 0xf6 /* GNU */ #define DW_OP_GNU_convert 0xf7 /* GNU */ #define DW_OP_GNU_reinterpret 0xf9 /* GNU */ #define DW_OP_GNU_parameter_ref 0xfa /* GNU */ #define DW_OP_GNU_addr_index 0xfb /* GNU Fission */ #define DW_OP_GNU_const_index 0xfc /* GNU Fission */ #define DW_OP_GNU_variable_value 0xfd /* GNU 2017 */ /* HP extensions. */ #define DW_OP_HP_unknown 0xe0 /* HP conflict: GNU */ #define DW_OP_HP_is_value 0xe1 /* HP */ #define DW_OP_HP_fltconst4 0xe2 /* HP */ #define DW_OP_HP_fltconst8 0xe3 /* HP */ #define DW_OP_HP_mod_range 0xe4 /* HP */ #define DW_OP_HP_unmod_range 0xe5 /* HP */ #define DW_OP_HP_tls 0xe6 /* HP */ /* Intel: made obsolete by DW_OP_bit_piece above. */ #define DW_OP_INTEL_bit_piece 0xe8 /* Apple extension. */ #define DW_OP_APPLE_uninit 0xf0 /* Apple */ #define DW_OP_PGI_omp_thread_num 0xf8 /* PGI (STMicroelectronics) */ #define DW_OP_hi_user 0xff #define DW_ATE_address 0x01 #define DW_ATE_boolean 0x02 #define DW_ATE_complex_float 0x03 #define DW_ATE_float 0x04 #define DW_ATE_signed 0x05 #define DW_ATE_signed_char 0x06 #define DW_ATE_unsigned 0x07 #define DW_ATE_unsigned_char 0x08 #define DW_ATE_imaginary_float 0x09 /* DWARF3 */ #define DW_ATE_packed_decimal 0x0a /* DWARF3f */ #define DW_ATE_numeric_string 0x0b /* DWARF3f */ #define DW_ATE_edited 0x0c /* DWARF3f */ #define DW_ATE_signed_fixed 0x0d /* DWARF3f */ #define DW_ATE_unsigned_fixed 0x0e /* DWARF3f */ #define DW_ATE_decimal_float 0x0f /* DWARF3f */ #define DW_ATE_UTF 0x10 /* DWARF4 */ #define DW_ATE_UCS 0x11 /* DWARF5 */ #define DW_ATE_ASCII 0x12 /* DWARF5 */ /* ALTIUM extensions. x80, x81 */ #define DW_ATE_ALTIUM_fract 0x80 /* ALTIUM __fract type */ /* Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_ATE_lo_user 0x80 /* Shown here to help dwarfdump build script. */ #define DW_ATE_ALTIUM_accum 0x81 /* ALTIUM __accum type */ /* HP Floating point extensions. */ #define DW_ATE_HP_float80 0x80 /* (80 bit). HP */ #define DW_ATE_HP_complex_float80 0x81 /* Complex (80 bit). HP */ #define DW_ATE_HP_float128 0x82 /* (128 bit). HP */ #define DW_ATE_HP_complex_float128 0x83 /* Complex (128 bit). HP */ #define DW_ATE_HP_floathpintel 0x84 /* (82 bit IA64). HP */ #define DW_ATE_HP_imaginary_float80 0x85 /* HP */ #define DW_ATE_HP_imaginary_float128 0x86 /* HP */ /* Sun extensions */ #define DW_ATE_SUN_interval_float 0x91 /* Obsolete: See DW_ATE_imaginary_float */ #define DW_ATE_SUN_imaginary_float 0x92 #define DW_ATE_hi_user 0xff /* DWARF5 Defaulted Member Encodings. */ #define DW_DEFAULTED_no 0x0 /* DWARF5 */ #define DW_DEFAULTED_in_class 0x1 /* DWARF5 */ #define DW_DEFAULTED_out_of_class 0x2 /* DWARF5 */ #define DW_IDX_compile_unit 0x1 /* DWARF5 */ #define DW_IDX_type_unit 0x2 /* DWARF5 */ #define DW_IDX_die_offset 0x3 /* DWARF5 */ #define DW_IDX_parent 0x4 /* DWARF5 */ #define DW_IDX_type_hash 0x5 /* DWARF5 */ #define DW_IDX_lo_user 0x2000 /* DWARF5 */ #define DW_IDX_hi_user 0x0fff /* DWARF5 */ /* These with not-quite-the-same-names were used in DWARF4 We call then DW_LLEX. Never official and should not be used by anyone.*/ #define DW_LLEX_end_of_list_entry 0x0 #define DW_LLEX_base_address_selection_entry 0x01 #define DW_LLEX_start_end_entry 0x02 #define DW_LLEX_start_length_entry 0x03 #define DW_LLEX_offset_pair_entry 0x04 /* DWARF5 Location List Entries in Split Objects */ #define DW_LLE_end_of_list 0x0 /* DWARF5 */ #define DW_LLE_base_addressx 0x01 /* DWARF5 */ #define DW_LLE_startx_endx 0x02 /* DWARF5 */ #define DW_LLE_startx_length 0x03 /* DWARF5 */ #define DW_LLE_offset_pair 0x04 /* DWARF5 */ #define DW_LLE_default_location 0x05 /* DWARF5 */ #define DW_LLE_base_address 0x06 /* DWARF5 */ #define DW_LLE_start_end 0x07 /* DWARF5 */ #define DW_LLE_start_length 0x08 /* DWARF5 */ /* DWARF5 Range List Entries */ #define DW_RLE_end_of_list 0x00 /* DWARF5 */ #define DW_RLE_base_addressx 0x01 /* DWARF5 */ #define DW_RLE_startx_endx 0x02 /* DWARF5 */ #define DW_RLE_startx_length 0x03 /* DWARF5 */ #define DW_RLE_offset_pair 0x04 /* DWARF5 */ #define DW_RLE_base_address 0x05 /* DWARF5 */ #define DW_RLE_start_end 0x06 /* DWARF5 */ #define DW_RLE_start_length 0x07 /* DWARF5 */ /* GNUIndex encodings non-standard. New in 2020, used in .debug_gnu_pubnames .debug_gnu_pubtypes but no spellings provided in documentation. */ #define DW_GNUIVIS_global 0 #define DW_GNUIVIS_static 1 /* GNUIndex encodings non-standard. New in 2020, used in .debug_gnu_pubnames .debug_gnu_pubtypes but no spellings provided in documentation. */ #define DW_GNUIKIND_none 0 #define DW_GNUIKIND_type 1 #define DW_GNUIKIND_variable 2 #define DW_GNUIKIND_function 3 #define DW_GNUIKIND_other 4 /* DWARF5 Unit header unit type encodings */ #define DW_UT_compile 0x01 /* DWARF5 */ #define DW_UT_type 0x02 /* DWARF5 */ #define DW_UT_partial 0x03 /* DWARF5 */ #define DW_UT_skeleton 0x04 /* DWARF5 */ #define DW_UT_split_compile 0x05 /* DWARF5 */ #define DW_UT_split_type 0x06 /* DWARF5 */ #define DW_UT_lo_user 0x80 /* DWARF5 */ #define DW_UT_hi_user 0xff /* DWARF5 */ /* DWARF5 DebugFission object section id values for .dwp object section offsets hash table. 0 is reserved, not used. 2 is actually reserved, not used in DWARF5. But 2 may be seen in some DWARF4 objects. */ #define DW_SECT_INFO 1 /* .debug_info.dwo DWARF5 */ #define DW_SECT_TYPES 2 /* .debug_types.dwo pre-DWARF5 */ #define DW_SECT_ABBREV 3 /* .debug_abbrev.dwo DWARF5 */ #define DW_SECT_LINE 4 /* .debug_line.dwo DWARF5 */ #define DW_SECT_LOCLISTS 5 /* .debug_loclists.dwo DWARF5 */ #define DW_SECT_STR_OFFSETS 6 /* .debug_str_offsets.dwo DWARF5 */ #define DW_SECT_MACRO 7 /* .debug_macro.dwo DWARF5 */ #define DW_SECT_RNGLISTS 8 /* .debug_rnglists.dwo DWARF5 */ /* Decimal Sign codes. */ #define DW_DS_unsigned 0x01 /* DWARF3f */ #define DW_DS_leading_overpunch 0x02 /* DWARF3f */ #define DW_DS_trailing_overpunch 0x03 /* DWARF3f */ #define DW_DS_leading_separate 0x04 /* DWARF3f */ #define DW_DS_trailing_separate 0x05 /* DWARF3f */ /* Endian code name. */ #define DW_END_default 0x00 /* DWARF3f */ #define DW_END_big 0x01 /* DWARF3f */ #define DW_END_little 0x02 /* DWARF3f */ #define DW_END_lo_user 0x40 /* DWARF3f */ #define DW_END_hi_user 0xff /* DWARF3f */ /* For use with DW_TAG_SUN_codeflags If DW_TAG_SUN_codeflags is accepted as a dwarf standard, then standard dwarf ATCF entries start at 0x01 */ #define DW_ATCF_lo_user 0x40 /* SUN */ #define DW_ATCF_SUN_mop_bitfield 0x41 /* SUN */ #define DW_ATCF_SUN_mop_spill 0x42 /* SUN */ #define DW_ATCF_SUN_mop_scopy 0x43 /* SUN */ #define DW_ATCF_SUN_func_start 0x44 /* SUN */ #define DW_ATCF_SUN_end_ctors 0x45 /* SUN */ #define DW_ATCF_SUN_branch_target 0x46 /* SUN */ #define DW_ATCF_SUN_mop_stack_probe 0x47 /* SUN */ #define DW_ATCF_SUN_func_epilog 0x48 /* SUN */ #define DW_ATCF_hi_user 0xff /* SUN */ /* Accessibility code name. */ #define DW_ACCESS_public 0x01 #define DW_ACCESS_protected 0x02 #define DW_ACCESS_private 0x03 /* Visibility code name. */ #define DW_VIS_local 0x01 #define DW_VIS_exported 0x02 #define DW_VIS_qualified 0x03 /* Virtuality code name. */ #define DW_VIRTUALITY_none 0x00 #define DW_VIRTUALITY_virtual 0x01 #define DW_VIRTUALITY_pure_virtual 0x02 #define DW_LANG_C89 0x0001 #define DW_LANG_C 0x0002 #define DW_LANG_Ada83 0x0003 #define DW_LANG_C_plus_plus 0x0004 #define DW_LANG_Cobol74 0x0005 #define DW_LANG_Cobol85 0x0006 #define DW_LANG_Fortran77 0x0007 #define DW_LANG_Fortran90 0x0008 #define DW_LANG_Pascal83 0x0009 #define DW_LANG_Modula2 0x000a #define DW_LANG_Java 0x000b /* DWARF3 */ #define DW_LANG_C99 0x000c /* DWARF3 */ #define DW_LANG_Ada95 0x000d /* DWARF3 */ #define DW_LANG_Fortran95 0x000e /* DWARF3 */ #define DW_LANG_PLI 0x000f /* DWARF3 */ #define DW_LANG_ObjC 0x0010 /* DWARF3f */ #define DW_LANG_ObjC_plus_plus 0x0011 /* DWARF3f */ #define DW_LANG_UPC 0x0012 /* DWARF3f */ #define DW_LANG_D 0x0013 /* DWARF3f */ #define DW_LANG_Python 0x0014 /* DWARF4 */ /* The following 2 are not yet formally approved October 2010, but it seems extremely likely they will be approved as the committee chair agrees these should be ok and no one on the committee has objected. */ #define DW_LANG_OpenCL 0x0015 /* DWARF5 */ #define DW_LANG_Go 0x0016 /* DWARF5 */ #define DW_LANG_Modula3 0x0017 /* DWARF5 */ #define DW_LANG_Haskel 0x0018 /* DWARF5 */ #define DW_LANG_C_plus_plus_03 0x0019 /* DWARF5 */ #define DW_LANG_C_plus_plus_11 0x001a /* DWARF5 */ #define DW_LANG_OCaml 0x001b /* DWARF5 */ #define DW_LANG_Rust 0x001c /* DWARF5 */ #define DW_LANG_C11 0x001d /* DWARF5 */ #define DW_LANG_Swift 0x001e /* DWARF5 */ #define DW_LANG_Julia 0x001f /* DWARF5 */ #define DW_LANG_Dylan 0x0020 /* DWARF5 */ #define DW_LANG_C_plus_plus_14 0x0021 /* DWARF5 */ #define DW_LANG_Fortran03 0x0022 /* DWARF5 */ #define DW_LANG_Fortran08 0x0023 /* DWARF5 */ #define DW_LANG_RenderScript 0x0024 /* DWARF5 */ #define DW_LANG_BLISS 0x0025 /* DWARF5 */ #define DW_LANG_lo_user 0x8000 #define DW_LANG_Mips_Assembler 0x8001 /* MIPS */ #define DW_LANG_Upc 0x8765 /* UPC, use DW_LANG_UPC instead. */ /* ALTIUM extension */ #define DW_LANG_ALTIUM_Assembler 0x9101 /* ALTIUM */ /* Sun extensions */ #define DW_LANG_SUN_Assembler 0x9001 /* SUN */ #define DW_LANG_hi_user 0xffff /* Identifier case name. */ #define DW_ID_case_sensitive 0x00 #define DW_ID_up_case 0x01 #define DW_ID_down_case 0x02 #define DW_ID_case_insensitive 0x03 /* Calling Convention Name. */ #define DW_CC_normal 0x01 #define DW_CC_program 0x02 #define DW_CC_nocall 0x03 #define DW_CC_pass_by_reference 0x04 /* DWARF5 */ #define DW_CC_pass_by_value 0x05 /* DWARF5 */ #define DW_CC_lo_user 0x40 #define DW_CC_GNU_renesas_sh 0x40 /* GNU */ #define DW_CC_GNU_borland_fastcall_i386 0x41 /* GNU */ /* ALTIUM extensions. */ /* Function is an interrupt handler, return address on system stack. */ #define DW_CC_ALTIUM_interrupt 0x65 /* ALTIUM*/ /* Near function model, return address on system stack. */ #define DW_CC_ALTIUM_near_system_stack 0x66 /*ALTIUM */ /* Near function model, return address on user stack. */ #define DW_CC_ALTIUM_near_user_stack 0x67 /* ALTIUM */ /* Huge function model, return address on user stack. */ #define DW_CC_ALTIUM_huge_user_stack 0x68 /* ALTIUM */ #define DW_CC_GNU_BORLAND_safecall 0xb0 #define DW_CC_GNU_BORLAND_stdcall 0xb1 #define DW_CC_GNU_BORLAND_pascal 0xb2 #define DW_CC_GNU_BORLAND_msfastcall 0xb3 #define DW_CC_GNU_BORLAND_msreturn 0xb4 #define DW_CC_GNU_BORLAND_thiscall 0xb5 #define DW_CC_GNU_BORLAND_fastcall 0xb6 #define DW_CC_LLVM_vectorcall 0xc0 #define DW_CC_LLVM_Win64 0xc1 #define DW_CC_LLVM_X86_64SysV 0xc2 #define DW_CC_LLVM_AAPCS 0xc3 #define DW_CC_LLVM_AAPCS_VFP 0xc4 #define DW_CC_LLVM_IntelOclBicc 0xc5 #define DW_CC_LLVM_SpirFunction 0xc6 #define DW_CC_LLVM_OpenCLKernel 0xc7 #define DW_CC_LLVM_Swift 0xc8 #define DW_CC_LLVM_PreserveMost 0xc9 #define DW_CC_LLVM_PreserveAll 0xca #define DW_CC_LLVM_X86RegCall 0xcb #define DW_CC_GDB_IBM_OpenCL 0xff #define DW_CC_hi_user 0xff /* Inline Code Name. */ #define DW_INL_not_inlined 0x00 #define DW_INL_inlined 0x01 #define DW_INL_declared_not_inlined 0x02 #define DW_INL_declared_inlined 0x03 /* Ordering Name. */ #define DW_ORD_row_major 0x00 #define DW_ORD_col_major 0x01 /* Discriminant Descriptor Name. */ #define DW_DSC_label 0x00 #define DW_DSC_range 0x01 /* Line number header entry format encodings. DWARF5 */ #define DW_LNCT_path 0x1 /* DWARF5 */ #define DW_LNCT_directory_index 0x2 /* DWARF5 */ #define DW_LNCT_timestamp 0x3 /* DWARF5 */ #define DW_LNCT_size 0x4 /* DWARF5 */ #define DW_LNCT_MD5 0x5 /* DWARF5 */ /* Experimental two-level line tables. Non standard */ #define DW_LNCT_GNU_subprogram_name 0x6 #define DW_LNCT_GNU_decl_file 0x7 #define DW_LNCT_GNU_decl_line 0x8 #define DW_LNCT_lo_user 0x2000 /* DWARF5 */ #define DW_LNCT_LLVM_source 0x2001 #define DW_LNCT_hi_user 0x3fff /* DWARF5 */ /* Line number standard opcode name. */ #define DW_LNS_copy 0x01 #define DW_LNS_advance_pc 0x02 #define DW_LNS_advance_line 0x03 #define DW_LNS_set_file 0x04 #define DW_LNS_set_column 0x05 #define DW_LNS_negate_stmt 0x06 #define DW_LNS_set_basic_block 0x07 #define DW_LNS_const_add_pc 0x08 #define DW_LNS_fixed_advance_pc 0x09 #define DW_LNS_set_prologue_end 0x0a /* DWARF3 */ #define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */ #define DW_LNS_set_isa 0x0c /* DWARF3 */ /* Experimental two-level line tables. NOT STD DWARF5 */ /* Not saying GNU or anything. There are no DW_LNS_lo_user or DW_LNS_hi_user values though. DW_LNS_set_address_from_logical and DW_LNS_set_subprogram being both 0xd to avoid using up more space in the special opcode table. EXPERIMENTAL DW_LNS follow. */ #define DW_LNS_set_address_from_logical 0x0d /* Actuals table only */ #define DW_LNS_set_subprogram 0x0d /* Logicals table only */ #define DW_LNS_inlined_call 0x0e /* Logicals table only */ #define DW_LNS_pop_context 0x0f /* Logicals table only */ /* Line number extended opcode name. */ #define DW_LNE_end_sequence 0x01 #define DW_LNE_set_address 0x02 #define DW_LNE_define_file 0x03 /* DWARF4 and earlier only */ #define DW_LNE_set_discriminator 0x04 /* DWARF4 */ /* HP extensions. */ #define DW_LNE_HP_negate_is_UV_update 0x11 /* 17 HP */ #define DW_LNE_HP_push_context 0x12 /* 18 HP */ #define DW_LNE_HP_pop_context 0x13 /* 19 HP */ #define DW_LNE_HP_set_file_line_column 0x14 /* 20 HP */ #define DW_LNE_HP_set_routine_name 0x15 /* 21 HP */ #define DW_LNE_HP_set_sequence 0x16 /* 22 HP */ #define DW_LNE_HP_negate_post_semantics 0x17 /* 23 HP */ #define DW_LNE_HP_negate_function_exit 0x18 /* 24 HP */ #define DW_LNE_HP_negate_front_end_logical 0x19 /* 25 HP */ #define DW_LNE_HP_define_proc 0x20 /* 32 HP */ #define DW_LNE_HP_source_file_correlation 0x80 /* HP */ #define DW_LNE_lo_user 0x80 /* DWARF3 */ #define DW_LNE_hi_user 0xff /* DWARF3 */ /* These are known values for DW_LNS_set_isa. */ /* These identifiers are not defined by any DWARFn standard. */ #define DW_ISA_UNKNOWN 0 /* The following two are ARM specific. */ #define DW_ISA_ARM_thumb 1 /* ARM ISA */ #define DW_ISA_ARM_arm 2 /* ARM ISA */ /* Macro information, DWARF5 */ #define DW_MACRO_define 0x01 /* DWARF5 */ #define DW_MACRO_undef 0x02 /* DWARF5 */ #define DW_MACRO_start_file 0x03 /* DWARF5 */ #define DW_MACRO_end_file 0x04 /* DWARF5 */ #define DW_MACRO_define_strp 0x05 /* DWARF5 */ #define DW_MACRO_undef_strp 0x06 /* DWARF5 */ #define DW_MACRO_import 0x07 /* DWARF5 */ #define DW_MACRO_define_sup 0x08 /* DWARF5 */ #define DW_MACRO_undef_sup 0x09 /* DWARF5 */ #define DW_MACRO_import_sup 0x0a /* DWARF5 */ #define DW_MACRO_define_strx 0x0b /* DWARF5 */ #define DW_MACRO_undef_strx 0x0c /* DWARF5 */ #define DW_MACRO_lo_user 0xe0 #define DW_MACRO_hi_user 0xff /* Macro information, DWARF2-DWARF4. */ #define DW_MACINFO_define 0x01 #define DW_MACINFO_undef 0x02 #define DW_MACINFO_start_file 0x03 #define DW_MACINFO_end_file 0x04 #define DW_MACINFO_vendor_ext 0xff /* CFA operator compaction (a space saving measure, see the DWARF standard) means DW_CFA_extended and DW_CFA_nop have the same value here. */ #define DW_CFA_advance_loc 0x40 #define DW_CFA_offset 0x80 #define DW_CFA_restore 0xc0 #define DW_CFA_extended 0 #define DW_CFA_nop 0x00 #define DW_CFA_set_loc 0x01 #define DW_CFA_advance_loc1 0x02 #define DW_CFA_advance_loc2 0x03 #define DW_CFA_advance_loc4 0x04 #define DW_CFA_offset_extended 0x05 #define DW_CFA_restore_extended 0x06 #define DW_CFA_undefined 0x07 #define DW_CFA_same_value 0x08 #define DW_CFA_register 0x09 #define DW_CFA_remember_state 0x0a #define DW_CFA_restore_state 0x0b #define DW_CFA_def_cfa 0x0c #define DW_CFA_def_cfa_register 0x0d #define DW_CFA_def_cfa_offset 0x0e #define DW_CFA_def_cfa_expression 0x0f /* DWARF3 */ #define DW_CFA_expression 0x10 /* DWARF3 */ #define DW_CFA_offset_extended_sf 0x11 /* DWARF3 */ #define DW_CFA_def_cfa_sf 0x12 /* DWARF3 */ #define DW_CFA_def_cfa_offset_sf 0x13 /* DWARF3 */ #define DW_CFA_val_offset 0x14 /* DWARF3f */ #define DW_CFA_val_offset_sf 0x15 /* DWARF3f */ #define DW_CFA_val_expression 0x16 /* DWARF3f */ #define DW_CFA_lo_user 0x1c #define DW_CFA_low_user 0x1c /* Incorrect spelling, do not use. */ /* SGI/MIPS extension. */ #define DW_CFA_MIPS_advance_loc8 0x1d /* MIPS */ /* GNU extensions. */ #define DW_CFA_GNU_window_save 0x2d /* GNU */ #define DW_CFA_AARCH64_negate_ra_state 0x2d #define DW_CFA_GNU_args_size 0x2e /* GNU */ #define DW_CFA_GNU_negative_offset_extended 0x2f /* GNU */ /* Metaware if HC is augmentation, apparently meaning High C and the op has a single uleb operand. See http://sourceforge.net/p/elftoolchain/tickets/397/ */ #define DW_CFA_METAWARE_info 0x34 #define DW_CFA_high_user 0x3f /* GNU exception header encoding. See the Generic Elf Specification of the Linux Standard Base (LSB). http://refspecs.freestandards.org/LSB_3.0.0/\ LSB-Core-generic/LSB-Core-generic/dwarfext.html The upper 4 bits indicate how the value is to be applied. The lower 4 bits indicate the format of the data. These identifiers are not defined by any DWARFn standard. */ #define DW_EH_PE_absptr 0x00 /* GNU */ #define DW_EH_PE_uleb128 0x01 /* GNU */ #define DW_EH_PE_udata2 0x02 /* GNU */ #define DW_EH_PE_udata4 0x03 /* GNU */ #define DW_EH_PE_udata8 0x04 /* GNU */ #define DW_EH_PE_sleb128 0x09 /* GNU */ #define DW_EH_PE_sdata2 0x0A /* GNU */ #define DW_EH_PE_sdata4 0x0B /* GNU */ #define DW_EH_PE_sdata8 0x0C /* GNU */ #define DW_EH_PE_pcrel 0x10 /* GNU */ #define DW_EH_PE_textrel 0x20 /* GNU */ #define DW_EH_PE_datarel 0x30 /* GNU */ #define DW_EH_PE_funcrel 0x40 /* GNU */ #define DW_EH_PE_aligned 0x50 /* GNU */ #define DW_EH_PE_omit 0xff /* GNU. Means no value present. */ /* Mapping from machine registers and pseudo-regs into the .debug_frame table. DW_FRAME entries are machine specific. These describe MIPS/SGI R3000, R4K, R4400 and all later MIPS/SGI IRIX machines. They describe a mapping from hardware register number to the number used in the table to identify that register. The CFA (Canonical Frame Address) described in DWARF is called the Virtual Frame Pointer on MIPS/SGI machines. The DW_FRAME* names here are MIPS/SGI specific. Libdwarf interfaces defined in 2008 make the frame definitions here (and the fixed table sizes they imply) obsolete. They are left here for compatibility. */ /* Default column used for CFA in the libdwarf reader client. Assumes reg 0 never appears as a register in DWARF information. Usable for MIPS, but never a good idea, really. */ /* These identifiers are not defined by any DWARFn standard. */ #define DW_FRAME_CFA_COL 0 #define DW_FRAME_REG1 1 /* integer reg 1 */ #define DW_FRAME_REG2 2 /* integer reg 2 */ #define DW_FRAME_REG3 3 /* integer reg 3 */ #define DW_FRAME_REG4 4 /* integer reg 4 */ #define DW_FRAME_REG5 5 /* integer reg 5 */ #define DW_FRAME_REG6 6 /* integer reg 6 */ #define DW_FRAME_REG7 7 /* integer reg 7 */ #define DW_FRAME_REG8 8 /* integer reg 8 */ #define DW_FRAME_REG9 9 /* integer reg 9 */ #define DW_FRAME_REG10 10 /* integer reg 10 */ #define DW_FRAME_REG11 11 /* integer reg 11 */ #define DW_FRAME_REG12 12 /* integer reg 12 */ #define DW_FRAME_REG13 13 /* integer reg 13 */ #define DW_FRAME_REG14 14 /* integer reg 14 */ #define DW_FRAME_REG15 15 /* integer reg 15 */ #define DW_FRAME_REG16 16 /* integer reg 16 */ #define DW_FRAME_REG17 17 /* integer reg 17 */ #define DW_FRAME_REG18 18 /* integer reg 18 */ #define DW_FRAME_REG19 19 /* integer reg 19 */ #define DW_FRAME_REG20 20 /* integer reg 20 */ #define DW_FRAME_REG21 21 /* integer reg 21 */ #define DW_FRAME_REG22 22 /* integer reg 22 */ #define DW_FRAME_REG23 23 /* integer reg 23 */ #define DW_FRAME_REG24 24 /* integer reg 24 */ #define DW_FRAME_REG25 25 /* integer reg 25 */ #define DW_FRAME_REG26 26 /* integer reg 26 */ #define DW_FRAME_REG27 27 /* integer reg 27 */ #define DW_FRAME_REG28 28 /* integer reg 28 */ #define DW_FRAME_REG29 29 /* integer reg 29 */ #define DW_FRAME_REG30 30 /* integer reg 30 */ #define DW_FRAME_REG31 31 /* integer reg 31, aka ra */ /* MIPS1,2 have only some of these 64-bit registers. ** MIPS1 save/restore takes 2 instructions per 64-bit reg, and ** in that case, the register is considered stored after ** the second swc1. */ #define DW_FRAME_FREG0 32 /* 64-bit floating point reg 0 */ #define DW_FRAME_FREG1 33 /* 64-bit floating point reg 1 */ #define DW_FRAME_FREG2 34 /* 64-bit floating point reg 2 */ #define DW_FRAME_FREG3 35 /* 64-bit floating point reg 3 */ #define DW_FRAME_FREG4 36 /* 64-bit floating point reg 4 */ #define DW_FRAME_FREG5 37 /* 64-bit floating point reg 5 */ #define DW_FRAME_FREG6 38 /* 64-bit floating point reg 6 */ #define DW_FRAME_FREG7 39 /* 64-bit floating point reg 7 */ #define DW_FRAME_FREG8 40 /* 64-bit floating point reg 8 */ #define DW_FRAME_FREG9 41 /* 64-bit floating point reg 9 */ #define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */ #define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */ #define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */ #define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */ #define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */ #define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */ #define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */ #define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */ #define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */ #define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */ #define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */ #define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */ #define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */ #define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */ #define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */ #define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */ #define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */ #define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */ #define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */ #define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */ #define DW_FRAME_FREG30 62 /* 64-bit floating point reg 30 */ #define DW_FRAME_FREG31 63 /* 64-bit floating point reg 31 */ #define DW_FRAME_FREG32 64 /* 64-bit floating point reg 32 */ #define DW_FRAME_FREG33 65 /* 64-bit floating point reg 33 */ #define DW_FRAME_FREG34 66 /* 64-bit floating point reg 34 */ #define DW_FRAME_FREG35 67 /* 64-bit floating point reg 35 */ #define DW_FRAME_FREG36 68 /* 64-bit floating point reg 36 */ #define DW_FRAME_FREG37 69 /* 64-bit floating point reg 37 */ #define DW_FRAME_FREG38 70 /* 64-bit floating point reg 38 */ #define DW_FRAME_FREG39 71 /* 64-bit floating point reg 39 */ #define DW_FRAME_FREG40 72 /* 64-bit floating point reg 40 */ #define DW_FRAME_FREG41 73 /* 64-bit floating point reg 41 */ #define DW_FRAME_FREG42 74 /* 64-bit floating point reg 42 */ #define DW_FRAME_FREG43 75 /* 64-bit floating point reg 43 */ #define DW_FRAME_FREG44 76 /* 64-bit floating point reg 44 */ #define DW_FRAME_FREG45 77 /* 64-bit floating point reg 45 */ #define DW_FRAME_FREG46 78 /* 64-bit floating point reg 46 */ #define DW_FRAME_FREG47 79 /* 64-bit floating point reg 47 */ #define DW_FRAME_FREG48 80 /* 64-bit floating point reg 48 */ #define DW_FRAME_FREG49 81 /* 64-bit floating point reg 49 */ #define DW_FRAME_FREG50 82 /* 64-bit floating point reg 50 */ #define DW_FRAME_FREG51 83 /* 64-bit floating point reg 51 */ #define DW_FRAME_FREG52 84 /* 64-bit floating point reg 52 */ #define DW_FRAME_FREG53 85 /* 64-bit floating point reg 53 */ #define DW_FRAME_FREG54 86 /* 64-bit floating point reg 54 */ #define DW_FRAME_FREG55 87 /* 64-bit floating point reg 55 */ #define DW_FRAME_FREG56 88 /* 64-bit floating point reg 56 */ #define DW_FRAME_FREG57 89 /* 64-bit floating point reg 57 */ #define DW_FRAME_FREG58 90 /* 64-bit floating point reg 58 */ #define DW_FRAME_FREG59 91 /* 64-bit floating point reg 59 */ #define DW_FRAME_FREG60 92 /* 64-bit floating point reg 60 */ #define DW_FRAME_FREG61 93 /* 64-bit floating point reg 61 */ #define DW_FRAME_FREG62 94 /* 64-bit floating point reg 62 */ #define DW_FRAME_FREG63 95 /* 64-bit floating point reg 63 */ #define DW_FRAME_FREG64 96 /* 64-bit floating point reg 64 */ #define DW_FRAME_FREG65 97 /* 64-bit floating point reg 65 */ #define DW_FRAME_FREG66 98 /* 64-bit floating point reg 66 */ #define DW_FRAME_FREG67 99 /* 64-bit floating point reg 67 */ #define DW_FRAME_FREG68 100 /* 64-bit floating point reg 68 */ #define DW_FRAME_FREG69 101 /* 64-bit floating point reg 69 */ #define DW_FRAME_FREG70 102 /* 64-bit floating point reg 70 */ #define DW_FRAME_FREG71 103 /* 64-bit floating point reg 71 */ #define DW_FRAME_FREG72 104 /* 64-bit floating point reg 72 */ #define DW_FRAME_FREG73 105 /* 64-bit floating point reg 73 */ #define DW_FRAME_FREG74 106 /* 64-bit floating point reg 74 */ #define DW_FRAME_FREG75 107 /* 64-bit floating point reg 75 */ #define DW_FRAME_FREG76 108 /* 64-bit floating point reg 76 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** The following 4 #defines are dependent on the target cpu(s) that you apply libdwarf to. Ensure that DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL do not conflict with the range [0-DW_FRAME_STATIC_LINK]. The value 63 works for MIPS cpus at least up to the R16000. For a cpu with more than 63 real registers DW_FRAME_HIGHEST_NORMAL_REGISTER must be increased for things to work properly! Also ensure that DW_FRAME_UNDEFINED_VAL DW_FRAME_SAME_VAL are not in the range [0-DW_FRAME_STATIC_LINK] Having DW_FRAME_HIGHEST_NORMAL_REGISTER be higher than is strictly needed is safe. */ #ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER #define DW_FRAME_HIGHEST_NORMAL_REGISTER 188 #endif /* This is the number of columns in the Frame Table. This constant should be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h It must also be large enough to be beyond the highest compiler-defined-register (meaning DW_FRAME_RA_COL DW_FRAME_STATIC_LINK in the MIPS/IRIX case */ #ifndef DW_FRAME_LAST_REG_NUM #define DW_FRAME_LAST_REG_NUM (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3) #endif /* Column recording ra (return address from a function call). This is common to many architectures, but as a 'simple register' is not necessarily adequate for all architectures. For MIPS/IRIX this register number is actually recorded on disk in the .debug_frame section. */ #define DW_FRAME_RA_COL (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1) /* Column recording static link applicable to up-level addressing, as in IRIX mp code, pascal, etc. This is common to many architectures but is not necessarily adequate for all architectures. For MIPS/IRIX this register number is actually recorded on disk in the .debug_frame section. */ #define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2) /* DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL are never on disk, just generated by libdwarf. See libdwarf.h for their values. */ #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 #define DW_ADDR_none 0 #ifdef __cplusplus } #endif #endif /* __DWARF_H */ libdwarf-20210528/libdwarf/dwarf_macro.c0000664000175000017500000003746313764007262014742 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_macro.h" #define LEFTPAREN '(' #define RIGHTPAREN ')' #define SPACE ' ' /* Given the dwarf macro string, return a pointer to the value. Returns pointer to 0 byte at end of string if no value found (meaning the value is the empty string). Only understands well-formed dwarf macinfo strings. */ char * dwarf_find_macro_value_start(char *str) { char *lcp; int funclike = 0; for (lcp = str; *lcp; ++lcp) { switch (*lcp) { case LEFTPAREN: funclike = 1; break; case RIGHTPAREN: /* lcp+1 must be a space, and following char is the value */ return lcp + 2; case SPACE: /* We allow extraneous spaces inside macro parameter ** list, just in case... This is not really needed. */ if (!funclike) { return lcp + 1; } break; } } /* Never found value: returns pointer to the 0 byte at end of string. */ return lcp; } /* Try to keep fileindex correct in every Macro_Details record by tracking file starts and ends. Uses high water mark: space reused, not freed. Presumption is that this makes sense for most uses. STARTERMAX is set so that the array need not be expanded for most files: it is the initial include file depth. */ struct macro_stack_s { Dwarf_Signed *st_base; long st_max; long st_next_to_use; int st_was_fault; }; static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms); static void free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms) { dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING); _dwarf_reset_index_macro_stack(ms); } #define STARTERMAX 10 static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms) { ms->st_base = 0; ms->st_max = 0; ms->st_next_to_use = 0; ms->st_was_fault = 0; } static int _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx, struct macro_stack_s *ms) { if (!ms->st_max || ms->st_next_to_use >= ms->st_max) { long new_size = ms->st_max; Dwarf_Signed *newbase = 0; if (!new_size) { new_size = STARTERMAX; } new_size = new_size * 2; newbase = (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING, new_size * sizeof(Dwarf_Signed)); if (!newbase) { /* just leave the old array in place */ ms->st_was_fault = 1; return DW_DLV_ERROR; } if (ms->st_base) { memcpy(newbase, ms->st_base, ms->st_next_to_use * sizeof(Dwarf_Signed)); dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING); } ms->st_base = newbase; ms->st_max = new_size; } ms->st_base[ms->st_next_to_use] = indx; ++ms->st_next_to_use; return DW_DLV_OK; } static Dwarf_Signed _dwarf_macro_stack_pop_index(struct macro_stack_s *ms) { if (ms->st_was_fault) { return -1; } if (ms->st_next_to_use > 0) { ms->st_next_to_use--; return (ms->st_base[ms->st_next_to_use]); } else { ms->st_was_fault = 1; } return -1; } /* Starting at macro_offset in .debug_macinfo, if maximum_count is 0, treat as if it is infinite. get macro data up thru maximum_count entries or the end of a compilation unit's entries (whichever comes first). .debug_macinfo never appears in a .dwp Package File. So offset adjustment for such is not needed. */ int dwarf_get_macro_details(Dwarf_Debug dbg, Dwarf_Off macro_offset, Dwarf_Unsigned maximum_count, Dwarf_Signed * entry_count, Dwarf_Macro_Details ** details, Dwarf_Error * error) { Dwarf_Small *macro_base = 0; Dwarf_Small *macro_end = 0; Dwarf_Small *pnext = 0; Dwarf_Unsigned endloc = 0; unsigned char uc = 0; unsigned long depth = 0; /* By section 6.3.2 Dwarf3 draft 8/9, the base file should appear as DW_MACINFO_start_file. See http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html on "[Bug debug/20253] New: [3.4/4.0 regression]: Macro debug info broken due to lexer change" for how gcc is broken in some versions. We no longer use depth as a stopping point, it's not needed as a stopping point anyway. */ int res = 0; /* count space used by strings */ unsigned long str_space = 0; int done = 0; unsigned long space_needed = 0; unsigned long string_offset = 0; Dwarf_Small *return_data = 0; Dwarf_Small *pdata = 0; unsigned long final_count = 0; Dwarf_Signed fileindex = -1; Dwarf_Small *latest_str_loc = 0; struct macro_stack_s msdata; unsigned long count = 0; unsigned long max_count = (unsigned long) maximum_count; _dwarf_reset_index_macro_stack(&msdata); if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); free_macro_stack(dbg,&msdata); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error); if (res != DW_DLV_OK) { free_macro_stack(dbg,&msdata); return res; } if (!dbg->de_debug_abbrev.dss_size) { free_macro_stack(dbg,&msdata); return DW_DLV_NO_ENTRY; } macro_base = dbg->de_debug_macinfo.dss_data; if (macro_base == NULL) { free_macro_stack(dbg,&msdata); return DW_DLV_NO_ENTRY; } if (macro_offset >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); return DW_DLV_NO_ENTRY; } macro_end = macro_base + dbg->de_debug_macinfo.dss_size; /* FIXME debugfission is NOT handled here. */ pnext = macro_base + macro_offset; if (maximum_count == 0) { max_count = ULONG_MAX; } /* how many entries and how much space will they take? */ endloc = (pnext - macro_base); if (endloc >= dbg->de_debug_macinfo.dss_size) { if (endloc == dbg->de_debug_macinfo.dss_size) { /* normal: found last entry */ free_macro_stack(dbg,&msdata); return DW_DLV_NO_ENTRY; } _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); free_macro_stack(dbg,&msdata); return DW_DLV_ERROR; } for (count = 0; !done && count < max_count; ++count) { unsigned long slen = 0; /* Set but not used */ UNUSEDARG Dwarf_Unsigned utemp = 0; uc = *pnext; ++pnext; /* get past the type code */ switch (uc) { case DW_MACINFO_define: case DW_MACINFO_undef: /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } res = _dwarf_check_string_valid(dbg, macro_base,pnext,macro_end, DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } slen = strlen((char *) pnext) + 1; pnext += slen; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } str_space += slen; break; case DW_MACINFO_start_file: /* line, file index */ DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } ++depth; break; case DW_MACINFO_end_file: if (--depth == 0) { /* done = 1; no, do not stop here, at least one gcc had the wrong depth settings in the gcc 3.4 timeframe. */ } /* no string or number here */ break; case 0: /* end of cu's entries */ done = 1; break; default: free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; /* bogus macinfo! */ } endloc = (pnext - macro_base); if (endloc == dbg->de_debug_macinfo.dss_size) { done = 1; } else if (endloc > dbg->de_debug_macinfo.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); free_macro_stack(dbg,&msdata); return DW_DLV_ERROR; } } /* ASSERT: The above loop will never let us get here with count < 1. No need to test for a zero count. We have 'count' array entries to allocate and str_space bytes of string space to provide for. */ string_offset = count * sizeof(Dwarf_Macro_Details); /* extra 2 not really needed */ space_needed = string_offset + str_space + 2; return_data = pdata = (Dwarf_Small *)_dwarf_get_alloc( dbg, DW_DLA_STRING, space_needed); latest_str_loc = pdata + string_offset; if (pdata == 0) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE); return DW_DLV_ERROR; } pnext = macro_base + macro_offset; done = 0; /* A series ends with a type code of 0. */ for (final_count = 0; !done && final_count < count; ++final_count) { unsigned long slen = 0; Dwarf_Unsigned v1 = 0; Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata + (final_count * sizeof (Dwarf_Macro_Details))); endloc = (pnext - macro_base); if (endloc > dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); return DW_DLV_ERROR; } uc = *pnext; pdmd->dmd_offset = (pnext - macro_base); pdmd->dmd_type = uc; pdmd->dmd_fileindex = fileindex; pdmd->dmd_lineno = 0; pdmd->dmd_macro = 0; ++pnext; /* get past the type code */ switch (uc) { case DW_MACINFO_define: case DW_MACINFO_undef: /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_lineno = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } res = _dwarf_check_string_valid(dbg, macro_base,pnext,macro_end, DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } slen = strlen((char *) pnext) + 1; strcpy((char *) latest_str_loc, (char *) pnext); pdmd->dmd_macro = (char *) latest_str_loc; latest_str_loc += slen; pnext += slen; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } break; case DW_MACINFO_start_file: /* Line, file index */ DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_lineno = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_fileindex = v1; (void) _dwarf_macro_stack_push_index(dbg, fileindex, &msdata); /* We ignore the error, we just let fileindex ** be -1 when we pop this one. */ fileindex = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } break; case DW_MACINFO_end_file: fileindex = _dwarf_macro_stack_pop_index(&msdata); break; /* no string or number here */ case 0: /* Type code of 0 means the end of cu's entries. */ done = 1; break; default: /* Bogus macinfo! */ dwarf_dealloc(dbg, return_data, DW_DLA_STRING); free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return DW_DLV_ERROR; } } *entry_count = count; *details = (Dwarf_Macro_Details *) return_data; free_macro_stack(dbg,&msdata); return DW_DLV_OK; } libdwarf-20210528/libdwarf/ChangeLog20080000664000175000017500000003335313644370703014370 000000000000002008-12-29 DavidAnderson * libdwarf.h: Add support for .debug_ranges with dwarf_get_ranges() and dwarf_ranges_dealloc(). * dwarf_init_finish.c: Add support for .debug_ranges. * dwarf_base_types.h: Add support for .debug_ranges functions. * dwarf_alloc.c, dwarf_alloc.h: Add support for .debug_ranges alloc/dealloc. * dwarf_opaque.h: Add support for .debug_ranges. * libdwarf2.1.mm: Documented dwarf_get_ranges() and dwarf_ranges_dealloc() (rev 1.72). * libdwarf2.1.pdf: Regenerated. 2008-12-09 DavidAnderson * dwarf_alloc.c: Remove useless comments and tweak a few comments. 2008-12-08 DavidAnderson * dwarf_opaque.h: Add di_abbrev_code field to record a DIE abbreviation value so consumers can report it. * libdwarf.h: Add dwarf_die_abbrev_code() interface. * dwarf_query.c: Add dwarf_die_abbrev_code() interface. * dwarf_die_deliv.c: Set di_abbrev_code for consumers. * libdwarf2.1.mm: Documented dwarf_die_abbrev_code(). * libdwarf2.1.pdf: Regenerated. * pro_util.h: Removed gratuitous tabs. Used a space instead. 2008-12-07 DavidAnderson * dwarf.h: Entered DWARF4 defines known so far. * dwarf_opaque.h: Updated dwarf 4 section-version comment with the latest info. 2008-12-07 DavidAnderson * dwarf_original_elf_init.c: Delete unused local variables. * pro_forms.c: Delete unused local variables and initialize local variables at definition. * dwarf_pubtypes.c, dwarf_line.c: Delete accidental duplicated /* comment-start. * malloc_check.c: In the 'do nothing' case, create an extern declaration to eliminate a compiler warning. 2008-11-19 DavidAnderson * dwarf_die_deliv.c: Handle the case where DW_AT_sibling uses DW_FORM_ref_addr. * dwarf_util.c: Add a comment about DW_FORM_ref_addr. * dwarf_opaque.h: Add a comment about CU fields, comment out an unused CU header field. * dwarf_query.c: Added dwarf_die_CU_offset_range() so dwarfdump can check for additional errors. * dwarf_form.c: Clarifying a comment. * dwarf_print_lines.c: Add additional print detail on line table headers (used by dwarfdump). * libdwarf2.1.mm: Documenting the new function dwarf_die_CU_offset_range(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h: Added dwarf_die_CU_offset_range() interface declaration. 2008-10-13 DavidAnderson * dwarf_frame2.c: Removed last use of DW_FRAME_LAST_REG_NUM: use dbg->de_frame_reg_rules_entry_count instead. 2008-09-30 DavidAnderson * dwarf_print_lines.c: Print corrected warning about bogus prologue length. * dwarf_line.c: Work around bogus prologue length compiler bug. * dwarf_line.h: Rename arguments. 2008-09-29 DavidAnderson * libdwarf2.1.mm: Documented requirement that dwarf_get_fde_n() dwarf_get_fde_at_pc() pass a pointer to an fde table that contains at least 1 entry. * libdwarf2.1.pdf: regenerated. * dwarf_opaque.h: Add new fields for cie/fde specific fields for eh. * dwarf_frame2.c: Initialize the new Dwarf_debug and Dwarf_Fde fields. * dwarf_frame.c: Access the new Dwarf_Fde fields. * dwarf_frame.h: Define a new Dwarf_Fde field so we keep eh and non-eh distinct. 2008-09-29 DavidAnderson * All .c files: Mechanically removed tab characters with the expand tool. 2008-09-29 DavidAnderson * libdwarf.h: DW_DLE_LINE_SET_ADDR_ERROR no longer used. The tests which generated it were bogus. * dwarf_print_lines.c: Print a warning if there are any apparently wasted bytes after the line prologue and before the line table instructions. Match the new prologue reading function prototype. * dwarf_sort_line.c: Match the new prologue reading function prototype. * dwarf_line.c: Modify the prologue reading function so it correctly finds the beginning of instructions even when there are 'wasted' bytes after the prologue. Drop bogus tests for minimum-instruction-size matching the ABI pointer size. Removing the tests removed all uses of DW_DLE_LINE_SET_ADDR_ERROR. * dwarf_line.h: Modify the prototype for the prologue reading function so it is possible for a caller to know about the possibly wasted bytes after a prologue. 2008-09-02 DavidAnderson * dwarf_init_finish.c (_dwarf_setup): Delete unused local variable 'section_error'. 2008-08-14 DavidAnderson * libdwarf2p.1.mm: Make it clearer that dwarf_get_pubnames, dwarf_get_varnames, etc return a result across all compilation units (an entire section), not just for a single compilation unit. Document version 1.68. * libdwarf2p.1.pdf: Regenerated. 2008-08-08 DavidAnderson * libdwarf2p.1.mm: Removed some long time spelling mistakes: no technical change in content. Document version 1.67. * libdwarf2p.1.pdf: Regenerated. 2008-08-05 DavidAnderson * libdwarf.h, dwarf_error.c: DW_DLA_PUBTYPE_CONTEXT was a mistake, DW_DLE_PUBTYPE_CONTEXT was intended and is now the spelling (neither is used). * dwarf_pubtypes.c dwarf_vars.c dwarf_funcs.c dwarf_global.c dwarf_weaks.c: tabs removed and previous strange formatting generated by a tool removed (4 space indent per level now present). 2008-08-05 DavidAnderson * libdwarf2.1.mm: There were numerous places the apostrophe was used incorrectly, thru is now spelled through, and a few other small typographical errors were corrected. The document revision id printed is now 1.67. There is no technical change in content. * libdwarf2.1.pdf: Regenerated. 2008-06-17 DavidAnderson * libdwarf.h: Add DW_DLE_STRP_OFFSET_BAD error code. * dwarf_form.c: Add runtime check for strp offset. * dwarf_error.c: Add DW_DLE_STRP_OFFSET_BAD error code string. * dwarf_init_finish.c, dwarf_opaque.h, dwarf_elf_access.h: Remove CR characters that crept in. 2008-06-13 DavidAnderson * libdwarf.h: Remove __SGI_FAST_LIBELF dwarf_original_elf_init.c: Remove __SGI_FAST_LIBELF and fix some indentation botches. * dwarf_init_finish.c: Fix typo in variable name introduced a few days ago. * dwarf_elf_access.c: Remove __SGI_FAST_LIBELF and fix some indentation botches. 2008-05-20 DavidAnderson * dwarf_init_finish.c: Expand tabs to spaces. 2008-05-20 DavidAnderson * dwarf_init_finish.c(dwarf_object_init): When there is no DWARF information return DW_DLV_NO_ENTRY gracefully. Thanks to Carlos Alberto Enciso for pointing out the bug. 2008-04-12 DavidAnderson * pro_section.c: Initialize local variables to zero. Change leading tabs to spaces. * pro_reloc_stream.c: Initialize local variables to zero. Change leading tabs to spaces. * pro_reloc.c: Initialize local variables to zero. Change leading tabs to spaces. 2008-04-04 DavidAnderson * dwarf_base_types.h: Removed unused macro definition. * dwarf_util.c: Altered abbreviations hash table for a small performance improvement and space saving. * dwarf_util.h: Changed declaration for space saving in dwarf abbreviations table. 2008-04-04 DavidAnderson * libdwarf.h: A trivial change to make a declaration look better. * dwarf_abbrev.h: We record tags in more than 16 bits now just in case we encounter such a thing (increased ab_tag field size), though we should not find such. * dwarf_abbrev.c: Adding a comment about the dwarf TAG value. * dwarf_util.c: Initialize local variables at declaration for safety. Removed truncation of some values: internally record more bits. Rewrote handling of the abbrev table as the old one did not scale to large numbers of abbreviations (things got very slow). * dwarf_util.h: Now has a larger field size in the argument to _dwarf_get_abbrev_for_code (not quite necessary but not harmful). * dwarf_die_deliv.c: Initializing local variables at declaration and removing truncation of bits from some uleb values. * dwarf_die_deliv.h: Increased size of ab_code field. * dwarf_opaque.h: Added a comment about abbreviations. * dwarf_base_types.h: Revised to match addition of new allocation table entry. * dwarf_alloc.h: Document macro definitions and increase one to match new table size. * dwarf_alloc.c: Arrange handling of new DW_DLA_HASH_TABLE_ENTRY (most of the work done in dwarf_util.c). 2008-02-27 DavidAnderson * libdwarf.h: Fixed minor typo in latest libdwarf.h that gcc did not complain about. Noted by Josh Fuhs. 2008-02-26 DavidAnderson * dwarf_alloc.h: Add comment giving placement of DWARF_SIMPLE_MALLOC. * pro_opaque.h: Remove de_access field, it is never used. * libdwarf.h: Add new data structures to allow reading of non-Elf object files. * dwarf_original_elf_init.c: dwarf_init(), dwarf_elf_init() moved here from dwarf_init_finish.c. * Makefile.in: Build new source files dwarf_original_elf_init.c and dwarf_elf_access.c. * dwarf_init_finish.c: All dependencies on libelf and elf have been removed. * dwarf_opaque.h: The elf related info is removed and Dwarf_Debug_s now contains a new structure (from libdwarf.h) to hide object information. * dwarf_elf_access.c: All the Elf-using code is now in this source file and elf details are kept in a struct defined and used here. Non-libelf and non-elf object access code would write a new source file with their own details using this as an example. * dwarf_elf_access.h: Prototypes for calling between dwarf_original_elf_init.c and dwarf_elf_access.c. 2008-02-18 DavidAnderson * libdwarf.h: Declare new object-access functions and structures. * dwarf_original_elf_init.c: Traditional dwarf_init() and dwarf_elf_init() are moved to this new source file. * Makefile.in: Add new source files. * dwarf_init_finish.c: Now uses the function pointers, not libelf specific fields or ifdefs. * pro_opaque.h: Remove de_access field, it is unused. * dwarf_opaque.h: New fields for new object-access functions. * dwarf_elf_access.c: New implementation details for elf access functions moved here from dwarf_init_finish.c. * dwarf_elf_access.h: New function interface so dwarf_elf_access.c and dwarf_original_elf_init.c can communicate. 2008-02-08 DavidAnderson * dwarf_print_lines.c: Added commentary to clarify that dwarf_print_lines() and _dwarf_print_lines are intentionally identical. Initialized local variables so they are alll visibly set to some sensible value. 2008-02-07 DavidAnderson * dwarf_frame.c (_dwarf_fde_section_offset): A typo in the last release made this an infinite loop. A one character change fixed it. Thanks to Carlos Alberto Enciso for noticing the bug. 2008-02-04 DavidAnderson * dwarf_incl.h, pro_incl.h: Moved #include of dwarf.h before libdwarf.h * pro_forms.c: Some newer attributes are now handled. * dwarf_print_lines.c: Removed unused #include. * dwarf_sort_line.c: Removed alloca use in favor of malloc and removed the alloca #include. * dwarf_line.c: Removed unused #include. * dwarf_line2.c: Removed unused #include. 2008-02-04 DavidAnderson * libdwarf.h: Fix commentary mistakes. 2008-02-02 DavidAnderson * libdwarf.h: Add DW_DLC_OFFSET_SIZE_64 for run-time selection of DWARF3 64bit extension producer offset generation. * libdwarf2p.1.mm: Document DW_DLC_OFFSET_SIZE_64. * pro_init.c (dwarf_producer_init): Now standard DWARF3 is the default. * configure.in: Add --enable-dwarf-format-sgi-irix for those wanting IRIX offset-style DWARF2. Add --enable-dwarf-format-strict-32bit for those wanting strictly 32bit offsets. Otherwise default to generating 64bit offsets from the producer code, but allow the DWARF3 extended 64bit offsets if the flag DW_DLC_OFFSET_SIZE_64 is turned on in the call to dwarf_producer_init(). * config.h.in: Provide undefs for the offset macros. 2008-01-25 DavidAnderson * pro_die.c: Changed leading tabs to spaces. 2008-01-23 DavidAnderson * pro_die.c: Using di_last_child field dwarf_die_link goes from O(N) to O(1) in adding a child. Thanks to Daniel Gollub for the suggestion. An omission in linking left/right children is fixed. Changed some leading TABs to spaces. * pro_opaque.h: Add di_last_child field. 2008-01-14 DavidAnderson * libdwarf2p.1.mm: Added missing backslash to correct formatting error. Thanks to Daniel Golub for pointing out the ommission. * libdwarf2.p1.pdf: Regenerated. libdwarf-20210528/libdwarf/NEWS0000664000175000017500000006676513771710375013024 00000000000000December 26, 2020 With mm -> pdf the table of contents of libdwarf2.1.pdf is at the end of the pdf and difficult to locate. Now we extract a companion pdf: libdwarftoc.pdf , which contains the 1 page abstract followed by the table of contents and list of figures. We hope this will make finding functions of interest easier. July 09, 2020 Access to .debug_gnu_pubtypes and .debug_gnu_pubnames is possible. See function dwarf_get_gnu_index_head(). Recently support for reading .debug_loclists was added. Recently support for reading .debug_rnglists was added. See libdwarf2.1.pdf and libdwarf.h for details. March 14, 2020 The documentation of dwarf_diename() and dwarf_die_text() has been corrected. Never dwarf_dealloc() the strings returned by these functions. The new function dwarf_set_de_alloc_flag(0) allows consumer code to save memory space at run time. If it is called it leaves all dwarf_dealloc() calls to the libdwarf caller: dwarf_finish() will not be able to free leftover allocations. By default libdwarf does keep track of allocations and dwarf_finish() will clean up any allocations not already dwarf_dealloc()-d. Unless the DWARF one is reading is really large it is best to let libdwarf keep track of its allocations. so there will be no leaks after dwarf_finish(). November 26, 2019 The dwarf_init*() functions no longer use libelf so calling dwarf_get_elf() cannot succeed unless dwarf_elf_init() or dwarf_elf_init_b() was used to open a Dwarf_Debug on an object file. This change actually happened around 5 May 2019 but was not documented properly till 26 November. January 15, 2019 All references to C data types spelled *int16* *int32* or *int64* have been removed. Dwarf_Unsigned is used instead. This simplifies builds in certain environments. December 05, 2018 Many new producer functions provided. Now no matter what producer task is to be done there is a version that returns DW_DLV_OK/DW_DLV_ERROR and no ugly casting of return values is needed to check for success/failure. All the old interfaces continue to work. One can switch from Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, char* name, Dwarf_Error* error); (requires a cast to check return code DW_DLV_BADADDR) to int dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, char* current_working_directory, Dwarf_P_Attribute * outattr, Dwarf_Error* error); (no cast,type safe) for example. The libdwarf2p.1.mm document table-of-contents lists only the latest functions, but all the documentation of all the earlier versions remain in the document as subsections. October 24, 2018 Now supports reading MacOS dSYM object files. May 17, 2017 Now supports some COMDAT groups as well as split-dwarf. Some new functions added so consumer code can know what the sections and groups contain. Some compilers emit groups findable only with relocation data: libdwarf does not understand those groups. April 02, 2017 The consumer code now reads DWARF5 split-dwarf sections. The functions dwarf_init_b() and dwarf_elf_init_b() and dwarf_object_init_b() have a groupnumber argument added. For non-split-dwarf objects the original dwarf_init() and dwarf_elf_init() and dwarf_object_init() functions continue to work properly. September 11, 2016 The producer code is getting a new batch of functions. For each existing producer call returning a value other than DW_DLV_OK/DW_DLV_ERROR/DW_DLV_NO_ENTRY a new function returning one of those three codes with a pointer argument added to return the actual desired value (that used to be the 'return'). The existing calls require the caller to do ugly casting to determine whether the call did its work or got an error. The new calls have type-safe interfaces that separate the desired result from the error-indication. So producer calls look more like consumer calls. The existing historical producer interfaces will remain unchanged and will continue to be supported. The existing interfaces will simply call the new interfaces so there is no code duplication: Old and new use the same implementation. Source and binary compatibility is retained, but users of the producer code can, when they wish, partially or fully convert to the new interfaces. This work will be ongoing and gradual, not 'all at once'. August 27, 2016 Now the producer is capable of producing .debug_str strings. Strings are never duplicated in .debug_str. See dwarf_pro_set_default_string_form() in libdwarf2p.1.pdf May 23, 2016 When building a shared-library the soname is set in the dynamic section "libdwarf.so.1". Much more testing of object correctness is done to catch corrupted dwarf and corrupted object files. March 14, 2016 When libdwarf callers provide neither an error argument nor an error-handler function pointer libdwarf gives up on detecting an error. Before now it emitted a short message on stderr and did abort(). Now it emits a short message on stdout and does abort(). Having libdwarf just stop application processing (stopping the entire application) was never good application-development policy, so one hopes no one ever relied on doing no-error-handling themselves. So one hopes no one will actually notice this change. The change makes it much easier to test that the error handling is all behaving as intended. March 1, 2016 Much support of GNU extensions to dwarf and of DWARF5 features now exist in libdwarf. Including the ability to deal with the most usual forms of split-dwarf. Handling of zlib compression of dwarf is now automatic (assuming you had zlib visible when configuring libdwarf). May 01, 2015 dwarf_next_cu_header_d() is the latest extension for CU reading. Earlier versions still supported. dwarf_die_from_hash_signature() added so readers can use a hash to access a dwp package file DIE. New support for some of DWARF5 and for dwp debug-fission package file reading. February 25, 2015 Now gennames uses dwgetopt() instead of getopt. So it will more easily build where no getopt() available. We copied dwgetopt.h, .c here (rather than reaching around to dwarfdump) to keep the libdwarf build more easily buildable separate from dwarfdump. January 8, 2015 When malloc fails (out of space) dwarfdump will now use a statically-allocated Dwarf_Error_s struct so it can get the original malloc failure (or other error) reported back to the calling client. Some checks for invalid Elf files were changed to actually report errors properly. Thanks to Edward Williamson for providing test cases with odd errors in the Elf and DWARF. May 19, 2014 REASON FOR RELEASE Now handles DebugFission (part of the unreleased standard named DWARF5) in which debug information can be split from objects and gathered into separate object files. MINOR POINT: Added a caveat that dwarf_errmsg() returned string pointers are not necessarily pointers that can be relied on to be valid for the duration of the current executable. It's best for consumers to print or copy the string right away and then forget the returned pointer. This restriction is probably already met by most conservative consumer code: earlier, nothing was said about the lifetime of the string! Eventually it would be nice to actually have more ephemeral strings as then some much better error strings could easily be produced with no leakage and no growth in the size of the running executable. For now, though, all dwarf_errmsg() strings continue to point to static strings. Just please don't depend on it! BINARY & SOURCE INCOMPATIBLITY: The Producer code drops old dwarf_producer_init* functions and provides an old name with a new interface: dwarf_producer_init(). The producer callback function is renamed Dwarf_Callback_Func. Hence code calling the libdwarf producer must change. Code calling the consumer interface is not affected. The determination of what/how to emit DWARF is now determined at run time, not at build time. It's now much simpler to get the sort of output you want. Provision is made for emitting DWARF3,4,5 and 5 (though that provision is at a very early stage and not much supported yet). The postal addresses for SGI in the copyright comments changed from time to time and are no longer accurate. So they are gradually being removed. March 17, 2014 The dwarf.v2.mm and index.v2.mm and their pdf files have been removed from the distribution. Those files are available on dwarfstd.org and they are 20 years old, so removed from libdwarf. January 29, 2014 Now using dwarf_tsearch() instead of the original complicated allocation code. October 14, 2013 The Callback_Func declarations in libdwarf.h were missing a const on the name argument. Adding it removes compiler warnings. But removing it means client code calling producer functions has to change to get their callback function declarations/definitions to match. The change does not affect those calling the consumer interfaces. August 15, 2013 Now the printf (stdout) here go through a callback function instead of actually using stdout. That way dwarfdump and other apps have full control of libdwarf output from dwarf_print_lines() for example. It also means callers of dwarf_print_lines() need to have called dwarf_register_printf_callback() to get any actual print output. January 26, 2013 Retracted the incompatible change. The interfaces are again compatible with previous releases and the January 25 release is withdrawn. Has all the fixes of Jan 25 present in the code. January 25, 2013 The definition of the Dwarf_Loc struct could not handle DW_OP_GNU_const_type so it had to change. The new field added makes this version of libdwarf incompatible with any existing dwarfdump. Rebuild dwarfdump and dwarfdump2 to use it with this libdwarf. Moved firmly into C89/C90 usage by more complete use of const and be using int x(void) for example to prototype parameter-less functions. Compiles close to cleanly with gcc options -Wsystem-headers -Wall -Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign November 29, 2012 The function dwarf_formflag() now returns the actual flag value instead of just 1 or 0. It has been coded wrong a very long time. The DWARF documents (DWARF2 on) have always made it clear any non-zero value means true and zero means false. Now consumers can properly note the value the compiler actually put into the flag byte. November 17, 2012 New headers contain the relocation codes for various object ABIs. These headers are needed in libdwarf and expected by builds of dwarfdump[2] for best dwarfdump[2] relocation handling. It is best to build libdwarf and dwarfdump together for best handling of relocatable objects. GNU compilers may generate the operator DW_OP_GNU_implicit_pointer which is generated differently in DWARF2 versus DWARF3/4. Hence a new interface to libdwarf dwarf_loclist_from_expr_b() adds the compilation unit DWARF version number to the argument list (as compared to dwarf_loclist_from_expr_a()). Hopefully few consumers will need to change to use the new interface. December 13, 2011 dwarf_lineoff() is now deprecated, dwarf_lineoff_b() is strongly recommended instead. dwarf_add_line_entry() does not have all the line fields needed for generating DWARF3/4, use dwarf_add_line_entry_b() instead. Generation of DWARF3/4 is not yet functional, this new function is a first step. October 29, 2011 Added support for reading .debug_types (type unit) data. October 26,2011 Revised the Makefile.in and README to make building libdwarf easier to accomplish with unusual locations of libelf headers or other headers or libraries. June 04,2011 Non-Elf objects could be used with libdwarf, but no one has contributed non-elf-reading code for libdwarf and a crucial detail was not documented so those writing such object-reading code have not done it entirely correctly. Fundamentally such code must treat a section index of 0 as a real but empty section with no name (an empty name). dwarf_elf_access.c and dwarf_elf_init_finish.c have some comments on this point now. March 29,2011 All the code changed a lot because indentations were all over the map, now they are consistent. Additions were made to DWARF4 support. Now we use dicheck (a new open source application) to check indentation. Library users will not see any change, all interfaces remain as before. January 12,2010 A libdwarf user has noticed that the April 4, 2009 consumer function changes introduced a problem: the default CFA column was DW_FRAME_CFA_COL even when a newer DWARF3 consumer frame interface like dwarf_get_fde_info_for_all_regs3() is used. The libdwarf2.1.pdf documentation stated the default should be DW_FRAME_CFA_COL3 in that case. The introduction of a caller-specified frame-column function (dwarf_set_frame_cfa_value()) in that April 4, 2009 release was flawed in that it failed to match the documentation. Now the default frame column is DW_FRAME_CFA_COL3 unless the configure option --enable-oldframecol is used at libdwarf build time. If you are using libdwarf old frame consumer interfaces dwarf_get_fde_info_for_reg(), dwarf_get_fde_info_for_cfa_reg(), and dwarf_get_fde_info_for_all_regs() and want unchanged operation then please configure libdwarf with --enable-oldframecol . or add the call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) after calling a libdwarf initialization function. It is impossible to configure a single libdwarf.a so that it transparently defaults to both DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3. A call such as dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL3) or dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) (or some other name/value of your choosing) following the dwarf_init() call gives your application full control of the frame cfa column independent of the libdwarf configure option. See the libdwarf2.1.pdf documentation for details. We strongly recommend that you use dwarf_set_frame_cfa_value() to avoid a configure-time dependency. July 7, 2009 Implemented support for elf 'rela' relocations so libdwarf and dwarfdump can read *nix .o files with such relocations reasonably, at least for some machines (see dwarf_elf_access.c for EM_ in 'case' statements.) This changes the binary access for non-Elf object users (folks who have coded there own non-Elf access routines do reference internals of dwarf_opaque.h), but the new data can be left zero and the rest of the code should work fine. dwarf_opaque.h gathers section data in Dwarf_Section_s structs which simplifies the code in dwarf_init_finish.c and clarifies what fields are section related. July 4, 2009 When something erroneous is detected in a die information about the CU context may be of interest. So we added dwarf_CU_dieoffset_given_die(), a function which allows clients to find the relevant CU die for any die. The consumer can use normal attribute access functions to print information about that CU die (and the erroneous die, of course). See the libdwarf consumer document for more information. April 27, 2009 Interface additions: dwarf_loclist_from_expr_a() and dwarf_get_ranges_a() are new interfaces like dwarf_loclist_from_expr() and dwarf_get_ranges() respectively, but with arguments allowing full support for different CIEs in an executable having different address-sizes (and their compilation unit DIEs if .debug_info is present). dwarf_get_loclist_entry() does not support differing address sizes per CIE/CU. April 4, 2009 Added new functions dwarf_set_frame_cfa_value() dwarf_set_frame_same_value(), and dwarf_set_frame_undefined_value(). These are essential for ABIs where the real register numbers exceed 1033 (such as ppc). Failing to use these leads to frame instructions DW_CFA_undefined and DW_CFA_same_value emitting values that cannot be interpreted correctly by a libdwarf consumer. See dwarfdump for examples of use. Feb 14, 2009 Added configure option --enable-nonstandardprintf which makes it easy to get printf of Dwarf_Unsigned (etc) types correct even for non-standard compilers. Dec 30, 2008 Added interfaces for getting and printing the .debug_ranges data. Dec 8, 2008 Record the abbreviation 'code' (index) in each DIE. Making it possible for a pretty-printer to print the abbreviation code. Sep 30, 2008 Phil Mucci provided an a.out test chase which demonstrates a bug in 64bit DWARF2 output by gcc. Now libdwarf works around this and with -v -v -v -v prints a warning. Sep 29, 2008 Thanks to Phil Mucci for providing a little-endian 64bit test object file that exposed a problem when there are 'extra' bytes (possibly unused) after a line table prologue header and before the line table itself. This releases fixes the bug. Thanks to Matthew Legendre for pointing out that we were sharing de_fde_count for eh and non-eh and that could cause erroneous error returns in a couple of functions. These counts are now separate. April 9, 2008 libdwarf would behave badly if one compilation unit had more than 64K abbreviations: It was both very slow dealing with abbreviations and would get mixed up and error-off. Increased the size of some internal variables and rewrote abbreviation lookup. February 18, 2008 It is now possible to write one's own access to objects, making it possible to use a different library than libelf or even read a completely different object format than ELF. See dwarf_object_init() and see the new source files dwarf_original_elf_init.c and dwarf_elf_access.c for example code using the new function-pointer approach as it's implementation. Thanks to Josh Fuhs for doing the design and 99% of the work to make this happen. February 2, 2008 Now pro_init() defaults to standard DWARF3 generated offset sizes. But if a new flag DW_DLC_OFFSET_SIZE_64 or'd into flags passed to dwarf_produser_init() or dwarf_producer_init_b, the DWARF3 extended offset size is generated (if the address size is 64 bit). The new configure option --enable-dwarf-format-strict-32bit forces pro_init() to always cause 32bit offset dwarf generation. The new configure option --enable-dwarf-format-sgi-irix forces the old SGI IRIX 64bit offset generation for 64bit pointer size objects. This is intended to simplify standard DWARF3 generation with the now-normal use of 32bit DWARF offsets for both 32 and 64 bit pointer objects. It does require that anyone wanting SGI IRIX dwarf generation with its non-standard offsets for 64bit objects use the new --enable-dwarf-format-sgi-irix configure time option. This has no effect on dwarf reader code. It affects code calling the libdwarf producer interfaces. December 8, 2007 Had to add an ugly configure conditional as libelf has unconditional use of off64_t in recent libelf.h July 3, 2007 A new interface function, dwarf_loclist_from_expr(), allows easy extraction of dwarf expression bytes from expressions in frame data. May 8, 2007 Now documents released as .mm and .pdf (no longer as .ps). May 7, 2007 Incorporates Sun Microsystems extensions to dwarf.h and to the consumer and producer libraries. The changes include corrections so the producer library cleans up it's memory use on a call to dwarf_producer_finish(dbg). Thanks to Chris Quenelle of Sun for these contributions. March 20, 2007 nroff/troff and the AT&T -mm package are not widely available, so now the Makefile refers to groff, which works quite nicely. February 20, 2007 Documented libdwarf thread safety in README. Fixed memory leak in dwarf macro reading code. Removed use of static data in dwarf macro reading code: now uses stack/heap (for thread safety). February 9, 2007 Maintenance of libdwarf is now outside SGI as David Anderson has left SGI. March 29, 2006 The March 27, 2006 version accommodates DWARF3. Some people have been using the library without altering dwarf.h, libdwarf.h to accommodate large numbers of registers. This exposed a bug (an off-by-one error) but also makes it clear additional documentation is needed. So in libdwarf large new comments near 'TARGET DEPENDENCY' attempt to explain better. Oct 03, 2005 The July version had an incompatible interface: old dealloc code did not always work right. The incompatibility is now fixed and the new features remain. July 15, 2005 New optional alloc-check code optionally checks all allocated memory is freed (malloc_check.h malloc_check.c) Various new dealloc routines written as the previous approach of letting client code do detailed dealloc turned out not to dealloc all memory. To get the new checking you must manually change a line in malloc_check.h and rebuild libdwarf. Mar 31, 2005 Documented the libexc.so/.debug_funcnames dependency and the 64bit-offset DWARF extension in mips_extentions.{mm,ps}. Mar 21, 2005 gcc 3.3 and 3.4 .eh_frame 'z' augmentations are not handled correctly, so libdwarf gives an error when attempting to print such. gcc 2 'eh' augmentation is simpler and prints correctly. (.eh_frame is a GNU section, not DWARF2/3, and what is recorded in .eh_frame is not specified by DWARF2/3, though .eh_frame does resemble DWARF2/3 .debug_frame). Oct 28, 2004 Updated contact address in copyright: SGI moved 1/4 mile in 2003 to a new address: 1500 Crittenden Lane. Documented additional vendor extensions. Oct 27, 2004 Added known vendor extensions to dwarf2/3 to dwarf.h HP, GNU, PGI and UPC extensions are now recorded. Recorded vendor extensions from Concurrent. Feb 3, 2004 If 'Dwarf_Word' is 64 bits, two macros reading leb numbers fail to initialize upper bits of the values read. First noticed with bogus line numbers printing from dwarfdump. Now we use already-existing functions, avoiding the problem. Oct 02, 2003 Support .debug_loc section fully. Sept 29, 2003 Support DW_FORM_indirect properly. Supports loclists in part (but not multiple loclist entries yet). Support 'padding bytes' at end of .debug_arange and .debug_pubnames and .debug_pubtypes per CU (recent dwarf committee email made it clear this is appropriate). May 23, 2002 Libdwarf now asks for sections only when they are used, so that unneeded sections aren't loaded. Support for using SGI's ELF library as an alternative to using AT&T libelf-style has been added (the SGI ELF library is presently only available internally to SGI). Jan 10, 2002 Fixed memory leak in dwarf_finish(). Aug 21, 2001 If one called dwarf_add_file_decl() or dwarf_add_directory_decl() but never added a line, .debug_line was not produced. This was a mistake, as if any file or directory was provided .debug_line should be produced. Now it is produced. June 14, 2001 Given a cu header offset, it was not easy to derive the CU header DIE offset. Created the new function dwarf_get_cu_die_offset_given_cu_header_offset() do get the CU header DIE offset. Added the function dwarf_get_arange_cu_header_offset() so the cu header offset could be retrieved from .debug_aranges information. June 07, 2001 Major bug in dwarf_leb.c decoding large integers (Dwarf_Signed 64 bit where library is compiled in ILP32) found and fixed. May 21, 2001 Some small fixes have been found by various folks, so it seems time to prepare a new source release. See ChangeLog for details. April 15, 2000 The libdwarf copyright has changed to version 2.1 of the GNU Lesser General Public License. Anyone holding a version of libdwarf that was published before this new copyright is allowed to use the copyright published in that earlier libdwarf source on the earlier source or to use this new copyright on the earlier source, at their option. December 08, 1999 The dwarf committee has adopted the offset-extension proposal. This allows compatibly emitting dwarf with 64bit offsets. The dwarf reader now automatically figures out which is in use. The dwarf writer configures itself at the time the writer initialization routine is called, though the writer is restricted, at libdwarf compile time, to one of mips/sgi pure 32/pure 64 offsets/pointers. 32bit offsets only (per dwarf 2.0.0 and cygnus) 32bit offsets with extension to 64bit offsets allowed (the offset-extension newly passed). In addition, a great deal of duplicate code for the sgi .debug_weaknames, .debug_funcnames, .debug_varnames and .debug_typenames sections has been removed: a single set of functions does the real work now. Sept 29, 1999 Just found out that cygnus is, on 64bit targets, generating 32bit offsets (as elf32 has, for example) with 64 bit pointers (in references to text and data). Whereas sgi has always generated 64bit dwarf with 64 bit offsets (as in elf64) and 64bit pointers for 64bit pointer objects. I'll call the sgi approach 64-bit and the cygnus approach 32bit-offsets. Cygnus is following the DWARF2 spec as written, so they are right in doing only 32bit-offsets. Folks at sgi (including me) think that, as for elf64, the offsets in dwarf for 64bit pointer-apps should be 64 bits. We think it is only a matter of time before we really *need* 64bit offsets and when that happens it will be on an important app. Disk space is cheap, so lets just go 64 bit on 64bit apps (such as ia64 apps) to avoid a future problem. I(davea@sgi.com) think the 'pointer-size' references in the dwarf spec were really written for 64-bit pointer apps. I don't recall serious consideration of 64bit pointer apps in the committee deliberations (I did miss a couple of meetings) and think 64bit offsets are consistent with dwarf2, even though the speci was not written for such. We think true full 64 bit dwarf2 is the right way to go (the spec changes are obvious: file and section offsets become 64bit with 64bit pointer objects. MIPS/SGI is definitely 64-bit offsets for 64 bit objects, cygnus is definitely 32bit-offsets for earlier 64bit pointer environments. At any rate, now the dwarf reader allows and accommodates both and the dwarf producer also accommodates both. Some tweaking of the pro_init.c or dwarf_init_finish.c files may be necessary in future: no other changes should be needed to accommodate the two 64bit approaches, as the library (and dwarfdump) now deal with both forms. August 20, 1999 Added some #ifndef/#define to pro_util.h to let libdwarf build on more hosts. (since those hosts don't need the producer code, AFAIK, zero values suffice for missing #defines.) July 21, 1999 Now reader transparently reads either-endianness data from an either-endianness object. Updated dwarf.h and libdwarf.h to recognize GNU egcs dwarf extensions and to print the egcs eh_frame section. June 10, 1999 gnu configure version of libdwarf made available for the first time. Still allows only same-endian-as-host in objects. August, 1994 libdwarf source made available for ftp on sgigate.sgi.com /ftp/pub June, 1994 Consumer interface changed completely, following "Candy Machine Interfaces" chapter from "Writing Solid Code" by Steve Maguire (Microsoft Press). April, 1993 Initial version of libdwarf for dwarf version 2 written at sgi. libdwarf-20210528/libdwarf/dwarf_macro5.h0000664000175000017500000001144614012266121015011 00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dwarf_macro5.h For the DWARF5 .debug_macro section (also appears as an extension to DWARF4) */ struct Dwarf_Macro_Forms_s { /* Code means DW_MACRO_define etc. */ Dwarf_Small mf_code; /* How many entries in mf_formbytes array. */ Dwarf_Small mf_formcount; /* Never free these, these are in the object file memory */ const Dwarf_Small * mf_formbytes; }; struct Dwarf_Macro_OperationsList_s { unsigned mol_count; struct Dwarf_Macro_Forms_s * mol_data; }; struct Dwarf_Macro_Operator_s { /* mo_opcode == mo_form->mf_code unless it is the final 0 byte in which case all 3 values are zero */ Dwarf_Small mo_opcode; struct Dwarf_Macro_Forms_s * mo_form; /* Points at the first byte of the data, meaning it points one-past the macro operation code byte. */ Dwarf_Small * mo_data; }; #define MACRO_OFFSET_SIZE_FLAG 1 #define MACRO_LINE_OFFSET_FLAG 2 #define MACRO_OP_TABLE_FLAG 4 #define DW_MACRO_VERSION4 4 /* GNU Extension for DWARF 4 */ #define DW_MACRO_VERSION5 5 /* DWARF 5 */ /* Could be reordered to be most space efficient. That might be a little harder to read. Hmm. */ struct Dwarf_Macro_Context_s { Dwarf_Unsigned mc_sentinel; Dwarf_Half mc_version_number; /* Section_offset in .debug_macro of macro header */ Dwarf_Unsigned mc_section_offset; Dwarf_Unsigned mc_section_size; /* Total length of the macro data for this macro unit. Calculated, not part of header. */ Dwarf_Unsigned mc_total_length; Dwarf_Half mc_macro_header_length; Dwarf_Small mc_flags; /* If DW_MACRO_start_file is in the operators of this table then the mc_debug_line_offset must be present from the header. */ Dwarf_Unsigned mc_debug_line_offset; /* the following three set from the bits in mc_flags */ /* If 1, offsets 64 bits */ Dwarf_Bool mc_offset_size_flag; /* if 1, debug_line offset is present. */ Dwarf_Bool mc_debug_line_offset_flag; /* 4 or 8, depending on mc_offset_size_flag */ Dwarf_Small mc_offset_size; /* If one the operands/opcodes (mc_opcode_forms) table is present in the header. If not we use a default table. Even when there are operands in the header the standardops may or may not be defined in the header. */ Dwarf_Bool mc_operands_table_flag; /* Count of the Dwarf_Macro_Forms_s structs pointed to by mc_opcode_forms. These from the header. */ Dwarf_Small mc_opcode_count; struct Dwarf_Macro_Forms_s *mc_opcode_forms; /* mc_ops must be free()d, but pointers inside mc_ops are to static or section data so must not be freed. */ Dwarf_Unsigned mc_macro_ops_count; Dwarf_Unsigned mc_ops_data_length; struct Dwarf_Macro_Operator_s *mc_ops; Dwarf_Small * mc_macro_header; Dwarf_Small * mc_macro_ops; /* These are malloc space, not _dwarf_get_alloc() so the DW_DLA_MACRO_CONTEXT dealloc will free them. */ char ** mc_srcfiles; Dwarf_Signed mc_srcfiles_count; /* These are from CU DIE attribute names. They may be NULL or point at data in a dwarf section. Do not free(). This attempts to make up for the lack of a base file name in DWARF2,3,4 line tables. */ const char * mc_at_comp_dir; const char * mc_at_name; /* The following is malloc,so macro_context_s destructor needs to free it. */ const char * mc_file_path; Dwarf_Debug mc_dbg; Dwarf_CU_Context mc_cu_context; }; int _dwarf_macro_constructor(Dwarf_Debug dbg, void *m); void _dwarf_macro_destructor(void *m); libdwarf-20210528/libdwarf/dwarf_names.c0000664000175000017500000032543714054205616014741 00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #include "dwarf.h" #include "libdwarf.h" /* ARGSUSED */ int dwarf_get_TAG_name (unsigned int val, const char ** s_out) { switch (val) { case DW_TAG_array_type: *s_out = "DW_TAG_array_type"; return DW_DLV_OK; case DW_TAG_class_type: *s_out = "DW_TAG_class_type"; return DW_DLV_OK; case DW_TAG_entry_point: *s_out = "DW_TAG_entry_point"; return DW_DLV_OK; case DW_TAG_enumeration_type: *s_out = "DW_TAG_enumeration_type"; return DW_DLV_OK; case DW_TAG_formal_parameter: *s_out = "DW_TAG_formal_parameter"; return DW_DLV_OK; case DW_TAG_imported_declaration: *s_out = "DW_TAG_imported_declaration"; return DW_DLV_OK; case DW_TAG_label: *s_out = "DW_TAG_label"; return DW_DLV_OK; case DW_TAG_lexical_block: *s_out = "DW_TAG_lexical_block"; return DW_DLV_OK; case DW_TAG_member: *s_out = "DW_TAG_member"; return DW_DLV_OK; case DW_TAG_pointer_type: *s_out = "DW_TAG_pointer_type"; return DW_DLV_OK; case DW_TAG_reference_type: *s_out = "DW_TAG_reference_type"; return DW_DLV_OK; case DW_TAG_compile_unit: *s_out = "DW_TAG_compile_unit"; return DW_DLV_OK; case DW_TAG_string_type: *s_out = "DW_TAG_string_type"; return DW_DLV_OK; case DW_TAG_structure_type: *s_out = "DW_TAG_structure_type"; return DW_DLV_OK; case DW_TAG_subroutine_type: *s_out = "DW_TAG_subroutine_type"; return DW_DLV_OK; case DW_TAG_typedef: *s_out = "DW_TAG_typedef"; return DW_DLV_OK; case DW_TAG_union_type: *s_out = "DW_TAG_union_type"; return DW_DLV_OK; case DW_TAG_unspecified_parameters: *s_out = "DW_TAG_unspecified_parameters"; return DW_DLV_OK; case DW_TAG_variant: *s_out = "DW_TAG_variant"; return DW_DLV_OK; case DW_TAG_common_block: *s_out = "DW_TAG_common_block"; return DW_DLV_OK; case DW_TAG_common_inclusion: *s_out = "DW_TAG_common_inclusion"; return DW_DLV_OK; case DW_TAG_inheritance: *s_out = "DW_TAG_inheritance"; return DW_DLV_OK; case DW_TAG_inlined_subroutine: *s_out = "DW_TAG_inlined_subroutine"; return DW_DLV_OK; case DW_TAG_module: *s_out = "DW_TAG_module"; return DW_DLV_OK; case DW_TAG_ptr_to_member_type: *s_out = "DW_TAG_ptr_to_member_type"; return DW_DLV_OK; case DW_TAG_set_type: *s_out = "DW_TAG_set_type"; return DW_DLV_OK; case DW_TAG_subrange_type: *s_out = "DW_TAG_subrange_type"; return DW_DLV_OK; case DW_TAG_with_stmt: *s_out = "DW_TAG_with_stmt"; return DW_DLV_OK; case DW_TAG_access_declaration: *s_out = "DW_TAG_access_declaration"; return DW_DLV_OK; case DW_TAG_base_type: *s_out = "DW_TAG_base_type"; return DW_DLV_OK; case DW_TAG_catch_block: *s_out = "DW_TAG_catch_block"; return DW_DLV_OK; case DW_TAG_const_type: *s_out = "DW_TAG_const_type"; return DW_DLV_OK; case DW_TAG_constant: *s_out = "DW_TAG_constant"; return DW_DLV_OK; case DW_TAG_enumerator: *s_out = "DW_TAG_enumerator"; return DW_DLV_OK; case DW_TAG_file_type: *s_out = "DW_TAG_file_type"; return DW_DLV_OK; case DW_TAG_friend: *s_out = "DW_TAG_friend"; return DW_DLV_OK; case DW_TAG_namelist: *s_out = "DW_TAG_namelist"; return DW_DLV_OK; case DW_TAG_namelist_item: *s_out = "DW_TAG_namelist_item"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2c. DW_TAG_namelist_items */ case DW_TAG_packed_type: *s_out = "DW_TAG_packed_type"; return DW_DLV_OK; case DW_TAG_subprogram: *s_out = "DW_TAG_subprogram"; return DW_DLV_OK; case DW_TAG_template_type_parameter: *s_out = "DW_TAG_template_type_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2f. DW_TAG_template_type_param */ case DW_TAG_template_value_parameter: *s_out = "DW_TAG_template_value_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x30. DW_TAG_template_value_param */ case DW_TAG_thrown_type: *s_out = "DW_TAG_thrown_type"; return DW_DLV_OK; case DW_TAG_try_block: *s_out = "DW_TAG_try_block"; return DW_DLV_OK; case DW_TAG_variant_part: *s_out = "DW_TAG_variant_part"; return DW_DLV_OK; case DW_TAG_variable: *s_out = "DW_TAG_variable"; return DW_DLV_OK; case DW_TAG_volatile_type: *s_out = "DW_TAG_volatile_type"; return DW_DLV_OK; case DW_TAG_dwarf_procedure: *s_out = "DW_TAG_dwarf_procedure"; return DW_DLV_OK; case DW_TAG_restrict_type: *s_out = "DW_TAG_restrict_type"; return DW_DLV_OK; case DW_TAG_interface_type: *s_out = "DW_TAG_interface_type"; return DW_DLV_OK; case DW_TAG_namespace: *s_out = "DW_TAG_namespace"; return DW_DLV_OK; case DW_TAG_imported_module: *s_out = "DW_TAG_imported_module"; return DW_DLV_OK; case DW_TAG_unspecified_type: *s_out = "DW_TAG_unspecified_type"; return DW_DLV_OK; case DW_TAG_partial_unit: *s_out = "DW_TAG_partial_unit"; return DW_DLV_OK; case DW_TAG_imported_unit: *s_out = "DW_TAG_imported_unit"; return DW_DLV_OK; case DW_TAG_mutable_type: *s_out = "DW_TAG_mutable_type"; return DW_DLV_OK; case DW_TAG_condition: *s_out = "DW_TAG_condition"; return DW_DLV_OK; case DW_TAG_shared_type: *s_out = "DW_TAG_shared_type"; return DW_DLV_OK; case DW_TAG_type_unit: *s_out = "DW_TAG_type_unit"; return DW_DLV_OK; case DW_TAG_rvalue_reference_type: *s_out = "DW_TAG_rvalue_reference_type"; return DW_DLV_OK; case DW_TAG_template_alias: *s_out = "DW_TAG_template_alias"; return DW_DLV_OK; case DW_TAG_coarray_type: *s_out = "DW_TAG_coarray_type"; return DW_DLV_OK; case DW_TAG_generic_subrange: *s_out = "DW_TAG_generic_subrange"; return DW_DLV_OK; case DW_TAG_dynamic_type: *s_out = "DW_TAG_dynamic_type"; return DW_DLV_OK; case DW_TAG_atomic_type: *s_out = "DW_TAG_atomic_type"; return DW_DLV_OK; case DW_TAG_call_site: *s_out = "DW_TAG_call_site"; return DW_DLV_OK; case DW_TAG_call_site_parameter: *s_out = "DW_TAG_call_site_parameter"; return DW_DLV_OK; case DW_TAG_skeleton_unit: *s_out = "DW_TAG_skeleton_unit"; return DW_DLV_OK; case DW_TAG_immutable_type: *s_out = "DW_TAG_immutable_type"; return DW_DLV_OK; case DW_TAG_lo_user: *s_out = "DW_TAG_lo_user"; return DW_DLV_OK; case DW_TAG_MIPS_loop: *s_out = "DW_TAG_MIPS_loop"; return DW_DLV_OK; case DW_TAG_HP_array_descriptor: *s_out = "DW_TAG_HP_array_descriptor"; return DW_DLV_OK; case DW_TAG_format_label: *s_out = "DW_TAG_format_label"; return DW_DLV_OK; case DW_TAG_function_template: *s_out = "DW_TAG_function_template"; return DW_DLV_OK; case DW_TAG_class_template: *s_out = "DW_TAG_class_template"; return DW_DLV_OK; case DW_TAG_GNU_BINCL: *s_out = "DW_TAG_GNU_BINCL"; return DW_DLV_OK; case DW_TAG_GNU_EINCL: *s_out = "DW_TAG_GNU_EINCL"; return DW_DLV_OK; case DW_TAG_GNU_template_template_parameter: *s_out = "DW_TAG_GNU_template_template_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x4106. DW_TAG_GNU_template_template_param */ case DW_TAG_GNU_template_parameter_pack: *s_out = "DW_TAG_GNU_template_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_formal_parameter_pack: *s_out = "DW_TAG_GNU_formal_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_call_site: *s_out = "DW_TAG_GNU_call_site"; return DW_DLV_OK; case DW_TAG_GNU_call_site_parameter: *s_out = "DW_TAG_GNU_call_site_parameter"; return DW_DLV_OK; case DW_TAG_SUN_function_template: *s_out = "DW_TAG_SUN_function_template"; return DW_DLV_OK; case DW_TAG_SUN_class_template: *s_out = "DW_TAG_SUN_class_template"; return DW_DLV_OK; case DW_TAG_SUN_struct_template: *s_out = "DW_TAG_SUN_struct_template"; return DW_DLV_OK; case DW_TAG_SUN_union_template: *s_out = "DW_TAG_SUN_union_template"; return DW_DLV_OK; case DW_TAG_SUN_indirect_inheritance: *s_out = "DW_TAG_SUN_indirect_inheritance"; return DW_DLV_OK; case DW_TAG_SUN_codeflags: *s_out = "DW_TAG_SUN_codeflags"; return DW_DLV_OK; case DW_TAG_SUN_memop_info: *s_out = "DW_TAG_SUN_memop_info"; return DW_DLV_OK; case DW_TAG_SUN_omp_child_func: *s_out = "DW_TAG_SUN_omp_child_func"; return DW_DLV_OK; case DW_TAG_SUN_rtti_descriptor: *s_out = "DW_TAG_SUN_rtti_descriptor"; return DW_DLV_OK; case DW_TAG_SUN_dtor_info: *s_out = "DW_TAG_SUN_dtor_info"; return DW_DLV_OK; case DW_TAG_SUN_dtor: *s_out = "DW_TAG_SUN_dtor"; return DW_DLV_OK; case DW_TAG_SUN_f90_interface: *s_out = "DW_TAG_SUN_f90_interface"; return DW_DLV_OK; case DW_TAG_SUN_fortran_vax_structure: *s_out = "DW_TAG_SUN_fortran_vax_structure"; return DW_DLV_OK; case DW_TAG_SUN_hi: *s_out = "DW_TAG_SUN_hi"; return DW_DLV_OK; case DW_TAG_ALTIUM_circ_type: *s_out = "DW_TAG_ALTIUM_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_mwa_circ_type: *s_out = "DW_TAG_ALTIUM_mwa_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rev_carry_type: *s_out = "DW_TAG_ALTIUM_rev_carry_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rom: *s_out = "DW_TAG_ALTIUM_rom"; return DW_DLV_OK; case DW_TAG_ghs_namespace: *s_out = "DW_TAG_ghs_namespace"; return DW_DLV_OK; case DW_TAG_ghs_using_namespace: *s_out = "DW_TAG_ghs_using_namespace"; return DW_DLV_OK; case DW_TAG_ghs_using_declaration: *s_out = "DW_TAG_ghs_using_declaration"; return DW_DLV_OK; case DW_TAG_ghs_template_templ_param: *s_out = "DW_TAG_ghs_template_templ_param"; return DW_DLV_OK; case DW_TAG_upc_shared_type: *s_out = "DW_TAG_upc_shared_type"; return DW_DLV_OK; case DW_TAG_upc_strict_type: *s_out = "DW_TAG_upc_strict_type"; return DW_DLV_OK; case DW_TAG_upc_relaxed_type: *s_out = "DW_TAG_upc_relaxed_type"; return DW_DLV_OK; case DW_TAG_PGI_kanji_type: *s_out = "DW_TAG_PGI_kanji_type"; return DW_DLV_OK; case DW_TAG_PGI_interface_block: *s_out = "DW_TAG_PGI_interface_block"; return DW_DLV_OK; case DW_TAG_BORLAND_property: *s_out = "DW_TAG_BORLAND_property"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_string: *s_out = "DW_TAG_BORLAND_Delphi_string"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_dynamic_array: *s_out = "DW_TAG_BORLAND_Delphi_dynamic_array"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_set: *s_out = "DW_TAG_BORLAND_Delphi_set"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_variant: *s_out = "DW_TAG_BORLAND_Delphi_variant"; return DW_DLV_OK; case DW_TAG_hi_user: *s_out = "DW_TAG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_children_name (unsigned int val, const char ** s_out) { switch (val) { case DW_children_no: *s_out = "DW_children_no"; return DW_DLV_OK; case DW_children_yes: *s_out = "DW_children_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FORM_name (unsigned int val, const char ** s_out) { switch (val) { case DW_FORM_addr: *s_out = "DW_FORM_addr"; return DW_DLV_OK; case DW_FORM_block2: *s_out = "DW_FORM_block2"; return DW_DLV_OK; case DW_FORM_block4: *s_out = "DW_FORM_block4"; return DW_DLV_OK; case DW_FORM_data2: *s_out = "DW_FORM_data2"; return DW_DLV_OK; case DW_FORM_data4: *s_out = "DW_FORM_data4"; return DW_DLV_OK; case DW_FORM_data8: *s_out = "DW_FORM_data8"; return DW_DLV_OK; case DW_FORM_string: *s_out = "DW_FORM_string"; return DW_DLV_OK; case DW_FORM_block: *s_out = "DW_FORM_block"; return DW_DLV_OK; case DW_FORM_block1: *s_out = "DW_FORM_block1"; return DW_DLV_OK; case DW_FORM_data1: *s_out = "DW_FORM_data1"; return DW_DLV_OK; case DW_FORM_flag: *s_out = "DW_FORM_flag"; return DW_DLV_OK; case DW_FORM_sdata: *s_out = "DW_FORM_sdata"; return DW_DLV_OK; case DW_FORM_strp: *s_out = "DW_FORM_strp"; return DW_DLV_OK; case DW_FORM_udata: *s_out = "DW_FORM_udata"; return DW_DLV_OK; case DW_FORM_ref_addr: *s_out = "DW_FORM_ref_addr"; return DW_DLV_OK; case DW_FORM_ref1: *s_out = "DW_FORM_ref1"; return DW_DLV_OK; case DW_FORM_ref2: *s_out = "DW_FORM_ref2"; return DW_DLV_OK; case DW_FORM_ref4: *s_out = "DW_FORM_ref4"; return DW_DLV_OK; case DW_FORM_ref8: *s_out = "DW_FORM_ref8"; return DW_DLV_OK; case DW_FORM_ref_udata: *s_out = "DW_FORM_ref_udata"; return DW_DLV_OK; case DW_FORM_indirect: *s_out = "DW_FORM_indirect"; return DW_DLV_OK; case DW_FORM_sec_offset: *s_out = "DW_FORM_sec_offset"; return DW_DLV_OK; case DW_FORM_exprloc: *s_out = "DW_FORM_exprloc"; return DW_DLV_OK; case DW_FORM_flag_present: *s_out = "DW_FORM_flag_present"; return DW_DLV_OK; case DW_FORM_strx: *s_out = "DW_FORM_strx"; return DW_DLV_OK; case DW_FORM_addrx: *s_out = "DW_FORM_addrx"; return DW_DLV_OK; case DW_FORM_ref_sup4: *s_out = "DW_FORM_ref_sup4"; return DW_DLV_OK; case DW_FORM_strp_sup: *s_out = "DW_FORM_strp_sup"; return DW_DLV_OK; case DW_FORM_data16: *s_out = "DW_FORM_data16"; return DW_DLV_OK; case DW_FORM_line_strp: *s_out = "DW_FORM_line_strp"; return DW_DLV_OK; case DW_FORM_ref_sig8: *s_out = "DW_FORM_ref_sig8"; return DW_DLV_OK; case DW_FORM_implicit_const: *s_out = "DW_FORM_implicit_const"; return DW_DLV_OK; case DW_FORM_loclistx: *s_out = "DW_FORM_loclistx"; return DW_DLV_OK; case DW_FORM_rnglistx: *s_out = "DW_FORM_rnglistx"; return DW_DLV_OK; case DW_FORM_ref_sup8: *s_out = "DW_FORM_ref_sup8"; return DW_DLV_OK; case DW_FORM_strx1: *s_out = "DW_FORM_strx1"; return DW_DLV_OK; case DW_FORM_strx2: *s_out = "DW_FORM_strx2"; return DW_DLV_OK; case DW_FORM_strx3: *s_out = "DW_FORM_strx3"; return DW_DLV_OK; case DW_FORM_strx4: *s_out = "DW_FORM_strx4"; return DW_DLV_OK; case DW_FORM_addrx1: *s_out = "DW_FORM_addrx1"; return DW_DLV_OK; case DW_FORM_addrx2: *s_out = "DW_FORM_addrx2"; return DW_DLV_OK; case DW_FORM_addrx3: *s_out = "DW_FORM_addrx3"; return DW_DLV_OK; case DW_FORM_addrx4: *s_out = "DW_FORM_addrx4"; return DW_DLV_OK; case DW_FORM_GNU_addr_index: *s_out = "DW_FORM_GNU_addr_index"; return DW_DLV_OK; case DW_FORM_GNU_str_index: *s_out = "DW_FORM_GNU_str_index"; return DW_DLV_OK; case DW_FORM_GNU_ref_alt: *s_out = "DW_FORM_GNU_ref_alt"; return DW_DLV_OK; case DW_FORM_GNU_strp_alt: *s_out = "DW_FORM_GNU_strp_alt"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_AT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_AT_sibling: *s_out = "DW_AT_sibling"; return DW_DLV_OK; case DW_AT_location: *s_out = "DW_AT_location"; return DW_DLV_OK; case DW_AT_name: *s_out = "DW_AT_name"; return DW_DLV_OK; case DW_AT_ordering: *s_out = "DW_AT_ordering"; return DW_DLV_OK; case DW_AT_subscr_data: *s_out = "DW_AT_subscr_data"; return DW_DLV_OK; case DW_AT_byte_size: *s_out = "DW_AT_byte_size"; return DW_DLV_OK; case DW_AT_bit_offset: *s_out = "DW_AT_bit_offset"; return DW_DLV_OK; case DW_AT_bit_size: *s_out = "DW_AT_bit_size"; return DW_DLV_OK; case DW_AT_element_list: *s_out = "DW_AT_element_list"; return DW_DLV_OK; case DW_AT_stmt_list: *s_out = "DW_AT_stmt_list"; return DW_DLV_OK; case DW_AT_low_pc: *s_out = "DW_AT_low_pc"; return DW_DLV_OK; case DW_AT_high_pc: *s_out = "DW_AT_high_pc"; return DW_DLV_OK; case DW_AT_language: *s_out = "DW_AT_language"; return DW_DLV_OK; case DW_AT_member: *s_out = "DW_AT_member"; return DW_DLV_OK; case DW_AT_discr: *s_out = "DW_AT_discr"; return DW_DLV_OK; case DW_AT_discr_value: *s_out = "DW_AT_discr_value"; return DW_DLV_OK; case DW_AT_visibility: *s_out = "DW_AT_visibility"; return DW_DLV_OK; case DW_AT_import: *s_out = "DW_AT_import"; return DW_DLV_OK; case DW_AT_string_length: *s_out = "DW_AT_string_length"; return DW_DLV_OK; case DW_AT_common_reference: *s_out = "DW_AT_common_reference"; return DW_DLV_OK; case DW_AT_comp_dir: *s_out = "DW_AT_comp_dir"; return DW_DLV_OK; case DW_AT_const_value: *s_out = "DW_AT_const_value"; return DW_DLV_OK; case DW_AT_containing_type: *s_out = "DW_AT_containing_type"; return DW_DLV_OK; case DW_AT_default_value: *s_out = "DW_AT_default_value"; return DW_DLV_OK; case DW_AT_inline: *s_out = "DW_AT_inline"; return DW_DLV_OK; case DW_AT_is_optional: *s_out = "DW_AT_is_optional"; return DW_DLV_OK; case DW_AT_lower_bound: *s_out = "DW_AT_lower_bound"; return DW_DLV_OK; case DW_AT_producer: *s_out = "DW_AT_producer"; return DW_DLV_OK; case DW_AT_prototyped: *s_out = "DW_AT_prototyped"; return DW_DLV_OK; case DW_AT_return_addr: *s_out = "DW_AT_return_addr"; return DW_DLV_OK; case DW_AT_start_scope: *s_out = "DW_AT_start_scope"; return DW_DLV_OK; case DW_AT_bit_stride: *s_out = "DW_AT_bit_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2e. DW_AT_stride_size */ case DW_AT_upper_bound: *s_out = "DW_AT_upper_bound"; return DW_DLV_OK; case DW_AT_abstract_origin: *s_out = "DW_AT_abstract_origin"; return DW_DLV_OK; case DW_AT_accessibility: *s_out = "DW_AT_accessibility"; return DW_DLV_OK; case DW_AT_address_class: *s_out = "DW_AT_address_class"; return DW_DLV_OK; case DW_AT_artificial: *s_out = "DW_AT_artificial"; return DW_DLV_OK; case DW_AT_base_types: *s_out = "DW_AT_base_types"; return DW_DLV_OK; case DW_AT_calling_convention: *s_out = "DW_AT_calling_convention"; return DW_DLV_OK; case DW_AT_count: *s_out = "DW_AT_count"; return DW_DLV_OK; case DW_AT_data_member_location: *s_out = "DW_AT_data_member_location"; return DW_DLV_OK; case DW_AT_decl_column: *s_out = "DW_AT_decl_column"; return DW_DLV_OK; case DW_AT_decl_file: *s_out = "DW_AT_decl_file"; return DW_DLV_OK; case DW_AT_decl_line: *s_out = "DW_AT_decl_line"; return DW_DLV_OK; case DW_AT_declaration: *s_out = "DW_AT_declaration"; return DW_DLV_OK; case DW_AT_discr_list: *s_out = "DW_AT_discr_list"; return DW_DLV_OK; case DW_AT_encoding: *s_out = "DW_AT_encoding"; return DW_DLV_OK; case DW_AT_external: *s_out = "DW_AT_external"; return DW_DLV_OK; case DW_AT_frame_base: *s_out = "DW_AT_frame_base"; return DW_DLV_OK; case DW_AT_friend: *s_out = "DW_AT_friend"; return DW_DLV_OK; case DW_AT_identifier_case: *s_out = "DW_AT_identifier_case"; return DW_DLV_OK; case DW_AT_macro_info: *s_out = "DW_AT_macro_info"; return DW_DLV_OK; case DW_AT_namelist_item: *s_out = "DW_AT_namelist_item"; return DW_DLV_OK; case DW_AT_priority: *s_out = "DW_AT_priority"; return DW_DLV_OK; case DW_AT_segment: *s_out = "DW_AT_segment"; return DW_DLV_OK; case DW_AT_specification: *s_out = "DW_AT_specification"; return DW_DLV_OK; case DW_AT_static_link: *s_out = "DW_AT_static_link"; return DW_DLV_OK; case DW_AT_type: *s_out = "DW_AT_type"; return DW_DLV_OK; case DW_AT_use_location: *s_out = "DW_AT_use_location"; return DW_DLV_OK; case DW_AT_variable_parameter: *s_out = "DW_AT_variable_parameter"; return DW_DLV_OK; case DW_AT_virtuality: *s_out = "DW_AT_virtuality"; return DW_DLV_OK; case DW_AT_vtable_elem_location: *s_out = "DW_AT_vtable_elem_location"; return DW_DLV_OK; case DW_AT_allocated: *s_out = "DW_AT_allocated"; return DW_DLV_OK; case DW_AT_associated: *s_out = "DW_AT_associated"; return DW_DLV_OK; case DW_AT_data_location: *s_out = "DW_AT_data_location"; return DW_DLV_OK; case DW_AT_byte_stride: *s_out = "DW_AT_byte_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x51. DW_AT_stride */ case DW_AT_entry_pc: *s_out = "DW_AT_entry_pc"; return DW_DLV_OK; case DW_AT_use_UTF8: *s_out = "DW_AT_use_UTF8"; return DW_DLV_OK; case DW_AT_extension: *s_out = "DW_AT_extension"; return DW_DLV_OK; case DW_AT_ranges: *s_out = "DW_AT_ranges"; return DW_DLV_OK; case DW_AT_trampoline: *s_out = "DW_AT_trampoline"; return DW_DLV_OK; case DW_AT_call_column: *s_out = "DW_AT_call_column"; return DW_DLV_OK; case DW_AT_call_file: *s_out = "DW_AT_call_file"; return DW_DLV_OK; case DW_AT_call_line: *s_out = "DW_AT_call_line"; return DW_DLV_OK; case DW_AT_description: *s_out = "DW_AT_description"; return DW_DLV_OK; case DW_AT_binary_scale: *s_out = "DW_AT_binary_scale"; return DW_DLV_OK; case DW_AT_decimal_scale: *s_out = "DW_AT_decimal_scale"; return DW_DLV_OK; case DW_AT_small: *s_out = "DW_AT_small"; return DW_DLV_OK; case DW_AT_decimal_sign: *s_out = "DW_AT_decimal_sign"; return DW_DLV_OK; case DW_AT_digit_count: *s_out = "DW_AT_digit_count"; return DW_DLV_OK; case DW_AT_picture_string: *s_out = "DW_AT_picture_string"; return DW_DLV_OK; case DW_AT_mutable: *s_out = "DW_AT_mutable"; return DW_DLV_OK; case DW_AT_threads_scaled: *s_out = "DW_AT_threads_scaled"; return DW_DLV_OK; case DW_AT_explicit: *s_out = "DW_AT_explicit"; return DW_DLV_OK; case DW_AT_object_pointer: *s_out = "DW_AT_object_pointer"; return DW_DLV_OK; case DW_AT_endianity: *s_out = "DW_AT_endianity"; return DW_DLV_OK; case DW_AT_elemental: *s_out = "DW_AT_elemental"; return DW_DLV_OK; case DW_AT_pure: *s_out = "DW_AT_pure"; return DW_DLV_OK; case DW_AT_recursive: *s_out = "DW_AT_recursive"; return DW_DLV_OK; case DW_AT_signature: *s_out = "DW_AT_signature"; return DW_DLV_OK; case DW_AT_main_subprogram: *s_out = "DW_AT_main_subprogram"; return DW_DLV_OK; case DW_AT_data_bit_offset: *s_out = "DW_AT_data_bit_offset"; return DW_DLV_OK; case DW_AT_const_expr: *s_out = "DW_AT_const_expr"; return DW_DLV_OK; case DW_AT_enum_class: *s_out = "DW_AT_enum_class"; return DW_DLV_OK; case DW_AT_linkage_name: *s_out = "DW_AT_linkage_name"; return DW_DLV_OK; case DW_AT_string_length_bit_size: *s_out = "DW_AT_string_length_bit_size"; return DW_DLV_OK; case DW_AT_string_length_byte_size: *s_out = "DW_AT_string_length_byte_size"; return DW_DLV_OK; case DW_AT_rank: *s_out = "DW_AT_rank"; return DW_DLV_OK; case DW_AT_str_offsets_base: *s_out = "DW_AT_str_offsets_base"; return DW_DLV_OK; case DW_AT_addr_base: *s_out = "DW_AT_addr_base"; return DW_DLV_OK; case DW_AT_rnglists_base: *s_out = "DW_AT_rnglists_base"; return DW_DLV_OK; case DW_AT_dwo_id: *s_out = "DW_AT_dwo_id"; return DW_DLV_OK; case DW_AT_dwo_name: *s_out = "DW_AT_dwo_name"; return DW_DLV_OK; case DW_AT_reference: *s_out = "DW_AT_reference"; return DW_DLV_OK; case DW_AT_rvalue_reference: *s_out = "DW_AT_rvalue_reference"; return DW_DLV_OK; case DW_AT_macros: *s_out = "DW_AT_macros"; return DW_DLV_OK; case DW_AT_call_all_calls: *s_out = "DW_AT_call_all_calls"; return DW_DLV_OK; case DW_AT_call_all_source_calls: *s_out = "DW_AT_call_all_source_calls"; return DW_DLV_OK; case DW_AT_call_all_tail_calls: *s_out = "DW_AT_call_all_tail_calls"; return DW_DLV_OK; case DW_AT_call_return_pc: *s_out = "DW_AT_call_return_pc"; return DW_DLV_OK; case DW_AT_call_value: *s_out = "DW_AT_call_value"; return DW_DLV_OK; case DW_AT_call_origin: *s_out = "DW_AT_call_origin"; return DW_DLV_OK; case DW_AT_call_parameter: *s_out = "DW_AT_call_parameter"; return DW_DLV_OK; case DW_AT_call_pc: *s_out = "DW_AT_call_pc"; return DW_DLV_OK; case DW_AT_call_tail_call: *s_out = "DW_AT_call_tail_call"; return DW_DLV_OK; case DW_AT_call_target: *s_out = "DW_AT_call_target"; return DW_DLV_OK; case DW_AT_call_target_clobbered: *s_out = "DW_AT_call_target_clobbered"; return DW_DLV_OK; case DW_AT_call_data_location: *s_out = "DW_AT_call_data_location"; return DW_DLV_OK; case DW_AT_call_data_value: *s_out = "DW_AT_call_data_value"; return DW_DLV_OK; case DW_AT_noreturn: *s_out = "DW_AT_noreturn"; return DW_DLV_OK; case DW_AT_alignment: *s_out = "DW_AT_alignment"; return DW_DLV_OK; case DW_AT_export_symbols: *s_out = "DW_AT_export_symbols"; return DW_DLV_OK; case DW_AT_deleted: *s_out = "DW_AT_deleted"; return DW_DLV_OK; case DW_AT_defaulted: *s_out = "DW_AT_defaulted"; return DW_DLV_OK; case DW_AT_loclists_base: *s_out = "DW_AT_loclists_base"; return DW_DLV_OK; case DW_AT_ghs_namespace_alias: *s_out = "DW_AT_ghs_namespace_alias"; return DW_DLV_OK; case DW_AT_ghs_using_namespace: *s_out = "DW_AT_ghs_using_namespace"; return DW_DLV_OK; case DW_AT_ghs_using_declaration: *s_out = "DW_AT_ghs_using_declaration"; return DW_DLV_OK; case DW_AT_HP_block_index: *s_out = "DW_AT_HP_block_index"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ case DW_AT_MIPS_fde: *s_out = "DW_AT_MIPS_fde"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2001. DW_AT_HP_unmodifiable */ /* Skipping alternate spelling of value 0x2001. DW_AT_CPQ_discontig_ranges */ case DW_AT_MIPS_loop_begin: *s_out = "DW_AT_MIPS_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2002. DW_AT_CPQ_semantic_events */ case DW_AT_MIPS_tail_loop_begin: *s_out = "DW_AT_MIPS_tail_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2003. DW_AT_CPQ_split_lifetimes_var */ case DW_AT_MIPS_epilog_begin: *s_out = "DW_AT_MIPS_epilog_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ case DW_AT_MIPS_loop_unroll_factor: *s_out = "DW_AT_MIPS_loop_unroll_factor"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2005. DW_AT_HP_prologue */ /* Skipping alternate spelling of value 0x2005. DW_AT_CPQ_prologue_length */ case DW_AT_MIPS_software_pipeline_depth: *s_out = "DW_AT_MIPS_software_pipeline_depth"; return DW_DLV_OK; case DW_AT_MIPS_linkage_name: *s_out = "DW_AT_MIPS_linkage_name"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2007. DW_AT_ghs_mangled */ case DW_AT_MIPS_stride: *s_out = "DW_AT_MIPS_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2008. DW_AT_HP_epilogue */ case DW_AT_MIPS_abstract_name: *s_out = "DW_AT_MIPS_abstract_name"; return DW_DLV_OK; case DW_AT_MIPS_clone_origin: *s_out = "DW_AT_MIPS_clone_origin"; return DW_DLV_OK; case DW_AT_MIPS_has_inlines: *s_out = "DW_AT_MIPS_has_inlines"; return DW_DLV_OK; case DW_AT_MIPS_stride_byte: *s_out = "DW_AT_MIPS_stride_byte"; return DW_DLV_OK; case DW_AT_MIPS_stride_elem: *s_out = "DW_AT_MIPS_stride_elem"; return DW_DLV_OK; case DW_AT_MIPS_ptr_dopetype: *s_out = "DW_AT_MIPS_ptr_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_allocatable_dopetype: *s_out = "DW_AT_MIPS_allocatable_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_assumed_shape_dopetype: *s_out = "DW_AT_MIPS_assumed_shape_dopetype"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2010. DW_AT_HP_actuals_stmt_list */ case DW_AT_MIPS_assumed_size: *s_out = "DW_AT_MIPS_assumed_size"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2011. DW_AT_HP_proc_per_section */ case DW_AT_HP_raw_data_ptr: *s_out = "DW_AT_HP_raw_data_ptr"; return DW_DLV_OK; case DW_AT_HP_pass_by_reference: *s_out = "DW_AT_HP_pass_by_reference"; return DW_DLV_OK; case DW_AT_HP_opt_level: *s_out = "DW_AT_HP_opt_level"; return DW_DLV_OK; case DW_AT_HP_prof_version_id: *s_out = "DW_AT_HP_prof_version_id"; return DW_DLV_OK; case DW_AT_HP_opt_flags: *s_out = "DW_AT_HP_opt_flags"; return DW_DLV_OK; case DW_AT_HP_cold_region_low_pc: *s_out = "DW_AT_HP_cold_region_low_pc"; return DW_DLV_OK; case DW_AT_HP_cold_region_high_pc: *s_out = "DW_AT_HP_cold_region_high_pc"; return DW_DLV_OK; case DW_AT_HP_all_variables_modifiable: *s_out = "DW_AT_HP_all_variables_modifiable"; return DW_DLV_OK; case DW_AT_HP_linkage_name: *s_out = "DW_AT_HP_linkage_name"; return DW_DLV_OK; case DW_AT_HP_prof_flags: *s_out = "DW_AT_HP_prof_flags"; return DW_DLV_OK; case DW_AT_HP_unit_name: *s_out = "DW_AT_HP_unit_name"; return DW_DLV_OK; case DW_AT_HP_unit_size: *s_out = "DW_AT_HP_unit_size"; return DW_DLV_OK; case DW_AT_HP_widened_byte_size: *s_out = "DW_AT_HP_widened_byte_size"; return DW_DLV_OK; case DW_AT_HP_definition_points: *s_out = "DW_AT_HP_definition_points"; return DW_DLV_OK; case DW_AT_HP_default_location: *s_out = "DW_AT_HP_default_location"; return DW_DLV_OK; case DW_AT_INTEL_other_endian: *s_out = "DW_AT_INTEL_other_endian"; return DW_DLV_OK; case DW_AT_HP_is_result_param: *s_out = "DW_AT_HP_is_result_param"; return DW_DLV_OK; case DW_AT_ghs_rsm: *s_out = "DW_AT_ghs_rsm"; return DW_DLV_OK; case DW_AT_ghs_frsm: *s_out = "DW_AT_ghs_frsm"; return DW_DLV_OK; case DW_AT_ghs_frames: *s_out = "DW_AT_ghs_frames"; return DW_DLV_OK; case DW_AT_ghs_rso: *s_out = "DW_AT_ghs_rso"; return DW_DLV_OK; case DW_AT_ghs_subcpu: *s_out = "DW_AT_ghs_subcpu"; return DW_DLV_OK; case DW_AT_ghs_lbrace_line: *s_out = "DW_AT_ghs_lbrace_line"; return DW_DLV_OK; case DW_AT_sf_names: *s_out = "DW_AT_sf_names"; return DW_DLV_OK; case DW_AT_src_info: *s_out = "DW_AT_src_info"; return DW_DLV_OK; case DW_AT_mac_info: *s_out = "DW_AT_mac_info"; return DW_DLV_OK; case DW_AT_src_coords: *s_out = "DW_AT_src_coords"; return DW_DLV_OK; case DW_AT_body_begin: *s_out = "DW_AT_body_begin"; return DW_DLV_OK; case DW_AT_body_end: *s_out = "DW_AT_body_end"; return DW_DLV_OK; case DW_AT_GNU_vector: *s_out = "DW_AT_GNU_vector"; return DW_DLV_OK; case DW_AT_GNU_guarded_by: *s_out = "DW_AT_GNU_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded_by: *s_out = "DW_AT_GNU_pt_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_guarded: *s_out = "DW_AT_GNU_guarded"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded: *s_out = "DW_AT_GNU_pt_guarded"; return DW_DLV_OK; case DW_AT_GNU_locks_excluded: *s_out = "DW_AT_GNU_locks_excluded"; return DW_DLV_OK; case DW_AT_GNU_exclusive_locks_required: *s_out = "DW_AT_GNU_exclusive_locks_required"; return DW_DLV_OK; case DW_AT_GNU_shared_locks_required: *s_out = "DW_AT_GNU_shared_locks_required"; return DW_DLV_OK; case DW_AT_GNU_odr_signature: *s_out = "DW_AT_GNU_odr_signature"; return DW_DLV_OK; case DW_AT_GNU_template_name: *s_out = "DW_AT_GNU_template_name"; return DW_DLV_OK; case DW_AT_GNU_call_site_value: *s_out = "DW_AT_GNU_call_site_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_data_value: *s_out = "DW_AT_GNU_call_site_data_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_target: *s_out = "DW_AT_GNU_call_site_target"; return DW_DLV_OK; case DW_AT_GNU_call_site_target_clobbered: *s_out = "DW_AT_GNU_call_site_target_clobbered"; return DW_DLV_OK; case DW_AT_GNU_tail_call: *s_out = "DW_AT_GNU_tail_call"; return DW_DLV_OK; case DW_AT_GNU_all_tail_call_sites: *s_out = "DW_AT_GNU_all_tail_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_call_sites: *s_out = "DW_AT_GNU_all_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_source_call_sites: *s_out = "DW_AT_GNU_all_source_call_sites"; return DW_DLV_OK; case DW_AT_GNU_macros: *s_out = "DW_AT_GNU_macros"; return DW_DLV_OK; case DW_AT_GNU_deleted: *s_out = "DW_AT_GNU_deleted"; return DW_DLV_OK; case DW_AT_GNU_dwo_name: *s_out = "DW_AT_GNU_dwo_name"; return DW_DLV_OK; case DW_AT_GNU_dwo_id: *s_out = "DW_AT_GNU_dwo_id"; return DW_DLV_OK; case DW_AT_GNU_ranges_base: *s_out = "DW_AT_GNU_ranges_base"; return DW_DLV_OK; case DW_AT_GNU_addr_base: *s_out = "DW_AT_GNU_addr_base"; return DW_DLV_OK; case DW_AT_GNU_pubnames: *s_out = "DW_AT_GNU_pubnames"; return DW_DLV_OK; case DW_AT_GNU_pubtypes: *s_out = "DW_AT_GNU_pubtypes"; return DW_DLV_OK; case DW_AT_GNU_discriminator: *s_out = "DW_AT_GNU_discriminator"; return DW_DLV_OK; case DW_AT_GNU_locviews: *s_out = "DW_AT_GNU_locviews"; return DW_DLV_OK; case DW_AT_GNU_entry_view: *s_out = "DW_AT_GNU_entry_view"; return DW_DLV_OK; case DW_AT_SUN_template: *s_out = "DW_AT_SUN_template"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2201. DW_AT_VMS_rtnbeg_pd_address */ case DW_AT_SUN_alignment: *s_out = "DW_AT_SUN_alignment"; return DW_DLV_OK; case DW_AT_SUN_vtable: *s_out = "DW_AT_SUN_vtable"; return DW_DLV_OK; case DW_AT_SUN_count_guarantee: *s_out = "DW_AT_SUN_count_guarantee"; return DW_DLV_OK; case DW_AT_SUN_command_line: *s_out = "DW_AT_SUN_command_line"; return DW_DLV_OK; case DW_AT_SUN_vbase: *s_out = "DW_AT_SUN_vbase"; return DW_DLV_OK; case DW_AT_SUN_compile_options: *s_out = "DW_AT_SUN_compile_options"; return DW_DLV_OK; case DW_AT_SUN_language: *s_out = "DW_AT_SUN_language"; return DW_DLV_OK; case DW_AT_SUN_browser_file: *s_out = "DW_AT_SUN_browser_file"; return DW_DLV_OK; case DW_AT_SUN_vtable_abi: *s_out = "DW_AT_SUN_vtable_abi"; return DW_DLV_OK; case DW_AT_SUN_func_offsets: *s_out = "DW_AT_SUN_func_offsets"; return DW_DLV_OK; case DW_AT_SUN_cf_kind: *s_out = "DW_AT_SUN_cf_kind"; return DW_DLV_OK; case DW_AT_SUN_vtable_index: *s_out = "DW_AT_SUN_vtable_index"; return DW_DLV_OK; case DW_AT_SUN_omp_tpriv_addr: *s_out = "DW_AT_SUN_omp_tpriv_addr"; return DW_DLV_OK; case DW_AT_SUN_omp_child_func: *s_out = "DW_AT_SUN_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_func_offset: *s_out = "DW_AT_SUN_func_offset"; return DW_DLV_OK; case DW_AT_SUN_memop_type_ref: *s_out = "DW_AT_SUN_memop_type_ref"; return DW_DLV_OK; case DW_AT_SUN_profile_id: *s_out = "DW_AT_SUN_profile_id"; return DW_DLV_OK; case DW_AT_SUN_memop_signature: *s_out = "DW_AT_SUN_memop_signature"; return DW_DLV_OK; case DW_AT_SUN_obj_dir: *s_out = "DW_AT_SUN_obj_dir"; return DW_DLV_OK; case DW_AT_SUN_obj_file: *s_out = "DW_AT_SUN_obj_file"; return DW_DLV_OK; case DW_AT_SUN_original_name: *s_out = "DW_AT_SUN_original_name"; return DW_DLV_OK; case DW_AT_SUN_hwcprof_signature: *s_out = "DW_AT_SUN_hwcprof_signature"; return DW_DLV_OK; case DW_AT_SUN_amd64_parmdump: *s_out = "DW_AT_SUN_amd64_parmdump"; return DW_DLV_OK; case DW_AT_SUN_part_link_name: *s_out = "DW_AT_SUN_part_link_name"; return DW_DLV_OK; case DW_AT_SUN_link_name: *s_out = "DW_AT_SUN_link_name"; return DW_DLV_OK; case DW_AT_SUN_pass_with_const: *s_out = "DW_AT_SUN_pass_with_const"; return DW_DLV_OK; case DW_AT_SUN_return_with_const: *s_out = "DW_AT_SUN_return_with_const"; return DW_DLV_OK; case DW_AT_SUN_import_by_name: *s_out = "DW_AT_SUN_import_by_name"; return DW_DLV_OK; case DW_AT_SUN_f90_pointer: *s_out = "DW_AT_SUN_f90_pointer"; return DW_DLV_OK; case DW_AT_SUN_pass_by_ref: *s_out = "DW_AT_SUN_pass_by_ref"; return DW_DLV_OK; case DW_AT_SUN_f90_allocatable: *s_out = "DW_AT_SUN_f90_allocatable"; return DW_DLV_OK; case DW_AT_SUN_f90_assumed_shape_array: *s_out = "DW_AT_SUN_f90_assumed_shape_array"; return DW_DLV_OK; case DW_AT_SUN_c_vla: *s_out = "DW_AT_SUN_c_vla"; return DW_DLV_OK; case DW_AT_SUN_return_value_ptr: *s_out = "DW_AT_SUN_return_value_ptr"; return DW_DLV_OK; case DW_AT_SUN_dtor_start: *s_out = "DW_AT_SUN_dtor_start"; return DW_DLV_OK; case DW_AT_SUN_dtor_length: *s_out = "DW_AT_SUN_dtor_length"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_initial: *s_out = "DW_AT_SUN_dtor_state_initial"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_final: *s_out = "DW_AT_SUN_dtor_state_final"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_deltas: *s_out = "DW_AT_SUN_dtor_state_deltas"; return DW_DLV_OK; case DW_AT_SUN_import_by_lname: *s_out = "DW_AT_SUN_import_by_lname"; return DW_DLV_OK; case DW_AT_SUN_f90_use_only: *s_out = "DW_AT_SUN_f90_use_only"; return DW_DLV_OK; case DW_AT_SUN_namelist_spec: *s_out = "DW_AT_SUN_namelist_spec"; return DW_DLV_OK; case DW_AT_SUN_is_omp_child_func: *s_out = "DW_AT_SUN_is_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_fortran_main_alias: *s_out = "DW_AT_SUN_fortran_main_alias"; return DW_DLV_OK; case DW_AT_SUN_fortran_based: *s_out = "DW_AT_SUN_fortran_based"; return DW_DLV_OK; case DW_AT_ALTIUM_loclist: *s_out = "DW_AT_ALTIUM_loclist"; return DW_DLV_OK; case DW_AT_use_GNAT_descriptive_type: *s_out = "DW_AT_use_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNAT_descriptive_type: *s_out = "DW_AT_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNU_numerator: *s_out = "DW_AT_GNU_numerator"; return DW_DLV_OK; case DW_AT_GNU_denominator: *s_out = "DW_AT_GNU_denominator"; return DW_DLV_OK; case DW_AT_GNU_bias: *s_out = "DW_AT_GNU_bias"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2305. DW_AT_GNU_bias */ case DW_AT_go_kind: *s_out = "DW_AT_go_kind"; return DW_DLV_OK; case DW_AT_go_key: *s_out = "DW_AT_go_key"; return DW_DLV_OK; case DW_AT_go_elem: *s_out = "DW_AT_go_elem"; return DW_DLV_OK; case DW_AT_go_embedded_field: *s_out = "DW_AT_go_embedded_field"; return DW_DLV_OK; case DW_AT_go_runtime_type: *s_out = "DW_AT_go_runtime_type"; return DW_DLV_OK; case DW_AT_upc_threads_scaled: *s_out = "DW_AT_upc_threads_scaled"; return DW_DLV_OK; case DW_AT_IBM_wsa_addr: *s_out = "DW_AT_IBM_wsa_addr"; return DW_DLV_OK; case DW_AT_IBM_home_location: *s_out = "DW_AT_IBM_home_location"; return DW_DLV_OK; case DW_AT_IBM_alt_srcview: *s_out = "DW_AT_IBM_alt_srcview"; return DW_DLV_OK; case DW_AT_PGI_lbase: *s_out = "DW_AT_PGI_lbase"; return DW_DLV_OK; case DW_AT_PGI_soffset: *s_out = "DW_AT_PGI_soffset"; return DW_DLV_OK; case DW_AT_PGI_lstride: *s_out = "DW_AT_PGI_lstride"; return DW_DLV_OK; case DW_AT_BORLAND_property_read: *s_out = "DW_AT_BORLAND_property_read"; return DW_DLV_OK; case DW_AT_BORLAND_property_write: *s_out = "DW_AT_BORLAND_property_write"; return DW_DLV_OK; case DW_AT_BORLAND_property_implements: *s_out = "DW_AT_BORLAND_property_implements"; return DW_DLV_OK; case DW_AT_BORLAND_property_index: *s_out = "DW_AT_BORLAND_property_index"; return DW_DLV_OK; case DW_AT_BORLAND_property_default: *s_out = "DW_AT_BORLAND_property_default"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_unit: *s_out = "DW_AT_BORLAND_Delphi_unit"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_class: *s_out = "DW_AT_BORLAND_Delphi_class"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_record: *s_out = "DW_AT_BORLAND_Delphi_record"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_metaclass: *s_out = "DW_AT_BORLAND_Delphi_metaclass"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_constructor: *s_out = "DW_AT_BORLAND_Delphi_constructor"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_destructor: *s_out = "DW_AT_BORLAND_Delphi_destructor"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_anonymous_method: *s_out = "DW_AT_BORLAND_Delphi_anonymous_method"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_interface: *s_out = "DW_AT_BORLAND_Delphi_interface"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_ABI: *s_out = "DW_AT_BORLAND_Delphi_ABI"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_frameptr: *s_out = "DW_AT_BORLAND_Delphi_frameptr"; return DW_DLV_OK; case DW_AT_BORLAND_closure: *s_out = "DW_AT_BORLAND_closure"; return DW_DLV_OK; case DW_AT_LLVM_include_path: *s_out = "DW_AT_LLVM_include_path"; return DW_DLV_OK; case DW_AT_LLVM_config_macros: *s_out = "DW_AT_LLVM_config_macros"; return DW_DLV_OK; case DW_AT_LLVM_sysroot: *s_out = "DW_AT_LLVM_sysroot"; return DW_DLV_OK; case DW_AT_LLVM_tag_offset: *s_out = "DW_AT_LLVM_tag_offset"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3e03. DW_AT_LLVM_apinotes */ case DW_AT_APPLE_optimized: *s_out = "DW_AT_APPLE_optimized"; return DW_DLV_OK; case DW_AT_APPLE_flags: *s_out = "DW_AT_APPLE_flags"; return DW_DLV_OK; case DW_AT_APPLE_isa: *s_out = "DW_AT_APPLE_isa"; return DW_DLV_OK; case DW_AT_APPLE_block: *s_out = "DW_AT_APPLE_block"; return DW_DLV_OK; case DW_AT_APPLE_major_runtime_vers: *s_out = "DW_AT_APPLE_major_runtime_vers"; return DW_DLV_OK; case DW_AT_APPLE_runtime_class: *s_out = "DW_AT_APPLE_runtime_class"; return DW_DLV_OK; case DW_AT_APPLE_omit_frame_ptr: *s_out = "DW_AT_APPLE_omit_frame_ptr"; return DW_DLV_OK; case DW_AT_APPLE_property_name: *s_out = "DW_AT_APPLE_property_name"; return DW_DLV_OK; case DW_AT_APPLE_property_getter: *s_out = "DW_AT_APPLE_property_getter"; return DW_DLV_OK; case DW_AT_APPLE_property_setter: *s_out = "DW_AT_APPLE_property_setter"; return DW_DLV_OK; case DW_AT_APPLE_property_attribute: *s_out = "DW_AT_APPLE_property_attribute"; return DW_DLV_OK; case DW_AT_APPLE_objc_complete_type: *s_out = "DW_AT_APPLE_objc_complete_type"; return DW_DLV_OK; case DW_AT_APPLE_property: *s_out = "DW_AT_APPLE_property"; return DW_DLV_OK; case DW_AT_APPLE_objc_direct: *s_out = "DW_AT_APPLE_objc_direct"; return DW_DLV_OK; case DW_AT_APPLE_sdk: *s_out = "DW_AT_APPLE_sdk"; return DW_DLV_OK; case DW_AT_hi_user: *s_out = "DW_AT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_OP_name (unsigned int val, const char ** s_out) { switch (val) { case DW_OP_addr: *s_out = "DW_OP_addr"; return DW_DLV_OK; case DW_OP_deref: *s_out = "DW_OP_deref"; return DW_DLV_OK; case DW_OP_const1u: *s_out = "DW_OP_const1u"; return DW_DLV_OK; case DW_OP_const1s: *s_out = "DW_OP_const1s"; return DW_DLV_OK; case DW_OP_const2u: *s_out = "DW_OP_const2u"; return DW_DLV_OK; case DW_OP_const2s: *s_out = "DW_OP_const2s"; return DW_DLV_OK; case DW_OP_const4u: *s_out = "DW_OP_const4u"; return DW_DLV_OK; case DW_OP_const4s: *s_out = "DW_OP_const4s"; return DW_DLV_OK; case DW_OP_const8u: *s_out = "DW_OP_const8u"; return DW_DLV_OK; case DW_OP_const8s: *s_out = "DW_OP_const8s"; return DW_DLV_OK; case DW_OP_constu: *s_out = "DW_OP_constu"; return DW_DLV_OK; case DW_OP_consts: *s_out = "DW_OP_consts"; return DW_DLV_OK; case DW_OP_dup: *s_out = "DW_OP_dup"; return DW_DLV_OK; case DW_OP_drop: *s_out = "DW_OP_drop"; return DW_DLV_OK; case DW_OP_over: *s_out = "DW_OP_over"; return DW_DLV_OK; case DW_OP_pick: *s_out = "DW_OP_pick"; return DW_DLV_OK; case DW_OP_swap: *s_out = "DW_OP_swap"; return DW_DLV_OK; case DW_OP_rot: *s_out = "DW_OP_rot"; return DW_DLV_OK; case DW_OP_xderef: *s_out = "DW_OP_xderef"; return DW_DLV_OK; case DW_OP_abs: *s_out = "DW_OP_abs"; return DW_DLV_OK; case DW_OP_and: *s_out = "DW_OP_and"; return DW_DLV_OK; case DW_OP_div: *s_out = "DW_OP_div"; return DW_DLV_OK; case DW_OP_minus: *s_out = "DW_OP_minus"; return DW_DLV_OK; case DW_OP_mod: *s_out = "DW_OP_mod"; return DW_DLV_OK; case DW_OP_mul: *s_out = "DW_OP_mul"; return DW_DLV_OK; case DW_OP_neg: *s_out = "DW_OP_neg"; return DW_DLV_OK; case DW_OP_not: *s_out = "DW_OP_not"; return DW_DLV_OK; case DW_OP_or: *s_out = "DW_OP_or"; return DW_DLV_OK; case DW_OP_plus: *s_out = "DW_OP_plus"; return DW_DLV_OK; case DW_OP_plus_uconst: *s_out = "DW_OP_plus_uconst"; return DW_DLV_OK; case DW_OP_shl: *s_out = "DW_OP_shl"; return DW_DLV_OK; case DW_OP_shr: *s_out = "DW_OP_shr"; return DW_DLV_OK; case DW_OP_shra: *s_out = "DW_OP_shra"; return DW_DLV_OK; case DW_OP_xor: *s_out = "DW_OP_xor"; return DW_DLV_OK; case DW_OP_bra: *s_out = "DW_OP_bra"; return DW_DLV_OK; case DW_OP_eq: *s_out = "DW_OP_eq"; return DW_DLV_OK; case DW_OP_ge: *s_out = "DW_OP_ge"; return DW_DLV_OK; case DW_OP_gt: *s_out = "DW_OP_gt"; return DW_DLV_OK; case DW_OP_le: *s_out = "DW_OP_le"; return DW_DLV_OK; case DW_OP_lt: *s_out = "DW_OP_lt"; return DW_DLV_OK; case DW_OP_ne: *s_out = "DW_OP_ne"; return DW_DLV_OK; case DW_OP_skip: *s_out = "DW_OP_skip"; return DW_DLV_OK; case DW_OP_lit0: *s_out = "DW_OP_lit0"; return DW_DLV_OK; case DW_OP_lit1: *s_out = "DW_OP_lit1"; return DW_DLV_OK; case DW_OP_lit2: *s_out = "DW_OP_lit2"; return DW_DLV_OK; case DW_OP_lit3: *s_out = "DW_OP_lit3"; return DW_DLV_OK; case DW_OP_lit4: *s_out = "DW_OP_lit4"; return DW_DLV_OK; case DW_OP_lit5: *s_out = "DW_OP_lit5"; return DW_DLV_OK; case DW_OP_lit6: *s_out = "DW_OP_lit6"; return DW_DLV_OK; case DW_OP_lit7: *s_out = "DW_OP_lit7"; return DW_DLV_OK; case DW_OP_lit8: *s_out = "DW_OP_lit8"; return DW_DLV_OK; case DW_OP_lit9: *s_out = "DW_OP_lit9"; return DW_DLV_OK; case DW_OP_lit10: *s_out = "DW_OP_lit10"; return DW_DLV_OK; case DW_OP_lit11: *s_out = "DW_OP_lit11"; return DW_DLV_OK; case DW_OP_lit12: *s_out = "DW_OP_lit12"; return DW_DLV_OK; case DW_OP_lit13: *s_out = "DW_OP_lit13"; return DW_DLV_OK; case DW_OP_lit14: *s_out = "DW_OP_lit14"; return DW_DLV_OK; case DW_OP_lit15: *s_out = "DW_OP_lit15"; return DW_DLV_OK; case DW_OP_lit16: *s_out = "DW_OP_lit16"; return DW_DLV_OK; case DW_OP_lit17: *s_out = "DW_OP_lit17"; return DW_DLV_OK; case DW_OP_lit18: *s_out = "DW_OP_lit18"; return DW_DLV_OK; case DW_OP_lit19: *s_out = "DW_OP_lit19"; return DW_DLV_OK; case DW_OP_lit20: *s_out = "DW_OP_lit20"; return DW_DLV_OK; case DW_OP_lit21: *s_out = "DW_OP_lit21"; return DW_DLV_OK; case DW_OP_lit22: *s_out = "DW_OP_lit22"; return DW_DLV_OK; case DW_OP_lit23: *s_out = "DW_OP_lit23"; return DW_DLV_OK; case DW_OP_lit24: *s_out = "DW_OP_lit24"; return DW_DLV_OK; case DW_OP_lit25: *s_out = "DW_OP_lit25"; return DW_DLV_OK; case DW_OP_lit26: *s_out = "DW_OP_lit26"; return DW_DLV_OK; case DW_OP_lit27: *s_out = "DW_OP_lit27"; return DW_DLV_OK; case DW_OP_lit28: *s_out = "DW_OP_lit28"; return DW_DLV_OK; case DW_OP_lit29: *s_out = "DW_OP_lit29"; return DW_DLV_OK; case DW_OP_lit30: *s_out = "DW_OP_lit30"; return DW_DLV_OK; case DW_OP_lit31: *s_out = "DW_OP_lit31"; return DW_DLV_OK; case DW_OP_reg0: *s_out = "DW_OP_reg0"; return DW_DLV_OK; case DW_OP_reg1: *s_out = "DW_OP_reg1"; return DW_DLV_OK; case DW_OP_reg2: *s_out = "DW_OP_reg2"; return DW_DLV_OK; case DW_OP_reg3: *s_out = "DW_OP_reg3"; return DW_DLV_OK; case DW_OP_reg4: *s_out = "DW_OP_reg4"; return DW_DLV_OK; case DW_OP_reg5: *s_out = "DW_OP_reg5"; return DW_DLV_OK; case DW_OP_reg6: *s_out = "DW_OP_reg6"; return DW_DLV_OK; case DW_OP_reg7: *s_out = "DW_OP_reg7"; return DW_DLV_OK; case DW_OP_reg8: *s_out = "DW_OP_reg8"; return DW_DLV_OK; case DW_OP_reg9: *s_out = "DW_OP_reg9"; return DW_DLV_OK; case DW_OP_reg10: *s_out = "DW_OP_reg10"; return DW_DLV_OK; case DW_OP_reg11: *s_out = "DW_OP_reg11"; return DW_DLV_OK; case DW_OP_reg12: *s_out = "DW_OP_reg12"; return DW_DLV_OK; case DW_OP_reg13: *s_out = "DW_OP_reg13"; return DW_DLV_OK; case DW_OP_reg14: *s_out = "DW_OP_reg14"; return DW_DLV_OK; case DW_OP_reg15: *s_out = "DW_OP_reg15"; return DW_DLV_OK; case DW_OP_reg16: *s_out = "DW_OP_reg16"; return DW_DLV_OK; case DW_OP_reg17: *s_out = "DW_OP_reg17"; return DW_DLV_OK; case DW_OP_reg18: *s_out = "DW_OP_reg18"; return DW_DLV_OK; case DW_OP_reg19: *s_out = "DW_OP_reg19"; return DW_DLV_OK; case DW_OP_reg20: *s_out = "DW_OP_reg20"; return DW_DLV_OK; case DW_OP_reg21: *s_out = "DW_OP_reg21"; return DW_DLV_OK; case DW_OP_reg22: *s_out = "DW_OP_reg22"; return DW_DLV_OK; case DW_OP_reg23: *s_out = "DW_OP_reg23"; return DW_DLV_OK; case DW_OP_reg24: *s_out = "DW_OP_reg24"; return DW_DLV_OK; case DW_OP_reg25: *s_out = "DW_OP_reg25"; return DW_DLV_OK; case DW_OP_reg26: *s_out = "DW_OP_reg26"; return DW_DLV_OK; case DW_OP_reg27: *s_out = "DW_OP_reg27"; return DW_DLV_OK; case DW_OP_reg28: *s_out = "DW_OP_reg28"; return DW_DLV_OK; case DW_OP_reg29: *s_out = "DW_OP_reg29"; return DW_DLV_OK; case DW_OP_reg30: *s_out = "DW_OP_reg30"; return DW_DLV_OK; case DW_OP_reg31: *s_out = "DW_OP_reg31"; return DW_DLV_OK; case DW_OP_breg0: *s_out = "DW_OP_breg0"; return DW_DLV_OK; case DW_OP_breg1: *s_out = "DW_OP_breg1"; return DW_DLV_OK; case DW_OP_breg2: *s_out = "DW_OP_breg2"; return DW_DLV_OK; case DW_OP_breg3: *s_out = "DW_OP_breg3"; return DW_DLV_OK; case DW_OP_breg4: *s_out = "DW_OP_breg4"; return DW_DLV_OK; case DW_OP_breg5: *s_out = "DW_OP_breg5"; return DW_DLV_OK; case DW_OP_breg6: *s_out = "DW_OP_breg6"; return DW_DLV_OK; case DW_OP_breg7: *s_out = "DW_OP_breg7"; return DW_DLV_OK; case DW_OP_breg8: *s_out = "DW_OP_breg8"; return DW_DLV_OK; case DW_OP_breg9: *s_out = "DW_OP_breg9"; return DW_DLV_OK; case DW_OP_breg10: *s_out = "DW_OP_breg10"; return DW_DLV_OK; case DW_OP_breg11: *s_out = "DW_OP_breg11"; return DW_DLV_OK; case DW_OP_breg12: *s_out = "DW_OP_breg12"; return DW_DLV_OK; case DW_OP_breg13: *s_out = "DW_OP_breg13"; return DW_DLV_OK; case DW_OP_breg14: *s_out = "DW_OP_breg14"; return DW_DLV_OK; case DW_OP_breg15: *s_out = "DW_OP_breg15"; return DW_DLV_OK; case DW_OP_breg16: *s_out = "DW_OP_breg16"; return DW_DLV_OK; case DW_OP_breg17: *s_out = "DW_OP_breg17"; return DW_DLV_OK; case DW_OP_breg18: *s_out = "DW_OP_breg18"; return DW_DLV_OK; case DW_OP_breg19: *s_out = "DW_OP_breg19"; return DW_DLV_OK; case DW_OP_breg20: *s_out = "DW_OP_breg20"; return DW_DLV_OK; case DW_OP_breg21: *s_out = "DW_OP_breg21"; return DW_DLV_OK; case DW_OP_breg22: *s_out = "DW_OP_breg22"; return DW_DLV_OK; case DW_OP_breg23: *s_out = "DW_OP_breg23"; return DW_DLV_OK; case DW_OP_breg24: *s_out = "DW_OP_breg24"; return DW_DLV_OK; case DW_OP_breg25: *s_out = "DW_OP_breg25"; return DW_DLV_OK; case DW_OP_breg26: *s_out = "DW_OP_breg26"; return DW_DLV_OK; case DW_OP_breg27: *s_out = "DW_OP_breg27"; return DW_DLV_OK; case DW_OP_breg28: *s_out = "DW_OP_breg28"; return DW_DLV_OK; case DW_OP_breg29: *s_out = "DW_OP_breg29"; return DW_DLV_OK; case DW_OP_breg30: *s_out = "DW_OP_breg30"; return DW_DLV_OK; case DW_OP_breg31: *s_out = "DW_OP_breg31"; return DW_DLV_OK; case DW_OP_regx: *s_out = "DW_OP_regx"; return DW_DLV_OK; case DW_OP_fbreg: *s_out = "DW_OP_fbreg"; return DW_DLV_OK; case DW_OP_bregx: *s_out = "DW_OP_bregx"; return DW_DLV_OK; case DW_OP_piece: *s_out = "DW_OP_piece"; return DW_DLV_OK; case DW_OP_deref_size: *s_out = "DW_OP_deref_size"; return DW_DLV_OK; case DW_OP_xderef_size: *s_out = "DW_OP_xderef_size"; return DW_DLV_OK; case DW_OP_nop: *s_out = "DW_OP_nop"; return DW_DLV_OK; case DW_OP_push_object_address: *s_out = "DW_OP_push_object_address"; return DW_DLV_OK; case DW_OP_call2: *s_out = "DW_OP_call2"; return DW_DLV_OK; case DW_OP_call4: *s_out = "DW_OP_call4"; return DW_DLV_OK; case DW_OP_call_ref: *s_out = "DW_OP_call_ref"; return DW_DLV_OK; case DW_OP_form_tls_address: *s_out = "DW_OP_form_tls_address"; return DW_DLV_OK; case DW_OP_call_frame_cfa: *s_out = "DW_OP_call_frame_cfa"; return DW_DLV_OK; case DW_OP_bit_piece: *s_out = "DW_OP_bit_piece"; return DW_DLV_OK; case DW_OP_implicit_value: *s_out = "DW_OP_implicit_value"; return DW_DLV_OK; case DW_OP_stack_value: *s_out = "DW_OP_stack_value"; return DW_DLV_OK; case DW_OP_implicit_pointer: *s_out = "DW_OP_implicit_pointer"; return DW_DLV_OK; case DW_OP_addrx: *s_out = "DW_OP_addrx"; return DW_DLV_OK; case DW_OP_constx: *s_out = "DW_OP_constx"; return DW_DLV_OK; case DW_OP_entry_value: *s_out = "DW_OP_entry_value"; return DW_DLV_OK; case DW_OP_const_type: *s_out = "DW_OP_const_type"; return DW_DLV_OK; case DW_OP_regval_type: *s_out = "DW_OP_regval_type"; return DW_DLV_OK; case DW_OP_deref_type: *s_out = "DW_OP_deref_type"; return DW_DLV_OK; case DW_OP_xderef_type: *s_out = "DW_OP_xderef_type"; return DW_DLV_OK; case DW_OP_convert: *s_out = "DW_OP_convert"; return DW_DLV_OK; case DW_OP_reinterpret: *s_out = "DW_OP_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_push_tls_address: *s_out = "DW_OP_GNU_push_tls_address"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xe0. DW_OP_lo_user */ /* Skipping alternate spelling of value 0xe0. DW_OP_HP_unknown */ case DW_OP_HP_is_value: *s_out = "DW_OP_HP_is_value"; return DW_DLV_OK; case DW_OP_HP_fltconst4: *s_out = "DW_OP_HP_fltconst4"; return DW_DLV_OK; case DW_OP_HP_fltconst8: *s_out = "DW_OP_HP_fltconst8"; return DW_DLV_OK; case DW_OP_HP_mod_range: *s_out = "DW_OP_HP_mod_range"; return DW_DLV_OK; case DW_OP_HP_unmod_range: *s_out = "DW_OP_HP_unmod_range"; return DW_DLV_OK; case DW_OP_HP_tls: *s_out = "DW_OP_HP_tls"; return DW_DLV_OK; case DW_OP_INTEL_bit_piece: *s_out = "DW_OP_INTEL_bit_piece"; return DW_DLV_OK; case DW_OP_WASM_location: *s_out = "DW_OP_WASM_location"; return DW_DLV_OK; case DW_OP_WASM_location_int: *s_out = "DW_OP_WASM_location_int"; return DW_DLV_OK; case DW_OP_GNU_uninit: *s_out = "DW_OP_GNU_uninit"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xf0. DW_OP_APPLE_uninit */ case DW_OP_GNU_encoded_addr: *s_out = "DW_OP_GNU_encoded_addr"; return DW_DLV_OK; case DW_OP_GNU_implicit_pointer: *s_out = "DW_OP_GNU_implicit_pointer"; return DW_DLV_OK; case DW_OP_GNU_entry_value: *s_out = "DW_OP_GNU_entry_value"; return DW_DLV_OK; case DW_OP_GNU_const_type: *s_out = "DW_OP_GNU_const_type"; return DW_DLV_OK; case DW_OP_GNU_regval_type: *s_out = "DW_OP_GNU_regval_type"; return DW_DLV_OK; case DW_OP_GNU_deref_type: *s_out = "DW_OP_GNU_deref_type"; return DW_DLV_OK; case DW_OP_GNU_convert: *s_out = "DW_OP_GNU_convert"; return DW_DLV_OK; case DW_OP_PGI_omp_thread_num: *s_out = "DW_OP_PGI_omp_thread_num"; return DW_DLV_OK; case DW_OP_GNU_reinterpret: *s_out = "DW_OP_GNU_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_parameter_ref: *s_out = "DW_OP_GNU_parameter_ref"; return DW_DLV_OK; case DW_OP_GNU_addr_index: *s_out = "DW_OP_GNU_addr_index"; return DW_DLV_OK; case DW_OP_GNU_const_index: *s_out = "DW_OP_GNU_const_index"; return DW_DLV_OK; case DW_OP_GNU_variable_value: *s_out = "DW_OP_GNU_variable_value"; return DW_DLV_OK; case DW_OP_hi_user: *s_out = "DW_OP_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ATE_address: *s_out = "DW_ATE_address"; return DW_DLV_OK; case DW_ATE_boolean: *s_out = "DW_ATE_boolean"; return DW_DLV_OK; case DW_ATE_complex_float: *s_out = "DW_ATE_complex_float"; return DW_DLV_OK; case DW_ATE_float: *s_out = "DW_ATE_float"; return DW_DLV_OK; case DW_ATE_signed: *s_out = "DW_ATE_signed"; return DW_DLV_OK; case DW_ATE_signed_char: *s_out = "DW_ATE_signed_char"; return DW_DLV_OK; case DW_ATE_unsigned: *s_out = "DW_ATE_unsigned"; return DW_DLV_OK; case DW_ATE_unsigned_char: *s_out = "DW_ATE_unsigned_char"; return DW_DLV_OK; case DW_ATE_imaginary_float: *s_out = "DW_ATE_imaginary_float"; return DW_DLV_OK; case DW_ATE_packed_decimal: *s_out = "DW_ATE_packed_decimal"; return DW_DLV_OK; case DW_ATE_numeric_string: *s_out = "DW_ATE_numeric_string"; return DW_DLV_OK; case DW_ATE_edited: *s_out = "DW_ATE_edited"; return DW_DLV_OK; case DW_ATE_signed_fixed: *s_out = "DW_ATE_signed_fixed"; return DW_DLV_OK; case DW_ATE_unsigned_fixed: *s_out = "DW_ATE_unsigned_fixed"; return DW_DLV_OK; case DW_ATE_decimal_float: *s_out = "DW_ATE_decimal_float"; return DW_DLV_OK; case DW_ATE_UTF: *s_out = "DW_ATE_UTF"; return DW_DLV_OK; case DW_ATE_UCS: *s_out = "DW_ATE_UCS"; return DW_DLV_OK; case DW_ATE_ASCII: *s_out = "DW_ATE_ASCII"; return DW_DLV_OK; case DW_ATE_ALTIUM_fract: *s_out = "DW_ATE_ALTIUM_fract"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_ATE_lo_user */ /* Skipping alternate spelling of value 0x80. DW_ATE_HP_float80 */ case DW_ATE_ALTIUM_accum: *s_out = "DW_ATE_ALTIUM_accum"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x81. DW_ATE_HP_complex_float80 */ case DW_ATE_HP_float128: *s_out = "DW_ATE_HP_float128"; return DW_DLV_OK; case DW_ATE_HP_complex_float128: *s_out = "DW_ATE_HP_complex_float128"; return DW_DLV_OK; case DW_ATE_HP_floathpintel: *s_out = "DW_ATE_HP_floathpintel"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float80: *s_out = "DW_ATE_HP_imaginary_float80"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float128: *s_out = "DW_ATE_HP_imaginary_float128"; return DW_DLV_OK; case DW_ATE_SUN_interval_float: *s_out = "DW_ATE_SUN_interval_float"; return DW_DLV_OK; case DW_ATE_SUN_imaginary_float: *s_out = "DW_ATE_SUN_imaginary_float"; return DW_DLV_OK; case DW_ATE_hi_user: *s_out = "DW_ATE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DEFAULTED_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DEFAULTED_no: *s_out = "DW_DEFAULTED_no"; return DW_DLV_OK; case DW_DEFAULTED_in_class: *s_out = "DW_DEFAULTED_in_class"; return DW_DLV_OK; case DW_DEFAULTED_out_of_class: *s_out = "DW_DEFAULTED_out_of_class"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_IDX_name (unsigned int val, const char ** s_out) { switch (val) { case DW_IDX_compile_unit: *s_out = "DW_IDX_compile_unit"; return DW_DLV_OK; case DW_IDX_type_unit: *s_out = "DW_IDX_type_unit"; return DW_DLV_OK; case DW_IDX_die_offset: *s_out = "DW_IDX_die_offset"; return DW_DLV_OK; case DW_IDX_parent: *s_out = "DW_IDX_parent"; return DW_DLV_OK; case DW_IDX_type_hash: *s_out = "DW_IDX_type_hash"; return DW_DLV_OK; case DW_IDX_hi_user: *s_out = "DW_IDX_hi_user"; return DW_DLV_OK; case DW_IDX_lo_user: *s_out = "DW_IDX_lo_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLEX_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LLEX_end_of_list_entry: *s_out = "DW_LLEX_end_of_list_entry"; return DW_DLV_OK; case DW_LLEX_base_address_selection_entry: *s_out = "DW_LLEX_base_address_selection_entry"; return DW_DLV_OK; case DW_LLEX_start_end_entry: *s_out = "DW_LLEX_start_end_entry"; return DW_DLV_OK; case DW_LLEX_start_length_entry: *s_out = "DW_LLEX_start_length_entry"; return DW_DLV_OK; case DW_LLEX_offset_pair_entry: *s_out = "DW_LLEX_offset_pair_entry"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LLE_end_of_list: *s_out = "DW_LLE_end_of_list"; return DW_DLV_OK; case DW_LLE_base_addressx: *s_out = "DW_LLE_base_addressx"; return DW_DLV_OK; case DW_LLE_startx_endx: *s_out = "DW_LLE_startx_endx"; return DW_DLV_OK; case DW_LLE_startx_length: *s_out = "DW_LLE_startx_length"; return DW_DLV_OK; case DW_LLE_offset_pair: *s_out = "DW_LLE_offset_pair"; return DW_DLV_OK; case DW_LLE_default_location: *s_out = "DW_LLE_default_location"; return DW_DLV_OK; case DW_LLE_base_address: *s_out = "DW_LLE_base_address"; return DW_DLV_OK; case DW_LLE_start_end: *s_out = "DW_LLE_start_end"; return DW_DLV_OK; case DW_LLE_start_length: *s_out = "DW_LLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_RLE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_RLE_end_of_list: *s_out = "DW_RLE_end_of_list"; return DW_DLV_OK; case DW_RLE_base_addressx: *s_out = "DW_RLE_base_addressx"; return DW_DLV_OK; case DW_RLE_startx_endx: *s_out = "DW_RLE_startx_endx"; return DW_DLV_OK; case DW_RLE_startx_length: *s_out = "DW_RLE_startx_length"; return DW_DLV_OK; case DW_RLE_offset_pair: *s_out = "DW_RLE_offset_pair"; return DW_DLV_OK; case DW_RLE_base_address: *s_out = "DW_RLE_base_address"; return DW_DLV_OK; case DW_RLE_start_end: *s_out = "DW_RLE_start_end"; return DW_DLV_OK; case DW_RLE_start_length: *s_out = "DW_RLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_GNUIVIS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_GNUIVIS_global: *s_out = "DW_GNUIVIS_global"; return DW_DLV_OK; case DW_GNUIVIS_static: *s_out = "DW_GNUIVIS_static"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_GNUIKIND_name (unsigned int val, const char ** s_out) { switch (val) { case DW_GNUIKIND_none: *s_out = "DW_GNUIKIND_none"; return DW_DLV_OK; case DW_GNUIKIND_type: *s_out = "DW_GNUIKIND_type"; return DW_DLV_OK; case DW_GNUIKIND_variable: *s_out = "DW_GNUIKIND_variable"; return DW_DLV_OK; case DW_GNUIKIND_function: *s_out = "DW_GNUIKIND_function"; return DW_DLV_OK; case DW_GNUIKIND_other: *s_out = "DW_GNUIKIND_other"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_UT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_UT_compile: *s_out = "DW_UT_compile"; return DW_DLV_OK; case DW_UT_type: *s_out = "DW_UT_type"; return DW_DLV_OK; case DW_UT_partial: *s_out = "DW_UT_partial"; return DW_DLV_OK; case DW_UT_skeleton: *s_out = "DW_UT_skeleton"; return DW_DLV_OK; case DW_UT_split_compile: *s_out = "DW_UT_split_compile"; return DW_DLV_OK; case DW_UT_split_type: *s_out = "DW_UT_split_type"; return DW_DLV_OK; case DW_UT_lo_user: *s_out = "DW_UT_lo_user"; return DW_DLV_OK; case DW_UT_hi_user: *s_out = "DW_UT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_SECT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_SECT_INFO: *s_out = "DW_SECT_INFO"; return DW_DLV_OK; case DW_SECT_TYPES: *s_out = "DW_SECT_TYPES"; return DW_DLV_OK; case DW_SECT_ABBREV: *s_out = "DW_SECT_ABBREV"; return DW_DLV_OK; case DW_SECT_LINE: *s_out = "DW_SECT_LINE"; return DW_DLV_OK; case DW_SECT_LOCLISTS: *s_out = "DW_SECT_LOCLISTS"; return DW_DLV_OK; case DW_SECT_STR_OFFSETS: *s_out = "DW_SECT_STR_OFFSETS"; return DW_DLV_OK; case DW_SECT_MACRO: *s_out = "DW_SECT_MACRO"; return DW_DLV_OK; case DW_SECT_RNGLISTS: *s_out = "DW_SECT_RNGLISTS"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DS_unsigned: *s_out = "DW_DS_unsigned"; return DW_DLV_OK; case DW_DS_leading_overpunch: *s_out = "DW_DS_leading_overpunch"; return DW_DLV_OK; case DW_DS_trailing_overpunch: *s_out = "DW_DS_trailing_overpunch"; return DW_DLV_OK; case DW_DS_leading_separate: *s_out = "DW_DS_leading_separate"; return DW_DLV_OK; case DW_DS_trailing_separate: *s_out = "DW_DS_trailing_separate"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_END_name (unsigned int val, const char ** s_out) { switch (val) { case DW_END_default: *s_out = "DW_END_default"; return DW_DLV_OK; case DW_END_big: *s_out = "DW_END_big"; return DW_DLV_OK; case DW_END_little: *s_out = "DW_END_little"; return DW_DLV_OK; case DW_END_lo_user: *s_out = "DW_END_lo_user"; return DW_DLV_OK; case DW_END_hi_user: *s_out = "DW_END_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATCF_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ATCF_lo_user: *s_out = "DW_ATCF_lo_user"; return DW_DLV_OK; case DW_ATCF_SUN_mop_bitfield: *s_out = "DW_ATCF_SUN_mop_bitfield"; return DW_DLV_OK; case DW_ATCF_SUN_mop_spill: *s_out = "DW_ATCF_SUN_mop_spill"; return DW_DLV_OK; case DW_ATCF_SUN_mop_scopy: *s_out = "DW_ATCF_SUN_mop_scopy"; return DW_DLV_OK; case DW_ATCF_SUN_func_start: *s_out = "DW_ATCF_SUN_func_start"; return DW_DLV_OK; case DW_ATCF_SUN_end_ctors: *s_out = "DW_ATCF_SUN_end_ctors"; return DW_DLV_OK; case DW_ATCF_SUN_branch_target: *s_out = "DW_ATCF_SUN_branch_target"; return DW_DLV_OK; case DW_ATCF_SUN_mop_stack_probe: *s_out = "DW_ATCF_SUN_mop_stack_probe"; return DW_DLV_OK; case DW_ATCF_SUN_func_epilog: *s_out = "DW_ATCF_SUN_func_epilog"; return DW_DLV_OK; case DW_ATCF_hi_user: *s_out = "DW_ATCF_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ACCESS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ACCESS_public: *s_out = "DW_ACCESS_public"; return DW_DLV_OK; case DW_ACCESS_protected: *s_out = "DW_ACCESS_protected"; return DW_DLV_OK; case DW_ACCESS_private: *s_out = "DW_ACCESS_private"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_VIS_local: *s_out = "DW_VIS_local"; return DW_DLV_OK; case DW_VIS_exported: *s_out = "DW_VIS_exported"; return DW_DLV_OK; case DW_VIS_qualified: *s_out = "DW_VIS_qualified"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIRTUALITY_name (unsigned int val, const char ** s_out) { switch (val) { case DW_VIRTUALITY_none: *s_out = "DW_VIRTUALITY_none"; return DW_DLV_OK; case DW_VIRTUALITY_virtual: *s_out = "DW_VIRTUALITY_virtual"; return DW_DLV_OK; case DW_VIRTUALITY_pure_virtual: *s_out = "DW_VIRTUALITY_pure_virtual"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LANG_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LANG_C89: *s_out = "DW_LANG_C89"; return DW_DLV_OK; case DW_LANG_C: *s_out = "DW_LANG_C"; return DW_DLV_OK; case DW_LANG_Ada83: *s_out = "DW_LANG_Ada83"; return DW_DLV_OK; case DW_LANG_C_plus_plus: *s_out = "DW_LANG_C_plus_plus"; return DW_DLV_OK; case DW_LANG_Cobol74: *s_out = "DW_LANG_Cobol74"; return DW_DLV_OK; case DW_LANG_Cobol85: *s_out = "DW_LANG_Cobol85"; return DW_DLV_OK; case DW_LANG_Fortran77: *s_out = "DW_LANG_Fortran77"; return DW_DLV_OK; case DW_LANG_Fortran90: *s_out = "DW_LANG_Fortran90"; return DW_DLV_OK; case DW_LANG_Pascal83: *s_out = "DW_LANG_Pascal83"; return DW_DLV_OK; case DW_LANG_Modula2: *s_out = "DW_LANG_Modula2"; return DW_DLV_OK; case DW_LANG_Java: *s_out = "DW_LANG_Java"; return DW_DLV_OK; case DW_LANG_C99: *s_out = "DW_LANG_C99"; return DW_DLV_OK; case DW_LANG_Ada95: *s_out = "DW_LANG_Ada95"; return DW_DLV_OK; case DW_LANG_Fortran95: *s_out = "DW_LANG_Fortran95"; return DW_DLV_OK; case DW_LANG_PLI: *s_out = "DW_LANG_PLI"; return DW_DLV_OK; case DW_LANG_ObjC: *s_out = "DW_LANG_ObjC"; return DW_DLV_OK; case DW_LANG_ObjC_plus_plus: *s_out = "DW_LANG_ObjC_plus_plus"; return DW_DLV_OK; case DW_LANG_UPC: *s_out = "DW_LANG_UPC"; return DW_DLV_OK; case DW_LANG_D: *s_out = "DW_LANG_D"; return DW_DLV_OK; case DW_LANG_Python: *s_out = "DW_LANG_Python"; return DW_DLV_OK; case DW_LANG_OpenCL: *s_out = "DW_LANG_OpenCL"; return DW_DLV_OK; case DW_LANG_Go: *s_out = "DW_LANG_Go"; return DW_DLV_OK; case DW_LANG_Modula3: *s_out = "DW_LANG_Modula3"; return DW_DLV_OK; case DW_LANG_Haskel: *s_out = "DW_LANG_Haskel"; return DW_DLV_OK; case DW_LANG_C_plus_plus_03: *s_out = "DW_LANG_C_plus_plus_03"; return DW_DLV_OK; case DW_LANG_C_plus_plus_11: *s_out = "DW_LANG_C_plus_plus_11"; return DW_DLV_OK; case DW_LANG_OCaml: *s_out = "DW_LANG_OCaml"; return DW_DLV_OK; case DW_LANG_Rust: *s_out = "DW_LANG_Rust"; return DW_DLV_OK; case DW_LANG_C11: *s_out = "DW_LANG_C11"; return DW_DLV_OK; case DW_LANG_Swift: *s_out = "DW_LANG_Swift"; return DW_DLV_OK; case DW_LANG_Julia: *s_out = "DW_LANG_Julia"; return DW_DLV_OK; case DW_LANG_Dylan: *s_out = "DW_LANG_Dylan"; return DW_DLV_OK; case DW_LANG_C_plus_plus_14: *s_out = "DW_LANG_C_plus_plus_14"; return DW_DLV_OK; case DW_LANG_Fortran03: *s_out = "DW_LANG_Fortran03"; return DW_DLV_OK; case DW_LANG_Fortran08: *s_out = "DW_LANG_Fortran08"; return DW_DLV_OK; case DW_LANG_RenderScript: *s_out = "DW_LANG_RenderScript"; return DW_DLV_OK; case DW_LANG_BLISS: *s_out = "DW_LANG_BLISS"; return DW_DLV_OK; case DW_LANG_lo_user: *s_out = "DW_LANG_lo_user"; return DW_DLV_OK; case DW_LANG_Mips_Assembler: *s_out = "DW_LANG_Mips_Assembler"; return DW_DLV_OK; case DW_LANG_Upc: *s_out = "DW_LANG_Upc"; return DW_DLV_OK; case DW_LANG_SUN_Assembler: *s_out = "DW_LANG_SUN_Assembler"; return DW_DLV_OK; case DW_LANG_ALTIUM_Assembler: *s_out = "DW_LANG_ALTIUM_Assembler"; return DW_DLV_OK; case DW_LANG_hi_user: *s_out = "DW_LANG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ID_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ID_case_sensitive: *s_out = "DW_ID_case_sensitive"; return DW_DLV_OK; case DW_ID_up_case: *s_out = "DW_ID_up_case"; return DW_DLV_OK; case DW_ID_down_case: *s_out = "DW_ID_down_case"; return DW_DLV_OK; case DW_ID_case_insensitive: *s_out = "DW_ID_case_insensitive"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CC_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CC_normal: *s_out = "DW_CC_normal"; return DW_DLV_OK; case DW_CC_program: *s_out = "DW_CC_program"; return DW_DLV_OK; case DW_CC_nocall: *s_out = "DW_CC_nocall"; return DW_DLV_OK; case DW_CC_pass_by_reference: *s_out = "DW_CC_pass_by_reference"; return DW_DLV_OK; case DW_CC_pass_by_value: *s_out = "DW_CC_pass_by_value"; return DW_DLV_OK; case DW_CC_lo_user: *s_out = "DW_CC_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x40. DW_CC_GNU_renesas_sh */ case DW_CC_GNU_borland_fastcall_i386: *s_out = "DW_CC_GNU_borland_fastcall_i386"; return DW_DLV_OK; case DW_CC_ALTIUM_interrupt: *s_out = "DW_CC_ALTIUM_interrupt"; return DW_DLV_OK; case DW_CC_ALTIUM_near_system_stack: *s_out = "DW_CC_ALTIUM_near_system_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_near_user_stack: *s_out = "DW_CC_ALTIUM_near_user_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_huge_user_stack: *s_out = "DW_CC_ALTIUM_huge_user_stack"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_safecall: *s_out = "DW_CC_GNU_BORLAND_safecall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_stdcall: *s_out = "DW_CC_GNU_BORLAND_stdcall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_pascal: *s_out = "DW_CC_GNU_BORLAND_pascal"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_msfastcall: *s_out = "DW_CC_GNU_BORLAND_msfastcall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_msreturn: *s_out = "DW_CC_GNU_BORLAND_msreturn"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_thiscall: *s_out = "DW_CC_GNU_BORLAND_thiscall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_fastcall: *s_out = "DW_CC_GNU_BORLAND_fastcall"; return DW_DLV_OK; case DW_CC_LLVM_vectorcall: *s_out = "DW_CC_LLVM_vectorcall"; return DW_DLV_OK; case DW_CC_LLVM_Win64: *s_out = "DW_CC_LLVM_Win64"; return DW_DLV_OK; case DW_CC_LLVM_X86_64SysV: *s_out = "DW_CC_LLVM_X86_64SysV"; return DW_DLV_OK; case DW_CC_LLVM_AAPCS: *s_out = "DW_CC_LLVM_AAPCS"; return DW_DLV_OK; case DW_CC_LLVM_AAPCS_VFP: *s_out = "DW_CC_LLVM_AAPCS_VFP"; return DW_DLV_OK; case DW_CC_LLVM_IntelOclBicc: *s_out = "DW_CC_LLVM_IntelOclBicc"; return DW_DLV_OK; case DW_CC_LLVM_SpirFunction: *s_out = "DW_CC_LLVM_SpirFunction"; return DW_DLV_OK; case DW_CC_LLVM_OpenCLKernel: *s_out = "DW_CC_LLVM_OpenCLKernel"; return DW_DLV_OK; case DW_CC_LLVM_Swift: *s_out = "DW_CC_LLVM_Swift"; return DW_DLV_OK; case DW_CC_LLVM_PreserveMost: *s_out = "DW_CC_LLVM_PreserveMost"; return DW_DLV_OK; case DW_CC_LLVM_PreserveAll: *s_out = "DW_CC_LLVM_PreserveAll"; return DW_DLV_OK; case DW_CC_LLVM_X86RegCall: *s_out = "DW_CC_LLVM_X86RegCall"; return DW_DLV_OK; case DW_CC_GDB_IBM_OpenCL: *s_out = "DW_CC_GDB_IBM_OpenCL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xff. DW_CC_hi_user */ } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_INL_name (unsigned int val, const char ** s_out) { switch (val) { case DW_INL_not_inlined: *s_out = "DW_INL_not_inlined"; return DW_DLV_OK; case DW_INL_inlined: *s_out = "DW_INL_inlined"; return DW_DLV_OK; case DW_INL_declared_not_inlined: *s_out = "DW_INL_declared_not_inlined"; return DW_DLV_OK; case DW_INL_declared_inlined: *s_out = "DW_INL_declared_inlined"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ORD_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ORD_row_major: *s_out = "DW_ORD_row_major"; return DW_DLV_OK; case DW_ORD_col_major: *s_out = "DW_ORD_col_major"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DSC_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DSC_label: *s_out = "DW_DSC_label"; return DW_DLV_OK; case DW_DSC_range: *s_out = "DW_DSC_range"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNCT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNCT_path: *s_out = "DW_LNCT_path"; return DW_DLV_OK; case DW_LNCT_directory_index: *s_out = "DW_LNCT_directory_index"; return DW_DLV_OK; case DW_LNCT_timestamp: *s_out = "DW_LNCT_timestamp"; return DW_DLV_OK; case DW_LNCT_size: *s_out = "DW_LNCT_size"; return DW_DLV_OK; case DW_LNCT_MD5: *s_out = "DW_LNCT_MD5"; return DW_DLV_OK; case DW_LNCT_GNU_subprogram_name: *s_out = "DW_LNCT_GNU_subprogram_name"; return DW_DLV_OK; case DW_LNCT_GNU_decl_file: *s_out = "DW_LNCT_GNU_decl_file"; return DW_DLV_OK; case DW_LNCT_GNU_decl_line: *s_out = "DW_LNCT_GNU_decl_line"; return DW_DLV_OK; case DW_LNCT_lo_user: *s_out = "DW_LNCT_lo_user"; return DW_DLV_OK; case DW_LNCT_LLVM_source: *s_out = "DW_LNCT_LLVM_source"; return DW_DLV_OK; case DW_LNCT_hi_user: *s_out = "DW_LNCT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNS_copy: *s_out = "DW_LNS_copy"; return DW_DLV_OK; case DW_LNS_advance_pc: *s_out = "DW_LNS_advance_pc"; return DW_DLV_OK; case DW_LNS_advance_line: *s_out = "DW_LNS_advance_line"; return DW_DLV_OK; case DW_LNS_set_file: *s_out = "DW_LNS_set_file"; return DW_DLV_OK; case DW_LNS_set_column: *s_out = "DW_LNS_set_column"; return DW_DLV_OK; case DW_LNS_negate_stmt: *s_out = "DW_LNS_negate_stmt"; return DW_DLV_OK; case DW_LNS_set_basic_block: *s_out = "DW_LNS_set_basic_block"; return DW_DLV_OK; case DW_LNS_const_add_pc: *s_out = "DW_LNS_const_add_pc"; return DW_DLV_OK; case DW_LNS_fixed_advance_pc: *s_out = "DW_LNS_fixed_advance_pc"; return DW_DLV_OK; case DW_LNS_set_prologue_end: *s_out = "DW_LNS_set_prologue_end"; return DW_DLV_OK; case DW_LNS_set_epilogue_begin: *s_out = "DW_LNS_set_epilogue_begin"; return DW_DLV_OK; case DW_LNS_set_isa: *s_out = "DW_LNS_set_isa"; return DW_DLV_OK; case DW_LNS_set_address_from_logical: *s_out = "DW_LNS_set_address_from_logical"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xd. DW_LNS_set_subprogram */ case DW_LNS_inlined_call: *s_out = "DW_LNS_inlined_call"; return DW_DLV_OK; case DW_LNS_pop_context: *s_out = "DW_LNS_pop_context"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNE_end_sequence: *s_out = "DW_LNE_end_sequence"; return DW_DLV_OK; case DW_LNE_set_address: *s_out = "DW_LNE_set_address"; return DW_DLV_OK; case DW_LNE_define_file: *s_out = "DW_LNE_define_file"; return DW_DLV_OK; case DW_LNE_set_discriminator: *s_out = "DW_LNE_set_discriminator"; return DW_DLV_OK; case DW_LNE_HP_negate_is_UV_update: *s_out = "DW_LNE_HP_negate_is_UV_update"; return DW_DLV_OK; case DW_LNE_HP_push_context: *s_out = "DW_LNE_HP_push_context"; return DW_DLV_OK; case DW_LNE_HP_pop_context: *s_out = "DW_LNE_HP_pop_context"; return DW_DLV_OK; case DW_LNE_HP_set_file_line_column: *s_out = "DW_LNE_HP_set_file_line_column"; return DW_DLV_OK; case DW_LNE_HP_set_routine_name: *s_out = "DW_LNE_HP_set_routine_name"; return DW_DLV_OK; case DW_LNE_HP_set_sequence: *s_out = "DW_LNE_HP_set_sequence"; return DW_DLV_OK; case DW_LNE_HP_negate_post_semantics: *s_out = "DW_LNE_HP_negate_post_semantics"; return DW_DLV_OK; case DW_LNE_HP_negate_function_exit: *s_out = "DW_LNE_HP_negate_function_exit"; return DW_DLV_OK; case DW_LNE_HP_negate_front_end_logical: *s_out = "DW_LNE_HP_negate_front_end_logical"; return DW_DLV_OK; case DW_LNE_HP_define_proc: *s_out = "DW_LNE_HP_define_proc"; return DW_DLV_OK; case DW_LNE_HP_source_file_correlation: *s_out = "DW_LNE_HP_source_file_correlation"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_LNE_lo_user */ case DW_LNE_hi_user: *s_out = "DW_LNE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ISA_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ISA_UNKNOWN: *s_out = "DW_ISA_UNKNOWN"; return DW_DLV_OK; case DW_ISA_ARM_thumb: *s_out = "DW_ISA_ARM_thumb"; return DW_DLV_OK; case DW_ISA_ARM_arm: *s_out = "DW_ISA_ARM_arm"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACRO_name (unsigned int val, const char ** s_out) { switch (val) { case DW_MACRO_define: *s_out = "DW_MACRO_define"; return DW_DLV_OK; case DW_MACRO_undef: *s_out = "DW_MACRO_undef"; return DW_DLV_OK; case DW_MACRO_start_file: *s_out = "DW_MACRO_start_file"; return DW_DLV_OK; case DW_MACRO_end_file: *s_out = "DW_MACRO_end_file"; return DW_DLV_OK; case DW_MACRO_define_strp: *s_out = "DW_MACRO_define_strp"; return DW_DLV_OK; case DW_MACRO_undef_strp: *s_out = "DW_MACRO_undef_strp"; return DW_DLV_OK; case DW_MACRO_import: *s_out = "DW_MACRO_import"; return DW_DLV_OK; case DW_MACRO_define_sup: *s_out = "DW_MACRO_define_sup"; return DW_DLV_OK; case DW_MACRO_undef_sup: *s_out = "DW_MACRO_undef_sup"; return DW_DLV_OK; case DW_MACRO_import_sup: *s_out = "DW_MACRO_import_sup"; return DW_DLV_OK; case DW_MACRO_define_strx: *s_out = "DW_MACRO_define_strx"; return DW_DLV_OK; case DW_MACRO_undef_strx: *s_out = "DW_MACRO_undef_strx"; return DW_DLV_OK; case DW_MACRO_lo_user: *s_out = "DW_MACRO_lo_user"; return DW_DLV_OK; case DW_MACRO_hi_user: *s_out = "DW_MACRO_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACINFO_name (unsigned int val, const char ** s_out) { switch (val) { case DW_MACINFO_define: *s_out = "DW_MACINFO_define"; return DW_DLV_OK; case DW_MACINFO_undef: *s_out = "DW_MACINFO_undef"; return DW_DLV_OK; case DW_MACINFO_start_file: *s_out = "DW_MACINFO_start_file"; return DW_DLV_OK; case DW_MACINFO_end_file: *s_out = "DW_MACINFO_end_file"; return DW_DLV_OK; case DW_MACINFO_vendor_ext: *s_out = "DW_MACINFO_vendor_ext"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CFA_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CFA_extended: *s_out = "DW_CFA_extended"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_CFA_nop */ case DW_CFA_set_loc: *s_out = "DW_CFA_set_loc"; return DW_DLV_OK; case DW_CFA_advance_loc1: *s_out = "DW_CFA_advance_loc1"; return DW_DLV_OK; case DW_CFA_advance_loc2: *s_out = "DW_CFA_advance_loc2"; return DW_DLV_OK; case DW_CFA_advance_loc4: *s_out = "DW_CFA_advance_loc4"; return DW_DLV_OK; case DW_CFA_offset_extended: *s_out = "DW_CFA_offset_extended"; return DW_DLV_OK; case DW_CFA_restore_extended: *s_out = "DW_CFA_restore_extended"; return DW_DLV_OK; case DW_CFA_undefined: *s_out = "DW_CFA_undefined"; return DW_DLV_OK; case DW_CFA_same_value: *s_out = "DW_CFA_same_value"; return DW_DLV_OK; case DW_CFA_register: *s_out = "DW_CFA_register"; return DW_DLV_OK; case DW_CFA_remember_state: *s_out = "DW_CFA_remember_state"; return DW_DLV_OK; case DW_CFA_restore_state: *s_out = "DW_CFA_restore_state"; return DW_DLV_OK; case DW_CFA_def_cfa: *s_out = "DW_CFA_def_cfa"; return DW_DLV_OK; case DW_CFA_def_cfa_register: *s_out = "DW_CFA_def_cfa_register"; return DW_DLV_OK; case DW_CFA_def_cfa_offset: *s_out = "DW_CFA_def_cfa_offset"; return DW_DLV_OK; case DW_CFA_def_cfa_expression: *s_out = "DW_CFA_def_cfa_expression"; return DW_DLV_OK; case DW_CFA_expression: *s_out = "DW_CFA_expression"; return DW_DLV_OK; case DW_CFA_offset_extended_sf: *s_out = "DW_CFA_offset_extended_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_sf: *s_out = "DW_CFA_def_cfa_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_offset_sf: *s_out = "DW_CFA_def_cfa_offset_sf"; return DW_DLV_OK; case DW_CFA_val_offset: *s_out = "DW_CFA_val_offset"; return DW_DLV_OK; case DW_CFA_val_offset_sf: *s_out = "DW_CFA_val_offset_sf"; return DW_DLV_OK; case DW_CFA_val_expression: *s_out = "DW_CFA_val_expression"; return DW_DLV_OK; case DW_CFA_lo_user: *s_out = "DW_CFA_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ case DW_CFA_MIPS_advance_loc8: *s_out = "DW_CFA_MIPS_advance_loc8"; return DW_DLV_OK; case DW_CFA_GNU_window_save: *s_out = "DW_CFA_GNU_window_save"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2d. DW_CFA_AARCH64_negate_ra_state */ case DW_CFA_GNU_args_size: *s_out = "DW_CFA_GNU_args_size"; return DW_DLV_OK; case DW_CFA_GNU_negative_offset_extended: *s_out = "DW_CFA_GNU_negative_offset_extended"; return DW_DLV_OK; case DW_CFA_METAWARE_info: *s_out = "DW_CFA_METAWARE_info"; return DW_DLV_OK; case DW_CFA_high_user: *s_out = "DW_CFA_high_user"; return DW_DLV_OK; case DW_CFA_advance_loc: *s_out = "DW_CFA_advance_loc"; return DW_DLV_OK; case DW_CFA_offset: *s_out = "DW_CFA_offset"; return DW_DLV_OK; case DW_CFA_restore: *s_out = "DW_CFA_restore"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_EH_name (unsigned int val, const char ** s_out) { switch (val) { case DW_EH_PE_absptr: *s_out = "DW_EH_PE_absptr"; return DW_DLV_OK; case DW_EH_PE_uleb128: *s_out = "DW_EH_PE_uleb128"; return DW_DLV_OK; case DW_EH_PE_udata2: *s_out = "DW_EH_PE_udata2"; return DW_DLV_OK; case DW_EH_PE_udata4: *s_out = "DW_EH_PE_udata4"; return DW_DLV_OK; case DW_EH_PE_udata8: *s_out = "DW_EH_PE_udata8"; return DW_DLV_OK; case DW_EH_PE_sleb128: *s_out = "DW_EH_PE_sleb128"; return DW_DLV_OK; case DW_EH_PE_sdata2: *s_out = "DW_EH_PE_sdata2"; return DW_DLV_OK; case DW_EH_PE_sdata4: *s_out = "DW_EH_PE_sdata4"; return DW_DLV_OK; case DW_EH_PE_sdata8: *s_out = "DW_EH_PE_sdata8"; return DW_DLV_OK; case DW_EH_PE_pcrel: *s_out = "DW_EH_PE_pcrel"; return DW_DLV_OK; case DW_EH_PE_textrel: *s_out = "DW_EH_PE_textrel"; return DW_DLV_OK; case DW_EH_PE_datarel: *s_out = "DW_EH_PE_datarel"; return DW_DLV_OK; case DW_EH_PE_funcrel: *s_out = "DW_EH_PE_funcrel"; return DW_DLV_OK; case DW_EH_PE_aligned: *s_out = "DW_EH_PE_aligned"; return DW_DLV_OK; case DW_EH_PE_omit: *s_out = "DW_EH_PE_omit"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FRAME_name (unsigned int val, const char ** s_out) { switch (val) { case DW_FRAME_CFA_COL: *s_out = "DW_FRAME_CFA_COL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_FRAME_LAST_REG_NUM */ /* Skipping alternate spelling of value 0x0. DW_FRAME_RA_COL */ /* Skipping alternate spelling of value 0x0. DW_FRAME_STATIC_LINK */ case DW_FRAME_REG1: *s_out = "DW_FRAME_REG1"; return DW_DLV_OK; case DW_FRAME_REG2: *s_out = "DW_FRAME_REG2"; return DW_DLV_OK; case DW_FRAME_REG3: *s_out = "DW_FRAME_REG3"; return DW_DLV_OK; case DW_FRAME_REG4: *s_out = "DW_FRAME_REG4"; return DW_DLV_OK; case DW_FRAME_REG5: *s_out = "DW_FRAME_REG5"; return DW_DLV_OK; case DW_FRAME_REG6: *s_out = "DW_FRAME_REG6"; return DW_DLV_OK; case DW_FRAME_REG7: *s_out = "DW_FRAME_REG7"; return DW_DLV_OK; case DW_FRAME_REG8: *s_out = "DW_FRAME_REG8"; return DW_DLV_OK; case DW_FRAME_REG9: *s_out = "DW_FRAME_REG9"; return DW_DLV_OK; case DW_FRAME_REG10: *s_out = "DW_FRAME_REG10"; return DW_DLV_OK; case DW_FRAME_REG11: *s_out = "DW_FRAME_REG11"; return DW_DLV_OK; case DW_FRAME_REG12: *s_out = "DW_FRAME_REG12"; return DW_DLV_OK; case DW_FRAME_REG13: *s_out = "DW_FRAME_REG13"; return DW_DLV_OK; case DW_FRAME_REG14: *s_out = "DW_FRAME_REG14"; return DW_DLV_OK; case DW_FRAME_REG15: *s_out = "DW_FRAME_REG15"; return DW_DLV_OK; case DW_FRAME_REG16: *s_out = "DW_FRAME_REG16"; return DW_DLV_OK; case DW_FRAME_REG17: *s_out = "DW_FRAME_REG17"; return DW_DLV_OK; case DW_FRAME_REG18: *s_out = "DW_FRAME_REG18"; return DW_DLV_OK; case DW_FRAME_REG19: *s_out = "DW_FRAME_REG19"; return DW_DLV_OK; case DW_FRAME_REG20: *s_out = "DW_FRAME_REG20"; return DW_DLV_OK; case DW_FRAME_REG21: *s_out = "DW_FRAME_REG21"; return DW_DLV_OK; case DW_FRAME_REG22: *s_out = "DW_FRAME_REG22"; return DW_DLV_OK; case DW_FRAME_REG23: *s_out = "DW_FRAME_REG23"; return DW_DLV_OK; case DW_FRAME_REG24: *s_out = "DW_FRAME_REG24"; return DW_DLV_OK; case DW_FRAME_REG25: *s_out = "DW_FRAME_REG25"; return DW_DLV_OK; case DW_FRAME_REG26: *s_out = "DW_FRAME_REG26"; return DW_DLV_OK; case DW_FRAME_REG27: *s_out = "DW_FRAME_REG27"; return DW_DLV_OK; case DW_FRAME_REG28: *s_out = "DW_FRAME_REG28"; return DW_DLV_OK; case DW_FRAME_REG29: *s_out = "DW_FRAME_REG29"; return DW_DLV_OK; case DW_FRAME_REG30: *s_out = "DW_FRAME_REG30"; return DW_DLV_OK; case DW_FRAME_REG31: *s_out = "DW_FRAME_REG31"; return DW_DLV_OK; case DW_FRAME_FREG0: *s_out = "DW_FRAME_FREG0"; return DW_DLV_OK; case DW_FRAME_FREG1: *s_out = "DW_FRAME_FREG1"; return DW_DLV_OK; case DW_FRAME_FREG2: *s_out = "DW_FRAME_FREG2"; return DW_DLV_OK; case DW_FRAME_FREG3: *s_out = "DW_FRAME_FREG3"; return DW_DLV_OK; case DW_FRAME_FREG4: *s_out = "DW_FRAME_FREG4"; return DW_DLV_OK; case DW_FRAME_FREG5: *s_out = "DW_FRAME_FREG5"; return DW_DLV_OK; case DW_FRAME_FREG6: *s_out = "DW_FRAME_FREG6"; return DW_DLV_OK; case DW_FRAME_FREG7: *s_out = "DW_FRAME_FREG7"; return DW_DLV_OK; case DW_FRAME_FREG8: *s_out = "DW_FRAME_FREG8"; return DW_DLV_OK; case DW_FRAME_FREG9: *s_out = "DW_FRAME_FREG9"; return DW_DLV_OK; case DW_FRAME_FREG10: *s_out = "DW_FRAME_FREG10"; return DW_DLV_OK; case DW_FRAME_FREG11: *s_out = "DW_FRAME_FREG11"; return DW_DLV_OK; case DW_FRAME_FREG12: *s_out = "DW_FRAME_FREG12"; return DW_DLV_OK; case DW_FRAME_FREG13: *s_out = "DW_FRAME_FREG13"; return DW_DLV_OK; case DW_FRAME_FREG14: *s_out = "DW_FRAME_FREG14"; return DW_DLV_OK; case DW_FRAME_FREG15: *s_out = "DW_FRAME_FREG15"; return DW_DLV_OK; case DW_FRAME_FREG16: *s_out = "DW_FRAME_FREG16"; return DW_DLV_OK; case DW_FRAME_FREG17: *s_out = "DW_FRAME_FREG17"; return DW_DLV_OK; case DW_FRAME_FREG18: *s_out = "DW_FRAME_FREG18"; return DW_DLV_OK; case DW_FRAME_FREG19: *s_out = "DW_FRAME_FREG19"; return DW_DLV_OK; case DW_FRAME_FREG20: *s_out = "DW_FRAME_FREG20"; return DW_DLV_OK; case DW_FRAME_FREG21: *s_out = "DW_FRAME_FREG21"; return DW_DLV_OK; case DW_FRAME_FREG22: *s_out = "DW_FRAME_FREG22"; return DW_DLV_OK; case DW_FRAME_FREG23: *s_out = "DW_FRAME_FREG23"; return DW_DLV_OK; case DW_FRAME_FREG24: *s_out = "DW_FRAME_FREG24"; return DW_DLV_OK; case DW_FRAME_FREG25: *s_out = "DW_FRAME_FREG25"; return DW_DLV_OK; case DW_FRAME_FREG26: *s_out = "DW_FRAME_FREG26"; return DW_DLV_OK; case DW_FRAME_FREG27: *s_out = "DW_FRAME_FREG27"; return DW_DLV_OK; case DW_FRAME_FREG28: *s_out = "DW_FRAME_FREG28"; return DW_DLV_OK; case DW_FRAME_FREG29: *s_out = "DW_FRAME_FREG29"; return DW_DLV_OK; case DW_FRAME_FREG30: *s_out = "DW_FRAME_FREG30"; return DW_DLV_OK; case DW_FRAME_FREG31: *s_out = "DW_FRAME_FREG31"; return DW_DLV_OK; case DW_FRAME_FREG32: *s_out = "DW_FRAME_FREG32"; return DW_DLV_OK; case DW_FRAME_FREG33: *s_out = "DW_FRAME_FREG33"; return DW_DLV_OK; case DW_FRAME_FREG34: *s_out = "DW_FRAME_FREG34"; return DW_DLV_OK; case DW_FRAME_FREG35: *s_out = "DW_FRAME_FREG35"; return DW_DLV_OK; case DW_FRAME_FREG36: *s_out = "DW_FRAME_FREG36"; return DW_DLV_OK; case DW_FRAME_FREG37: *s_out = "DW_FRAME_FREG37"; return DW_DLV_OK; case DW_FRAME_FREG38: *s_out = "DW_FRAME_FREG38"; return DW_DLV_OK; case DW_FRAME_FREG39: *s_out = "DW_FRAME_FREG39"; return DW_DLV_OK; case DW_FRAME_FREG40: *s_out = "DW_FRAME_FREG40"; return DW_DLV_OK; case DW_FRAME_FREG41: *s_out = "DW_FRAME_FREG41"; return DW_DLV_OK; case DW_FRAME_FREG42: *s_out = "DW_FRAME_FREG42"; return DW_DLV_OK; case DW_FRAME_FREG43: *s_out = "DW_FRAME_FREG43"; return DW_DLV_OK; case DW_FRAME_FREG44: *s_out = "DW_FRAME_FREG44"; return DW_DLV_OK; case DW_FRAME_FREG45: *s_out = "DW_FRAME_FREG45"; return DW_DLV_OK; case DW_FRAME_FREG46: *s_out = "DW_FRAME_FREG46"; return DW_DLV_OK; case DW_FRAME_FREG47: *s_out = "DW_FRAME_FREG47"; return DW_DLV_OK; case DW_FRAME_FREG48: *s_out = "DW_FRAME_FREG48"; return DW_DLV_OK; case DW_FRAME_FREG49: *s_out = "DW_FRAME_FREG49"; return DW_DLV_OK; case DW_FRAME_FREG50: *s_out = "DW_FRAME_FREG50"; return DW_DLV_OK; case DW_FRAME_FREG51: *s_out = "DW_FRAME_FREG51"; return DW_DLV_OK; case DW_FRAME_FREG52: *s_out = "DW_FRAME_FREG52"; return DW_DLV_OK; case DW_FRAME_FREG53: *s_out = "DW_FRAME_FREG53"; return DW_DLV_OK; case DW_FRAME_FREG54: *s_out = "DW_FRAME_FREG54"; return DW_DLV_OK; case DW_FRAME_FREG55: *s_out = "DW_FRAME_FREG55"; return DW_DLV_OK; case DW_FRAME_FREG56: *s_out = "DW_FRAME_FREG56"; return DW_DLV_OK; case DW_FRAME_FREG57: *s_out = "DW_FRAME_FREG57"; return DW_DLV_OK; case DW_FRAME_FREG58: *s_out = "DW_FRAME_FREG58"; return DW_DLV_OK; case DW_FRAME_FREG59: *s_out = "DW_FRAME_FREG59"; return DW_DLV_OK; case DW_FRAME_FREG60: *s_out = "DW_FRAME_FREG60"; return DW_DLV_OK; case DW_FRAME_FREG61: *s_out = "DW_FRAME_FREG61"; return DW_DLV_OK; case DW_FRAME_FREG62: *s_out = "DW_FRAME_FREG62"; return DW_DLV_OK; case DW_FRAME_FREG63: *s_out = "DW_FRAME_FREG63"; return DW_DLV_OK; case DW_FRAME_FREG64: *s_out = "DW_FRAME_FREG64"; return DW_DLV_OK; case DW_FRAME_FREG65: *s_out = "DW_FRAME_FREG65"; return DW_DLV_OK; case DW_FRAME_FREG66: *s_out = "DW_FRAME_FREG66"; return DW_DLV_OK; case DW_FRAME_FREG67: *s_out = "DW_FRAME_FREG67"; return DW_DLV_OK; case DW_FRAME_FREG68: *s_out = "DW_FRAME_FREG68"; return DW_DLV_OK; case DW_FRAME_FREG69: *s_out = "DW_FRAME_FREG69"; return DW_DLV_OK; case DW_FRAME_FREG70: *s_out = "DW_FRAME_FREG70"; return DW_DLV_OK; case DW_FRAME_FREG71: *s_out = "DW_FRAME_FREG71"; return DW_DLV_OK; case DW_FRAME_FREG72: *s_out = "DW_FRAME_FREG72"; return DW_DLV_OK; case DW_FRAME_FREG73: *s_out = "DW_FRAME_FREG73"; return DW_DLV_OK; case DW_FRAME_FREG74: *s_out = "DW_FRAME_FREG74"; return DW_DLV_OK; case DW_FRAME_FREG75: *s_out = "DW_FRAME_FREG75"; return DW_DLV_OK; case DW_FRAME_FREG76: *s_out = "DW_FRAME_FREG76"; return DW_DLV_OK; case DW_FRAME_HIGHEST_NORMAL_REGISTER: *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CHILDREN_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CHILDREN_no: *s_out = "DW_CHILDREN_no"; return DW_DLV_OK; case DW_CHILDREN_yes: *s_out = "DW_CHILDREN_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ADDR_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ADDR_none: *s_out = "DW_ADDR_none"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* END FILE */ libdwarf-20210528/libdwarf/dwarf_names_new.h0000664000175000017500000000511214054205616015600 00000000000000/* Automatically generated, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ /* define DWARF_PRINT_PREFIX before this point if you wish to. */ #ifndef DWARF_PRINT_PREFIX #define DWARF_PRINT_PREFIX dwarf_ #endif #define dw_glue(x,y) x##y #define dw_glue2(x,y) dw_glue(x,y) #define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x) int DWPREFIX(get_TAG_name) (unsigned int, const char **); int DWPREFIX(get_children_name) (unsigned int, const char **); int DWPREFIX(get_FORM_name) (unsigned int, const char **); int DWPREFIX(get_AT_name) (unsigned int, const char **); int DWPREFIX(get_OP_name) (unsigned int, const char **); int DWPREFIX(get_ATE_name) (unsigned int, const char **); int DWPREFIX(get_DEFAULTED_name) (unsigned int, const char **); int DWPREFIX(get_IDX_name) (unsigned int, const char **); int DWPREFIX(get_LLEX_name) (unsigned int, const char **); int DWPREFIX(get_LLE_name) (unsigned int, const char **); int DWPREFIX(get_RLE_name) (unsigned int, const char **); int DWPREFIX(get_GNUIVIS_name) (unsigned int, const char **); int DWPREFIX(get_GNUIKIND_name) (unsigned int, const char **); int DWPREFIX(get_UT_name) (unsigned int, const char **); int DWPREFIX(get_SECT_name) (unsigned int, const char **); int DWPREFIX(get_DS_name) (unsigned int, const char **); int DWPREFIX(get_END_name) (unsigned int, const char **); int DWPREFIX(get_ATCF_name) (unsigned int, const char **); int DWPREFIX(get_ACCESS_name) (unsigned int, const char **); int DWPREFIX(get_VIS_name) (unsigned int, const char **); int DWPREFIX(get_VIRTUALITY_name) (unsigned int, const char **); int DWPREFIX(get_LANG_name) (unsigned int, const char **); int DWPREFIX(get_ID_name) (unsigned int, const char **); int DWPREFIX(get_CC_name) (unsigned int, const char **); int DWPREFIX(get_INL_name) (unsigned int, const char **); int DWPREFIX(get_ORD_name) (unsigned int, const char **); int DWPREFIX(get_DSC_name) (unsigned int, const char **); int DWPREFIX(get_LNCT_name) (unsigned int, const char **); int DWPREFIX(get_LNS_name) (unsigned int, const char **); int DWPREFIX(get_LNE_name) (unsigned int, const char **); int DWPREFIX(get_ISA_name) (unsigned int, const char **); int DWPREFIX(get_MACRO_name) (unsigned int, const char **); int DWPREFIX(get_MACINFO_name) (unsigned int, const char **); int DWPREFIX(get_CFA_name) (unsigned int, const char **); int DWPREFIX(get_EH_name) (unsigned int, const char **); int DWPREFIX(get_FRAME_name) (unsigned int, const char **); int DWPREFIX(get_CHILDREN_name) (unsigned int, const char **); int DWPREFIX(get_ADDR_name) (unsigned int, const char **); /* END FILE */ libdwarf-20210528/libdwarf/dwarf_crc32.c0000664000175000017500000001103514053234475014540 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef HAVE_STDLIB_H #include /* for free() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_TYPES_H #include /* off_t ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #include #ifdef HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) /* Want to have SEEK_CUR and SEEK_SET defined. */ #include #include /* Should we have include instead? */ typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ #endif /* HAVE_UNISTD_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_error.h" unsigned int dwarf_basic_crc32 (const unsigned char *buf, unsigned long len, unsigned int init) { return _dwarf_crc32(init,buf,len); } /* Returns DW_DLV_OK DW_DLV_NO_ENTRY or DW_DLV_ERROR crc32 used for debuglink crc calculation. Caller passes pointer to array of 4 unsighed char and if this returns DW_DLV_OK that is filled in.*/ int dwarf_crc32 (Dwarf_Debug dbg,unsigned char *crcbuf, Dwarf_Error *error) { off_t size_left = 0; off_t fsize = 0; off_t lsval = 0; ssize_t readlen = 1000; unsigned char *readbuf = 0; ssize_t readval = 0; unsigned int tcrc = 0; unsigned int init = 0; int fd = -1; if (!dbg) { _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: Bad call to dwarf_crc32"); return DW_DLV_ERROR; } if (!crcbuf) { return DW_DLV_NO_ENTRY; } if (!dbg->de_owns_fd) { return DW_DLV_NO_ENTRY; } fd = dbg->de_fd; if (fd < 0) { return DW_DLV_NO_ENTRY; } fd = dbg->de_fd; if (dbg->de_filesize) { fsize = size_left = dbg->de_filesize; } else { fsize = size_left = lseek(fd,0L,SEEK_END); if (fsize == (off_t)-1) { _dwarf_error_string(dbg,error,DW_DLE_SEEK_ERROR, "DW_DLE_SEEK_ERROR: dwarf_crc32 seek " "to end fails"); return DW_DLV_ERROR; } } if (fsize <= (off_t)500) { /* Not a real object file. A random length check. */ return DW_DLV_NO_ENTRY; } lsval = lseek(fd,0L,SEEK_SET); if (lsval < 0) { _dwarf_error_string(dbg,error,DW_DLE_SEEK_ERROR, "DW_DLE_SEEK_ERROR: dwarf_crc32 seek " "to start fails"); return DW_DLV_ERROR; } readbuf = (unsigned char *)malloc(readlen); if (!readbuf) { _dwarf_error_string(dbg,error,DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: dwarf_crc32 read buffer" " alloc fails"); return DW_DLV_ERROR; } while (size_left > 0) { if (size_left < readlen) { readlen = size_left; } readval = read(fd,readbuf,readlen); if (readval != (ssize_t)readlen) { _dwarf_error_string(dbg,error,DW_DLE_READ_ERROR, "DW_DLE_READ_ERROR: dwarf_crc32 read fails "); free(readbuf); return DW_DLV_ERROR; } tcrc = _dwarf_crc32(init,readbuf,readlen); init = tcrc; size_left -= readlen; } /* endianness issues? */ free(readbuf); memcpy(crcbuf,(void *)&tcrc,4); return DW_DLV_OK; } libdwarf-20210528/libdwarf/ChangeLog20060000664000175000017500000010532413644370703014364 000000000000002006-12-05 David Anderson * dwarf_error.c, libdwarf.h: added DW_DLE_FRAME_REGISTER_COUNT_MISMATCH. * dwarf_frame.c (_dwarf_exec_frame_instr): removed references to compile-time constants for register table size. Now uses run-time-chosen sizes. Now uses heap for reg table instead of stack. Now uses SIMPLE_ERROR_RETURN macro to simplify the code. 2006-11-08 David Anderson * pro_expr.c (dwarf_add_expr_gen): DW_OP_deref_size, DW_OP_xderef_size, and DW_OP_pick were incorrect, missing & operator. Would coredump. Thanks to Alan Chambers for mentioning the coredump. 2006-09-26 David Anderson * dwarf_die_deliv.c (dwarf_offdie): Now returns the correct die (worked before, almost always, but worked by accident). Thanks to Mattias Lindblad for supplying a test case. 2006-09-01 David Anderson * libdwarf2.1.mm (dwarf_loclist_n): Minor refinement of the description. * libdwarf2.1.ps: regenerated 2006-08-31 David Anderson * libdwarf2.1.mm (dwarf_loclist_n): A location expression sets ld_lopc to 0, ld_hipc to all-bits-on, and this is now documented. * libdwarf2.1.ps: regenerated 2006-06-14 David Anderson * dwarf_opaque.h dwarf_frame.h dwarf_frame.c dwarf_init_finish.c dwarf_frame2.c: Corrected handling of eh_frame zP encoding. Thanks to Cristi Vlasceanu for noticing it was broken. * Makefile.in: remove libdwarf.so in 'clean' rule. Thanks to Cristi Vlasceanu for noticing it was missing. 2006-04-28 David Anderson * dwarf_frame.c: Changed local variable type to avoid compiler warning. 2006-04-21 David Anderson * dwarf_frame.c: Initialized local to 0, wrong value. Thanks to Cristi Vlasceanu for noticing. 2006-04-18 David Anderson * All *.c: Ran indent so all c files follow a standard look. 2006-04-16 David Anderson * dwarf.h: Remove #if 0 around some #defines, it is ok to leave the defines visible (the defines are HP extensions). * libdwarf.h: Add new dwarf3 interface to frames. (which actually is also a better interface to dwarf2 info, not strictly for dwarf3). * dwarf_alloc.c: Add 'constructor/destructor' pointers to the initialization table so we can handle a more flexible (dwarf3) frame interface.Call the functions at the appropriate times. * dwarf_frame.c: Using macro FDE_NULL_CHECKS_AND_SET_DBG reduce duplicate coding.Internal code now handles dwarf2 and dwarf3 and interfaces to exported interfaces appropriately. * dwarf_frame.h: Alter internal struct to handle frames more flexibly. * dwarf_frame2.c: Remove unused local variable. * dwarf_init_finish.c: Add initialization of new Dwarf_Debug struct entries allowing handling of run-time-config of frame info. * dwarf_loc.c: Add DWARF3 operators, such as DW_OP_call4. * dwarf_opaque.h: Declaration of new Dwarf_Debug struct entries allowing handling of run-time-config of frame info. * pro_expr.c: Add entries allowing creation of DWARF3 DW_OP such as call2. * pro_section.c: Change crucial code handling section lengths, using a macro BEGIN_LEN_SIZE to clarify and correct a few places. 2006-03-31 David Anderson * libdwarf.h: Added dwarf_get_fde_info_for_cfa_reg3() prototype preparing for dwarf3 frame interface. * dwarf_frame.c: Now uses separate rule, not DW_FRAME_CFA_COL, to record CFA. * dwarf_frame.h: Add commentary on frame access. 2006-03-30 David Anderson * Makefile.in configure.in: Adding --enable-shared --enable-nonshared --disable-shared and --disable-nonshared. * configure: regenerated with 2.59 autoconf. * README: Added explanation on changing dwarf.h libdwarf.h. 2006-03-29 David Anderson * dwarf_print_lines.c dwarf_sort_line.c: Clean up initialization code for line table reading. When returning rules table data to caller ensure fully filled out yet no overrun (handling case where rules table sizes not defined identically by caller and library). * dwarf.h: New commentary on ABI/register-number issues. * libdwarf.h: New commentary on ABI/register-number issues. 2006-03-26 David Anderson * dwarf_line.c: file_entry_count local was not initialized. Initialized some locals at declaration. Thanks to Mikael Vidstedt for noticing. 2006-03-23 David Anderson * dwarf_error.c: added error strings for codes 200,201 * dwarf_line.c dwarf_line.h dwarf_print_lines.c dwarf_sort_line.c: Moved line prefix reading to a common routine, filling in a new internal struct to make it simple. Removed much duplicate code. Added more support for dwarf3 line table standard opcodes. Now prints details (with -v -v) of standard opcodes it does not understand (if any present). 2006-03-13 David Anderson * dwarf.h: add ALTIUM #defines (extensions to dwarf) * libdwarf.h: Alter arguments to new functions dwarf_get_fde_augmentation_data() and dwarf_get_cie_augmentation_data() used by GNU eh_frame. * dwarf_frame.h: Add new fields so we can handle GNU eh_frame. * dwarf_frame.c: Remove erroneous load_sections calls (wrong for eh_frame data) and correct the new dwarf_get_fde_augmentation_data() and dwarf_get_cie_augmentation_data() implementation. * dwarf_frame2.c: Implement support for GNU eh_frame. * dwarf_line.h: Correct handling of DWARF3 opcode base check. * dwarf_line.c: Add new macro use to get DWARF3 opcode base handling correct. * dwarf_print_lines.c: Add new macro use to get DWARF3 opcode base handling correct. * dwarf_sort_lines.c: Add new macro use to get DWARF3 opcode base handling correct. 2006-03-08 David Anderson * dwarf_frame2.c: ensure local variables initialized to avoid coredump. 2006-03-08 David Anderson * dwarf_die_deliv.c: Remove Richard Stukey's -1 and replace with a simpler more complete fix. 2006-03-07 David Anderson * Makefile.in: Add dwarf_line2.c dwarf_frame3.c to files to build. * dwarf_addr_finder.c: Add comments about file purpose. * dwarf_frame.c: Move IRIX specific function out of this file. * dwarf_frame3.c: Move IRIX specific function to this new file. * dwarf_frame.h: Add interface declaration. * dwarf_line.c: Move IRIX specific function out of this file. * dwarf_line2.c: Move IRIX specific function to this new file. * dwarf_line.h: Add interface declaration. * dwarf_frame2.c: Altered comments so indent handles them better, ran indent. 2006-03-07 David Anderson * dwarf_die_deliv.c (dwarf_siblingof): -1 to point to end of cu, not one-past-end. With thanks to Richard Stuckey. * libdwarf2.1.mm: document existing function dwarf_get_fde_exception_info() * dwarf_frame.h: Add new internal interfaces. * dwarf_frame.c: Remove cie/fde reader to dwarf_frame2.c. * dwarf_frame2.c: Contains heavily refactored cie/fde reader, preparing for eh_frame support and avoids some searching in fde creation. Removes duplicated code into new internal functions. * Makefile.in: Adding comment about flag for malloc_checking code. Add dwarf_frame2.c to source list. * libdwarf.h: added declarations for eh_frame information, though these are not yet supported. * dwarf.h: Added defines for eh_frame information, though these are not yet used. 2006-02-23 David Anderson * dwarf_line.h dwarf_line.c: added dwarf_line_srcfileno() to complement dwarf_lineno. * libdwarf2.1.mm: document dwarf_line_srcfileno(). 2005-11-25 David Anderson * dwarf.h: Now matches 2005 DWARF3 public review document. 2005-11-08 David Anderson * dwarf_alloc.c, dwarf_init_finish.c, dwarf_sort_line.c, malloc_check.c: remove malloc.h include, it is not needed, stdlib.h suffices. 2005-10-24 David Anderson * dwarf.h: Updated to match DWARF3 public review document. 2005-10-03 David Anderson * dwarf_alloc.c: Change some entries to BASE_ALLOC. * dwarf_global.h: Add argument to interface so we do not universally use DW_DLA_GLOBAL, but cater to compatibility. * dwarf_funcs.c, dwarf_global.c, dwarf_weaks.c, dwarf_funcs.c, dwarf_types.c: Restored use of DW_DLA_* instead of universally using DW_DLA_GLOBAL. * dwarf_pubtypes.c: added comments about DW_DLA_GLOBAL use. 2005-08-01 David Anderson * malloc_check.c: Moved the #ifdef WANT_LIBBDWARF_MALLOC_CHECK down after #includes so the test is meaningful. 2005-07-15 David Anderson * libdwarf.h: New DW_DLA codes and full .debug_types support added. new dealloc functions declared. * Makefile.in: Add dwarf_pubtypes.o (.debug_pubtypes support). * dwarf_abbrev.c: Add dealloc() calls where needed. * dwarf_alloc.c: Add dwarf_malloc_check calls, rename and update _DW_RESERVE to DW_RESERVE, make hash table declaration in array more readable. Add optional final dealloc loop. * dwarf_alloc.h: Increase the index array to add .debug_pubtypes support. * dwarf_base_types.h: Increase the index array to add .debug_pubtypes support. * dwarf_die_deliv.c: Add dealloc calls to get full dealloc. * dwarf_error.c: Document new error codes for .debug_pubtypes. * dwarf_init_finish.c: Add .debug_pubtypes support, add dwarf_malloc_check_complete() call for alloc checking. * dwarf_form.c: Document dwarf_formstring() use. * dwarf_frame.c: Add dwarf_fde_cie_list_dealloc() for complete dealloc. * dwarf_global.h: Add _dwarf_internal_globals_dealloc declaration for libdwarf-internal use. * dwarf_global.c dwarf_funcs.c dwarf_types.c dwarf_vars.c dwarf_weaks.c: Add new dealloc public routines for complete dealloc and add .debug_pubtypes support. * dwarf_pubtypes.c: Support for .debug_pubtypes. * dwarf_malloc_check.h dwarf_malloc_check.c : New checking for complete accurate dealloc (off by default). * dwarf_opaque.h: Add internal .debug_pubtypes support. * libdwarf2.1.mm: Document new dealloc code, correct dwarf_formstring documentation. 2005-07-14 David Anderson * dwarf_line.c: Added dwarf_srclines_dealloc and call it for dwarf_srclines output. Does complete deallocation, unlike previous method, which was incomplete deallocation. Thanks to Alan Alexander for pointing out there was incomplete deallocation. * dwarf_print_lines.c: remove references and allocation of line_context. Memory was leaking due to unreferenced variable. * libdwarf2.1.mm: Document new dwarf_srclines_dealloc() deallocation routine for dwarf_srclines(). 2005-07-13 David Anderson * dwarf_init_finish.c (dwarf_init): if _dwarf_setup() fails, free elf resources with elf_end() call. Thanks to Cristi Vlasceanu for pointing out that a memory leak existed here. 2005-06-13 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): Corrected test so that .o files (pre-relocation) are less likely to generate DW_DLE_DF_NEW_LOC_LESS_OLD_LOC error. Renamed local variable for better readability. 2005-04-13 David Anderson * dwarf_error.c: Error codes 194 and 195 were missing strings, added them to table. * dwarf_frame.c: Check for newer gcc .eh_frame augmentation strings and avoid trying to handle these for now. * dwarf_global.c: Add an error check for pubnames-style sections for bad offset. * dwarf_init_finish.c: Add dwarf_get_section_max_offsets() to allow clients to do additional error checking. This code will have to change again, so leaving it undocumented. As written it's not useful for COMDAT style DWARF sections. * libdwarf.h: Added prototype for dwarf_get_section_max_offsets(). 2005-03-31 David Anderson * mips_extensions.mm: Documented the libexc/.debug_funcnames dependency and the 64bit-offset DWARF extension. * mips_extensions.ps: Regenerated. 2005-03-21 David Anderson * dwarf_line.c: Added commentary. * libdwarf2.1.mm: Documented dwarf_lineendsequence() better. * libdwarf2.1.ps: Regenerated. * libdwarf.h: Added DW_DLE_FRAME_AUGMENTATION_UNKNOWN as error code 195. * dwarf_init_finish.c: Corrected comment spelling. * dwarf_frame.h dwarf_frame.c: Added handling for much (but not all) of gcc 3.3 gcc 3.4 .eh_frame 'z' augmentation. Gives error on attempting to get z augmentation data since such is not completely handled. 2005-03-18 David Anderson * dwarf_frame.h dwarf_frame.c: The gcc .eh_frame info did not print correctly so we now access the correct section data so it prints. Still no support for dwarf3 frame operators. * dwarf_macro.c: Detect end-of-macros properly (stopped too soon before). 2005-02-14 David Anderson * pro_incl.h: Added #elif defined(HAVE_LIBELF_H) enabling build on a platform missing normal elf.h. 2005-02-11 David Anderson * dwarf_base_types.h: Added DW_CIE_VERSION3 define. * dwarf_die_deliv.c: Allowed CURRENT_VERSION_STAMP3. * dwarf_frame.c: Allowed DW_CIE_VERSION3. * dwarf_frame.h: Define DW_DEBUG_FRAME_VERSION3. * dwarf_line.c: Allow CURRENT_VERSION_STAMP3. * dwarf_line.h: Add lc_version_number to line structure. * dwarf_opaque.h: Add CURRENT_VERSION_STAMP3 and comment showing version numbers (DWARF3 vs DWARF2) by DWARF section. 2004-11-21 David Anderson * configure.in libdwarfdefs.h: Now tests more precisely for __uint32_t and __uint64_t (previous test was not sufficient for debian/mips). Regenerated configure config.h.in. 2004-10-28 David Anderson * LIBDWARFCOPYRIGHT Makefile.in NEWS config.h dwarf_abbrev.c dwarf_abbrev.h dwarf_addr_finder.c dwarf_alloc.c dwarf_alloc.h dwarf_arange.c dwarf_arange.h dwarf_base_types.h dwarf_die_deliv.c dwarf_die_deliv.h dwarf_error.c dwarf_error.h dwarf_form.c dwarf_frame.c dwarf_frame.h dwarf_funcs.c dwarf_funcs.h dwarf_global.c dwarf_global.h dwarf_incl.h dwarf_init_finish.c dwarf_leb.c dwarf_line.c dwarf_line.h dwarf_loc.c dwarf_loc.h dwarf_macro.c dwarf_macro.h dwarf_opaque.h dwarf_print_lines.c dwarf_query.c dwarf_sort_line.c dwarf_string.c dwarf_stubs.c dwarf_types.c dwarf_types.h dwarf_util.c dwarf_util.h dwarf_vars.c dwarf_vars.h dwarf_weaks.c dwarf_weaks.h libdwarfdefs.h pro_alloc.c pro_alloc.h pro_arange.c pro_arange.h pro_die.c pro_die.h pro_encode_nm.c pro_encode_nm.h pro_error.c pro_error.h pro_expr.c pro_expr.h pro_finish.c pro_forms.c pro_frame.c pro_frame.h pro_funcs.c pro_funcs.h pro_incl.h pro_init.c pro_line.c pro_line.h pro_macinfo.c pro_macinfo.h pro_opaque.h pro_pubnames.c pro_pubnames.h pro_reloc.c pro_reloc.h pro_reloc_stream.c pro_reloc_stream.h pro_reloc_symbolic.c pro_reloc_symbolic.h pro_section.c pro_section.h pro_types.c pro_types.h pro_util.c pro_util.h pro_vars.c pro_vars.h pro_weaks.c pro_weaks.h: Copyright update with 2004 and new SGI official address. 2004-10-26 David Anderson * acconfig.h: removed. Was old style autoconf usage. * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. * config.guess: Updated. timestamp='2004-06-11'. * config.sub: Updated. timestamp='2004-03-12'. * configure config.h.in: regenerated with autoconf 2.58. 2004-06-09 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): Was not setting ru_offset to 1 in DW_CFA_def_cfa_offset case, now it does. 2004-02-24 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): DW_CFA_def_cfa_register case, was setting offset, which is incorrect. Thanks to Tom Hughes for pointing this out. 2004-02-03 David Anderson * dwarf_util.h: DECODE_LEB128_UWORD DECODE_LEB128_SWORD were simply wrong if Dwarf_Word or Dwarf_Sword longer than 4 bytes. Upper bits left random. Large values not extracted correctly. 2004-01-15 David Anderson * dwarf_alloc.c pro_alloc.c pro_init.c: changing BSD-ish bzero() to posix-standard memset() calls. * configure.in: remove bstring.h test, add alloca.h test. No longer useing bzero, some environments have alloca in malloc.h, no alloca.h. If neither exist it's up to you to deal with it. * dwarf_line.c dwarf_print_lines.c dwarf_sort_line.c: Test HAVE_ALLOCA_H * configure config.h.in: regenerated 2003-12-31 David Anderson * dwarf_init_finish.c: added #error to detect and describe absence of libelf.h. * README: Added mention of libelf.h requirement, minor cleanout of obsolete comments, added configure example. * Makefile.in: Removed bogus LIBS line, updated copyright date. * acconfig.h: Updated copyright date. * config.guess config.sub: new versions from automake-1.6. * config.h.in configure: Regenerated. 2003-12-15 David Anderson * dwarf_init_finish.c (_dwarf_setup): test for (section_size) was wrong for eh_frame section. Changed this one to (section_size == 0) so it is like all the others testing section_size. Thanks to David Mosberger for pointing out this inconsistency. 2003-12-08 David Anderson * dwarf_line.h: reference in comment to li_dbg meant to refer to li_offset. Corrected and amplified comment. 2003-10-06 David Anderson * dwarf_abbrev.c dwarf_die_deliv.c dwarf_form.c dwarf_loc.c dwarf_util.c: applied indent(1). 2003-10-02 David Anderson * dwarf_loc.c: Implemented dwarf_get_loclist_entry(), implemented new dwarf_loclist_n() fully implementing loclist support. * dwarf_stubs.c: removed dwarf_get_loclist_entry stub. * libdwarf2.1.mm: Documented dwarf_loclist_n() and updated documentation on dwarf_loclist(). 2003-09-29 David Anderson * dwarf_abbrev.c: Ensure the .debug_abbrev section is loaded. * dwarf_arange.c dwarf_global.c: Recent dwarf committee discussions have revealed we were wrong in not allowing padding in aranges. * dwarf_die_deliv.c dwarf_query.c: handle DW_FORM_indirect. * dwarf_form.c: Add dwarf_whatform_direct() so folks can report on DW_FORM_indirect use. Fill in new Dwarf_Locdesc fields. * dwarf_loc.c: Handle .debug_loc partially. Fill in new Dwarf_Locdesc fields. Load .debug_loc if not present and if it's needed. * dwarf_opaque.h: Added ar_attribute_form_direct field so we can report DW_FORM_indirect in libdwarf-using code (where such wants to). * dwarf_util.c: Don't confuse DW_FORM_indirect uleb length with other lengths. * libdwarf2.1.mm: Document new function dwarf_whatform_direct() Not needed by ordinary clients, just for clients wanting to print certain debug info. 2003-04-15 Brian Ford * configure.in (AC_C_BIGENDIAN): Move after AC_PROG_CC so a proper working compiler is used for the test. 2003-01-21 David Anderson * dwarf_die_deliv.c (dwarf_next_cu_header, dwarf_offdie): Add calls to dwarf_load_object() to load .debug_info, .debug_abbrev * dwarf_init_finish.c (_dwarf_setup): Remove calls to dwarf_load_object for .debug_info, .debug_abbrev sections. * dwarf_opaque.h: Add new fields to Dwarf_Debug so we don't need to pre-load .debug_info, .debug_abbrev * dwarf_util.h: Fix READ_AREA_LENGTH macro so it uses only length itself to determine which format the length is. 2003-01-14 David Anderson * dwarf_loc.c: Made comment at head of dwarf_loclist() a bit clearer. 2002-11-22 Tom Hughes * dwarf_macro.c: Corrected bugs in macro-info functions. 2002-10-29 David Anderson * dwarf_init_finish.c: The libelf_sgi mods left a HAVE_ELF64_GETSHDR ifdef in the wrong place so folks without Elf64 could not build. Fixed. 2002-10-21 David Anderson * dwarf_form.c: the form_ref functions were failing to add in cc_extension_size when checking for offset legality. Thanks to Kelly O'Hair for pointing out the 4 places this was wrong. Used cu_context local pointer to avoid numerous double indirections. 2002-08-14 David Anderson * dwarf_string.c (dwarf_get_str): Return DW_DLV_NO_ENTRY when offset is just at the end of the sections, making it possible to use dwarf_get_str to print the section independently. * libdwarf2.1.mm, libdwarf2.1.ps: Document the revised dwarf_get_str interface (which was not fully thought thru before). * dwarf_line.c (dwarf_srcfiles): Avoid core dump when DW_AT_comp_dir absent (it's not required). 2002-07-31 David Anderson * pro_types.c (_dwarf_transform_simplename_to_disk): correct generation of .debug_info size field. Thanks to Kelly O'Hair for pointing out the bug. 2002-05-23 Daniel Gohman * dwarf_init_finish.c: Add support for using SGI's ELF library as an alternative to using AT&T-style libelf. Add a new function _dwarf_load_section to handle loading of sections. * dwarf_opaque.h: Add entries to Dwarf_Debug_s to store section indicies. * most consumer files: Load sections on demand so that unneeded sections don't get loaded. * dwarf_init_finish.c: Fixed an incorrect check for duplicate .eh_frame sections. 2002-04-25 Kelly O'Hair * pro_section.c (_dwarf_pro_generate_debuginfo): add required dwarf2 sec 7.5.3 trailing null byte to .debug_abbrev per compilation-unit. 2002-03-31 David Anderson * dwarf_abbref.c (dwarf_get_abbrev): change DW_DLE_DEBUG_ABBREV_NULL to DW_DLE_DWARF_ABBREV_NULL. Former was wrong code. * libdwarf2.1.mm: correct argument reference, returned_abbrev not returned_fde in dwarf_get_abbrev discussion. 2002-03-07 David Anderson * libdwarf.h: added struct Elf declaration to reduce dependency on header include ordering. 2002-02-11 David Anderson * libdwarf2.1.mm libdwarf2.1.ps: dwarf_offdie can return DW_DLV_NO_ENTRY and that is now documented. * dwarf_loc.c: if the length of a location description is zero that is ok, not an error. dwarf2 sec 2.4.1. 2002-01-10 David Anderson * dwarf_opaque.h, dwarf_init_finish.c: if libdwarf does the elf_begin() it must also do the elf_end() to avoid a memory leak, and now does this correctly. 2002-01-10 David Anderson * dwarf_init_finish.c: Using a variable to hold ELF_C_READ_MMAP. Really motivated by code not added to this source. * dwarf_die_deliv.c: Added comments, moved a couple variables to local scope from function scope. * dwarf.h: Added some #defines which were specified in the Dwarf 2.1 Dwarf draft 5 (now called dwarf 3 draft 5). 2001-09-18 David Anderson davea@sgi.com * all files: applied gnu indent with -bad -bap -nbbo -br -ce -brs -l72 -lc72 -hnl -nprs -fca -i4 -lp -psl -npcs Code should use this set in libdwarf. 2001-08-21 "kelly o'hair" * pro_section.c: If one called dwarf_add_file_decl() or dwarf_add_directory_decl() but never added a line, .debug_line was not produced. This was a mistake, as if any file or directory was provided .debug_line should be produced. 2001-08-06 davea@sgi.com * libdwarf2.1.mm: documented dwarf_dealloc rules more clearly. (.ps updated too) * mips_extensions.mm: documented the way SGI gets frame stack pointer out of debug_frame. (.ps updated too) 2001-06-14 davea@sgi.com * dwarf_leb.c: changed around where bytes counted in _dwarf_decode_s_leb128 so it's easier to tell it is correct. And removed one loop completely: it was an early attempt at performance improvement and is no longer relevant. * dwarf_global.c: added new dwarf_get_cu_die_offset_given_cu_header_offset function to get CU die offset (as the long name says). A variety of functions return cu-header-offsets, so this is useful at times. Used locals to reduce the number of indirections and make things easier to follow. * dwarf_arange.c: added new dwarf_get_arange_cu_header_offset function so dwarfdump could print the cu header offset (which appears in the arange headers). * libdwarf2.1.mm: documented the above new functions. 2001-06-07 davea@sgi.com * dwarf_leb.c: shift operator was not being applied to full size of Dwarf_Signed/Unsigned for 64bit Dwarf_Signed/Unsigned (ILP32 compile) so large numbers not decoded if signed. * pro_encode_nm.c: added {} in a couple if/else for 'clarity' and to make inserting debug printf easier. * pro_expr.c: Added comments explaining why possible compiler (gcc) warnings are ok, the result is safe. 2001-05-30 davea@sgi.com * pro_reloc_stream.c: Wrote Set_REL32_info and Set_REL64_info macros from generic ELF abi documents to make use acceptable when IRIX elfaccess.h is not available. 2001-05-30 "kelly o'hair" * Makefile.in: was missing pro_macinfo.o pro_encode_nm.o dwarf_macro.o from the OBJS list. 2001-05-22 davea@sgi.com * dwarf_frame.c, pro_expr.c: Added comments on why casts are safe in spite of gcc warnings (4 places total). 2001-05-18 Dan Gritter * dwarf_loc.c DW_OP_bregx operands are unsigned reg num followed by signed offset. 2001-04-11 David Anderson * dwarf_die_deliv.c: check for 0 abbreviation code and return a 'no entry' return value when found. (normal dwarf2, 0 means no DIE, the end of some set of DIEs.) 2001-01-16 David Anderson * pro_die.c: set ar_reloc_len field in all cases. 2000-12-14 David Anderson * dwarf_frame.h: clarified some comments. 2000-12-14 Ulrich Drepper * dwarf_line.c: Now sets DW_LNE_end_sequence to default_is_stmt, the correct value, not is_stmt. 2000 Aug 24 davea@sgi.com dwarf_error.c: a dwarf_init() failure resulted in this using a static Dwarf_Error struct. And dwarf_dealloc did not deal properly with that. dwarf_alloc.c dwarf_alloc.h: these had DYNAMIC_CHUNK protected code which was never used. Deleted the unused code. Added a small comment (hopefully useful) to dwarf_alloc.h. And now deals correctly with a null dbg on DW_DLA_ERROR due to failed dwarf_init() call (or due to other error in calling libdwarf that results in libdwarf not knowing the dbg, a likely far more common case) and frees the memory. This used to result in chaos (depending on your luck...). 2000 Aug 23 davea@sgi.com libdwarf2.1.mm, ps. Failed to mention that dwarf_finish() has to be accompanied by elf_end() if dwarf_init() was used to initialize libdwarf to truly release all stuff. Added text to dwarf_finish() describing how to do that. 2000 April 14 davea@sgi.com dwarf_abbrev.c - 1.22 - When it is a null abbrev entry, return it correctly so it can be printed (meaning fill out all the return-parameters so the caller can do the right thing). dwarf_init_finish.c - 1.48 - For most sections, simply having an empty section (present but empty) is just fine. There is no reason to register an error in such a case. Copyright has changed. See LIBDWARFCOPYRIGHT and NEWS dwarfdump/print_die.c - 1.42 - Explain what combo checker is doing and make it more maintainable (and fix bug which would not be hit, but was real enough). dwarfdump/tag_tree.list - 1.2 - Add valid parent/child relationships so checker does not report valid entries as bogus. dwarf_form.c - 1.26 - Correct dwarf reader to use appropriate size, not de_length_size. This is part of the handling of the new dwarf2 64bit facilities. I overlooked this small aspect before in one place dwarf_query.c - 1.48 - Use correct size, not de_length_size. For offset size. libdwarf2.1.mm - 1.41 - Tried to make frame register output args meaning clearer libdwarf2.1.ps - 1.19 - Tried to make frame register output args meaning clearer pro_forms.c - 1.33 - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 spec. even if pointer size is 64 bits. pro_init.c - 1.18 - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 spec. even if pointer size is 64 bits. davea@sgi.com 2000 March 7 dwarf_line.c - 1.48 dwarf_line.h - 1.16 dwarf_print_lines.c - 1.10 dwarf_sort_line.c - 1.8 - Now handles opcode_base of line section to be other than that at compile time of libdwarf. Important as the dwarf2 committee is adding a new standard opcode davea@sgi.com 2000 Feb 24 pro_forms.c 1.31 ar_next field not always zeroed before. Could lead to infinite loop in the producer code. Now the field is always zeroed. Makefile.in - 1.3 Jason Merrill provided fix so gcc will work on libdwarf print_sections.c - 1.54 - casts to avoid warnings davea@sgi.com 1999 Dec 14 acconfig.h - 1.3 config.h.in - 1.5 configure - 1.4 configure.in - 1.5 - HAVE_DWARF2_99_EXTENSION HAVE_OLD_DWARF2_32BIT_OFFSET refinements added. CHANGES - 1.3 Makefile.base - 1.98 NEWS - 1.5 config.h - 1.4 config.h.in - 1.4 configure.in - 1.4 dwarf_alloc.c - 1.36 dwarf_arange.c - 1.19 dwarf_arange.h - 1.6 dwarf_die_deliv.c - 1.51 dwarf_frame.c - 1.62 dwarf_frame.h - 1.23 dwarf_funcs.c - 1.10 dwarf_funcs.h - 1.3 dwarf_global.c - 1.21 dwarf_global.h - 1.7 dwarf_init_finish.c - 1.45 dwarf_line.c - 1.44 dwarf_opaque.h - 1.52 dwarf_print_lines.c - 1.8 dwarf_query.c - 1.45 dwarf_types.c - 1.10 dwarf_types.h - 1.3 dwarf_util.c - 1.40 dwarf_util.h - 1.22 dwarf_vars.c - 1.11 dwarf_vars.h - 1.3 dwarf_weaks.c - 1.10 dwarf_weaks.h - 1.3 libdwarf2.1.mm - 1.40 libdwarf2.1.ps - 1.18 pro_arange.c - 1.15 pro_die.c - 1.23 pro_frame.c - 1.29 pro_init.c - 1.15 pro_macinfo.c - 1.7 pro_opaque.h - 1.14 pro_pubnames.c - 1.18 pro_reloc_stream.c - 1.5 pro_section.c - 1.70 pro_section.h - 1.16 pro_types.c - 1.12 - Allowing generation of correct dwarf2 with the 1999 64bit dwarf extension, and reading all forms of dwarf2 compatibly (all 32/64bit dwarf2 section forms). This adds the ability to consume and produce both sgi 64bit and the new dwarf2 committee-approved 64bit dwarf extension. As a result of the new dwarf2 stuff , a producer (compiler) can mix 32 and 64bit dwarf (for a 64bit object) and the linker will work seamlessly. (as long as section sizes don't get over 2GBytes). And the producer is easily configured to produce mips/sgi style 64bit dwarf or the new form of 64bit dwarf. This also eliminates a fair amount of rather silly duplicated code. davea@sgi.com 1999 Nov 4 pro_section.c - 1.69 - A pointer size entity had an offset-size value used at one place. davea@sgi.com 1999 Sep 30 dwarf_arange.c - 1.18 - Changed // comment to /* */. // failed to compile with C89 compiler... davea@sgi.com 1999 Sep 29 Changed all the producer code substantially to allow generating assembler code for the dwarf2 (rather similar to what gcc does) allowing symbolic relocations. MIPS output still generates the binary form. davea@sgi.com 1999 Aug 20 Stan Shebs (shebs@cygnus.com) pointed out that the pro_util.h use of R_MIPS* was a problem compiling on Sun. Since the producer code is not really used at present except for MIPS/sgi, I've added #ifndefs to pro_util.h which provide zero values when does not provide the macros. When anyone needs the producer code to actually *work* for non-MIPS something better will have to be done. This has no effect on those simply compiling libdwarf for use by dwarfdump. davea@sgi.com 1999 July 21 Changed the READ_UNALAGNED macro to call a function depending on endianness of the host and the object being read. So all the dwarf_* source changed in a trivial way. Added support for printing egcs eh_frame section. Added a local memcpy-like function to do the cross-endian thing where applicable (called by READ_UNALIGNED macro). Because the .eh_frame section after linking can have some zeroed out bytes at the end of the CIE/FDE data the code looking for CIEs and FDEs now assumes a zero CIE/FDE length means it has reached the end of the CIE/FDE data. davea@sgi.com 1999 June 14 Fred Fish fnf@ninemoons.com contributed autoconf'ing of the libdwarf and dwarfdump source. mips_extensions.* Documented additional old errors in the Dwarf Version 2 spec. The ChangeLog before this is incomplete. ------------------------------------------------------------- Since Oct 95 and before May, 1996 davea@sgi.com David Anderson Added the function dwarf_get_cie_of_fde() which makes it possible to remember a single fde/cie set out of a block usefully. Enhanced doc of dwarf_bitoffset() Added new function dwarf_global_formref() so all reference forms can be retrieved. Fixed bug in retrieving array bounds: was failing to sign extend formsdata. Added function dwarf_get_fde_info_for_all_regs(), which makes retrieval of the complete set of registers (as needed by debuggers and exception handlers) effectively N times faster than getting them one a time where N is the number of registers. Added support for exception table handling (really just support for a reference to an exception table for c++ exceptions). Fixed a bug where useless extra space (several megabytes) were malloc'ed for the abbreviations table by the libdwarf consumer code. ------------------------------------------------------------- June 10, 1999 Changelog started. ------------------------------------------------------------- libdwarf-20210528/libdwarf/dwgetopt.c0000664000175000017500000002630114004647055014276 00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). renamed to make it clear this is a private version. Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* This does not presently handle the option string leading + or leading - features. Such are not used by by libdwarfdump. Nor does it understand the GNU Env var POSIXLY_CORRECT . It does know of the leading ":" in the option string. See BADCH below. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include "dwgetopt.h" #define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a)) int dwopterr = 1, /* if error message should be printed */ dwoptind = 1, /* index into parent argv vector */ dwoptopt, /* character checked for validity */ dwoptreset; /* reset getopt */ char *dwoptarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING ONLY */ /* Use for testing dwgetopt only. Not a standard function. */ void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } #endif /* FOR DEBUGGING ONLY */ static const char *place = EMSG;/* option letter processing */ /* Post Condition: if return FALSE then *argerr is set false. */ static int dwoptnamematches( const struct dwoption *dwlopt, const char *iplace, const char **argloc, int *argerr) { const char *eq = 0; unsigned namelen = 0; unsigned arglen = 0; int d = 0; for (eq = iplace; *eq; ++eq) { if (*eq != '=') { continue; } /* Found =, arg should follow */ namelen = (eq - iplace); if (namelen != (unsigned)strlen(dwlopt->name)) { return FALSE; } eq++; arglen = strlen(eq); break; } if (namelen) { d = strncmp(iplace,dwlopt->name,namelen); if (d) { return FALSE; } if (dwlopt->has_arg == 0) { *argerr = TRUE; return TRUE; } if (arglen) { /* Discarding const, avoiding warning. Data is in user space, so this is ok. */ dwoptarg = (char *)eq; *argloc = (const char *)eq; } else { /* Has arg = but arg is empty. */ dwoptarg = 0; } return TRUE; } else { d = strcmp(iplace,dwlopt->name); if (d) { return FALSE; } if (dwlopt->has_arg == 1) { *argerr = TRUE; return TRUE; } dwoptarg = 0; return TRUE; } } /* dwgetopt_long A reimplementation of a portion of the getopt(3) GNU/Linux getopt_long(). See dwgetopt.h for more details. */ int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex) { char *lplace = 0; if (dwoptreset) { /* Not really supported. */ place = EMSG; return (-1); } if (*place) { int v = dwgetopt(nargc,nargv,ostr); return v; } /* Use local lplace in case we need to call getopt() just below. */ lplace = nargv[dwoptind]; if (dwoptind >= nargc || *lplace++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } if (*lplace != '-') { /* Notice place not disturbed. */ int v = dwgetopt(nargc,nargv,ostr); return v; } /* Starts with two dashes. Now we set the global place */ place = lplace+1; if (!*place) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } /* We think this is a longopt. */ { int lo_num = 0; for (;;lo_num++) { const struct dwoption *dwlopt = longopts +lo_num; const char * argloc = 0; int argerr = 0; int resmatch = 0; if (!dwlopt->name) { dwoptind++; (void)fprintf(stderr, "%s: invalid long option '--%s'\n", nargv[0]?nargv[0]:"", place); /* Leave longindex unchanged. */ place = EMSG; return (BADCH); } resmatch= dwoptnamematches(dwlopt,place, &argloc,&argerr); if (resmatch) { dwoptarg = 0; if (argloc) { /* Must drop const here. Ugh. */ dwoptarg = (char *)argloc; } } if (argerr) { /* resmatch == TRUE arg option missing if required, present but not allowed. GNU Behavior not well documented. Had to experiment. if argument-not-allowed, and we have one, do ??? If argument-required, then here GNU would take the next argv as the argument. we are not currently doing that. */ /**longindex = lo_num; */ if (dwlopt->has_arg) { /* Missing required arg, this does not match GNU getopt_long behavior of taking next argv as the arg value. and thus making getopt_long succeed. */ (void)fprintf(stderr, "%s: missing required long option " "argument '--%s'\n", nargv[0]?nargv[0]:"", place); } else { /* has arg but should not */ (void)fprintf(stderr, "%s: option '--%s' does not allow an argument\n", nargv[0]?nargv[0]:"", dwlopt->name); } dwoptind++; place = EMSG; return (BADCH); } if (resmatch) { *longindex = lo_num; place = EMSG; dwoptind++; return dwlopt->val; } } /* Can never get here */ place = EMSG; dwoptind++; return (-1); } } /* * getopt -- * Parse argc/argv argument vector. * a: means * -afoo * -a foo * and 'foo' is returned in dwoptarg * b:: means * -b * and dwoptarg is null * -bother * and dwoptarg is 'other' */ int dwgetopt(int nargc, char * const nargv[], const char *ostr) { char *oli; /* option letter list index */ if (dwoptreset || *place == 0) { /* update scanning pointer */ dwoptreset = 0; place = nargv[dwoptind]; if (dwoptind >= nargc || *place++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } dwoptopt = *place++; if (dwoptopt == '-' && *place == 0) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } if (dwoptopt == 0) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ place = EMSG; if (strchr(ostr, '-') == NULL) { return -1; } dwoptopt = '-'; } } else { dwoptopt = *place++; } /* See if option letter is one the caller wanted... */ if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) { if (*place == 0) { ++dwoptind; } if (dwopterr && *ostr != ':') { (void)fprintf(stderr, "%s: invalid option -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ dwoptarg = NULL; if (*place == 0) { ++dwoptind; } } else { int reqnextarg = 1; if (oli[1] && (oli[2] == ':')) { /* Pair of :: means special treatment of dwoptarg */ reqnextarg = 0; } /* Option-argument is either the rest of this argument or the entire next argument. */ if (*place ) { /* Whether : or :: */ dwoptarg = STRIP_OFF_CONSTNESS(place); } else if (reqnextarg) { /* ! *place */ if (nargc > (++dwoptind)) { dwoptarg = nargv[dwoptind]; } else { place=EMSG; /* Next arg required, but is missing */ if (*ostr == ':') { /* Leading : in ostr calls for BADARG return. */ return (BADARG); } if (dwopterr) { (void)fprintf(stderr, "%s: option requires an argument. -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } } else { /* ! *place */ /* The key part of :: treatment. */ dwoptarg = NULL; } place = EMSG; ++dwoptind; } return (dwoptopt); /* return option letter */ } libdwarf-20210528/libdwarf/libdwarf2.1.pdf0000664000175000017500000223771514047776064015034 00000000000000%PDF-1.4 %Çì¢ %%Invocation: path/gs -P- -dSAFER -dCompatibilityLevel=1.4 -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=? -sOutputFile=? -P- -dSAFER -dCompatibilityLevel=1.4 ? 5 0 obj <> stream xœ•XÛrÛ8}×W ò2Ô–…¯»Ož8ÉhÊ“xm¥R)g(’¸C‘’²âýú= ð&ljwË®rB¾œ>}À¿˜Ësé§û»9Ì^߆l×Ì\¶›ý5æ%ëþlì×ÕLqŸ­6X1á±Õvf· &üˆ+O² x Øê0s.ßÌWÿ†-¬—Ї"ÀÂU:sÊ¢9tÍ®³uÔlY´ºÞ&ÍÚ’]Ñž…àADûDsÉnãçËѠ䞌D÷âö½x} W…"¯Âwy+¶’VÜ;WÉC–²Ë"Õõ<æqì…žÓ”Åü_«ß'Ñ,D¨à~ÌQ@ûL¸§™#8[~XÝÒ)¾änäö'¼úôfµüø¡;_2ü’~ÕBšu.WQD–îÕ>kXZn‚¢e©n6u¶Ö K –™DÌ…Ë]WŽÍHç!…fL $X^w~ž­ÓS‚M8_ÙC6SG<¤aôö"ɇ Šˆ{*ŽØà_hýëŠRnÙöXlÚ Õ¢ºTu9y2©Y²Ùè¦1Þ-¤ïsylAYLg‚ËÀ¤mROÏ3e<þ¾˜pÅ÷»"ߣ˜ÈÊz.‘áyÎq·ËŠr³-ëCBþ°ZoÊ:m.`Üß[‘Tx??€ìçY¡Yq<¬Â‰á‹'Þ ß¦_¶g6y"äJNrø;IšÖÈ«“b‡´)Ûåå:ÉY‘P÷³óO:ùó¹çç~©PþÏý"<ãÞÖ°il¨È"ÂÞMÉU`WY$V&Á?ˉ²ÿ—7-öoÙ¨¾³æ©—+v?1÷0—>ºÃNRgÉ:'“H©ÅPÐæ…Òlï‚t®>O ‹Xv–]ù%Ì·•ž†Í­›Ý⮋Òt1šX=¼O–—À(ý{uÊZ¼õ©È¾Yr+ŒM”ü¦.w(Å} <“nè(rôÕBÛ9w•ÞdØ`¶ë¦eïëòX½b_›ë»åû¯ó v$.c§}ÙUǦÊÐæà«ù/¬ 9PïOêµ)áVÛjÍN´­$•ß7kÒXŒƒv‘üã±–5(qˆ;—¸ˆcÁç‹ @GÂy&¯p Ñ0\€q–fÍe„…¬01À‚Û˜f)J“\ÐvWca8ÎÑߦDpáuDædMÛtų{êö„‘àEà‰ÿ'?ÕqgÍÎ>3ly/š’ì÷cþÈdxAaªÎ[к½å±§ŒÇK›C–v9iÏæeˆÞçmgÓ‘òÕ9í³ÍÞ,Ý/,ô‰ôDÀ#¿O߃½ž¦µîê¡þA_—Gžo믋´¬^ æ9bŒ  <Ž©®EÙÒéÖ±²fIE3嬨ғ\јt;ë@ø3‡G¾S<²Êìs­ÿ8¬êÄ£¤_ó¤s3¯qDãõë0$KB…#(8¯§HggòíÉ&(D=1É܃¶Ã;úgOÂ&+’GÂíŒ,@lvÊl·,=ry…«clyfÇü)k÷ì]­õ] ˜'˜ø¼¬-YB—ÅÝÔð‡};ˆ´Â!¤Ày m2Ýh˜Ï™U\†&…r©†øÓ CLŽ6› Oݰ/²k-/€¼ñŸç:+Žß˜‘ Âõyßltžmr"M;vh}.SŒ0¦6èËùÃA6˜º<«lZ—U¥S;ù1i~EX_³L»íN•–¡ô†¨œíX²»àüÞ+åÙChÐ#nvÙœ„ˆÇN!Ç^V.÷G2FÝ ¿aü%=ãÞS3 „aöµ€nÚôé¡¿ÂU½³»Ó˜;$u O¯›¬Õ]ùâ¬ç¹OÈÈæ«}ÛVýút2¦Pš@õð½wxjFZ<ºC¡ù!Ð?m¿™»W S“mŽuML>¸ømºLfÿ±¨¨9•%R!˜µÍ´]×Éh`fgSVÒ&Z¼F{?Kh(×Ù¶cÞ¡©”:ÓDHsï·w›áŠ„JútqXHïüŠ$Ø›²z¬³Ý¾}r"öº¶–W»w°¬»äÇ®7ƒ$ú’¯$¾®dÚ€Í+;âH:ï!Iglgot}ÈšÆh݆í!±ÀÃPf`唯¥ï¢ðºé5ºM3HS3TSד,š{¥èÌ5…vt§hæI«¡ZÛ±!Êø9Ûɤ3ÀôpÏsºŸ)Ûâʇê{(HiÁFZ[FZ²Î¬"×s3QCßù¶ÑÆó>i¡'uÑ+šß‡²ÖôdÍ!ÁÉÉtÕZ´žÞYyqRå:¡€7¥Ñí Oç”ë÷ gËlòÑÝÏ Õså3?»²?îüB1‰»¤À ²u徬´ JÉÎ~éaöË ž«lÊÊcžb4RͶÇü‚Yƒ®¯`}^®~ûøiÅ.?|9¿ƒ.zs}'þpß^~X}±sÇ Þ²Kv3G'!>FØÜ·wgµ|óéúò–Ý|º½ùx÷–?ù\£ F’ìæX£q½€Ç¢ïDKh•¹&^wèmýôsM¿¡ÓY(f †êX›ÝO[ް®µø 4Ÿ~<±ßJžÞâ㈇áË7³É×…Q¿Ð‚˜Çƒ‚‚š l&¾ÿfb„:.ãB¥Í´AÄ1MÆÍD+ë–™kzf0…Ò}Í0wŠZãÝ]Ùî}†"c,·‘÷zœB@á0¯ÔÛÓ2a.3<ù#ÁýÈ•b2ÃH‘ Â̰`añv5û'~þ ¤bwõendstream endobj 6 0 obj 2277 endobj 17 0 obj <> stream xœYÛ’Û6}×W æe9)‰!^½ž$ž]»²k«Öã-EBŠTHj”É×ïiÜDií85®Ò EݧOwŸ†cQÈYD?ö³:,¾Ÿ±Ý¸ˆØnñÛ‚ë/™ý¨ìïë…dë oqÁðo½]˜•œ‰L„2f™LÙú°x Vü^$Q­îÿ»þöꕈdE1[%x©^ÈP¤[ŸA¿eÓ^Š ªê‡zdåˆ=4ãxRø{P¬¬ëA£ªÙ¨ŽåPNª}aŸ‚Q)v÷ŠýkèëS¥ö¶Ù åðr¿þeÁc¶~KgŸëïž‚ÇnRÃö¾‹"‹’ ¬›zö  \ñ0ŽÉÈ4 y’ð _Ñ>Úzž‡I"ìó÷?Þ}ºé»U‡Y”ålïé«WuÝLMß•m«ÈBe´AR„y!ÜËé²³ÄÙÒ<ÍÛg ¸WlÛW§‘itš‘Õøë º  \l{ê*skŒk< #ÎsrmÉÊ®&ÇSµ_3J V\›ª šÃ±U´mI{ÑŠ³j[úìSshþ0Ïg Ã:ç"kv]?¨ZƒñýûœÑÞÛNô2Lô<”ìÁZÿ·E^„±t@¼iÆ©7ñQ~ï•}ä±ðÎ#e܆*2k 8ÓY‡ZÆE@N ͳY¹éOãEÁÙyßT{¶/A(øÙ–kËú–³ˆnRò07§Hw A<†ì£ÙUÇY$rn½Úh‡V1¬¶hós®—UÈÙvèì ‚÷ºŽý a^²õ¾œ.‘®ÕX Íœ/Ykˆ R È“²nºÈK§8îJ`•eÙ7¹Ë sáJ(Eáé€tÔÔ Ö WyB  hA…E"=Þ"µxŸ&Øw,H¾ª?6` ÒŠZõ‡á£Ø¹™öæQ«Ê¬Q÷EäyahÉÓt”Ò§üRT½Ž‰!Y!è,ŽDH“x¯×®vªy¼däj讼XÃ5kôó§ ³µeÉ6÷‚Åàk\悲”¹€é2Í”… é˜Ä뵕 ¢LŸ1ÎÓJ'ÍMÆð8 cñÍ„&_`¾‰ƒ@„QbðüÐA7¹ˆ¯yœÿùÖOØ›=ëTàQ¨a¤R‹Í: ŽñT ]³ ñgþ޼T]¥Ð†c3ÔÃÜîì{ ,çK2Œh›ºÆŸî ˜²{Àlòe,7ÐðÖað¬O ã… äÅ9äÙ¬•EqìŠài: Ê–š ­Ç³'0‹02—ÎbžÞ?7ƒî{ט¦"LEúípÑóÜl§Mʸ…/gkÐŽ…tq@Ç›·Ô/Ôê‹Èºj_v;]`(yb‚ïÔ5¨É´{£$Nž&<7!ðèL¦Q 34 :á>p<7<Þ¡ž¢yãäqUõµ²ZGCÂàóýã燷ºb1u>ýçóÏÿdjª>Ý/ÙNujÐýzÛ·m/b$/‚3xnL ŽŠ‹éq.­éTøTWë„É{]Í÷å8±©™Z`r÷¬zaïÊjßtŠY½E†ql%3çal=$Tï(ÌwÔGÉ’}ÛÔ¦–Ú%WZå5`¸ƒ²a›¾ÿ•m^Øƒà…´“B¸’@b”¥Ø;wxž;>˜]ËÝ©ÞãiÓ6ãž`ëwM5ôc¿ -+÷. qNµX‰Øt§ubö ´ÛÔh¤×’¶ÔÖ`™Þ*÷º“:çç^;FT²tj¿Bù¨ÕÆt“”§ÝÎvâ£ÑmHýZò§àáñÊwj»-˜H‰`GUUçÛ|å±E|ˆè–ÖÖ—“):p °RG™« ! ;í>g_r^¦Ô§\…H(†`£ª ³€<ü¦E1D¤¡ û;*VÛt¿–;Å46©“ jiI&j%õ3S·8Çõìî—׺-´ÄÎîtØ€ºŸ¥i©Š²Í‰¬ñå°+6ö§¡R«öšk2`~vU ¥9ô¦@¶3ÍŠË…OQe:_”I;#VSEBC…ﶉa×{µ¥|3úªÅ 4NìΚ;íY¬‹$t¥xÎ%´¼4ò\JÐAigâÒƒÚXÞJ÷ìÒ8Ünše3®è’[à_…õW}ÂÕE¦NwÛ9:qœºSHŸÏgmZ[áQ k-ò"†@¶ãT‡P Zª»Ã’ ’Ͱ»jPNFµèB]˜ÑÔ²»<ÌñJSÇXS1úAÍd‰ÖèGƒd-­ŒÐv;Ø"(J¬Ðžue‰ 2Öö"ÏèY_›r"8)km’Î…«.Ê_¥BÄ/cíרpC‚‹ÚÿK,°½ZèÂ_ t#߃ûy˜/ƒ[àˆB"¨¸%Š˜åù²*‡L.Z‡¦ 52±”ËØ”Œ$¼_a½-xœ UØm;!¦kT8#¹Øí <± ²¿·õ/ªYr£íÊ#¦H”Ç® Õé<‘@ל4‰†|§ÏgŠ8¥9ÀÁÁâ@@~o;Í.¶nOíÿw¡ÈÌÇèûW](a?k¼bA®û‚3èÌI…€ÌRgmàU2oÛùqpP‡DCÀ}¥¾½–0Édñy Ü誱µ#›ŸË|öê;g…k$> stream xœXÛrÛÈ}çWLž n–0fpÏ›"ǧ¼•DVâiKC+ q­¿ÏéžÁ…´½›òÖÚE`¦o§OŸÆá¹RxôÇþWoïb±ïVžØ¯¾¬$?ö¯ü(þz¿òÅ}Ž·¤øï~·2'¥P±rý@Ä~$î«g#×*ôœd³þõþ¸§6Êó]Ï Ä&ÄK^:fÏe½ýA‹6Ãÿ[QeíZ&®'£ÈÙkÑé^4;±ê¼/›ZäYUuBg]‰wûF u¡Û®ÏêÂe; †>®LÅýyuÿÓƒóŸºÒ]'ºþ\v¸ó¤ór·V¬øSêâgk'#Àu¢ëÛ!ï‡Vw¢;4CUˆ­}ö¼NÝ4•AäèZd~¤ Ý•ûZìƒ Ø‡Ñþ®iÅ;½]KLgØïáz3î_º­<5»GNÆci í¹u¯ÛÝZ’ïAêd¹¦ôô‡²U¹m³öUàŸ%ÞBb ʼ:üsû /·lÍW±ë%ʆ"ø0ê“Qc¡s,¯ï[E¨U'æ­§œ-{iB–ù®Ÿ"Û »XI7Jø6ò¨¡{”tc™¦æ缩øö N% <ö”oÍ8/ü0àKò•”¸z|T=:ôŒ‘$âWrô-¯ÔÁg8èdíîq-¶¦Â2p†^tÃé„Rv¨fÙ¶º²Î{.ÃY&ž¥ÑèC6Û!çkÇ©{¤°ÏÊÊ]:J×P7óÎM1NÑÁx¹Çº0‰ÓÑqSÔs ôXq9ìôÍ®ŸºsrÑaž¤ì>8Ù¶kÚ-ãèš#õÊ_ÄÛgm?œÉözÆŒLìõx[2}_A­¨Ñd{×Ç®˜œ,èµ q›9_s}êÉb­5zpzô rn`xJ²©4J‰¾Œ.*íóíW•®ûe¡ý4š }@Óq8§¶ÙfÛêÕÆEm\61M‡Ä+eQŽñùÑA϶úË »N?ö´ï”̰ˇáˆ0"[3÷Ñ?…%K?¡Q"²€ÁO¼è’ÒÞ¬åÓˆó‘zÎöæÜ–=OÔ[R-äxÌ °±yöEš­f„Û;a ý‚|‚k—²Ð6<Æáàš>j ­óØtÀä4B&¦1ßò»¨‰þ^îW|¢L‘’W´Í‡~‡0Pgüc>8À.©¿Kmi&JÿÓÙrdxÞhƒ¢3ê&ÏI>:Àli’ÕjNUÆÆ¯MS¿zÉ·Qûßš.—Q{Óƒg¡˜Â˜¢ýÓãÚµs=d’tî9ª7ÿÕ6û6;BtùfQvtËq[B-Ûá%1òÆó&LË?[š"•ÑDewª²WÁªÇ„h‚ðCw.ëïhžeÇ0zL úPޱš[P–/utUÖzd¸VÂl;d“8{á\R_ª*šCð®“OV-Yuw#Ž”6mØ õ#õM@‹6¼jdý¤ü"³“@çhı?Þ}¾ æ©[œ›»÷ë˜zÓíTÝŒolüåD¦F:–]®«*«u3L=±Šþoœ>3;A,ëV«øò÷ãwÚ¿0µê¶¥&B¾’y‘qj=щÑI3GGwMÎä(çL9‚7™Ø¶¥Þ ÒTw+.r˜Ø“†®§Ã’¥ÇL–»¶9Ž:¤XhZ<*Úl×_oHf="¾ç\Q“äûÑ\x Áðßµ$°Bû[ä¥dĵ:‡×£¯¦RoïAVw«M‚æl$A†¬¡ Ň^™¦#øâè–ïaq·X{7ö²36N”IêMA›×˜ű?íuÿDs÷éöãͧOOuvÔŽ¢ãÞ6ÐrBã”Ç*@]'ò Ý/^Œ˜`jKŸUƒéçñçÁ¸h7€Ù8ž´Fãºç¸j‘PËœ÷zÛä–Pi†|pŠ1RÁUŒ´ÓF>—þ©ÐySè§Jo¥J8:ª^â’§ ½*¦‹,[ÍÇ̽<}™›–“cD£¹k)ƒÑRÌï@^7iàÍ4ô/;ˆað—gaçÍ ¼M¥'÷ŽYÞ6OØ×{Îv"éÛÂ8’¾öO}ÓgÜ®÷ýÝÞê<ƒ¿ü©‚¼nvÆiðLN| Ýn²—@–¦0ó¿öOÛ×'œçâ¼Z KÔháFrìW›¯£¦¥3r0¼–£¡9‡Òƒ]ÕXç¼X¸b~ÅüNmÌQÿ7'î äÞŸðgƒ@êYÛAg”QH$ãI0+Bwy[žFváäK¬á$ )-]›súa/JÆà!-ÌÎVéŽC¯³¥ðƒœô˜y9F×.)ÄŸ<8zWa£eÔ`Lbh@'iâìt«ëœ…+¯žg)Ó+øÑp´B{§q2ïI`6º­îÏ{êå‚ú®œ¤°Z0]r÷>d½IQAJ%á¤åÇ7ó¹lvï…á!@/½¾Îð#”èÎfÓjóÍ•CÇß²X^@þøóZò£RÌ(ÒSV»S`ÙOTx½«6ù0­´h(²Oæ«‚ˆ0¥~§l¯…”ñ4c^Ö’Ê’(Ũ¡©œ¾–™ž•Ç¥„ÊÛÜWKJšú·YWæ‹W ï\ ¯iÏùÞ'¾I‘')9jòüÖþ€}i(«bSâöî±ÄèóÈûâÛŸs[e- øf¥bðÄ\o/¶^Ò÷<^£{9ŸŸÞ}¼ýÉé)7‰£ù˜©)ÂÏj*-'œ2ÀÀÞšJË–Èx„Ìt°Ý¹†)ëV0} œ/gI`¿d¾mMÏOÚ{¯UΑÏöC7ñË‹?·A¸œEP–¿ü’™i4ŸŽ‘¾xҗߘÿv¿ú7þüI^0Yendstream endobj 25 0 obj 2552 endobj 29 0 obj <> stream xœYÛrÛF}çWÌ›À”ˆÌƒKòä]Û[•Jœ]­vý`m¡@r(a  Š’¿~»{.)EÞ²+rÈ™žžîÓ§Oþ`<Œã÷s³_üx“±ûaÁÙýâ… /™û±Ù³¿Ü.»ÝÀ*!ü½Ý-ìNÁd&c•°L¥ìv¿ø­ÄRj«ån{°k%¹Š9OØJâíBÆZæìö«7Õ`Øû¥âÑçòý¯-o>¼{Ïê}3}ǪvkÿŒ†umóÌö¦jëö~wlØ#¡”Ž%ØãÞt¦£ª96vìP «ÈÀòö¿‹•_¾‰Ý ³ÌúrUm6f®XÕ/EÝ÷¦Y·cÛÓ²ˆ‹ŒÕh¶1EYfiÌÓÔG™“ wÑ?Ía4û5„Eæ×LrÉï–¸^r “‚pqû×èÝvk¶zÁ)ê÷f,ûª½7C¹¾‹ð¸ü¨!EÃP£_ï)¦+' z.§!DŸßMWÊc­]„¾D76K´R„ëUìoŸþÅŒM•Ìb‘9cO£iH£u¥ò ¢w~]wËÀm‚Én)$B&QÝV  j)“¸(DíC(ÃUö‚ñr¥9? —à!\èK+.C¤3Æy_ÀÍL H!TÝ—"IéKÓÌlª¦AÈÙð+侌Cø\˜’8MeñѰŠ. ë$­Sq–å9Í©šâœÅ<Ï oAqkáÙA»Z7T¢½}ël*BãJ È"luÞž2U!{@Ë¢°¡üwùáæ†.¡Í¢p'óXöäßoØ©XÅÞŸÐ^&p™˜–IË¡}Ewèêv„ø[c×ÅÎÓÂÕ!\L&~„5ñÙ°p# °N…ˆ…;©;±c¸²W\zsØB]Q†«íc½q4¦eœ«¨s©-ê€d¶êîJt2Ôã‘èšÛz÷<ûPgB`S¯©Þ€ÌÁ„ â1ðóLŸa²¸žQXäÐyåjYB­„Þ":» ª¥Á×Yµ54˜L~Ÿ>5 55£ó‚ªÑ¹Œý¸r´ín%S«¼¸ì <¡<ÇýŒG¹Hµ"E%”@K 5vg÷HypÈwXêš¾5gHÁ\+tí¾=–‡ãz|†ÞE‰Ÿ\×b¶ ­öÆõêJšsáÿ9çIHîªÛ­í@KÀø.¾poIxݧòœ¢\n‰… &ZúŽmMy3ø­Šs®üµŸJ,î¦Ûø½E¬Uâ¯þ  çÐtžÊ5ìùŠ‡Ú»(Îã<»ìXo\èÂR 9íŸé.}Å”=Û¢Û3ÄS3ûáf¡áôD¼L%d(Éy@ý<“PÝÍ,ìO%·L ißšzM`ÅÜO.LT‘€ëž—,Æò¶w))%×–]9ˆZÐ…¾û8# –ïuR€§NÅÎìáá”ß’¨k ›—­ùÅÚ¯b» èDŒ;ì ”u´Æ6"h1fiŸÊ‘ |kñûË(N¤êL?Vu{Á‚§P±êmàD0hÙ %Ü*ûÙf¡ ?~atjæe;ÑR·qá`új„¦°‚¬Ÿ‘ÜJAÊ&™™§É،ㄌҨö‡ÆÑmšúb¤ŸËßÿ^¢hK$”K;Àü„0²x¿ŸùuÂ>¼%ǰ4Ï„и‹•Ý¡|t:h¿pñ(â¬Hüb!3ª<¡Èbº[¥~é—( è`GJ2×ytÂ,5ݹ7‡®ñš–z±¶¦ØùJBNœ„IÃ\ñ¢–P)tÐok/i¤…†*@ƒ„¦ÓÍ“‘BŽšGrƒÂèÅT—À_J³ºl:€°?yV‘ å¹Ðß 5Uujì  À;/«A-=yId´iÌÌ¥Ànòÿ8ƒB™3$ô—¢ôç¸ÔA"…Ëyv²¼ì!XÁy‰šœ‡FyZOÚÄ@⯭‚µ“§9UÞX !u·NP"CjyÞ™§±ƒZ2ˆ:¥.9]Û¡?#xÔ+¤c@V¨WÛóDê4‰q׃ð"Ü~@Óõ-Š¥‚2«©þ 8Vç©WàBÙfþÕÃp4¾¬–CNÔw¤ rmJÏ(ñß,øŸ4¥ £¿íàRÙ¯àXMÃÏÑÓÇp®’ ±óëi`ùmˆÙ§ 3™¦îô"ÐhÅ7‡¹?óˆß›˜¬aÇÁüdGu Sr’ÿ˜ñ&%lÜ—õ0I›ÀÉ‚Ðí«æÉ¼NÈ 6tnko;¯9¡t,‚p c¾Ë¿ì.`£6Ív(+[ˆ–Ô`‚“™|«K¦0Hé©OãtRc‚»¾œ‘]vL+?9gMCà¡x¸”/3\/µö ?KD5Íq2´y ¬<‘îù C&ñ‰ipLN3È¥”ÊÅ’«U«Jb{õ¡½¶ˆdý¾Y8ݦ7xÍm ¼¦Þæ5'Ü ’æÄæóe›Ûë8p„è8w˜±äÉ[ù/×Ò “æ†_ÓiXhš’ú3X¾pgnÁ£RÍÅõk^á#†Î_õª·­d@3t¶IêXzÅH = ã´W´ç“×°Ô9=v™âœ\‡Ae}6•úBØÖó9SiþÖÁëYཡ/ÛšHPžå¯Z0ëÝ"gû%ÐFFãÇáCßÙt¤:z¬·†¡[ Õθ—-’61pÌôöë‡{R5 fSïì<­»†q«+2<=ÏýVÁÄþ0ÇA+û7‡ÏÕÈ,¥ :9ùéízÿ ÿ…ô]…—Æ´÷ãC9ÔßÌôŽWžc\¼è#•áGÛãþ€/ºÕf<’Ur,œ=„èDy§:´Â\õ !íóã]”0 ¤œ‘ü?{DÅÉ)ËÅÛ­NÿËku«@|þJIžÝh+v’8)nû~ÞIˆAÅV뺩Çgç5èöª… we[ŠÀ7D'=g!µ¨…ÊT‰>W9UoØÚ>lwí™Ãi‹4Ì©¯w·¨Íöš~ÇPï ƒAa_Ã5"óªÛYŸ cîfV?g’[(ÂHpáåÞ °ù+ùJæPÛÀ§+é÷ÝàkåXå¸ ±Ÿoð I‡ˆ E&G eKÁQÁÈÊž¥J[»¦º·otõæÁM Nâž ÇßâVnìH¬qè„à»ÖãwÝRå".¤ŽvÍô«"™TæWQ`©„×ʱ~ÁIˇÇO‘X¥Cµø¾>«è±¯6_1¹˜úî,Ã"qâÀ…ânæ8O¥öŠsíZ<>ñóó±H!ÿ(—•‘Ë­ØÊ&|˜Ÿ’ó L¿±¯Š6Æøû7xÀÀˆÊ’î´í06S´j6eÏñb‰Á'–¹¤˜vëYhyç¿Äûp»øüùë)£×endstream endobj 30 0 obj 2917 endobj 34 0 obj <> stream xœ…YkÛÆý®_1ßBÞ1çÁW¾%µS´¨4–QÞBàR#‰±D*$eyûë{î¼È]Û)lÀ^‰3¼ÏsνûK¹`)ýñÿ6çÕËß vW);¬þX û%óÿ4göÓf¥Ø¦ÁSB2üÝìWî¤`²\iV¨œmΫÉ\Ë,MÒ»õ6Ç}8u'SÅÓT³» íV8ls[%ƒ©O§Gv®§É #»µÓ‘Úº›Ø«õæ÷ÕàZÓ B¼Èñ>œNþõ#}go%Ï2é>§[KºõCòÛÏl4ÍÔöÝx¿æë»¼*¸’*Ù Ûõk©yUVerëÆvgX¿gÓuèÚî€ÿZ«3wU³’BsÞ»Ÿæ÷J^øOqåþTX;Z‹U©8BÂ¯ñCælj`ÌõlÖôxçù:N0…Á}6‘U·u£2•%õ°ßî(.}sŸÜ¯YƒÿެFs‚¡8bM¼K¹´¡Q*å….½5ŸúÙF¥>8I»cgsî‡Gv2õÇ‘;cµäYZcS›“ûäM=4G&ô &S™Þ¯éY¤xó•æe)ìSé‡!6;g~ßÀ·nª)æPøó²SqUx è¨t¡°¶¦«Ïæö·‰ÝÖ"E}¨"©GÖ™àŸ(]¨/³èŸ!c w—õQD߇zö½à2Í*ÿÅå2ô—¡­'Cñ»ŽÆ;/xVêà|“ñ1ži-ÜIÁ•r…ºH ƒ‡äó8 T2—¾íP¼l0TDˆÇ]#…â…*çkr{Íubï/lj‘õÎfJ»¯šU.y*9¹-*-ÇÑ“c;ÆX³±FRÇ+RU;‡Òœ£¯–ÉDÙQ…¹‹TQ€óǵÌ}‘¥é×ÒMñ—)å;yÛSSÄDXk`o¢ó!¹ÝÖeQrf‰ÙÍý®+ò]¹§ wλf@"ŽõÄÚ=‚i(##sá·HQéùè¢dÚ®lGôCè—JËøÕöÁéêGæUþçéM«g÷o/õt´÷X)Ïûkg¡„ÞiëÈAÌ´EKúíº~¢d4%€(OÖK¤«ëÙ©ïÆ› fÕí®/ŠùñõÓð¥á³ $uwŸì‡þÌNí³¦ w¥ó‹>í(JY¬5×Qéœp¹Ì©(Då0àN¢¯.¤{ä­q%œæ®Ï+kx¿t ¢ŠAÏ¥k†9®x2Ó<Ÿ[Ö¸»¢çl;å)Ь¦]§¶ûhOùÄzRæÑˆfIi¦ªPº8HŒCxŠœ#Û¯%%WȤ5§Ýèòÿ×·ï×çKKûºU Ìä¢på݀̀0u·£‚¦›ÉJüÌÞÌ€–q}ùüð7ש~8Ùký ³K=ÐõÏxQd<µñ-b$#/R@ƒ£×à Ì4Q_ö¿Ñ™£@¡s´Od“qŒ¡©Rùœ1Þ™ËdlÅT®`^°ëeW=üÒL½-¥XF›ï?$¾Km3í1_g)›³*½ÙŸ§msÝM½3Ãvgó~ŸPœ©={ê4fêáÔâßOk4XU¥2Aˆÿ-»6q¦s} ÝÅ ÷ª^v¿ÕËàUEJ1V˜?îWE¨fëâ9 —òp߸Ûv.h)K³4‚ew9ÕÕulç=À­³5!$Q|êÄÆ ·M¥IꤑWÃmûÑLÜw¸­Êu9㜊4vl/ÇÊÀAöëfUdP •øj@Ò2"†ȳ8Œp¢sN³èr㨠ÀYÌ`Œ7"¼NTmáõ™:çeˆtÛœjte=ØWTu‘PÂáƒå“‘³÷Ý -LOVŠgbÿäce·8^Y’‚„+ÎŽÑ[%y©ª6{ß½NnUÀ¸< ^ïÛxŠî §íK s&(\h%üÇÅTxp{êƒfyв…!cÄ"€K”;À£{ ŠÔtì:.^Í›Ér¾k.b'›(_rN •óØî›£W³yËóY#¸%0“^h_©H¶XxÔ¹Ò¹špE2Ÿ¦& ¼™ïžá#4·ÎÃaíØ'ã„•k4d# J÷»@µñb(¨*žÍ½ü-“ HQs ˆmÛ"¯ˆô].n@_É2Tô­™~z÷ Ó : >@Óôf0bŽ¢çp¼jœÕ~×8Mr/¦i# ¥ÁH;gž…ÎJéŠÔœÍˆlYÉ}‡¸tß ñ€“?Bùž,‡B†Š*ø!勱ã ÒôÄŽè*?ImæÙD+eñ2c–b„ÂÏ´XøÞcLÐzäUî^äO+ó—ÜvKÝ^Å‘Å\ Ë!NOY¡®(¨\cð‡e^¥Òá +umV©Ô|Þ©Lð\˃ʄéüh}rrêé˜#„’÷£ jP¨ò+âÑ)T›–ØŸG ÖR<œ.Jm7Nà7ÿmãîYoÀ »Ìõ%DÆ‚ÙäÒÝÛõݳuL„éæÍæhš#£‚)%Ñ-%ítE­b6¤@õC=Q‚¨·Î{î²l&ÔæèÅ ¢´c :ÕîõBÉzŽé øÀÞÝÔ$ó×’³ Z¨Ê“w-ƒk¾K?L–¶éÍþZ4ˆ/¸¤‚æµsfFŠL-¤ãK‡¨ q A3”ÇÓÝõ|ñe9‘[5ÔÍ0ù~@×Na&!éæ5;ÀZH›$VÐ[ç* ó­•%AL jVPˆ?ir†E^å®fK.‚h½#«ÉÔÍÍÓ<’9)¾*•ûëé©•£õ”«-ñ>xœ(¤øÔéÇ éXú>´Ý³éèûÚÇå‹\Žâ˜¬í«!ãÇþ:4LnCÜ¡ì¨Ê3¶á™î×|q‡kIÿ|\›(§Y;‚ÜÁ\­ÝÙÑ»&œ?ú¡ŽgËh3*Ì}Cèž2òè®Ç]äÙx쯧¯5~6ˆÝÁÍ8þ|°Äž>›šöCˆõH­2…RÓ%¤†ï"¦–îªw;Ccûž›äÞ›ºùåÛ½û÷ŸHg䯯ç""¿J¤L…r.¥ (êʺ3 ¢ƒŽª Tíí2ÆùäÎ>åŸ8×Z ¡X%ªäFä(,€’¨¿öcûùåû®ýÌö;¸: þû8lþ½î®õðäþ¼JVê.µO5H™•Nê"ÙÛŠ,OHF†±[äŽ^†á<¶ÛîJ‡…ϱwüh…'Q©-‹|ösÌç àJŽ5Pcàñ˜EÁ‹4*³T¥Tq£ýd2 =úÍOT•¦ýή·¸âÜÊ3 8“¯¼ ?^ÓY;\žÎK”*³ùé>#›p „zµhêpËá©Ë1d¥œ%¶›Ì~§5#M öe.`V X)›«ûâå÷Ér» Ó·¾‚tµ£p³]é \¤Äúó2 î³ô›¢äöfޤ‚¢ÌçŘö|Øïz×3•pÕMãiÝÚõ¬W…²!´8G8bå‡G_N‹ba~HlÌÍnýâgÌO¼ÐÿgpƼ‡^%õb~Sv©›XÀÝÑ«ö´û ¢DÇÇ<çp¶¡¥=XB”G‹‰”üüçÏ74a ¼õKKsLÐa¡qq*’jêØ·è‚ËxdEŒ‡&¢û¤ÅLšd¢Ã⊪oá®ðÛzÔ5.f·cÛÙǶ³Èà1Êë3í†u´ÏQÁìÇ…j&Æ× Ý ¡ òk‘‚퀷Ï.ý“ S)ƒ/QQ×fì"Æ“ƒ W,œæGÞv?x·ñy±ó|GñDà½AL%OÆ[Ò’*s¶ ÌÖé¦~˜Ï†,Øu't·žÍùâÐÞ®;ü¶ž6úâ‹ÝK\°èe{ÐÍÝÛ¢.(b0{”`G ‰¸xHJµsñ缺ý墨±~¶2Ä\­³8“œ¿:”å¼sò/NŒ!à:DZÑÞ§5/ õd©Ü‰§k0$¡^+».’qšWÌ2_l ?$„ñã4\›éétôü— ¥àe¬ù?yo24OÐpžøí’oç×:’çå¢O¤r¤Lä¸ gJFo¿1@êx¼= Y´°‹Ñ 6‡šÐ`Ÿ}>‚>kˆ³e_¬\‹2¬ âN{¿3(ö}OK™­ƒ+Z3qSvPah™A¿N°)ó+úÕ£U¾ì-WºB. ¡'jþÍ€š•oö4®6?©€ÊBÇ㼃~q!æ=:AHhÊç¿|½Yýþ> stream xœ•YÛŽÛF}×WôÛr#†ÍnÞöÍYÇ‹ ÖqÖ™À3 "{$Æ©”åÉ×奄‘’ÇžàÀêKuÕ©S§Š¿³(ä,¢?öïê°úî}Ævã*b»Õï+®dö¯êÀ¾¿[ vWaþ»{\™œÅY É2‘²»Ãê>XÇ7q|}ó¿»Wë(”9í\Ç‘£H²u‚…õ*øÐÜÜý†ûð—!Ï%Nÿó0KqþyL{öš–¬y(%-‹ãPF±Y|x5oÏÃ$‰çí‚¶ßïß$¬™ØVUåA±}9Ôj`SÏN£bõù¦‹Û‚rxÜŒCÕ67u9•›íCðpÃÊ×ë'øû‹8ÌóüÛèk«}ÙíT­­i&YÎÖ\Ó$3ª²Ú3º—Må¶…‰ª$o8lËe4­û fÿ¡†~½-GU³¦«Õ œVRŸ›nLJþÀúNÙAÙÕì€ãØ´WútûVQ˜q}ûÝßïƒãÐÊá ÆQñXê õá´C˜µÕ*‡ÍijŸ÷ùùÙIIY˜„;9€7!û¥§…ôÏ:þ2 eœÙCÊN»& …?'å.€‚6Ð9gXæîŠ„(±wEæP¬9uÕÔôÅ+Æilº¿Œ¬yd”zäÆ?6ûx„Í.†ŸÕüHréb>jd j: ÝÈ>é;‹ó¢pkOjÔo“QFiá£Î aQ]NˆÌGZ$Í¿Â9q˜‰Ì®š!‹PrLÆLãƒï–óóÆ'ÂÅ8©#¢<ô§ÝžQØ«²mÉ!œÞ›e_ø¨º±Ù¶Oì¼W@ÉࡲNóP&Èrk|¤ _µ¯2O…‹Î×2ƒ22¾·ò–õK›uEÁC𶱸eqÄó‡cCž 0YÁÀ^ 2ãU]àÿ|÷ÖY DL7eb¾ ~r«ïØ8c( ádkeê<ý0…콪T7Ñ✢‘x\ÛuU8:ÃÈvªSC9©g¬à"A²ÿ3üñJyDê>Â;cP.ERMŸI#¨àõ‡¥“yá°‡‰(Ì¥ïß ™qÚ¡¤£ ¸ýiBò±G´FKŽÍ|Pv°M^hŸ4´ÍQÕJ CEd„wKÈ3î~Ø+Ö©‹qæ…cˆàÜÎ3Zâ¡Ül-!ö„WQÈ0+-rL”GÖ?^cbA$/+Á%ÿÞ⑺F?o`RHW˜46 TÊãÜW Kc1°¹ŸU§aðô½%Cÿ<ó4Ã{”‡Á+H@MÊ9€™xy¥F±.È–zÖn…¯Ç"Í–$dÏeT½®œØŠ"{ÑY s¹'ñVáÓØnû*4/5÷"I¢0Ž2‚¾\";õ5ç>@vjƸRDl …nôÌ…œ ÇŽ´Î°J޶¥ÎH —.«%hôMCïx®Rƒç”éËÜ¥ªÓÝeYUjÔEzo ÿ¥¦Õ$ßeOGÐnóhå¢'*Pú.˜xóæÝû·:òsÈ~QÊÜO6,æ%èÐCI# >5ªÞÔÛcñ_ÔqRDÈzK’ÊZr54­'Gޤaq¡ß©Ù»b†Vðøf ƒ Ï .@”8èç†Ë:ÃÑÍÊÓ 73û¯[¿^]2)\ú|ø™f‰Gé2ðîæ[" ˜Ú‚T~­hv¶íŠ%„ܦ:mÌìkSk[Æ‚/@¨4ôh»Ë-úØë&E ÃaÔñù‡Î¦qÒJòØ7Dvfƒ3Fˆ°¶&uYA{£¹À¤ó€ Èbw«:îÕ­~{«ÕUé=ïðê e£Ç@±Ît®mS³£‚àëŒ £s3s"¼™ÇT×EÿºÄ*÷4EX¥³«¾VÎdh54èP2ý`>âa*gôWýÑaÑ¡Y!ÝOÍ È4Í‚i»*A×¹›õF=™D–›nŠžÛëéP{ݤ3WV‘«ñùQU‘Bq’ͧš÷4{}¶=D>Ó8ïµÑ}è="?îƒ|§²«L ´éøär,õ`zçDç›\öÉäˆì@Ú‰kzÚ&îf±„^J@G¼šNXùd}?™Žÿ»÷°Ñ Ái*“;ÅŒS db1—_LÌ¥}ô猎I¤ûÌ\¨N&óâý9vB©Êç¾ovûcåf{½E¼¦ÑkɇÜÌ“:n­Xô>!CžÎ q£×òé\ ïôí›cE×Um ΦìÒ%ÓË„X¡þí"€>3AYÈÓ»h~ÏI}ø;ÂÅUº(RßÒv4‘2a)Mhžy–tïƒ×Ê”Aì£â[³½‰¦ÀBúó™oÏÓbÂu=Ün†çû¥àÜ_té<£=Ò Pë>¡eÜ÷îç ”óFûg3=õ8Õ(§Ú—åËîD£yOû&SX‰©g¹l6iám§àxKš-Ó íSÛà6úJ°ÑÈ—”|>7^)ŠÓ—Ò9ô¨®Eº¶ê!Ïé¦ÓÅšàg$Iü’¼Î. •iÊãø_鉀¤Ü¿a$ƒ‚ø™Þ3ƒ©/Í¥é¤Ü}2BÓ«¦ÊÎÁèIhíbªT9×½£^ŽÄ ýf§-qD߯<Ñ>ãq?b„£Kr´pFÒÙ«`FV¸0„ì{U•§Q» ÀïÉ\&ìÚûÀ8^èO83¾ Ú¦j¦«€ýQ€­VöcH&L&Ô =2xTfx@~t£M«´ÜÝ/MŸ#7yŽi®Ó鈴%]ÿÉÐ"°é@d?QôÆg:ã”*aúç;cäIìºb ¯€Š÷]q\¤‹4qB;.´Ð–À›ÓçÁyþ䄦¢HÿYJ¯ÖƒãÎêµrÓoü¢8"þŠØ>·hÒa ¹dÛïP —‚Úyñ§QMÖ_r¸„æ·Eû1v覂<ÒSA"˜ÑMBA/9Ò²‹zfòƒ(ÂÖ…‚‡yü¥#4V„/ËîùÔŠÚÆR.'µßÒwÿÖ¢ŸŠYš³ÂIú¢7w©è !HúGÃV·öz´¼:…÷÷Ðu£ìR{ejfnka¾A¿ŸÒ(mâ‹`† P!ÉG1ŸwgP™wÁå7ðîVÿÅŸÿî¢.Áendstream endobj 40 0 obj 3226 endobj 44 0 obj <> stream xœ­Y[sœF~Ÿ_ÑoF[š^šöM‰í­¤r©õª*ÒÖ=3$ L¸HÖþúýN_€‘­øeË®XúÜÏw¾Óú“…\°þ¸ËóæïŸ;›7n„yÉÜ?å™}w¿‘ì¾ÄW"bø{ØØ“‚E*â2fJ¦ìþ¼y¶ÑM”„A´½ùÏý‡SÛ(”< c¶MðQ…ªç›œçYEØõ¸+§]Uë]wÀiŠ0 k#f K3%dÌ“ Š!&xÒ7÷¿[Bpûç-I;é¢Ò= Ä7JA¿Ìí{ò8f÷Ï«bÿ<ÞÜ2˜„ÓŒËùÃÙ8²¬nÝørÑÃîÐGs†l£\ðÎoEü–oƒ.Ǻkwçâóì`d¬zn¼Œ õ§Mð‹¾y·‘\äÊzÌÓ<ŠœEχÅå„g‰²ÏCû5\šZ£k`E[±¦;Ö%¦Ë¥ëGVTUMUz,êFWL÷}׳^Óu{dCÇÆS1²s×kVvç ¾êŸ!b›Ìœ'qy‡ƒý´Î‚JCgkÄ…ÊMÇ•EËöÚ)‚ÞA·C½o^ØþjÚa:ë?Tš=ÅÀ:X<à³±c§‚ÄKò4MfÉ ~žÈæ¦ÞÛ˜ç*I)èì÷imÝÈ8âq”xcÉ&il*Ò g!Á‚·Ý&fû¦n«ÆX…ˆL¤ kÙs=žL°ZÝM«Š± ¬‘e©à‰t–¿t.X®\cgñ7Êõ¼‡ïQhËIfŠ‹TÍÑÐ ôBD<™~ÿ·‡à‡ÔçÕgŠ"©)V•>Ü ºC‘äA15#=Ûw°ü½­¯LðT §ö·ÝÇOw?Ø}ÿÑtHÆã$ñ…·ûþן(Îjn¤^¦ž-ƽÿmñ(‡h_¥W’S8ÍöUÂeîrgtHV·¬` ö7‚Ò˜ˆ`ª›Šu‡UneœSnom‰jã«u*â¡Êñ¶ŒûõÀZ“yÈ}¼M£oãHr¹ô­‚±ë â¼¯òŒ2xOçO•È¿¸Ù«©mô0CQHèy.T2€\*µ õ!Ûnu[ u*·B ŠÔªVãȆªkªC_œuÙ5äÓpÑeídf‰FAË=&~©ë³æ7Û&&aÜØƒÃ‚;R*Ãd©ÄƒX„‰FÛ®tÕ$³ Ø=ÝD1`MáçfÒZ®Ãœg5°5LLÏÅ µüäúøº14•ÆâÑ÷u¥çlSsä,ö˜‡é’ë@5«¯ÙMÌ«~”§¢+µÒÊy¥z(“äêŒÇªâriê²°X{˜šÆvo˜‰—`Øô”ôHÝcP„’xª'ÔW¤žÏº­tE€²MÂ0x ~,Ú©è_˜P·.ÖÖvwŽP…)5ç®×MWîVöQ® ´]µM,¸tóbÅÈb»3–k©?4öÎ`¦¤Ê'I7Å;ÛR¦ZÔR afå“\¬P ¦§¶ÂLár£R4oàà·»%î(ÛÄÇýÓGæÆè€8Syb¤xycuÑœðŽ™b‰€¾*œ«%ÌLìL´á¸0Ò·úª<øåË+øüFQ–ÓHM‹!e£Tˆù $pË"ÐpÂTˆí‡‰ÐmGÝê¾hÜäqȳØ%•ÚiImjÉÞ§jI’{ÿ×yî» cK³ÜÀêg«8ð?é0qhM§ž2l:Ì>,7 Z±œÃ—` ueî[ƾY0¶Xbe¸_èUf¾$Šwl]õÅ9Ô3j Þ€µ†Òú|2EûfÞ¤ã ohÒUÂ@=c7r^0¾™ë˜TÝ„!Óë¢AZ8¡âžkÑ9eÏ­¥•%G·ë9527€_VÑÆ$ú¹¯Gô:ÑÙžË3ž§~Œ<·®i0zäªiЙ¯šfW_;8¥ò¹¶#?)Á Ið¹8_0U×Y1è8öÅ+V ®àæ‰ÆA?hª)e÷ý¶šÍLƒõVx”…0q5„ƒk‚¡ÖA¯°ÐeæSÏ:hÑ€ ð4Íç¨k\Ζ©ÜŒH<rå"P¡ªÊ± >®ñAüÇ. ¢©ãÉÒÄ·ÚrÖœ8¤ÈÓn÷ëˆeË‹ÉèºhúF7TCõè2˜§þÜF€ü©q^Ï@„· ‡aŽ)@=€ŒX¢2O€wä/ÍB/Ìï÷.ޱIrœrß:wÿ\ìMAÞܨíÄÂÝÀøøë§ŸÙ…'6ðŠg™?t¿Êž‡‰˜YzœØª„(°6*^„cÔýa©šrá$ 6¾tŒÛ½ ÃÕÄ¥}. ‡±7,ý`þïÚi‘Ñ"uí·üÂïÛÕЉ±gxbòŒ½îv}Ëô 6iðsF™ª¸YóÝàÙFÚ³4uíy5´¥šSÕí«e1ÏjÇÏQO¹Ê+0¡©bhÝyg*>å3sÿ|é”%¬Ï§ãÝiÖŒ¶´tAL3 ,ZøaE±µøWfè™m±\ꀤËMÉjÄP[žÇ6Âó Hìl3–±µe½&‹\Q5„Õg]´3§G¸[„åƒ&œ%öÌ Ík&}?ÑR'–5Ý}÷ÃÀÙû®4õ¬+ä™–2_Û€Ú¼± »™Q„Dô*Gœ}o Ó•ÝØ1—… #à&¶ÓË[Ó§\FÓ„GoÝ-VôSCwPõX·¨ŸÌ,ÇbälÊcpwék‹K“ˆüpð a &f©Ç©ˆK7¡m3ø{# «+yßr½#ç)YÓÈ5«#žK5ß5|Õ?€ÖKvÐrO¤Ü"m†¹@¼ª¯ÏmˆèyœX„Þ1r¿¬/ÅÔz.¿®W“ \‰œñÏM$­ÉŠP Å‘½f2CŠî˺žˆ?íÚýÔni»¦þ1We¨ÐÕ=ŠÍÞ e÷¶ü[kÇ÷Ð8êÿq•ð4ήÒîo1R¨ô«fÄš Æçê"`ÿ›†ù†ˆÞh5•¾ªGç~N{Œ¯HÖò!‚5>‘<Ÿ÷?•½Ý!—Ø|,†½³“GéG§[ÊžÞtæ ‘Î'0~øÔkmt‡·Äö—ÕrÝ]Ø£ÅLOÑ]©åi`tÛùîöEòîºn†ËÍî_·¯ôÞßùLÇÝeÚ›+j¿sç8D*Øl†Ûf´¢ÑjVá{;×´gûHHó.>ÕT厪’äkšVÑ>Õ•&%~D[ÓÅ3Ïq~»C†æòík—ÚéjfúqåHQ9[ìÒ™`(Q>©Ã- 4z+óÅ„-8’™×s:Â<~EÊV׌»¡ÏjAÉÖþöFïâÂB¿Ö ¢4 ´xødBèÎÙévÖã©«f» ŽÒN·È¶Tœ yªËTZÛæ±Âäi£RWËV¯°I·eq1PeH€Ö†-5¥eÖ*ª@l5Å‘nܡ֬ä•pBâû}]6]wCãØüc¦ŒÊ‘ýÏã±é–_ª¨pA¥~Ÿ½¢¹ âÕ"IÌ7t¤ª-zÖ½±Ÿ•'¢ËöZñ¢{xãÆqLtñº3Z¶ùùzúI®êÍeÏ(ä‘bxbIb$–Ó@“\ÍUyý+®÷›áÏÿ€šƒ¤endstream endobj 45 0 obj 2937 endobj 49 0 obj <> stream xœµXÛŽÛÈ}×W4üb*°¸ìn^š^Û‹ì"Æ&žAÁ8PdKj›-/3™|}NßHJöØ Á `Ô—ªS§NUõï$ )‰ôû·l6?|ÈÈqØDä¸ù}CÍ—ÄýS6äÇÛ '·%VQFð{{ØØ”°Œ…<&OÉm³¹ vlË’(à»í?oÁyصc£(&»‹*,êZ2ž$Q£l¢ìa%÷[…¥q0ïÏÓ¾-9A–£êÚÐÈpâ_6,dQBn7Áëº&‡©5+ò({Iš®R‡íË eYÈ“VâN½#Ö;î%+2v¤—ãÔ·dèjY?‘¢%²ï»ž”]%Ãí.¢ï=€B„i;¸°Á¶4¥aF~Öl×ËSº@|Mçíˆõ%—Ä©ă\æd©ßWÙ‹ç|ÜÑ(ÍÜo·TçT#ð‡ûÛm¦y'ÁÓYûšá0Ä@9#‚Y,.,12@)lõŸWÃÚÂ4õŸ«¶D`q ‚¬l;RwíβTEmÛQ¸¥³ÕwAõh˜*¬½zwø|Üó9(üœ±Œ†‰ßÿËX$2×ÁõÆ^¡û®®Õ0:Xiœ?c)¾9û#–ÊZjé úºae­¶½ð6ëdkŠÑ㜄Y$ž5ýÇnj«Á3"Ξ:ú‡,ßÛ{NÅEîeÈ¿zû%õ¢å›ÜR¶ä([Ùµú·¬¬›Œ‹0çì9:µV,â޳YS™Î ,ÿ+%WdKfq8לJ«ÎÓ'PYž=sGk4¢0NÅr0÷ß—ÓýI•ìÍù¦þj-ÖZûz‰p­²ñ‰¼u&Œ(М…óìþíõ‚°a¥×’Ÿ¬8ST%,vZˆdV… »N¿qQê-ö%28˱4dÞtÞß Q®Œ¯)2w®jÿ ÒÚø«H‹Œ›déZ”âi‡É°ñt®²kΪ¶UdjÕèð‰c0çBõÜÒX‡OGÕ¶8`@™éÐnª“:_F]u°°oôU&×\gˆeʾBJµÐ> c{Fe:ŸöàÏa&tH™dÎâ¡[v§záw÷Ù}(š¥qâjIÊ׬ïá•2UÞ·=–ùœ%!}^HQEëªlGƒ¹úº,妤3¹q¬µ³=®ÌŒ'Lv§bÔªtìºJ‡ÓS;3²‚ÒjÇÐ…0…ɳ){î“D(„ྱHbnãQ£;0Né[uÅÂ<ùfj‚ó>Ó3ö«*lÐ@¾1]J]loý "Ÿ¯ök†X‹h®|æŒG“%D5gÛUXmÔñ„VFb¾ªÐN`„ï†é|îú‘øÔ:•6,ð6¿ô¾_âpÑ#äs¿ë4 5}|²h`( æÑ`¡H˜µ¹õc\á&È·¶ÓñÀGZ´ãïÿwLŠÔ绾„Ú&£4ÔG%ê`åípm©°›t­Î‘m™Ÿ¤n—‹ñ¹`3§´,Œî¦ †f8%s*;[Í5Å×»pPó ™¦´‡_36“Ê©qvYh-ÖHu½BeDÏQbè ÏcfhPõ4É´¶±X·:ñr¦EÆOt“æüØ•²h7~üt)– 1{¢ì§OV²GÎX=Ú‘Ç“*O¨ùíÁ›ü°…®Ùö¿žäj GS6L%6 :-KPÛÕx"Kž¤È¦Y÷Ky¶vZr!9‘ C#.µ¾ päó\‘$™å\®ø«Ÿ¸ÿ¢PõÔë)ì|‰ؘ‚]ŒÅKL«•m¸ž³ Âû‹©Q¶ôE:¿ØÊ§ 5ÿŒ ³`¯§A¿ÁKí ü–ÍåƒE,²Õ,ËL˜»ò­…Å’Œ;¶ÆÜÏý,ä™m€ä#YJä$›s—Úõë‡íÉG¨«V•þâ>`žÏz¼j$³ÎÍâiuÐéé)ÆvÌ•é’uh rXJA\çeá{B²œ-Éóe•‰‘G™W¾{…vòO¦À@ÓíjTbžð|YΫe½Þ¡ù¦ z%‡²W{ðbôÆ=eÄnöŠ (ù’?7ÀçJ6WÚø?ÎU– N˜uUεît­ùÊkî}É몒¦3H0*¬0¯Ví8|Eÿ}ß-‡û½v×µl,ÇË.^‚÷Z<µ<£"ê( ÍSÕÊÎ+¹F¿$ØwäúzøÁÁ>R=©QýbØ·G;#ùK\‡ü]0?2F¹yd¬»ÒlqŽÁð+§zÐøÚ-=3Í^Ißu&vøáX/IfÊ €±’÷ JWÞêâh¨3衦¦EFO:`57ÖÒu‡êüÂ(R÷ÂÕó½ª}×8)×Lb9];ÍVqmE6¢GEËŸ,Úu^?úÑ<Î}ŸàÏèU)Crã^ì,çžÂö=H‡ùÌÙM3Žqd.ÛÁIº·²kŒï‚_ŠvB¹Ì4ßî#‡ëš,˜ ®º+ÆDȲïÌÅš5:-ÿúŽtûOftUKwäw¨+ó<ƒüZŽK*`SÄòoØô¾(½!ÕÍ?Þ¯ÏǾº$eúå:€ž¿tɽ.â|…½oÐDà—Yt5v¢f³s—/îïn7ÃÏ¡H€endstream endobj 50 0 obj 2512 endobj 54 0 obj <> stream xœXÛŽÛF}×Wô[¨Å¨Ýݼ¶÷ɋ٠rÁÚü0XÙ’˜P¤LRžè9?žSÝÍ‹F‰'‹}9uêÔ©â|f‚K&èǧ՛÷);ô+Á«Ï+i2ÿQœØ¶«m ¬’Šáßv¿r;%S©âaÄÒ0aÛÓê)بµŠEmÖÿßþ€ó°k£DÈ…ˆØ&Æ¢r•à¬çU „LÙ»²4åzûëJªˆk­p&V» ¿œÏm7°}Û±Æä]}ey]³vÏiÇFò(¢ó¥Š¹ÊÜÎàã;zfï•cbðþÛ˜Û]*Éx¦F¹?\p.°DôT ·\òP[ ["ކñC¹ûT5¥¡=‘]‹ëÉ“1‚à÷~Æs§ÙtræŽ6ÅPµ Ëœ?äÝp‹2Mx³ŒhûSÀK³[+Bu\ŸŠ‹CBtÛ$¥1×#ˆ|˜*“ ~ŸÜüò´áåiYƵÁßDò$¿w±ôžáLñLÌ ÿR íÎtD²´ 'µÛÁãÇeÒ¤VžÅ§àÝûo£Z:“—Us˜Ë8¶À¯gÓ³œÒÅ-úö¨ ÆOyW™=} ác;CH€oŒ¬û!I·‚ ±àër{‚ÞûðÝ÷¬ìòýÀvf-IßB‡ªé=@FMøž ÄÆ0­7Q$Ó` í/Ig†K× ¾Î°â˜7ˆehý×3]×voúKQ˜¾gE[À®¯ëÚI8Nè¦WÛ×sWÕȈHÖ›P†:ø°àøÑãë+~5^„âÖ¦¿œèölºÜ ‚US·½!´E{:׆¾ç^ÙÏâ9A?·>52óŠ²ÈŸÿÅÌ÷J.£läùä•%ÖHx¬}Á~Y“daä]Õ^zøÇ,iìæ‘LüÉÏûe¡&‰CòÜ÷¶B«Ó¹»…§Õ¼ð%¼ 4]€¥ ™4Åo³£#©­¨IN°d“k¸V$(6’~ÿ•Té+¼.ΘõçºXù¼ÖÐ¥Œ0µw*yó>cä6{”2¢ÉÍ&²îòØY7g[:ZQ¥¨[S±uøhö6:‚ª©,é¸åîDɾ3 tSÓÁð<5eèÑôEWéz¶hB¿nTÐÖy&V¿B…s–ž‚ºÚ•ψs-QGìtZL 'Ÿ¦&a#:Âr 2ìUYTµ!­9*™‘ï”fïTrî dB%ˆÔ”Ä7¨‘j^Þ©šÒ’¦0K¬7x!\诧][Wkò6\ú±æ÷¦3Mßý ߥ3æc˜‚Æ¢Ø~ÓÉ#Á“LŒÂäÛe9À‰Fî`G9Å%­h0í® >ÅY§†%м¤ÇS†Uóp‚,éùªWÒ‰Çr¬Rš.ä/G›”›Mqy"ô×-$h¬Ã"1¹-/MûÛRN6ÙÜ#ÁúôB…QÂõrKB°|GÝ3öˆ e©¨~·r)`Ü;×åÃ$á…;²æ”w®óÂò…ð:ƒóÁ)‡¶«LÿvÁŒ°yÄ{hOþxRã™p K"¯ìE^çÏë[F-§_~5¥:ô¹Fæü“Öpi–dÿ0uÐßBRÔͦ+bÓ ¦¡ þæ…28a’TæÕ´ƒm3y}—z yÉ4sý}ê+[HÖàK!ؤe),jláxYUØ»8¼ílšQ)ãQ¨³1ÁníSÐ6V¥*ŒÃ^_ªò¤0E%…„%{ Þ¼ÐâI Ÿû¦xýúx×€Át# —V˜®1j4ʼ¾˜’jk-Úcš3úÐÚ¾ËíGŸïçÁ>Â¥“K×¹ëc =nV¤zöç¿ÕdðîpèŒÏ °“™ÒÎÝóC¾Ì J&Æ£,qÑfÒñ‡ödÆ@g6ÒÞƒ‚cäÒ¦G¾{å¬G6ëíÿÛÎß–´­&Ê]†æJE!'ÈéÒÿõéE[×~Øo÷ ­Á¦âÒŒßø{!Ã7ôðŽŠµH^¡xl!Ã…zˆ”»Ìó¯f÷+åØý圾˜§ð㜙T> Ùö¹£éÇIe«VÔv{ªdi®œøïp'­ŸäêØ®0ð–5N¡(ºëbÂ|`ÏÇ cÒs…Fp­L]2SáP¢wâÍʶÊýú­|-çÂѪSTÔZ‘<Ûe+©Ý {öÆn/d‰áQ̪#B…uS…Ø_Ó ¾²(Œ8"”£÷úàf`$?—Ø}}ÒÐT–N ¼×f¨(•ú•Ò°÷øªYŸäKy1A¦—zðÚ˜f>¸OJ–v7¡á…ÆõX¢Ô‚Aã’sn¯Ëñ!›†Ã*x9¼ehމ֣½kÙ÷TLëê7Ë‚gz©Wt'¶qòxÙdB¹Pÿ¬E³ý¼uÌ |CoŒ’dOo5 ã ¹Çÿ%\D9N*eøÏO9ý5AÉy#Þrt:AºýûÈ·«ÿáçOûO›7endstream endobj 55 0 obj 1868 endobj 59 0 obj <> stream xœ•XkoÛÈý®_1ß–ZD̼H»Ÿ¬“M‘‡7VP´v± ¤‘Ä]JTHÊ®þøžy‘2í¨X69sï¹ïsõИjþùÏånòúKF6í„’ÍäÛ„Ù—Ä,wäÍ|"È|‰SŒüŸ¯'î&#<ã±$)™ï&7ÑŒOyB£d6ý÷üïçnåþÖŒSS*É,ÁùÎw½ÒkRî»é,O)~½/šõoêºúÅÊ`’Ì?LúƒÇ}[nözEªz¿q?ÜÏëõ/ÓŸ^pð«aNϾyz¡ÝÖ ÐÚ£ù­¨Öͳ–Û¢Áùýõ®¨ª§Æ€¦3¦†;”¹ôÿ¸X­š±wu¹šÎ”„ÈŸÝ©«®yŠÂ³šoÃÁߊýªÒÍíôÖ£¹lšº!Úü|EzaæAÑln§NêI>¥_ï‰e1§™B~ Ä"ÎsEæ÷“(È([RìItÛ’5Ô[M¤Ûj²­ÛŽšzÓ;²„K˜l^T媦ó?'©¹œˆTÅ2ãNQôjo^Ú”c‰=âž×QbÞÍ$eq d3“T« “41Øn¢FGï;£ï°œÝM¹„ žGEuÔíkW·ä¾ì¶åÞbêvã.dŒ A¦´öntGêÅŸz ýF{¢b•¥mÒ++ÃÃæ„¤q–¡XF‚B¼çŒ»ÏZCc[•3õ”öVEwÅàS®˜“Hah,Û*©âÃYö¼Iœ ʆè²ÁŒùV[;dœJþDR[ì•&-ÂZ4Ĥ#)Z“ß;øI±¨½YÌF—e2–\:),‰“r‡[½}œÆ2Ížhj´u”=‡$¥¡ýˆ<‰E&‚§n"dÕÊ$÷”%Q¼'u"ã„IâA™‹G·-:äæž4ºX!—Wä¾);MŸ-J8«!©´¿-Ê}Ñ”ðu|úÚ亵8èñ°Dœ$6-£]±DŒÇ¢ÙJžöæ†cÆ•-ÙQ: wNÄi€G(zóEA•wgTš¦RPi‡¦,:]=Xi($¥ “‰IÑ•@^¯‰u“‘Á T*Ž‹ÍS—† Ò,ëÓðb5¤afð„4t§ÛeS‚¤aû(5Zâ“óúÝû×ß_]½Ÿ¢@(ãitW6µÍS›ÒÆ­Ïm,÷åˆté¢úhÞDûÒNªýÛaRq…: +*7Gä³^Î'¿Od¬È=&f1†½›äYó„H‘Só¹›ÈLðÓ'Õäú;p‘Ûv<ªÑLe’2—Dre†jôéâÔ‘Te¾C¤°‡º”üxI®ßÿëÒ†Vd!ÎÌ%ÈŇ÷ï>}¼ü4'W_¿\}¾¾ìm p1¶À?ù¾ϰ¹y¼³ãÀ :RÅBômÍŒy"m[áHW÷©À‘còMo|š"¿B{´YáºF!¶HUÝÚZâÚ ¾/q``&m’@[D¢TÓ‘Ìnt°<1­~üìù‘öDÔhžãiÇͼ‚)\¸i÷ÖÌÝ~fã¥LBj6ôc0îžØF±'zaåaÈ_;B1Ÿf9Ú_šF†Yxš Ò-¥ vdÈ@¿¬;±Ø’‹ÍÆb1´çñèÙ`è@´eßyv*º2 ±ùÚylø¸_9ÀéÀ¹ªª¶óB)ݛ壀J MqÉÁõ¼­›Gìž§=¡Gœ ÐÃùp+Ï3î¸Þâ!` l˜až&œ…ëç©°àoÞÙa©GÆcõõ¾ñëã‡z9 IjØ“_ÔFf’ç'Uäï¯@ÇaE§ÿŽ Sv¼©êå_£ûHþÒûoQèúχ‘SŒj”uAXÀc_ô¦+•þÏø"H–Ù£«>ù.†öÒþ1lFØWÀ•Ãödo!©·†¢ìL3«×#Õ¦­'I(©>FaD/è Áˆå.™‹eg×4 FwÇfß’ÖîÄmÒ*Sn“Æ ßíØÂûYÊMËúP|;êÐ]N¿Â*ªïFrk6R4î®9.¡ 2[­w­ùa}¬b×Á ³ p«Þ=ÿÔCéð8Ëùàå7©W»Y;°¬¢žÊ~åú-ª<=Áê–QÝ[ÇEU.O™,÷ëÊS0¯ÿ”ˆ!^,ŒÖ—Ø@*ö²‡å£/1²ÐâX쾩ˆÐÞíÔ7ëÚ®°ë䲆£° -°þÕº­óÁ(žbñGc b³³jìÞ ì}m}l–Vd[ÃæeÑêöv ©»ÀEY•ÝÃ4µß†ä«Ánò‡IôEOò«•ˆiOîĉ !3yFðÇÇâpÊÙ°“aÉÏÃ?þúÐŽ­ß'ÿÙ‚S7endstream endobj 60 0 obj 2064 endobj 64 0 obj <> stream xœÍYmÛÆþ®_±ßLÑ–ûJ.üÉÁ%AÛ¤Mmnq)<‰’XS䙤îr(òß3³o¤x§;û[á–ÉáîìÌ3Ï<³ùLRÊHŠüß›ãâÏï3²ï)Ù/>/˜}Iü_›#ùv½d½+Æ ü·Þ-Ü—ŒðŒS!I&4Y×ÉŠ/¹J½ZþgýWXÏ~•&ð£OMSIVÊõv!(Wdý°H` ðåÇvS UÛ,×ÿ]ä’æZâ.`—¼/7m·ÅçVÁ–µVëCéMŒ7á‚*W¹z(ºÝ ì2[HšÁ¬£~¢OÃã]IªmÙ Õ?PšêÜ䣙s½*{R¾jöuIŠ¡=’vj²-ûMWÝÙßm7yƒk® 9ÆhÅTJSø½bÒúZþ†ïmü£Lú}Þ½»®ì{X†’õ¡êÑ8ó6<ÚT=ioû¶.p­Ù’þОê-iÚÜ–äÔ—ÛoÈÏöR äáRQ¥Æ…„]¨í>Á)·åçS1”õ#ÙµwóîÃŽT›Ñý«£û9e†sŸƒwï¿çt–¥U0ñ‰Lcü·åŽôCwÚ äÖ»œÆ= `î”.­ŽE]“º»Á¼Ec4ûÑ}2šýÒôÕ¾)·hÙœŽ·e÷vùæòK~ám»Ûõå€/3Êm¦®%¿_ÅãsFµ?{€ßÛ9­ÍJÈK(æTgy@±?âl %©d&ØL`+Mcøá7¬`;Þüãç›?½èäÎfAÑ4—Á¯¦²…P5þÓÔ*auæñ{l1RK&©1)OèÁrÉ4`Â(Ê2âíƒw%–œß°½+;W‰p.@=üÐ{„4VX۲ö(KûA5”G|÷ùTöøE«°X²¹ys–IYð;‰¨ñµÁåŒ43x¦B™&»*‚$ÃÁ¢¾ì¤ÊðD×I ÕZMÎ't§ÀÚE'ñͦ¨7§Ú±¿+7wd’ YÞ’ÛG›N±æRF¥!;Õs®ÇX_t;¥F»‚¯ßZ’ÁŠÄE{ô¼€£8L[ä> > LZo)ùÐ-ö”¡\ëqigã6¤´'ÕñèÈ×¥ ~OúqàH(ER.òs¨4åسè1œ›¢œsðbŽ{Ȱ–ò¬ƒ|°ÛÍÀŸ¬lç!·ööÔyÀNaÉ Úú<ƒ¿ˆ+=m–—ÄÐè ®zh­«/ f¨É³ðÃYfóý„“žóO)Èå«þ9Ü´Mý8ï"Ïè´· ù|ûþ»þ5Ït¬TE<²TÛlŠ~>)ÀH˜€¾`4C_FUè¹ãB_¾cñujÂrØEý?!0ªŽE¯ ¾om„(çVï1 ¢±uwEÌÛÔ½ ú‚1gãRmªá澨OåÌMÐ2v}I»J ë£uy^Dã¨â¾¨â/¢ k  wmÕ ® ø½WbžSÊÏñÏíã–Î=ÚjM3©#œ‚!¥Yyæ¤â4=¸Ì¤:×I½{–ø¥M"€Ïä³íg*os*óP×þuÛìér¥èL ä ®Äp4-qµŽ°ãA'¿¹„ÚÃHè‚›X»cÕ`îlÆmvEƒØÛûžƒ@;¢@Ï=ùµE›­LëŒÅI„áý’£ðÆbä̱¨€kà±ÂÙ‰Áã ÐPAoõº !W6gBtL›HWå­ ¼(EÜö˜éM l!F1²^0ç,®L :$ä´ÊÃvnÇ8tZð{ɬw*Ù»J:´ÝX[Ö;íVIœ£& ¦ÿÓ#Vž·'ò€‡l@­x$‡âŒ¼ KÅcÉëqrBÃaM8ƒÖǧ¤ÝN±ñ ¬bqe?XI®#¶‹7£=4—Ø”S$î7çÓ)Ò§1W¹£ɸç;'^Ä2ûbâºÉóîÿåºy?Ü`x»AcÚ^á]I3ó´›MAvYݦP<Üæ\xúEùk‡c9¸€ß‚Pÿ¸PoÄŽEMNa2Ãr"ûÊ…^dɽg ÎuĬ+ÿ][×­+4f’0ûÆ?Ã÷ì/61<xÅ`Å,1Ëcõv§Ú^VºúÁ+CUý—¹¬VØqøùeׇ¿ýåç'J0Ôw³­ðÑñ8±¾›+s(¹PpîÕxSÎ`hÊÙ“‹rþÂEùÕxÛüÊm¹ Ê_†p}õU1¬˜f!Š7Åí';|^90Ri1‘IÜ1 æã»)Á¨ ãtX¯‰ÇùI p!Ú~ý¾Œr â”ÆQâ^LäÝD©%XžüS9‡ lü¼2AÌÏÿïÅwëÅ?áÏŸ›=endstream endobj 65 0 obj 2291 endobj 69 0 obj <> stream xœ­XmoÛ6þî_Áo•‡ŠII”ÐO-ºÚ½¤ú¡Y¢m­’èJroØßI½Xušb$ˆu¼;>÷Üs§|"e$À/÷;¯WßßH²ïVÙ¯>­˜yHܯ¼&/6+A69X1Nà{³[Ù“ŒpÉ©‰1ÙÔ«÷žÏ×< <é¯ÿØüþì©Ôòy h„ÄÀ¾Xy/ï³vwûZç…êòõæÏyˆ4¡LÆ€%£‘ŒÈæ~åõç£"­:¶ªSMß‘¬!º-T« R•]OôÎù‚²8¥!³n¦€‹``# €5jU.;rêÀiÙþ ÐÜ"¦ïÏB´ h`NyVå§*ëK ÆšT:Ïz…™•½ª)žeaHc&m<ÈÍÁŸ5Øõ‡¬Ç0uÖ ©°OóUPØÚœÎ&c( ©HÒÄ=È:Õ=ÅmXL!GLšêL¶Š ©©Â\ ¸h8]ÁdáÛSÓ—µôŒ«¬ët^â)rlõ¾Íì-f¨Bb›×¶…Ú‘®oOyOþ^?Yñ„&ƒÿ( ¡ aq^-©ŠÛJógãåòé¡Ä§àˆÑxvø÷¦+÷ –¹¸Í±ôh³…ýŸ›g’ýyBÞ?/G ✆ÏÔð/ìùå .€›É@0w»…(¢‚kŠ¥ NyÏ\ ¦^ È ‰m7"`myìá0ºÃd •dàÚ6 ³ª,(y¡ûÚà¢!Ó ˆm¦–|䲿Ð#L„^i²ÏZE:ÕCo™tŒ`hn€.®Œï½¿T»#{t´€ã!eõÆo—ëãØN(ðÏ:ë¾ìtíË(b1d\ÝEÙKß•mÊ*sNKõZÕº=O–OI£î=8RÊ„Ë8ì»Îßµºö;]+¨o³§Ä1™‰ÇžC¸¸dŠƒY)‰%eéŒ.§Ó`cÎ:’Âöðe¾õ¶Ó•2ûHA:(¸) ,¸ààî€Â…­rÎySî.ˆÞ„ñ¦Ûàê£ij3B}FC´Œ(‹ß=ŸÚ91#Ã|~n^ñQz曡)ȸ˜8d¯Ý8°„ ˜0*ãÙ^Xº¥ JèšÇ4Ìݰ‚ñ„OçÜÔA!ÁΚ÷Ð [;|Xè´ûƒîÌp¬Ñ¹ɆãË´ÖŠÁC9%ÿîöÕ/7on·˜>[äÏ‚`$ÇÓ ɸ‘\¸àßî"üvÉc.ü¢ „Yv,LòkžÑÚ‘³Eã¦bÌ„þ8ß'GÌCÛAšê$Àr¡”«ª¼? ªJq1~À!çËäµý|4‰H¤SHn¹c¸Å#Ë!lKRvÖL‘@`ňÆYO¡b¼ÑÐO;‡+Ìè@\ª±[•€™Ýr9l-7›ñç‹õ¶º­T3[ÌCqaøkߢMâôlð8=}[gU…Ïq&ÜãëØ¸‡_Ö©w¯[½Ãå¿ììF ØØÃà¡ÉÁ©œ·½õC³ËôèØÖ8ѽÛf¿T;?àëÝöÜÜu#1œÍ\r}´ø¦Myn,\KÔ Ü¶íµ¯˜±îã/ÌXØ!…d_—A*/å#PÁt“òÚ†cÁhÝ¢FNù^ó! kræ¸,AЗeàÛ²ÉA«ÍD3b’P™ŒC)sMÃÄÅÛ2óé±4ÿØ`ðÎ=lÍÞ˜zÑaoŽrIà“7°phÑé´„•thåå¿@~ج~ƒ¯ñ×^endstream endobj 70 0 obj 1706 endobj 74 0 obj <> stream xœX[oÛÈ~ׯìK©Àšr†÷îSšÔhŠÙf äÁ. JÚìR¤BRöªÅþ÷~gn¤¨MZØ€$ræÜæ;ç|g¾² ÒŸýÜVüœ±§a²§ÕוÐ/™ýØØŸïV»Ûa• ÿwÕÊìLf’G1Ë¢”ÝV÷ÁF®eùfýÏ»¿AžÙUØ]F< c¶I°~¿ Þ¿–}õøÓدïþ5Ÿf<³*°*Ä–œÝ½®‚gÕ+ÖµŠNÃÈvÝ‘¶Eæõn•gxXë(‚"ºnŠ£Ìy’Ç΋"Z2‚±+[Vî÷¬nw½:¨vÈ¡ºÝ+§Pè0ĈOY£Å'â²H §ÿ¹ïNOÏ ¡`ûr,ùz“ä°¦Hƒ;ûÈÆmOj¶gmáÅ!GO#„`Û<Ò®Å'wÎhGêµÝÈZµSÃPö5Å}´¡×èaÎã4wç{šìOì³AU§†• NƒÂÀÆœ‰HÛ%²”ç€3¢åð:Ñš˜rÛ—0 :IÓ¹iŸŽª/ǺkÙ»n¯†?±÷ú¨OôQ  Έ/o½a2ä¹L"?ß2¹ˆò!æaž1|1Ç*cÒxP#œÕºàE`åN1<-÷êë©«º–PôaJ›Pèt¼²DäSjÜÃɶk¹y\§Q«{…¨§z,·ÍïËOÂ(ý¾Èö60R'vªÝÚ­dµp›ù´y‹˜æÓêƒH¸L3`ÊÜ&pðúLj3^È̼f9E¯:µ;:¯²yX»( Êü$sQl•Ú«=Àæ9d˜€/½-€¸ìwö:œ3%Bä^ â:œ*#5´QRð(t‡TÕ^j†HáópWãHì9‰ s*G#ŠŠL„òèÊŒFé±Wí€^ÊÝ®¥ Ò@ ¹N "áYìò祜¼™‡÷>¨}ú×aã6:(~Y–:Ì?+…œ:­uP:ðì‡Ý”¸'é¿~œÛ„HTŸô» 2ÏzõÂÔ´?åH]®æv^¸Â©Kè”ÄÌçëðÛª¦³ ³Ü”`Ƈÿ•O(”&’S2†‰ÎF]÷\ÊdèòœÿÏ4˾ñ, MóÓuçñÓqQ:ežør&‘6E÷&œði0åw×µcY·¾Z³®b%êöIá0ö'} Æz@‘øÂ,x[I*mjçË7jŒjb¼2IdpÙûºi” «Ða•¢È£K¿Œ0áÐÔsä¥~™cœlQy¦àV}w¸–uâ­ØšV€‰8Ç2*l¦©L¢8£§åÊõ‘xZ: fíëÖ´ßí™} ,@Yº+2´à8¾p—ÔF×î¾›Ü-x$£I±ñ0=T¬íÏäNõØ#ûæi²jx„ ÖÃëL ¯2Å&Äy|&©ÀÈ^!r _`rã6m"S| b{U1öZî‘OÑ5 1ðýùŠÄªãã¶ÔcwüQc ?^­P¿Ž ¤d¯Wý‹x<ôײ©hU¯žêA§%á\‘æX´¢«ªAôÞ¾ú¤Ð+ áÙm+¥öÌþà·÷S‡¢çÉø£½ua™\\dj––„…kB±%f¶ ËͶF/‡zǺ#à»WË1ø‡¯&—ºª 襮\:©V¡Q@í9Í\²b /-bÍ|mÐ?RCM»#Ù¾[W »R”Lß®¿í~¡E¹æÑîAš57Ôdýuj‰ÕµF3_Oœq.(hÔe»§ÒöoÕw¶ÓÄØ›û´4=­‡«RÁþ¨mtèÁÙÏlÌ¡SþˆréNÈÐËD?”™kÀÁyÎ3’‰¹Üà6÷j-µoqP÷Ãzx…Œc{Á4wÁÝšºä€¬LC•"ÎN¢–ZFÈvŒïtþøbF‰|*âqjÝ™Ê7ÈbŠ´–ø¡½Ò•-«ü2–‘ò…|Oi±‚SNÂ}·;Û&µ‹6‰ÔÈó¬ø~Ÿ>eˆ7`·õÓ Ø‰Ã›ºuU05eP¦èï¿Ì%ŠBÎKß}ðöóm¢>‹bP<¬iž ÃàC¥Ù™®ó¯õhæÎýZó¨_ 7Nc?¾-Ó6‡B:È%áEUÀ¸¶6ÜÍXÞ Ëê² d¤nÄ£=ÒÒYˆ¿!F&Ø!IÎR³9²’ïC‹¦=ŸÕ-á˜:(lôƒk’›þ¢qÇþ/l¡¯ŠÔZy¶ О¨“žöMÊF=õ ×7F×8Jlô®Êb\÷螺hƘO“é·H°é;”²ÃswjÀhÊFôæeíCJx«ôÁ6¤·0ða½°//ÜÀlh‰‚TêÌAni r •›ºÿCk#’ºYýL„‰KÁóŒQ¥³Yž$XŽò§ÀtœMù± jßÐÊò`jÊ~ ¤£¸%Á“~B¨uOCà)„äðý«FX”ž9ºz¸[ˆfÌT7vn)ˆ€Ns6쑘³Ë™Ûxêú7º7`µe ²žQµ7`MæuKè_À¡(›s=‘©\Š1Ñó6þÁÜHËÛè›§çU{qC’åÅd¡en×õc*ºT£]#†SÓ-kCõѽ^7 |ê´´¨Ð‹&Àêa» s“ˆý$ñåñÝíÛG”€Ç]µ¼h¡{és§ë—Fj%ÉBÒKÙ€…ÐD9Øáᢉä<ý¶ÀM,%0ͪ´–ùmy’ºk6KÜe{§Kǰ¾YqS¸)\ÓD‹ö2€êÉü¦Ï²À›Ã¶M·ûÅÖK|˜»K°?$™H.‡ìƒ:týÙ_=8@“0ø±ýÜéÐjœÝÜ%z®4æÓ±ëšj'š+>²’P­›u˜9­]@F¾êÒWç5y³=àlHuê¢Ð­šëýJ;¾©ò@i=:3-³Z汸Ÿ3ŽôGo£1ÊuQ×jG.ûq  ½P§lÉžjw+bçÇ8¦[Ú‹êz˜j«ù­îtspoÿ½v}}ÉD7È,°—èˆÑe6Ydfó™ô:/Ñõµ"rŸáÇßË3“¡ÓÆŒø¢¿º¼úþËÝêøû/Û«Dendstream endobj 75 0 obj 2438 endobj 79 0 obj <> stream xœYkoÛÈýî_1Ø~(D΃¯¦(àMâ6E¼Ù:*RÔJÉ,(É!);Þ¢ÿ½ç΃¤å8I‹ˆÎܹsν3ùÌb.XL¿üŸËíÉ‹‹ŒmÚ“˜mN>Ÿû‘ù?–[öóìD±Ù«„dø=[Ÿ¸‚ÉLr¥Y¦R6Ûž\FS9‘IÓɧÙ_aÏîÊ™P´i*cÅãX³iR°ÙêDq™°ÙÝI"&Áó‘/DöþÆ lp£ý‰=ŠQÄ/À=ï p ÈÏž€¿ñ\)[Âf+Õ\ˆPº[W·™°—>ï~ÈL€Ä:zu;¨ž-²"s«TfY g¿óu}oÅ.çºòØ9›©Å=¼ UI†eű¹Ãfƒ8{ki™H®ûE½©Ëè~`wU{M™_™õ¤@9•.¢òPwôoÏiŽBùòd`Ê@y‰™(å•èOtí à4Û¯q£ÓP¹ó³‹Óó7óWg!æžL0ÖÚéüÕûwÏY{c–ÕúžM§fG›ïëÕš¾Ü×(–+´ÌxV ŽÖÕbugý̸ …Ó‚ËÂ¥%ÐAÐ|žGÕæuÕÖðÉTí"‰ÞH«À°$<Ù„xsþ˜Ë‡Xš,Î[ÓÍ­gó¥kBæQ9¿HEEnË}­›ç¯'’6êdœ :Bð½Ã@'‡T\MX¹F Ø0ŸPè}AȇjWuóÅUt5qZ—¥Y÷C)²\Y‹Ós[jhwS£|­-¡‚’%ˆ ¯Jv¯öé#¤¸‹˜Ž.÷Û›ª6SJ!s¢°kݵKéªÕ˜`9ÔëõÇAÍ@YÕ·Ç!9™¢D.Ü÷D·ÖKUìœ{ñ ˆS”}…ä^¼ùó|6)$mÑéÏïÞÌ?¼ýç¶=´‚^×Pjóî°] ·À+TBÿ© š`OSCÙŸ]EtD_»w§fö¤_þ~NUjmm/‡T;Û-™K¦ Jw9!“ïN¢g/&¿Gµ†#~,DdÁÇË¢Êncž/®²CŒ´UÌ wƒ Ø% ‡Úê7îMcž3ÌW$œ4…¼x{ñö:Òü©€ª¨I8\dm×Á[¼ä¼‡ZôÔH—ë§®q| åCjæûõšøÓ˜ÚÜ–»î%íƒì棵)ë5-mÌÕz‰Œù§«U3Ø £ ‡ÚØ©ÿ4£9!ö´9Ô¦½|í³Úgï“õ|ï;2ózï[ú¸¾<0íBT‘vÄFweeÓ”÷Ì™+ó íä>dPÙè‹ý¨±W<î;«ÅD%X‘D÷M`›³Üè,S±Ù )YÎ,ƒ ïéàSàLcL I°Ãgƒt£LO!7ªL½ Rयµ3åòÚ…J^á@žEÜÇZÖ1Ô§A…Ч9\4$0Ôfçæ‡Qhè©Ëö—޳3ß¾brßSßáÞ².›ª»gwÃAV\¯(Ä8®üA`}Lt Ù$Š‘1ÀG={èÌ©c®âù'vc`«v4S?j¤~„¤6è¾~Œï D®Ÿ!37BÂÈC¡úQ¦.Ç`(d0Mˆ´ÆéR0ô¯° èÖì:0IežˆèËÕÄ©òxRŒ­¸=f7:žzKú ¦ÜDÜvÓßL³§‰§UKº†t&R2 ‹€þ8Ÿ©n«)¦í´_¾®údhJ=ßÈ—BÔ¾lM¹CMÖ‡šûk„Â@+ä&z»fÎßk³ûŠ£Y‹~lzèèØ?ÜmüœkíÑTÕ^ïpx¬6;Œ½+þH¤5%²oˆQ¯•G —æý%Pàçïaµ­£9ôÊòæ¦FI vÜÍ"¸ˆdBn #p¬Äqì&Ž®J¨âaž»ÌÕ7K¸— ‡LŸvÒÒ> ÐTùŽ>¾C Dœ†ïþ.Bì£ zâÆ¢xã žA éøqrÎm2 Åq?˜=ÊÅTC>b¨]P­H‰{$#þubD’çì«á#¼8MžŸô9îÓÓíýhåÏësçI¸‰Ð€S²E‰ŸHª¶è^ ãÇ|…[jO­oŒù—a¼·-ÁA§ÐýíMmh†¢kĵ9VKM¢“'˜~ü,5U)5ðäÛjËн¬Q‘-¤M‹[@Ƕ;{¥OÒu>dç>ߘ'é:pC!ɧ·Ǧ0ËIʾÍ];ùüU¸ÔÛ!M~[`P ™*⢢×€) «±˜Ú´Ê~˜Åšx G'é 5YAJÏwá¹åI®äÿWz}G¡‹â¸ŸôT1Ä÷ö°µÄ_™ ±tïsU´š÷4™Ëû»;ÑÅ)½í÷É®‡O¡uƒ1ïäSX D.õ÷°Ð7 ¶g7Í~uXŽñkáÞ¼ýþéUäHìc|zôôš~ëéµTb¯¯öøV Æiñ•WÏ/°ôìÉÄcí²õ?túÇ\BÎ÷ŸrÝó©}èdîÒû`êÎ3ôzö¨õϺÊ=ëÞ¹¿Ñdç¾cȱ/ 3™æôF o¿õð+éêñÿ?læ¸Ð©ïo—È ásw•S!Ó¯^«sèrÿ®äRpzq¦!µ 7ÙJA¯ÎwÃsèbÞ$òÀûÛѳähÒŽša–BU‰:Œ~f™ ™ò”•ÌÇ3²‡²÷ûnÕèTS*þrŽ®#c)† ”õ{ø_of'ïÿ' a+endstream endobj 80 0 obj 2542 endobj 84 0 obj <> stream xœ­XkoÛÊý®_±ß.UDÛ}ð™´ÜØF]äÕD··€}!P¥°¥(‡¤ì¨Eÿ{Ï샤dßøK‘‹›@Ü9;sæÌ~c‚K&èû{µ›üþs¶íD°íäÛDšÌýµÚ±?Ï'šÍWX%ÃóÍÄî”L%Šë%:fóÝä6˜é©ŠD fÓ_ç…=³+eRÓ¦™š ²Y”±ùz¢¹ŠØüqÀOØu“ïŠéüŸØŒâö±F˜Ÿ‹m—/«â5»¤3‰d;ŽxÆÒ. ~¹ æP%xªbe?ÜŸ¯™fwÁfªBže"ö ,‘‹ƒ)¸½`vËë5«ò®hjÊL…Чñ)³\ò05Þó¯eËÊ»6S)‚Šƒ|U0üš¯‹oØc›±SaH§Ë(…{ϸ%ñ{ô¬WìÁ@˜òXhLèýЦ-÷uËÙMG«¢˜«,e§Îð©6÷àöÍ#™øãKÿÑúÓ2ÿ±®5ÀÈ2÷¡\®él¥©Ã¡¡94o6,oÙ~cîW§Çy3`iVI)-Ž÷MY1%ḐÈ"$JÜ‚­ 6ÈUÇVû7M(G:(·‡¦€]V2ž¥‰ÎÌyeÝM×:ÐU!7bõâúóÅû«ÅÛkgE™wZÒ}Ãé‹ÅÛï4ùÝ}-¬ãp‰zÏr ¿Ëˆ#÷ÝþPóÌ"m¼µ'„±ùqEG%:ñ¨]¬z8cÁ³P9œÝrØØW‡]ÍÙÇÆœÛJ«'ç¬×,g«¼2—3Ã#„Ø;y8\Ò`Y´E·ØP-.V6Y¥Jƒ|ñ`Š'ÍðïêPÜëåöÕåTÑÆ0ãeÀ #.–Ñ^wS–o(SûCÃlVH:ô9DN”uÙ-–w-²™Nb§}B€.\ÞPP¯?’–þÉšâ¾Ba™a}%R.üÍš½Úf“Áßæ…‰S§tölµßÝ—U1ëÊ]rR‘–4a³Ç²ûjkTpmˆcæÍû;¿üe(ŒÇºg¡¢DÜ™„»¢·‹yPV;~É¿(ð¤Î<Û]>Nžõ¡bxìÓHv„Vw¼7œsh‹5ëöT)]^Ö¬¦°$¹ò7lËe0D•+í¸"˜5EÛíQWe ÖÚåXÅð—O1-p|Ô_˜°xãI9”*gì×!3·¥‡T¦¦P×"Ôî°ã˜é@J†©Ç³þdšÍÛ‡¡Ùh@”Dn…¶Ékãì¹YUGSÍ ‘@6j0·AdyDÊ,-uH¶[¸hogt ¸¨É÷7E¨"ÕXÛ5‡UÇN/fqUwÍQ/ZöƒcÊ{T¢„ÇÆE»ã 9ˆzXì7ªÁ¦¨Š‡¼îÞØ{aówOV>Pp :ÿÍô§Iòtdï/yµ¡EM±­;Z ÇÇý\·å¶FÔÉûf±¬ö«-ª¢¦õ‰­ÿÔQ±º÷]C fãp‚ÿ>ù6¹/ú$üM¸,P?àtüÙéL¦BM§ÁXù¢9T€ƒ.Í‚FM4<Ç…˜…µÔ–ÿ6Z_¸ÇßÙÍ8¥5 qeiàŠAA |ç<‰ôÍù@+gÚõ<ˆ ã u·¼iò#3bm/•4oJß.¾»¾­Bù´\ÖË©Ž4e›Ó‚Ó‚‡IꙥØ6² ­Y£ˆ¾‘TKK‰?z”ˆ¼>ì$èÔÚ{‚ˆ¨AeQ­™í+®­´†EŠ|õÕ†J^ရ¤ècÍëqOŒ »jÊe±vÍC4e«nÆ¡¡kÆíïg¦!ë§^ ÿý–”ãªÊ›²;²Çá àè–膙Ç•žÖÇDFS¸t4PS3VO*ʆã-™QÒݾÿZö=[e½…ð3ìèíIÅQâì«“d‘àU°¯ý8SÐÜFÂÈ© p}ߪ|œ ™ò¦)#ñV‡Ö y—Y$Á^»¢îú”M#®3¯ÕÑNܲïwSŽpL½DѨ÷ü@yáe6¥ÐÜ=›ßöÛ¾Ðÿþ>•š’Kï^µmjQYôbÛö]ûç—W×7®.aÔä‡öC ÒÒRëÅ;ÔjÁê=t…/Táç‹$íØ:Ä¥ýdUœ>‹x÷Ú’À9`æÈ¤P' ð¤vƒöœj̼QŸ)Œ|¾”ÃnÔL/7wèàp2ØžÅøÕ Íïlï&†YÐ*Ó¤/Í?L‰ôþhS EGòÕ_‰%i×6ÃÄaE&¶Ç~7}È,I‚—f1°ˆÓÚ¿Ùº².HøP͹èX~wh114M`ë¼ËY{OƒªÕæ‹?ùEŸ„ë–c—  ) šk†vgÒ'&Ø}ªÛ¶`pê‰Ì›¶ìÏ[M{Ôê-14Tß‘¬ÀG ŠW_<µéyÜï1„¶$ýÌ6+Y¬@£‘àUái$„XA³UÓ«BŠÐ‰­ej èCIú,ñK=èÐÔ%JM5!A¨^î‚¥AFМã-:—à˜¸H™ñ˜âÙåGŒ4,”yEn“ª-(L n”­vî&:6H1Tƒÿh³MÖ„•ºñ[GØ’©g¢ÂÖ_“igûª²‰Ÿ!޾̑m6qª…ƒüþ¾¢ÄÀM˜n7¸aœ{ÿúLû/7{Iw¦0¿&Yè* 7s•­×÷èüÛqïfÆ‹]²U¹JDùþ½áfsæÂΆQÿ‡~xñ^¶Ž¬<ëš);ùÿ°n–¸¦ v§ë§Þ°¯Ï5‚¤ë¥ ƒ’T¯d&10Ä^8ƒnfx?´YÌEãýo@g<ê• Ñ•×M¶e¡ç Ù땳Že¤ ô5pœ`bL(ƒ}ËãiqëÔ~«Q¤'ªÑûÿpÒj„òÐ E4ðæ$:µ{œmfa<”û =øáÕm÷Iú4wp]™z)wâ„÷zÕ¼CaÜFH¶[”·y©Èt˜û*¶üŒŽ”™©:“ÚÇ×Of7z^!7FÅ4 QgÎdPôR¹[T&–Œ×PÞ™vBg¦ÙìÃöÕ'£çNå_A”´S©Ãþ .¤¹Úî†5 ¯ºðÏaCõèbX¿T=‘äîydqõOŸ¯¯¿\ÍÁ°ânúÊ¥ 2÷1¨&³Ðé%z™xçvݛΟôhëä3ˆR'ö÷ÑkÒ§'Ä=wÆoã’¿¼‡6TBÉaw>s7|ú25Ÿü þ˜ü9nendstream endobj 85 0 obj 2511 endobj 89 0 obj <> stream xœíYÛrã¸}×Wà-Tj„àFÌ›³¶SNÍeãQ²©²R*Z¢4Ü•I/EyÆùútãFŠ’í™÷-OÉch§»OŸ†~'ŒrÂðÇÿ^=Lþr›‘í~ÂÈvòû„Û—ÄÿZ=¿Í'’ÌW0Š ÿ曉›É‰È•ŠdR“ùÃä.™É©HYÂgÓÿÎÿö`ÖŒ§)eL‘Y ƒÖNSÅÉü+Œ.ê5é¾”¤ÙÀ,£y²Ù—Ý"ù¸˜’ö°+§3- UR$MkG¶å”[ki²­ö]Ù.’[?¬Ø!—vé§Jáò"cÔHØ,,ür1ÿê¶Å MSáŸß^K‚›¹Ä×q*ì[šÜ¼9WØYRK*“+|ÎÜ×ÍêðPÖ)wU¹§ÓYÊX2‡>M…¢¹ÉLRì%©ö¤¬àí_í” –’› .èç}MS7¶þºl6ˆÛ²-wåSQw~xt–4”+?<ø î-릞ý¯l›wˆ\=Z%Ïi®™èWiËm}xÏàÔÁ6˜tPˆŒæ¹¸KJç`®D²)W]å\hNÉ(SYæm<•=μ߷à4“ÓÝ3©¶uÓ–kr?,9täá°ïÈ=€¸¬«U±#]ÁØ„0T`,O³ˆêå/ý:9Õ2ty}{ñájùÓ5¾ÖåÂp÷ŠQp/"w±üéÓ{I!€ÇÀÁšü5r…^RIÊzg>ÃÓ³¸v‚!cwÇé§ÍÝ&‚ù™äæe8ëKV!uæA=Ø fB‚‘™—å ·)öd¡å™¢ÙÐ’¶àÞ’P¹çL‚æ, û½x‚/$ófp{¿†Hƒ-»Üà™H!ÀTïË#ŒsÊÁÍ# KÓùpieòè]; N`yfØuR žV‡]ÑUMíÁ Åz cö¤ªÉCùдÏ~£¨@ƒ ®=Õ}EÃÁ0ís‘BÌáQ®d9‡XW[¤¦Yš†}2ålοÀfü~…ª1…ú3Œ’!X<— @¹ðÙÀ\¼ÇáGÍhÞÇùkÜXÐ…îГyF3L!¾›Ë$øL(ŒQËÇHÕGÖ@]¹?“™œ Ê2ùBf uššÚălªxÀŒ²\Ä“—»µ§=NeŸuÜÒ:Ê2-TYÔU½ÝvXråB„J€ìB€;Gi裣íàÕ¡mYäÄÚ ,þ~2ÿó]ŒáŒóHBê ËÈY‚D¬‚ŒªÜi‘g©+»)2iCâˆK3¨äi|ç9Ô7€c*ÀcPÝ•Ek§R‘ºR<ã ¼kúxÓð>p‹rc!(j¥-¡´6R€ºAYäÙ/¦”`>ÙÕ€ôM`¤ÞœÇßS¼gc²µQ¸Ù%ŸM#~ ÷$Ù?–+›:3­Ýˆ™|Yž ªöºgÙ=?–ãTb‚*‘Y`à¿!Z/§X“yÊÁ…WÿùùvùéúúóÕ*‡ƒ¡V€ž|†üâèI]‰7ëO²ƒ ÄW0ž… 1&šg™lDB RdU/šÔîtΡ “èLmSqDõ§z‚+(=}Ÿ(ŸåÝ—ÂVŒË©å”óì<'AłЦ([úzó<ÊÀª†zlËN±?7È—D!g3èb‘´–m˜_ÔG5ËÕ¢3•þOÖªu¡ÀzíAÝ?õ ‚ÚÓ1Â~÷j1È —Ä¢ò”~¡’ö{-@Áµ\‡P½Tñàūϟo>}„3‹7âÓ)΂LD…š”ßΊN—‚ˆÄ"¹z59„\®ÔÔÓrÈ£LœÖæ]ÞïšÕoË]ê1‘AÝäÒ¯ àJ5ä+¿í¾ P¹ƪè·^Õ3·y?9Jô…ÙébW…$Øéñä±Áð„À½ý<.( ð©Öƒúê¶üص£-ƒü81æÐGêùEPkbxøÖCZŠ· Øö ƒb2òUF5èŽ7X#÷òâöšØà’š(be|ý-D%W6WtŽåœÌÜaÆ€2!–)\úq¦ûé$4Ä^~:zÞ¢ >j/S§‚-§&´LžªÔ´ †ŸN-ÔŦ9Ôk§8g굆ºËíë ½Ö¡CP¾C°ù‹h2še2ö×.›ÿ훦ï'¦®¾?Nvy&Ù—s V1k@¤ ‰téaà²wÁ¹?ºOà ‡¸øŽ5û(¿¡ǘý#¿ÿÈïïÉï˜ÍJüH6Ÿ$1ÊaÏ‚"Ç^­{Tb2x¥íärµ)–ƒ1¥á QïBú.äLs‹oAÿg*¹ ä¦é›qY†ô0êͲœRáb±ÂÎgWý†ãŒ{¼š(Ey¯ËÂËo·D€Ée¼ Ë¡ZвTyZnßX?¶ëH‹Ô4í«¶º‡ ú[›â¾9^=‡‹Üéîºpßf¼F²˜.Â2*èw É·UùØÙ`ÓŒ„>)tR/õvÀÏ*öv ùµoîVE ë=¸nÐÃe˜Ú@ëv{õwIšvt©¬}ç Û¿>^^]ß|¼ºtœÏ%ĵÔ!§´ œ ¹z¡ ù3'Íågüp°·ˆÒ ,xÉ&œêfR. {±;“ f}¿âºN·s E!‡zð.ñ=¥•Ïi”Ïï=ôØ©­/YB=yÂ¥uŠfÎÒ «Ò‹k¸X€ò¡XµŽáðñj¢Að—'ÍåI;l§OË®¨v{r[®šv=òðÌ@$ð¾˜ÏOîD€N F„ˆ¿üZ´›%n¦Y^:Ããj¤ `}5r·Q V²­Ž‚ú*Ñ“Š vífŒ‚}ßß­—¥ýEa½iÚ׎A*ó ²¯ê-dÐM‹—±è ‰÷áG×å½—Ìdy$uWÿ’Ö>«  {¼“†ÉXÐÃ^Ò7ª~ðnÔ HlÞþâ@¾;w«µÏK“u<ÆíµÂ»‹Ë)‡uyÒ¼¿èïÈa_n;Py­»­–TR’°ÝŽEQú./vãÉ“ìwÃŽŠŒÀ“Å3Lð~vÅ qü•ÐÕ|òOøù?0˜½†endstream endobj 90 0 obj 2312 endobj 94 0 obj <> stream xœXÛnÛÊ}×WÌ[©@b9Ã{ó”Ÿ-’Mä!.Œ9’ÙC‘ /qŒ¢ÿÞµçBR´Q[Üœ}[{í5úΟ³€~ìÿÅeóçÏ);÷›€7ß7\?dö¿âÂþzØ„ìPÀŠ †‡ÓƼəH…F, v¸l¾yûp+âÀûí¿ß쟛½B?"¶ñw¹ñî¾nÿ†?<ã™Ïs!p|óÞ}~Ïbæ—ê¸å¹Ÿg¹7ž.²èZÖ«b¨Ú†•r¾v€ˆrÑÞ_ÚE?tc1°»'Ù>ÒwjUÝ?ôì?äžG>"â™ î#²'D¦í?N¬¼”íéÔ«á­±f‡›Ô ³/Y×Úpx¾ª·Û?QJóÓêܨR?®«F5-¼|vªjU5¥úIo¾yÅ£ìØ›í>Aà‘…Nÿ­)é2hï¿:2œ—êÄþoʯ|J©Z6Þœ,>[4:ÍüP$¶;!~)Áo^Õ³áQ±ãó X{ÚŠˆZ•ytÀŽ=UÃcÕhÝH ùah;Y5§©—;¼ ;œ¦s4):Ÿ.Kz¡»H²÷)ßE×=WûÛ¨î‡qj‚ü4ÎtWlÌdΊ¶T·¾™ŽK5C÷Ìî½¶cÁneŽ&UÂhÎx  eo=ÙPS?¡_àKŸkª¦$W³›ŒvV©žá&áãr­jódlªAç¡ßIjëï}QjU€½3pźûúðñÝoûÇûO€`G/¼_!€"sæNÍ£ˆdDÆmÝL³¼Óùr?ŠÈ4Âl&™=âë»å4DZ £\¶ÅxAžëÆaJ…/¢l×yJ¬åünÀGæ¬/GÕ±§GÕ)ÓMÓ§-'Ô¥©'©ÀcSkh*«¨éd Óf8WÁÀø×knë?Û8Æ¡qî½àïf”oáȃÀ²Ìe‘eÙMŸÀÛ0¥ÏMŒM±Is?NáÃ’ãÏv§"ȽӠ-uÑÃÐçAš9+{$™Eö\GÇÂ5/å‰mÒvÙÿ4 \÷êô ÷ygÖ8q±{ªôÙÕ&“` óuz”]ÛÔÏì<ÊN6ƒR¥FP&¾ó©Ü~J½(Ù`¶Nc÷˜\&ÃÁQd+±‘Ij¨vÆ{?ÈnÐ=˜(™Iàa=‚ Ђŕç™Kø 8.p¡YÄ© -B&ôŒÍÀ0FÞS¶è•éÛ>äˆL¬±¤›<6šñdv ª;m1A9OJ3À¥(KÃÌ÷Û×fXò–ëСÐ3æ7 —\·@1–ª«ç@à^ÄIìð^#!2gÐC?š³×É©F‹ xªyßÚ¼Ê=7´“øi誾¤H“—†À‰ sÄÌç¦Ñ¼ P©†%x7ãw°$ø‘‘¬Gå³÷šó2 q^\Ö€˜v…,áÀóüeà u2Ò¯ßR(ýI´ì0—4„‰ðºÅ\ ´fâSo.£ŒVý?‰ÄM?&ç¿Ò¬L¨à•uð{¨íÔÏaÝ–8÷“Ü¢ †“äÅ Ó5O/G :ÍÐ ÞžJE‰G ÊàƒÕ ‘cgÏ@‚SÙäkÑ·c—| ×o¯÷H˜¡ÏÑœðrò×Sc?3§—¬u’/·žÍ<°[+ct8œ%™Ÿ)¼Xi5äÑ2ýt•ßGe»¥Zö¦æÓÃóì2ö³D¸"]U¿êÈ>§MLg]ùœFÕs*üm£›Â­vxRI÷Þ[Aëu#ãïÔq<ßPÇâä »-šˆbdt¹° uTy¿Ý±Êô,ÄŠf%‰ ›Y%ýc;Ö%;bKuXâ; …^ÉqâÓ”:_ìÜŽÚâ޻߮¢5˜T] ¶¡áПÁ3V·ÍÂåQ•NÉ’¸HÇ*ÂXo=«S Oô -tº”&7'2œ5e&(Ûe»£~^r`µ’=Z ½WÈ^ÍBQ²þªŠ Ë»kÇÁn¶½u悸šFÃÍ'ÁÆ&¹U ௺,& ,´u%cÔ&M~¹’©v1y›´WÓ¬¬:Œ4X÷UùÖ¿¼@ˆ wژϪ=ö]A²·Õå´ùлÈ8„`a_Ú‹>=ŽækÄdâ›#ÕŠwôØeoærÉqæÞ¡Élª5'0™Ò9Gçn£ŒD¤9ƒ][-´H¸é«*ÙhAW­±ÌõO-‚h'7—} ^hº·$A{Òç銲¥¾›ørÙ¢ÝÝXÛû^?r FŽß–‡„5Ýg1Æ"I\¡­ñx?ÌÁN[àä¾.Ñ+×*þ%'aw¹+ñ/,ƒ<å|vmõ„6¨ŠF li {¸éÌ¡¡mûoH s×±Õ±“^‚¡yZl€½,K îä’ª’Ô}ïà5zò«NK熉8¡rË騈ž €S#—²Øwc„­˜hžPÝÉ ¶I> stream xœÍX[oÛ6~÷¯àÛäÁâDRÔ}ꖬȖvXg ’Á%ÊV'K®.5òïwHŠ’¥(išì¡H [ÑÑááù.<Êgä`‚ùÓ}ƇÅO}´«Ú->/ˆº‰ºø€~^/ZÇE(‚ët¡Ÿ$ˆú3ùÌCëÃâÖ²Ù’rÇböòŸõož²©Ã°ã¸Èæ”,vBÈqZXu»­ÅçV ŠâXÔ5jJt(ëf¹þ$ Íb PXž¶òl›œ¢*íbLAÁ^H» [+m‹¸ÉÊ¢Feš}Ô rûIÄ ^Ú<„ ˆk­÷ÕMYE;ŽeV4"õUÝ6 ]ìCb›¸2Å¡«KÞÞC¶¬F‰¨ã*;Âã¨Þ—mž ­@EÙÈ´"Y¡¶ÎŠD‹Én¨Ï±ã‘n;j/›DDy^ÆwÖÝr²/B,κh³-,£l„º±ºJGUxUÔˆUÊtÊšý¤‚aF踂4+²z?W€ãà  Å“DªODöÉÕÍýQ$"…¾VmÜ  •ú"›úÇáâÍd Ï^/8v¹¯vð¶@l"*bÊEËFd6Á~õz}ÎIJŸaÊy¨£dfOe–å!@¯M[B6©< Õ­¢_Úæ( $ âfßÃ,ôL»»ÆÕÙ6 Ët®w”bSêj’.€]xN8!Þgy"㸼9‘œb£U)ƒ”ºˆ+C –Õi¸IÉx‘2M@d;[¯jöt8Õ5œÖ­PT$Ð?M>, …ŽVH[C_£ºz¦‘þƒÐ«LÀmÙ6€0üîÉ´Giõi©^\]*¦10— ðM9CÔ gÂÕ•ta])½üƒªÑ“º=ìŒX¹ï>[¬®Z\GKå)­úA߯{žf»Ê¥û é9`F=ƒûÅÍæâúíú3Y8`2Ÿ ;íEf„ò²Ø‰ °;¹¿R±ƒ€QzŠ[<3è)uì)$£D*ªh›ßŸu)æ40´[ÅC†®¹››ªÈ…ôŽC'*êzºfÎõ•…½eÚßZ‘Š±Ù™κÑuVœÙ‘¼šú‘öô^*mN‘tìB>œÁØ…dª),T¥¼E•x©ûp|Ú·ºŠÁ}Dýˆ˜ÁzîΈYÖc;h£žl]¶U¬¹l2w¥ÀqÖù«*£µ®žûØea0 ‚n­‡‡®–§¨Å¨†A Y‘dKêâ0àõ%KZhÓýX¶òØ>o—Y|–f³Òí8«©c´‹ž–'!è>‘çõÕ‡ú¤øIq>`3sÀº!qÇçy*¿ËËm”dÖ×S:sìÃIø:ƒÙ÷’?O6ÉÂÁdŽÕWÚóÁÛø¡h6;µô,§¥ÈiW(ø; žÏé]¿GÛdÍREt€Ø;ëØnÕ×»å( Ïõ#ð܈èßyõFw}<øš`æ‡#€d©syË}!>è¯wWv}q¦fkÀdá˜Á3‹ú8œÿl: IøNPؼ!à¬3M‚Cö:C:uû·MÞ®†´½Þ<³´x•…<|¦©…ŸoC!æ¬#x ¾~‹qx§cÞØŽn.ßþ¾ùåëË¿×ÓÕÜ@a¨ãï¬r:?Ú. à´lô,§šÐQo­U¤^‹rx¤0@÷Sƒ–XžH¤V@Ë㱬$ì¸<a£Û,Ïšû»%zžo‡ËÁäißü7S^M=󥚔¹¾KMJ‘=®I6h’½nHh²øL•ll¨&/ÒÚü3]Ã/ÌäÕÿj¦ëALßprÝÇ€ ¼þÝÈíÞ&^ DU=l2ï9l·À±Ts;¡0€K§”ea¥l˜I%jtYù‘ý5ãÎ6¼pógê#¸xÝ#êPÒ ©:ô{ÿ-ér½ø~þt2ƒendstream endobj 100 0 obj 1455 endobj 104 0 obj <> stream xœ­XÙŽÛ6}÷Wð­v0f¹I”§I3-R$(:uÓ‡IaÐ2íQaKŽó÷½$EmÖlMáÆ’ÈË»œsî•¿"‚)"æÓüO޳o%Ú—3‚ö³¯3j¢æ_rDïV3ŽV ¬¢ Áßj7s;)b’a.ä!Zgwó%_°€ÌÅrñ÷êW°çvÅÍ®%#"Ð2€õÛÙ¼z8é­Þ¡²*ê¤Bï¿©b·þ¬Šuù¦»x»XýÓ?›Ù3Še Õ·ÙüCVV*Kt‰òÝâ‡þy¡ÀŒË<5‡µGö±ð«ŒKHºª‹LoÑ®ÈH¡²NàŒrWP¢T娺×è_>,Ë“NÒ1Ë"0Fxc+Mš£ÚÆ1‡d-©°+¶Ö§½®ÖgU”_æ_#ç(#8 ƒ ‡ðÕ﫳¤Jóì ©lkÝ­KpU•h«Ë¤HOU^”h—èk­‹r£6y]A¢Uå¼Zl‹ºô'x—ÎÊ<¶¥£Ñ&š"U›ƒ.ñ8&¿jÉ­bœ¬ìMQä½ÚÚËqu9«7wóÕ}Úò4«J“zÕX®!ôê^UèTä *pEl~Naì«Tz€¬¤$â¨L¾š4hsri1j¢þ8#XÌ:»tRÁ®ÍÃLAŒEÔ‚énlíŒ÷¡Û< H qØ,Åv ° Íý»y©¡F¨Ôàé¡ fÜF1òĹ Xo{þP GðpŸ>¶)æà[í’–Û„¥¥Å—‹˜ùÚÌbÚd¡Í¹‘:¬0™Ï7Ö ¡ËÌš•6».1,6as‹úÌáU—އÌ? v1œ Œ›j¯]½¡UîÜåUÚºK1 „ݲy°1õ¡RÞçõª¨¿Zo¯Àÿ4Û°kôˆ{Ç·Š‘'ST¤ÌHüÙN~¾¥Õ½ Ûîs¹0èÓ„ÓB´<{ÿ×úýÇëõÍíío·ã“ˆÁZО`5GÝë e9À"ÛC12ˆ ’ãr ÂB"a²Êˆ+ª‹êêÔ¦›3»¤a³Þéý0Ü,:Ê_%Ýf ÐeþÄz)mà(¡#ikÒ¹¶˜˜Jjíå„\«í¥ÀØ5ÏËËuU馮t'1í­é&Â_ÒD¢Ë&Òš½€ˆ°ÿS+¹;‚ªp>J¨‚£iYù\ è¿rÜjmýóŽnvúHŠÑyÛ•,›3&}| üÒŠÏÝ|س”MöÂÂKò9dt3`TÔ¸úí€ÍºZ¹Œ‚F¡Çm{ÆüRaÐS"b¦‘Ä"èžfÛÔ<U粓±0rG€†×VØŸ \%œ¾X¨µîV¿Px(¸'}Óñªs½ZEg Gm+x\p®@q,nÇÇáT(kåù2TÄŸá?çÜnàîo6…>÷ˆo¯Ç¬7xqÔu†Ò†òÀx¤†œ§ÐB!†œ·ÇL0‹ú„=Ï÷ ®Ç´B91*{¬Ï¸Eƒ1ÛYÜÎWƒá-¼%Ž[@LðÐóR¡Q§QϽÚ)Ú‚¬„ÌYþ³Zïúqܨ©A%Þêu9î‰Å¼Þ»ˆœtÙõÐtDoJ9—]CÖl­umU¦c8 CzVt>¼’á KÑÁ¤ì:õääs>g¯àmàQBì×WL†À #¿{w{óyŒF‰i×¼‡äuT`F²v€š;B ÇÝHüx£ýyÛk±pñÖ±gØ[%–Œ=Ó[eˆIÌØ€g`o–Ú¶c¢1Ë[×¾§½Ô²â’r;¯ßbû•lEájdÏd– ám¯ÖÛ´Õ¾€Û•#‡AGâ®e‡¬guܱaäŠÜëôdªZŸ&ÑXJéùÈ×vï¡H8Æ46ÝcW¨£ìžFÚ4È~J{ ƒ‹GAÆ_2A {S ãÆØÿ‡±)Yc1Ž|#eöëw¼ò»ò4&å鿼ÙWhPÆ$?Í%¼)êæW9)†)Â+´î7*|û+Ô¹š_Žð!8 Ÿîá…¥êõp{=îáð¶Mès%‡©*vokk¬—!+eýî}YëQ¥Ë^©—TB~ÌDÈ#kâÖÞæÍ°MÚq潞ִÌ£î|RxN»ÝA,™ÿ¥`ø³ÚÍjö;|þ1Óq)endstream endobj 105 0 obj 1640 endobj 109 0 obj <> stream xœ¥˜[oã¶Çßý)øVy±fy%¡O9ǽb[ [[ [²D;êq¤¬(åòí;¼é'Ùâ âH"gøŸ™ßŒüL1?þoq»úöc‚NzEÐiõeEíMäÿ·è?»G»ž¢ Áïî¸r+)b Ã\ „K´»]]G¾f1‰âÍú¯Ý/°Ÿ[•ùUF8&D M Ï—«¨|ÈÛãþ¤º}ÞæõIéÏÑçõz÷÷*ÆiÌ–6¹Ä)X5 ß7æ)»?öYw½5—'3œŠ”ÄþîÒ\°63c¶c°3œüaûºèª¦ÖïQ^—(o굂ڬ߰Lâ Vm¨0ë(Ž%3뮣R颭ÕèØ´èK¯ÚJi”š¾CyY¶Jkä×É!* ‹v7 iX”Ÿºkªº[]ƒO¨»©4wµ:«V³81Vwï®#}Óôçªê²‚ €î,º¯Ê>?ŸŸÐ±Uª|g¨ê“Ýb¢ÍÎ’d¦Y©`YS\ŒÆÖ®}Ú¸ZÁªî|UÈ®Ëv¨{ºS‹øl8‘˜Ayå¢í§ýöÃÕþêãÕo?~¿0"Kg‡87ªFuƒÎ ¨×¢ޤJ¼´`Wm¸ÛÞ¸Pª#hÛöE‡¶öp?–I=îõ»Å•ï0b„†Kj=ø¹Ö]^Ïæ¸þfj6¡˜Ê,ó"Îw]*H2L$õm~µªëÛâ~l›[¤ûÌècFHªM6€¼ËÃÒ”€œtÓg|8àÊKÕ^ŠbB°ä<¤=áó´Ÿ'=˜¶†)çX2:.vÑc׿ mUC¾ßºÈÛ#ä¶T81I2ƒs{ã+ûŒISÔ"Á"^’G=»Äq&¼Iÿ4˜TÖKŒvPæY™â˜ÊàXÆbWŒÚ=‡ ‚rt*ŠoÁ6…Úâสu8­«²êT»›4¶…»íŠK2ð1Dø!|Ü b¤| ‚:X¹¸šø'‚;¯ú“ÉÞãšㆌr `°Ñ6†Ë¼ËAK„Í.¶Ø% 7 õ–'zÚÁVIÈ?¹Ç¾Ž)i1PŠÙâ!œÖ#Y,DC@O“–°ß"#iÉ¥s‡t4\JFI±2(kH’£{›r'šççª\€ –¼^uöû·”¥˜Q¿’à”R•W4Öí86R´i:våÄe°£‘«(“T`x” ©è »¦XÅ0Ѐºè± ÷¨‡R"É0‚à‘V`2´Æk‹fj<ÆJç­W‡­ÃIÒ àƒ±„¥cÙû4‚OiW÷Ç$!ãŸóäÓ3oóÿY.1 2åfwÙÒ‘&Ìnt×h]ÎjB(\>˜5Ü=®’S´j&gXÀpBœˆÔ…8øvZÇQ9Õ‚{PŠÑÃjÃ#¦.ïò¶ƒ2°õ¹õÞx¾Ø˜3q¡ÊvHôu-ðÏÞöמ½ðdÿ´{¼Ú?TµÚÿ·»½Fï.\¶-Ð ¤Ûâ ·ôþ`Åùfî±À$ŽCtEl§»Èµ03Ùm-¤¡ä0ÏYRÒI¤®¡‰ÀiÛ¦?ݘÂö‡N3êmÛéw®³$&ßl¹¶;r_êPf!>³Ñ•s6Q:²úômHÆP ×­Fäòd6Mžnv9!àýeì\Guç8?­% =#‡.iÎÈ+ql S'ûbÄpÍFнŒ¾¸Ú&Ëåþâwh÷Š ·Þ̓Ÿ¤8I|esûÑ(i TQ˜Ã|HIÿ}3kÊc·>Û¢Ê0ãthl®Ç̈,9LÄaDy mÆ)ÿîo gëgû:Œ™ã:óÊê߉ϕîÌ‹ TáœZFÕ.Ë,‚ù.d’'#‡Ç’¡/;C#0’:#–ÓÀ£0?åg›Â…IÿºÓ¡‹æ‡fÑÄÀ™ DÀÜL÷ uãq'/gÞ¶3i€ “ì‘I=¸`˜¼L4ӳͷ,¯"ã×¼h› ̘]ŸBà š·öfán>g°ÑÎ5 õ%xNŸ—vÞžöÍñ¨UwÞLB -ÒÍ| 5 ^Õù@ BÙáVÆÀ%.$dÃØ%¾%N¡e¸'öÛŸ¤sŒ¡Ú·öv±Ê˜Iµôµ€‚B†2z‹XV#÷Êj§ÿ‚4ئ‹´ÅÃDœff"v«ý¤ñ,iø+\Ùj1KÂ¥ SüWY´ù½©»K­…c:@ÇÜWò¬·Ø2ãi4µr¡wdœ]Ývl"— [Ίô¿Õ;_¤3ƒÆ,KÛOû«ÝäüϾɃ¡!»®­kjFcÑéöy›P„Áý$7i}>´!>ywñ×0KüãFKFÇ…ÐN³d°=ÿùûÝêwøùÜ­?‹endstream endobj 110 0 obj 2168 endobj 114 0 obj <> stream xœ¥XËŽ7Ýë+¸si1$ë½ôÄ6ƃÉbÚ ¼è4ØU”º©J®‡Í×Ϲ|”J‚#H€ Éû:÷ÜC}a‚K&èå?«ãêLJœí‡•`ûÕ—•´™ÿ¨ŽìïÛU̶VIÅðÞîVn§d*W·î{ñ¼qöÎ)y’áXñRΆ?¿½zTð4õ9™ >F˜>ºµJxYÊ2:l|5l ëv6X$¾ èE÷Ýçç·Ûg¬|F•‹»I‘ð.¹¥OÑ­—èú¾‹®¬b¦ÛÚ%®\`‰O\tШÎÓÚÛn¢üi‘—K7ß“w.æ)WYñxH»‡ yȼ7„”ádªfwA.7J¨G¼Ç—©©ÆLWã„ì_œåÅ2Mn]±]×õÈ×›î*>»ãü£Ñ-68‹ÍÎïÀΕµ,yYäQÓ]Ë4;é~lªé {Ö½üj*lÂ{°%'þµ’¼È]€ÓÉ¢®R/X çfx¥Ok$Ù(«WÝ#(Zu껓éZDh:èv?é½Ùè=ê$kýafÊÕy7µÕØtˆb>ö—¶©ºúš¼ÅV$íÍ*s›Ñ‡1Î …‰øMÁÔ ðòí§Ÿ>~\ú‰ä.ësn[•€àµ©‡£ólŽîüj°½wSYéˆú&àŽ¶CÕ,1/2”ú>ÞÂ#ÎéêÁÑLk] Ý/“,ñÕ\£ÃiI@p?^Ù Sð$Í‚û …lA0EGQÓÒÔ>ªVYÉ(+PÙy6¢¨DW¶-ÓÒ£Ùtɨº¾€ ”°°ÞäIÆÓ¼ˆ†©zs 0¾˜µ$êÍÒèÒ¡elêA«Ä6È›¢ä3;FuWMGÓú ‚f•”äÆöoÑÇØ‘èxø-¤L,âa¦ì -Aé^ô œôÎPùõ0LG¢Ý%О‹VÁV3tÏE‘–™Ú–o©#ì'—‰ÝS„ö'±óZЍëcÎÇ–­¹=ÔòJ›ËècËLcaTéº"<VN¤,\Î)„áµ›52im Æ´Ä»P©Ó‰`øéªÛ‘ø… Hðl©¿èxyüøê’Œú¼K×þ¾gºvì»Ã7zg´@’M]“›]l¿œ} h ZJÄ~&Ȱâ1ªt‹À‰$^tÍ0ñì0BX; j 2šã a„&Chç³’WjÂX{DQÆÑצ2ȆÅ!zSÃÙÅÖ‡§5÷ã-ȘĖ:ˆ—„³÷}ZÄh éò磬ì(þù»)¿Ø ´§(î:ÜöHmFcÉ΂¨n†S74ö;ªhúKîºñ|H„ ©‚Õ“Ue†&4%Þú _à­Ì1¡áƒ;ßïi[Óº B†¾6úN~\åiàÊ?Ô^)¦Ïõ|´š@÷úîiG¥7&ržäÙ_0± . Æ\‚' °æ¹ãçJŸÐÝ–OÐéõTÙ|µ.«´5'ñhÙpŒ‹ Qøv94¤HeˆÑ.ÇÉ4f_¶Ú Uß¼§–|e`ôåå.f…&ÍUüݘ“4<0…1Q z8½w†ƒ°  ªCcÜ(Ú÷ú8| : ÊT„ {ÂÏÝ0²kZ‰`ðÍmH•ßõ9Ïr_§G"sm“Öý¥.Ë\E{KÞ¤8œ˜¾vïRYBHçY¨Å;²öü>Tì¦ÁR(ŸëXSž¢\=N#¢ÇD&iu§ KÔú:ÞþØ@‘@†‘º8•jOtàÄ앃ZÙ>ŒÔ .g³xÈ`úFâpöÐM#æ½0HÑ)Š îÝZ«ú¬¤º©²k|qc4IApPVRÎ 7j|ΉX¿L¦wžÝ¥|ì†9û'I‰A²r&¡ä}ÒQSJQ«±n·:×Ouã³E\ÕD´”r6eÁÄœ2‘½Õ×ðœm]~¡m¤Tóm(¬tnÖÀ.q(•:Kƒìz&kŽGS;Aɼì ÇÏÔR gÀ´U7„—”b£²úbQ-’ÊÃUœó" <`ê¹6tùªžÍ7’.´„ˆCÒqÿ³N Ó»Þ˜kq^BGf‹*ZLå\‰p1ÿ8õ7×—-J©9ÿÚ`@Ú]ÆáµÆMß¹¤.öiÇ}m×nè½ÉÛQl·úûvœEú0×Kú`†Ðu4׺NùŒévàÄ=/Šr¦ã"Í=·¿Yv]`é? ¿¸Ž¦4s.œmonN ìMkz¨7ôâÁ^¥?!¯õy]’úHéß]=OËS_‘Þ¹ ®*s9$:j ˆRXwŠ9™çÊe!×Aò±˜±«ÉÁß5Ô±þÒ¯¡i\\V >–"×Îtï)D4—?187Ì|“ÈÑe²üÎMbö,qìÌmhà'Xô¼»îÏ0Uxf‹¿³CêÅ÷„º ‘K¡%²Pê¢ý2§ƒ*æFÝÇP÷•¸áŽ`j)‰¹D¢èÔ´›ö Š88ø5^%•3|ùY_˜ÃÑ·1G®cîöŸ°÷ÛÕ¿ñú–m†endstream endobj 115 0 obj 2160 endobj 119 0 obj <> stream xœTMoÚ@½ûWÌ­á? B¹´pH›&*²ZU¥²{±·5»t½EQÿ{g׆@àÙxv>Þ¼7;À'øæé~³µs5¡¨ çØCè~²5¼Oœ’ ½‚ðMVN@‡$B]C²v~¸^Ô G¾{½ŸÉGÌ×F»(/ˆÇÄ÷‡àÐ?w\.4°¿t½©XšÉœÑçé–ªU:e˦€|Y ºo΀‹œ³A/ùå„7ä¼`xHÁ딋•À‹w¿æKãß™fJI}¦Ô¢gRx'9ž/fU¬†[ð'æÐ˜ï7“¢Ö•sÕ,tÍZ—wŽÛºç¶¯¸(ä*].\ÓF ~³Ã†Q'E-ºÉ9<¾‚E›þ¦ßÒéý×t6Ÿ?Î=8G®˜n”0à'pÕ¿gJ^”LAÅžX9ËxÎ`[R ZB.ÏP‘×°åU"tC«j‚±ü%ÂmûDŪJf)3ô.\D7%7ŠSͪéÐÕ%ƒ¶a ªhÖÌ BMV²Üx¡:M–;0æÅ¯U#2Í¥€þ:Å$4åbr}€ûEÕ‚Qg#a øñ™î ôÃÀ8´ñŒã.òõŠž%Î|þ¶ô¿Üendstream endobj 120 0 obj 746 endobj 124 0 obj <> stream xœ•XkoÛFý®_1Ÿ¶T`M†Ã÷ùàÂÐ…›b½BƒE´(q$±+‘*IYöýï{îLÞ?&lÛNÛN~Ÿøú!³¿Ööã|°ù«|Éðo¾™˜>“‰äAÈ’ fóÃä«7 ¦2^:›þgþØ3»2»kæ'"d³닉WVSÏùá¸WËu]¨Õwç¼Ù,ïÔê´eÅj{ÃÖuÕvl½Ëöî]«ÖË*?¨›éü·‰LyÊf~Ø[*ÛeYmêÅ”žÎ.ÿñjƒ9è¾iê†)ö‘‰´„>kjÍ×?L<ó¹Ð[¶ª[¥Z—®¬+íÏÂ#_íù7ØqqTï5û›ZL?¼ö®Ü°…9ã#»û²¼{øuyÿøøËãbÊ^;n¼(T¾ß×륢ž³›pI9÷ÔG/tþQ¡7šƒñ_g©QÝ©©(Ðìý»½êØ®ÜîTÃöêIíY¡Öe¡Øy—w¬«YQ›¬û|°ð¹îveµeÚ—¼S++Öí[ãÖv%~ªç²íZÎÞ½98‹™¯ÞŸå4ÂÛ,¼7a€¥Â::NÍç_–÷ŸçÿvÙ•Á–Çñçu†ÿ¤¯è²ò'#dÏ$ÁS?<tçg8ø“ «ÉŠ­¥¬(|¤ï:x†'U25…?YÞó.?µ”,Æþæ…R…L®…\±œÝu¸Ašð Jl°=,M¹ì3ënÀEì— Õ®›òØ¿9;Ö€,*ë9òžw%UàeT˜Ñò3•e…htýUÁ§³$ЏÈBo¾Cf¿q§"¥óÆÇaI¥ÈØ<\ORÁã ÊL_½s9b¸f^u7*¨à2É\˜j­+x,ÒE¡ÖB.cáj»¦‡Ú€¨›M"èj[:G/ò¹}m²ð )Œ ÇÒf5ò¶i”.¨I{ñdhÉc?5i+¹H¸ê°Wm‹¦.;Öª®Õ@Ñ­Êž¦’àdˆá¤\¿Œ ,JÙ è‹u/ß}q­ìgȳtiF3Ü/?M“æDæÝþôð¯ÛO÷ÄÆU÷šïï@µ‰ô×Û>Ÿ>b‰MAÈ£T#Ë{XL9››D„÷#³Àïë¶-W{EܼÙçÄ‚¬Þ˜øZ vÄä:B'ÃFwægÚjèWõ<øãs?´îý‘NsM´ðòªº‹3m ¶V&z%Ü$ù²m~á‚ï'ȇÊ{ÒqÆÈ¥^qçÊãâ9fň>À!ÒÈ{¦‘‘€´&?6¯l9ÛÁMï¥lK¦Òº#+à6›¸ CÛßåKÒT97ÈËJuºówyäM‘,½'p>òaȃ̃}¹Ò=rÕ Ý8¾]D¡\uº0©[¯ê¦ûF{EwˆCáÀŠy³/UcW9""Ž,ý+%’ÃmA3Ý!³ йO¼-õÄ5"¾(Öôó°çifÖtM]mÑÍíi»U(ë¡ÆüxÜ£Ë Ú­®'¥óÒw©!ñ–ï1O’ØqÒ¦c®Æu ù;ç$RZábЬwÔjHùž3 Ùžµ‘YHŒ F´Øñ¹”±ÁÏÂ;æhbÝ–‘Ò(#• %_ SˆåEÑ™Y¦ÚôófJ ?𶧃‚ZÒ]ïu…;Ì/dá­LÁáfˆ§Ç«Ž2 ß4bð3ibèô¦‰ÜžÖ;ã7|Š’±óvuâN‘…@WÞ¸Þ¢×S5}¤ò7u¾ÞAw*Y¡Ñ~¡ÛLe“Þ]㪠x€BXWÑlnVw¤¡Wd€YGÓÄCïì˜ëeª’Ü´v*I_â0×sD”Û¤îB´kµ—f@ÐXS¨â´ ·ÔÇȸ¦›?? /óCP3Ò“R'ÂáG€˜«<¶Íɵ‹Ô‹`çÐ7Sc¾3Ò‰‚È B¥‘Q¦›]dKè¡oK<€T±¡ñ3ÎÕ »Zƒ*ÃO?QÏ;í!=’[iÓAˣ€[Àá\¢,n3Hµ*öÅæTiůË€fŤ *¸ô{œ%"rsÉh.=tôΖöÚ˜œIh&Íb¶,\„Æ?«Ó{½#†–.ißm+1&Ï›+ 1!²7ù7‘=‡é@ŒGWƒ(ÓÝ®ßc® ¦ÞÜ(ªiݔ۲ʑ$Ì àŒre”¼/3E‘‡°Ó•ùÑ^õBCù%W€ÖU¬êïT°m!øt?Ká±ïQ{SK¢Q ¥;6t'ì1AeÓ³ÑR]/A“#>~k8Š~8šIú1¸ÙÍ/}çðn9û¤¥ x>rÄò2 úêÙ^0§©ŸIß›¹0õ%%wÉ›m›ü€oÁ/GÜë6P¯C*P‚IQ'<BM-‚G¡+ÓS?t¬¨äÉ Òÿ; <½¨ôŠ^ÈAÃ`&JSÃÓ§›ö³"rȰX]y0×,Ô·¯jë²*»³êZ¢ŠW@´—xs ÅË•.Âú_„˜ŸVCzusmTž¤Ì#SǼÛ}ë: %©t RÍ`1–vƒ>’~æÄ‡{nÞ}àþBLHÂVð$쳞_5lÊ_øoH8è¡m¸3†šHêSWVÊf|ÄZ’èU¤FáAꎸ¹©IÜ÷7]{•F$ÑU—š®;_ZŒ4ϸT;5NLi’ ¸ÙöçepCôkfõß Óuaç¶BÓóVÚÖ(«BMºn“HÏÁVŠÐ5\ÃÌ]Â]›ÑæÖ.$”sAªúżÇ0ý“wFFà})™¿£C, sK'ùvJ:*‰pµ£9®Ô5;ÐM,îåî+|^!J€•¢ô»¥pƒ¿PéH'taxæ¦çn1MÞaü¤"´SØfɪ>°‘Ä'`ŽS‹ŒDµÏÑ¡P0YÁåä¬ì}ð’‡ñ˼à2°„®¥—ÅhëÊuÉ`ôþ&0;H$ šL¯_R¦ÃXûÂ5üÙb àpó.)ƒÜÁ°.þ–ª®" l] qz>J”Ö!ïÇŠGª“åZy¢Skï3™½y˜ Í5Õ\#¹po¼§`tEµì£áðßüŒ‚H!ýa·®ýK„˶÷óÉ?ñ÷ÿ›ÐHendstream endobj 125 0 obj 2373 endobj 129 0 obj <> stream xœ•YËrÛÈÝó+z°JDÐ<:³ÊŒ½pÊ“©Q”ÌBN¹ 1Zv¾>çö DÉž’ª$îû8÷Üs[°$æ,¡/÷s{\ýõ6gÃ*a«?VÜ;Iª˜g§Ñ Xãžû=‹Bîùå†eÿè÷Ëã[,\"Vîµø7ZeÌíÇí{O«èPµl¾½½ýåv—"›¬7†•ÆiÁ6Â|˜Ä*±–¿Û_~*‡¡Ú±ºe%½Å¹Žeák»vÓž›fb¥â$ÓÚ- ®_#µ9ÎåÈ<…I^pûÙ}ôx>ÒñµâE4ta¢±-›†í×ñ4êvW·¬lMx6‚óXg…òdƒŒ¥&rYÈÔ›x3†tê8˲`Ú¡Z¸ÆUœ…×¾ "ÖÒy²¼©[“‚$ŠMaòAýÜcàEŒl°eh[¨P€ðÙ9T}Åv]5°¶]rUœ÷åéTµ.í’ ¥ÙFšgÚìøcÌÞ“¡•³7£ßÍsÊÁžž‹<ι.Ãóº-¤d¨nØã¢xìé¸H{&•ˆÛ"P*‹u.‹ic9/Œ•ðî±Sß­yŠ´'Yô¹ÞÁý’ººEØØ¦‹Ùð"‰ 1áIÛÛ+°D$Eê“¿«†m_ŸF»,C™§”rR=tÊ)[i,¸ÐÞ³±iw0Û#”4ÔPïO¦ªÀŠ¢àÓ›™u¾¬·*ÖZIïíh1.Á2i-ø\±³…¦± ¬&c%Bï;=MM ÉTB°¹ ÷¾KÁ§µÈò4#Ð=ÇëÃWG¬ x:›5¯¨:ÖãhØw‹®]âBÂK-&\à”çº#b뚦[#ͺ(Šè‰Ø¶+)ã”gWXrLê@\Ór QDî Ù•Ž»‘È*Ÿº2ز¬1…ù²tÌtœE„jÈ•õ•9%ª'ø² p™^Š.Å…ÍpgTýÒ‘%q.Ôd f …Ï®ä]*ѳ<ØÐ¿uÞ¯ä+AÏìŽóñ sS ów¶ Ü*N¿¥AdObhPj²’»ÉìE1æF¬'”Á‰zʤ}¸È¥ä˜H_¿´×‰SÌÏ*Ž-Š‹+'|gJ]† CüØIÌ•Y±YÕÔÏÙóf’¥±z­•@$¯U› g¸$·k‹S u!4^*ì<Î^=jQÏV¾ž H8"ϰDsZ©PV0¢p¤ %º«. ±à~0µypš“vìË#›«Ï¢ˆUxêËl'&6§9¾¾ W H¶i—?!W„F{ÕpE §È3;S¼‡7vânˆ ê{UölßwGWþ4Xdõô|fhÁÂõiÞ(§" ¶€Én»=÷½¹˜ër·õ÷Éò{#×pýI7 <†Îùf-‰µeDÕ³¦:gG¦ŒÖÊü‘G¿Ü’‹ÞæØ6'N¸Â(R;°üÑ€*h´„~®«±½öôÏ1½)¯«‡Éº˜Án0%1x3»)q¢“ýÔVÂ@tЧ!¨ŸâxFÊKù8V®ÊÍÅÐú0ÖÈ:mN¹D£Yè…Nù¸ã–W2Éey_%€ÄlñbQúš Þ—Ž)„ß·†{”ì4|NãäͽþâBRØ5Ÿ0ÐÝêÞj¤Ã|2ÊHž$âeæxÑ ²‹÷Î;@Õ³Åu U}‘û`}˜ÏDUôiF “8ŒvŽÃ!¬±ØQ8àÃ3ɶԼ4£¥\¼Iø«ñÐvélB7<f@¬œìu¶›K/ºÁäI Î™PœæË{œ½ƒ6]óÜ›*—xö‡ à4i@´ìÀÎí®ÚÛi'ϰ“ μšjÖÝ0m0 Ä©HsœÊ~¬·çÆbÓ‚6³1ÝNÒ=•SµÃŒÄ›r»gœO§æ«i§Ëa1‹å4,^mdR¦§ m!Í©þžTåaÛ‹ÞQeot}ÙV§Ñ^™1+ÎLŽ‚Èürjêm=6_Cäh|v‘SæÙ˜JW'#¦ˆë†œ8Ó²}Œ6"Xþhg+– v»#p5ÐÖçvÛvlWŽ%w¦‡tG˜b/íÅåÞX p„”¡²#ƒ$Z.éÌ#:ŽÅºþ87²˜vVTh1-åîšÌŽ0l8o¶'N¨$¨jn¬¸ Ò8äâX~eûé^¹n\Ä 5{:Ðý2+þ$ gC[OÙ¢;.SM‘ö°¨­È9uuaX;V%¢þ¸?7n]{>>TîVÒì #!EîEµȉÇñOMEÅlzŠWS¤eþÿDtèLpŒXYˆ¢¼ˆ‹©2¿!Š0v_äÅ’"´°N)¢}wõ¯îè¨Ù^÷” ¨â¡úãL—ÝecÕ Z†¿ívWRa’Åø‚ÕW¿ÓeŒÖÝýÁÜ8Kåò~ÝVë¿ØÿPQpd¨yq•{Ù/X†O~F> stream xœXm“Û¶þ®_O •9¡À°™~¸Ô—ŒûÜœ§_ç†'Q:¶©ÔÉî¯ï³x!y<ÛI;Éı`»Ï>û,~c!,¤ÜŸ›ÃâO7)Ûw‹í¿-„ùÈÜ›ûn½Pl½Á*!þ]ïv§`2•\E,U [ïƒU´”q„«å?×Ãyص’¡âa±UŒEÛÌ&[ŸA[ô§¶.ë=ËkV´mÓ.×ÿZ$öûf¡#®DD–°+àWôÑœ(‡ðÃ|x|ÈǪèØy)BIМª-»/XÎvm~(XUÔûþÕM_=v8U}‰m¬Ù‘õ|»m‹®³n¯Dr-b¶™\DÒxÜ•ÿ).Ìú6¯÷+kÆ·Å=y&`GŸÂ:iñ†,ô-âÀ”½s†õÅRD<ËB|è)­pîÀW"Ky,Ý•ƒõCÙ™¬DÈJ’DÞÁКð÷a‡ü#!°Ü×M[lY¹sAAz·Û6¥ø¼Ìx¦•’AŽoˆÓ}Ë­um – ¼æ.Rš‘ÝÝBi¶~µP<6ˆPÒ7tËå׋8ã2M\•8÷j¸òhLf©òê7ìe‡Lä~é‹v—o W þÍêåOGu›¸¼ËÇò”Lè ó0KoƘM¼¸ÿè’æ3®Î0uQ®Ê{“ðYb¬É@v‘÷¸£¸•õ¶D´ Ð"Ýz åmÁŠút(Z,@.j[V±BYEc‘§Úù÷åþ„’Ó²Xr%bÈ~1s5EÒ]6xñËÝ‹Wïî®ßÜ]]¯o~¹/2b×nòøèØ©+v§ÊTÎx£º€£ÓkõyoÝÖÇqÎë„GBÚܞʊÖðÝQaœ9áŒmó>g¦ )üÃ"J¯ŒRÃΡ?΋ÛgÁW”´Áœ´ dP¤ }*ø÷#Éi(0ÚMŸdÄã8ö¿Zƾ˜…r¥2Å“t^óD,~³» n—óˆJÍ=Ò€:›?*={Ñ™À'€ù»¹R<™œl£2ψÿÂi’Rj¨ç©Pò!IÁÙ‡¥YÅu*2O³]múeÓ+SÔ[œMê6°hyµ^ü ÖìŒn šb”€` йŒY2£?‹H%rúKµxû™.ohåIQÈ£ŒEZSÞþúú»7¯^þ•]›Þ‘ð4ñ< ·ušw/__±w¦•Ç ß-C]¾úùн¾º¼~yýÃp‹Ág­æ>»_>ï3bNâã“êÄ{ŸJãý‹_FŽÊx¢ ,3°"õªwwW77&±†þÈ\"b8Úë½¹aÂvü}ÖUNpåõËàÐJd‡`ðûÆ<ÕHÈÓjÒ”­±÷îîÍ,4AY±ÖSh¼µtG ²É«êÿr`W&hø"3˜ï¨h¨ž_WtÒ¦cÿ“¸PNѱÇpÐLz4ÔÂÛ=+ ‡Ç%(05]ɘ~ õ Îj„óü·OƒþùYóbù_JC ^,’‘A—iC@LÑ™B~:Ÿ±N6{i©†‚É« —øž l[æ¿Ê¡åáú¹m⦈Pèæ–¬¼Ê)ä1Q¿Ǧ6¢ØŸaQe<ö• xeVÀï‹vÐù}ã)PJ²!õ}ôüHÁ2#€]Çj@æ®"„v”Iϵb¥•ÿÝ+Ž—»½£9I=cwÔò››y¡"t¦½<”ö.åDœvÈÙ±11$ÚÍ禴·eúÔ@Sê £%ÛEüÁ0yÌ»ÎtzsE Ѓ¦42}g"Ð.(ܘ@Ø‹³e¡rËsv¸þí=ÂÜQo+£4†ûõmsÚ?˜¼9g pín¢x˜øõRjˆàLM3™¨:LFµNÎ"²0Gdc/|œà<Ôp¦τƧ(&jJâÈ x `£Ï#¢p4¬ü)Óœ]îœ?1‰xßÐÉÛyF1n¤Bü~F1ïz™J.k¨¥ªÁ ×Rñ·‹®¿x†œ•LE”ÌDζy7›Û`{¿¿Øži¶¹0¾´~¦|¤N¸ÖîÖ(r©íPØØ¸Yá6Íò‡Û3Y‚üxl›c[IÓ``.PËõ¨WBÒ¬.,»1wjD]p¤¼œ:#ë'æË¢ö`Œ»I3Ò_(aLºÙVÓC™byð×&‚³ÜöM`´ghšÒ!w³ÉÙL~Ác|ÔS‡ßü8Ÿ[4Oc1LD™«Ñ‰Û¦¨gGCÄaü ЧOê9³õ¬ÔÈÞr©$Æ·(ØMe§„n÷‡œ¨1“W¥Sû£(ýÝ>u UkÿÖœì\‚!h:C)±pµ.¢GÍT‡`…ð BºYÝð‰M Æ&7ªÒ|\<§1we;èù¯6 ˆR^1EÜÎJÁK‚®fF0’M¶> o@{é8&Ò–7ʲ8µyµñF; ™’¡±Úv’ù¦ÛñøÈ5ÆíÒþGÈb8°éŒžÏ=4cKß#í[ƒ½Bs•fŸ/ñ¦6B€^¡Ú¾Üœª|¤‰!°Ÿ£3neª}q­ ÿ»þÐÊy½üÃ$-Ù<tp~GE´«ñï‹)¦ç“ÞS]©T–gª¼sS±Jx&õì5fê¿ ‘”·K}¦#芽ÆÐë‘E ½æ˜Î±þæ}pYUÏD”°"jœÑÉm¯ôž’%ù»k›ÃØV)v¥“P†/éÖ¤?|80¶7KÆT:Á®Ÿ”cf^]c˜­6>·¥+oô½ˆêņoÕìV0¼ªÊû6o?Z4$Š«x¢'0ì;@c¾G–û6ß–îÕ‡ ~¾þæÌÀ¶ÍÆÉøíòÂ0Á§/hÈFFfêP`»,–“ûɉF„žÜúXkå/höÚ ¢´˘fÝÊ ÓÉ%ÍDL¦ê€¯§OÅCép*v`úPîìSÜŸçý9ÕôÔ(3-ï¾Bvaµ.¾5Q ¸OoË=e½«šÝî[ ?å–g&œM•OŸÜ@_!þˆ°ÿ…Ùb§Ã±ý6 ÿ¹øÊwñ6Þ.ië´û›$¤RÖ¦êÐ RÒãO¤,$sKò±ÙÜ8É¿D„ChÕ2/k¹Lþòì"C)FIbRK‡?}ò7CÛO‹ÿp endstream endobj 135 0 obj 2581 endobj 139 0 obj <> stream xœX]oÛ:}ϯ ú²rñJ¤>wŸz·}ØE ì¶îCr06mkkK®$'È¿ßÃRòGÐ^¤h‰"çãÌ™3ü!™ŠÄýø—û›ß¾–b3Ü$bsóã&¥—Âÿ³Ü‹ßïn´¸[bUªþÜ­oøËT¨RI‰RânsÅÙBåI”Æ‹?ïþýø«Ú«DË$ÉDœcýê&jÚQ¬^L¿~Ü5­íÖë‡è#ýú¿ ÷ìvq÷¿UÉJÄiFßð‚oͦµ+ñ¾·ã±oÃç´Ú­ûÖ}êû®/lß?,þ±øÛ©1o«·m&ó6½ÀӮĸm±ê–ǽ…‰½]Û~c‡çV¬írlºV˜AðñM»¡7Ï •ɺÎëÈìŽúî¸ÙŠ÷8]t=…$:·iY ‚TQI+AæÜGën¡%+UFýqަ*¥*¿*Á§Ú v ÛÞ V¼ãCÑ´ôx×- ™|èrÄ ®<½º¨¼“`ä%+y×è[··c³·ƒ{ë²’E^‡ø't^‡]{14ûfgzê LoÅq°+Ú󷯕pŸ¬o2Jˆ–9}šKñÅî»þ¾;ô¤Á›è‹iÍÆºˆó÷s¦Â:Ÿ¬è›%Ó€àÊ%Me°ý™Þ$þišUü JJoÔ›èÖg‰t¡3£XvûCß Öž¨ãðBwÍöÂÂ,—YŽ ñ"޾6€óuóˆXÙaÙ7‡±ë‡‡’@^¨,‘5 ÈXÉ:I9©c\b'ë Üš3¯«RæY‘ò™°à¯ž­xšb \^+„ygk[±zm;YšÝîUà/‡¨ À4O½AаO%kÚ))dQåÞCyç^åü*­¤*Óà|·ŸOO¥Ò!*Ê-ÆÙ”äp:#,/dYUs”+,ÝNÎråã%M÷/b*YYrç!zX\d)M5ííK %~è»Ešƒ“ªƒü!bø=Á—<#ºŠe êDfõ„ÁÈÅÅQi.+Тß]«Šöf @5ÓÍòè(aÙô Ïa4íÒÌ1YEø›6c8Ü9¦,3j0Élc[‹re „!-ÏXèÞUY¤Žu“2Ú¼r¡ ÛAÁæû¢–u•ë<æn$f×8R‡‹›ÞìÝ{‡IGâ•Á'IévœóX×'ù÷WØIÌÌÓÀ ™¿@§*裟fº@MkàÎò;X{î(sèH—¸Ï@Juz†ûuÓ6Ãö-Ø'5˜ÐÛéü`,wÖ`óã‹°Je1ÅO5gûÔ°¾½4E£ªŸ– £,u© tFGðg/T%ˆ JѲš)eh'JÑ…¬’‰h»‘ÊÌwœº †¿ÙKCã 8)Êt9Û:Øö>’ÁëÙ¼Á*dèÉî:ïRY1/J]d!/r²tî${°HÄιÕI'LÅWkVq×î˜jk™MŒ~ý§_€Z“$­Ñ?,J Ùò´3†O|g*2îsÀ>¿j@ܧ˜õ»žNœPØqiíà\Šé ö"àZü^êN~±õ}ô… Uéȵ– OГ2º&¯¸ÖˆDçr6ƒ;¸‡|sÿéC· w| HS©Я‹³®Åâ u`¶„Wã8ûïµLë Ý!+Ÿ¥D«¥rž@c:Ÿð´îú+í ËâWT_žH‡$è”ûˆiÊ·~3Žv _úf´ÔX`+7/•E›kug G‰¿ à&ëݹ¯ë£=CÀe¾cp—Ô¥ºàÜ«| N- I³â­Ô¦:—yâÛ.¥ôB ÆaÅU(ñ©Ø}P:R¨B©}´33]éE¿ÒWœr·+Pk çÝ×€gêw ¥"ŸÔu®üD€PMZ:4TôVª®õ$Iê*2KûîV˜§ŽU¤NÁ¬Uè¬O5m}.Q£ÛõŒÎ„ÆOrýi7ýq”¹FbgáÈÊœ(šXqðó„‹eû×ÕRµ«s@Ä>F¿¥ìÅi•ÐfSŒë„³öapìñż •àÝHѳ*ñ§z;_¶Ír+lkžvHÏëÁÆË­]~c-úûU¤)ï̉Gë¦=rålÒKsÑåËhWÃõ[1y\56ĥͻ!÷¢‡¡…}Í”= rÅÜ®zwœ!*ç=(ˆ2‡ü9ŽöÍ”›ªGsõàMì(Sé »ÐѺ–¹“n¡Óþ4éqX=¥µJ¹îö)©©î!dA룛eÉQbÛ8îYä®3¥‹ù8ËxóXs,ÿسgs5ôlQeg|ítã_÷‡Ù0·é4'9I—$ÃÐÀŽ[w'‚`± fmCEð• Iœ'ÄpnBéPþó› ºÐ `¬ùJ ’à®o&Ñ[aðbëÂí pe› YÐLè@AæA¡"¡~/¾kûØXÁÿûxì+RY˜D¢«ÝÁŒ ë‹»>ºÃ»ØÉ]Xé0M‚¤X.º@Sîv,ÓAÛEUÖó2Of/4íybšGä¦FÈI¾ B$Ác €mSeŠÐàß2žRˆ¤ùÀÉä¯Üàý“LGÏzN_~ãHªRà‰ï—éü5 ¦.'‚<¿Yýtwó_üüktáendstream endobj 140 0 obj 2330 endobj 144 0 obj <> stream xœ­VÛnÓ@}÷WÌkT/Þ‹oêSQ‚*BD<´(ríMjˆãÔvâß™];ŽÓ¦%TU,%ÎîÜΜ³³wàR®þtßia½™0¯-æÖÅÌ"t_iocK@œâ.ÆŸxfµ– xÀ©âº"Ž´¹çîØßâè­î êº7e™•U•*’|YÃl½Xl¡^¯VeÕ¨ìÌŽ¿ë8Q‡£‹K‹ü,ó ²MRͦ™J‹2½&#ó:R7ë9d7ó3û•ÅC‚ä cl^׫$UÓ¦ÜÙ™zzÍ— $«UU®ªªC캺MwÕdpE0€ŽÔÜbX|té­J˜†2•ÑMä*Çí‹9Bñ†}ߊ­éÚyr«D¬‡E§‘S¾,9û>= ¨”4 øS½WÛÿp² Û[œHD/x@Dq„ˆW‡LLš¦Êol®Éɺ9¨÷QbÒGÏ#'—tÇMƒôE—d@ƒž¶}̈F©•Þãù{OÎ~SR嵂YUb¼Úü¼wÐ:‚G”»þ=Èuý‹¼nŽÈ‘±î˜5ÓÈ—ŽC$°O GUUY™ááˆø—¶ Ÿ¤-ï…µ5`ÞêíÑœJî?%µ4ZB¡7ÐNÓ[²³¹&­Ñù«gþòßšÃ|m<Ô¢0ôˆNüÁé.=Op =ùÅ5ZzÉG§\÷ËŒB·ïg¼o´OƒHör3Û1­Fh5·¹UKs¶Á"¿ÉLD&|*üÆ[(QL~Ð3³Ó‡V+Þ”šu…7¥‘-´*ÑC)£_$ù2O&&$õ]9lŸ&3MâLó^d¦ ¤é°0¢n¨»ÍŒã‰ÚŸxñë‡èÏÁÕÈÛÉÀ—ɸËÙÞ0hHGÃ[å8¶>ãç/“Gáªendstream endobj 145 0 obj 924 endobj 149 0 obj <> stream xœ…WÛŽÛ6}÷Wð-r`1$EÝš§»R¤ÝèúXÐm+•%G’×1Šþ{‡WÉŠ“bwáµEÎåÌ™3ã/ˆ`Šˆú±¯Åqñî)Eû~AÐ~ñeAõCd_Š#úe½ˆÐº€S”!ø]ïæ&E,e8â(´>.žƒ/YL‚(\þµþ ì™[¹½2aB8 c8_.‚×¶*QyÝ¢®ÛâEv]Ûm‚ýáƒÜž÷¨ÜîWËõçËp†BÊõU{ ’èx-+¹Y¾WGÞ=eÖWÆ1Ir¢ÿZíÏ:¡3KóI' '_«AÔ¥f¡d`Зþÿ#qB°•Ö9$? Õ g@rV k¦Ô$¤9Óþ@÷ŒéŠpžÇZmæ#É:1ÊP„ôÔ•R‡ü÷~h;±÷$Ð Ÿñ[½ò-¿½ã)ÑA2â] c G±ô 㢮d3©¼&‘ güèä¹—ªáTU³ŸAÒ,ѽ¯Qýyt”¸> stream xœ}V]oÛ6}÷¯¸èC+§1CRßëú!-Ð-ðÔXâ"`$Úf#K®$Çs‡ý÷]~ÉVÒ ›¼¼<÷òœC~JPýãþ›ÉÅM «nBa5ù:afÜ¿b¿Ì'!Ì Œbðw¾œØ• xÊIA&0ßLnƒY4å1 ¢ÙôóüWÌgVenÑ,Hž¥9Ìb /'Á{µÚµÓù›žg$Š9¦ÕS2Õã&‹HÈ3æ&ˆ?A’ÛñÛàÝßb³­$ƒr?e”Pš¦h—w¢ïÛJuý"XL *\œ{D,ŽIš'0c‘Éþب¤Ë´®ö:ռ߭ ¼_»ïJB×ld©$¦D8zñõ$øgúJ‘ ÙløGµªe ¢/š]ÝÃ[ oô"7{‰ðÔý®—p&zÓ¼òóïÚ¶iAš¿ã—W à ³cà£à™å†Êý¸®‚sxi÷=éâˆÙn1ÕI\mj —é-\}º»ºþëîßSxVô.‹ Áýì ¯_+³‹­¸8ƒ]'Á¸UŸáìÂ4È".¥¨ª¦0ÈM£Ái!¦soòÌתÑ$Âô†ÔÌ4­Z©ZT€à6Ðõªª`ß´aÓÌ„{4£]>ö#´s[ûåÝå|~£w×8î«ÉlTÒ¿Ï ¥ò\ø8·U|'Áw‡"˜…§H—ªVÝÚ°{¬ FQ8‰Ó%1~Ô½Øëâ&´úë¡U`gšV¬p¬ëšBál {Õ¯AÔ ê®u!¡Y‚p;eä¶ßèæ ¨,"QèUÆTØJj¥„…Ôë}+Ú^»J£p+ŠI“˜†®¸à\ùÉÈ8#qÊ|†~´’Ô„˜qn£qó7?ÀO”ÐmE!í)Иdiä ¶,{Úµ~-Ÿ4*Ç6±Ü£þŸ.!8TÊ®hÕf0JlPLÓÌ×.Žå±§¼ ê–SŽVÈXhúc1ñ`LÐ$Jr’„±‡#ûÓDIù®%Q L(1)ÐÒYÊ|ŠÇztíJ•θñ2 g"ÊH†Á,LuHH¸¥ž"‰mÏ)'QFó-ߢ˜;¸‘=Þx3ä9g¶Á%~ÍÐõ“0h6Ps¦Ç(‘þ ôqvþ ð­žù-ðL--œNæk‰¦dœ°Ñj^l´gQ¹úõz¬3ŒHâªÜŸ”"?Øp9:(wú–»oßT½‚æþ‹,úîû©?è¡VÔ%bÄ+ÏŒó@T;Ùa@ßÔH6¼"S>fKDàAâ wRjµ¢fÂ`.sËY”‡ÇÓ«5u£ÈBÖèÖ§„fN+¡Ó jô£4¤ŽÆT{±îûm÷ÓÅ…¬É^=¨-^-‚ gQqyò`u¡‡/ÞÛê_ØzPË$§™o}pùD.FÉX.æ>|n*qÆ3¯ë0³x[MË l«íG†ôâ‰×áé†XÕÈù«áÎwì5Ïð13ʆT1 Óÿ6•¬~œnRTãp´$ ™)¢[7»ª„{i,ª·ÎR©s¸6J‹MÛÑðvž¡™;ä¹h'a¹M\ ˆÀQð1ãþ®ð›£ƒ¹·‡ŽLüvh¾ìx.ä“Çb†ÃòÌ÷Ev#I ”¡6\ë¹G‡®9ÅRPÅq`aúºY[ú;0žkm{îíû)š* ‘eMy|w†#ÃÞ™=Lgœ“llÞŸPThâzO«{2Å”Èyø²Cíß˪9Ú'C‰$¾Ðý‰{Æ:§4N”%ܤßGm 5Í-UWìºN55qÇub$ÁLÞy”qHhèù1|¶_@x øåwqN9;.ÔïthØø‘þn>ùþ¬2°endstream endobj 155 0 obj 1394 endobj 159 0 obj <> stream xœµV[oÛ6~ׯà^*°’¢nò°!Š¡C»ÔkâÁ%ÊÖ&K.%Ç Šý÷’º6[6 Ä1y®ßùÎ9üŒ(aˆêŸî3=8×!Ú5E;ç³ÃÌ%ê>Òúaåxh•‚ã~W¹c5â!'ž@¡ ÕÁyÄKárŸbéþºúÑYRÂ…Ö\²0&” ´ôA0sðSí®~pÇ ÊÁ\<â"CÒe>H3¿$‡c)‹ªhs7&qL…ÀIQ®qZWM‹Ò}¢ÐÕ1i÷ ãÜyq$À Öš•hÕIn´ØÖåTÇááSnU´à[Ÿª¦ØU2C­+eµp/'§IšÊ¦™ŸíT}:V§ÃVªµ 7K@¦ó‹¿êìÆïøîì2ðÌü'*ß¼Iª¬” I¥öð/ºEôÆ„³ºz!û¾5r‰2¦¡Ob?Ž,dxwK0¹0û‹}¼d”’G˽Rµñ_‹ãNZôø´CÙv7Ÿ–DÉFª'[FßÇ2c¯šþ¥ÇtªÇèñÿ¨çz¸¨Z-`O.€*®­ÙÃÌÚ¤ahlj²®¬±!Ö·Üñ'Ü™xàMG• ;\¡õ"/ºrO™§ã°Õe!‰£˜áÝâ°]LRb4ÐG:( è,d.^È{ö_˜Ò®Ý›9GHg__¡÷Jæ "3à ‘&RÀI]Wâ'9mW&:†QcC5E]¡«k£ ¸˜Sähm‘¾Ew.‡.Ž‚Úܽu53u—ÜÜ?<”˜ñ»‡µ‹¾¾"ýè2ðN©‡“ÆDš”%ÌŠnÐta„r/š…í}6®Ú1˜_žwûú´Ûj ªNeù]ŸWŸ†“.Úè\"aX“I¦N×X—Î>䳸s=M€ 6Yo’õô4 <“ìMߨ¶ =óTË ¶xŠõ#®¤ =D‰ðH^«** ‚V~$åÒHëÃAVím]¦½ú ŸZtj$j÷=\—Yo+ÙÖš'=ž!À6ÀC‰óg+ÊG#@V°)#`’€Wèˆb[”EûÜ#È#ÊÆèÎE»GÖuYl;> stream xœVÛnã6}÷W ö¥2syÑ…DÑ-6-¶X45Ú‡¸h™¶Õ•¥D’cEÿ½3$%9Á.Z8@l‰œË9gùœ àô‰ÿËÓâý]‡~Áá°xZÿâ¿ò?® Ö%®ðo½_„d!™J¡P9¬O‹ûd•.eÆ“|µüsý3ÆÃ]+‘eŒóV.Úá¢òôع¾ƒ~èðû&y^ Z’g‰ë–Ê0£µLnÞI.9×R¾Û,¿õñD 다ÚÃf ò=ðÍþ^~³ÀÂV´€2ì.K%Ml·Ø9[×mùຮí6Én{¸ _cXÊœö'ÿ¸åú¯P½H×…ÁféEÝ;Ì…ïV’k3mÙwÎm’),-¹ø?HD)õ©8Ës ëË"ùi/í¹ûøXW¥ª¶Æ¹]C [vÛ·õypõ ôçÎAÓàë_!ÁšzYê =<û— ã¾AÁDªã»ÆöSçR1¥¸€©œÂ—S5‡ÚÁöepP;û¹‡}מÀž6 ‰9Mܓتv;_IÊ5Ë 5u[W[¤ßÈ‚I‘O9²Iƒª©ØŸ›Ò7\"ƒ0´ÍØ'âѵ¶6L‹œË±Á•/Âu=eö"4\£ÊÚj;`À©|‘I†#¶ªi+ÖÏàwߟaE–‰9¶¼ŠÝ#}ÃÅ9J‚¨ ¤È6»)#ík…b†O`¥yˆõŒ”Ϥq&³w£¨Hߩ̘1³bíó,rΊIä<´PÕv‹DO G;À¥BgÛÙfpøEz bòÚöÈXP—¯%G‘ª»lçlŠ)E‚BêY`ÇàP ;ÔJP-÷_]‹ÓOZ/-ÒŽ–@¤¡7© Ê‹4 þ=éZ*×;@ÈU.TnP¨ú Ek–šÔ\M]{àWJk&fuK tL‚}-C°»çªD、 ¼8Hn¦"Z÷×¶ueXË”3.Ò"¹ù°TœÓ$<|øøÃÃíÝ]pH‰I>Ý¡h«>Ôh j`¬1¼uýp–Ziχã5*#‰B ù°x¹TÃqB˹‡~ëöm÷ æë] UÐ9,ÍÔW]ýÜdÓ¸àD:ÛÕÕõLÊ\3Í#…é A>|c8ñÚÄsÊòØFj^™¹ýëQRdg`¥vÆ%gzôSÒ, ®vˆ+á;û¥ðdš(Öxde*›åJ¹É)¶9øikqû‰í\éš!¶îu\ ßˆ9ùÜúÔ„29Ë2=‹•ÇU$g8ÙÏ´* OËEš3™óQöÎî#aÀS4·qX$ºw4Î Ì2¡5é87”Ìãäâáx:Wx”<¶}_‘ßœ›¡ Nÿ†yß>â„Ý“¿G*W&cEŽãv­ë¯œÿÎ »÷w„¢‹ MêGœtMª+cØÜv^(ÐÛSͯ]ñ>AÁ}ðSȵ£(“%ƒÁtôzá]«|yt}Ì8ÝVcà(z…¨Ÿ}m—íÎ{ ºmµCv«ý‹‡£ÚΩ ½×ãP…s‘Ž?ÂS˜˜BqìH´í.¯ìd³Œ«§Ë]r²q5Úi8³M¦~‹¬ëË®Úb˜5L0£†«¾: K·º§Ý9D1¸ö¨äxQó°Œgž¢€?~±/db¶Ÿ"ef<`ß^/o׋_ñó/'äÞÂendstream endobj 165 0 obj 1292 endobj 169 0 obj <> stream xœ­XÛrÚ:}÷WèÑt&Š$Û²õh°¡ôhmÓæLzÆcÀáÐH ôò÷Ý’/Š“Öé$Œ/’µö}mé "˜""ÿŠëüA»l´Üi-µ/Uƒ¨¸ÌP7Ò Íaeþ£{-ÿ’"f3l˜È68Š´;ýÊì0‹èöUç¿èæGÚ;ÍÄú¼ß'€q0³w‘×ÍäBÔ߬µ°AëÀ9Žm‡!n;RJml9pûMÓ‡ž?ކý¡ iè{è“vëS.µaŒca0X#Zh›p+¿‰&¨/'5ÇÆ¦e‰|Žø¾QZU:ØÆ¹Å›f@ƒ7´Ò†3©î}¨„¡óR^JLlSI{#7£`8 ùÿIöªÐ3Ǹ*>»¢¦R¢iAfÀ?.8šô÷MÎe€eVn„$»GÛù)c&¦pÿ ˆ`XpóÃóÃ'qé®%6®cù£Ñ0Œ.A5Iâùëõj·GõÍv»tñ±ÓNOçÔ9ÝÉtì…Ocw·‡Íb÷rl@‚;5p°ò?&î®·óÏ­€òÕ=¿+G9Á–!œ£&ËE˜ hjÊùGµï”^:ë0‚ ¦~X‚þ‹-*LUäÏMÀ¤ëkö÷†~£¼UÚÎÎ ´AY-˜‡ãf”ÑjÓ&_Û•cÒ€‚•ðPæÊ|¢ 4²ô-¦äöu÷ûl5ëÀšBXT?ìÓvF͉þ}Û¬d¤^[˜WRJ¾i×J ç¤\ôb  ›PÁŸ tŠ9­U¬pÚ {ÁÓYf»yöò,Ë£IýÄ(hXÀ¹Xî¨ô‹Z×,5XogÉúÈ~ÈQK€»…( â`ø)äI¦‰…S÷’ŸeÛ¬eȳӺ¦*j¢`Àgœ˜[•Òí=Ú>&_)’…<[=î·Ùî œZ@—¿©·L2er›b‡õFؘˆ<§ýÊâLåÇ™ÿe¾ú þ¬À¸;4'†›%›e»ü*9¡L·Û ü÷—ŠtŸÍ²z0L(7ô¯írݘ©%V?poüxò¶Q¿~–<¤ñä±eT±eï‰jÝk]­ÍSVì{Í ýE;ûŒyx›Ù·“Û9jOÃP8sÎõ°Êi9ð_è: ‰¹QcÃþtÜÜ×õ›vMÝ‘„ƪ˜µºë0l† ”e€‰²ðÞe Y-ÉJ/aÂ÷%Û•²…,d·ÎÈN]€÷J)´;<µloà{nÖ\þÁw/ú:üÐqT{¥§Éç¶€ÆI+ízÞEšÍ ÐbÑŽ]„8Ý€¨’z±iV8,©çTò{Hà° e0žÆÃ±ç߯¯}×Cxí¨Â³±QÑæa/7‡x!sýx˜m q~A¶eÅ}6Y v]Çñ@rhø x¶YJ6m‡éä À±t•ÂÍ3XÌV¨Ó„0SÿÞ’E :µ0½-,Ý |{ˆ‡ XŠì0ý{ü:MiË<á¿î6óº?¹ãŒÛ•&Û9áÌbkû4”ì‰ÚÂÁäŒkd=£›´gKÄ»èÆír/A˜Þ ”c #fÙÑ›ÐvåhÜ›Œ#ÿ6ª2›üÄÝ7É<ÛÆ½ífŸ»\®ù}ß¾e±küã…¹=š÷}»Ü/Ùû*² l•¨å`Â+ ëP™ûF}à©:Ò^÷õ hñ¤ßýèbÕÌmî³xr ¢~¿K÷;àC‡èÉlìÊ£-à™³£­ò<Ú:wùï×µÎÿþè¨Ï¶°mr$Ôi£Þ_-ŠkÔé$´‘¦Uú'uŽ&3±ÁZ `ù¾vî&Jã¸kè„’ýj»¹öÒ¤z@ÃEºÙ¯î«3ŠU ¢¼Mº’çŽòt0­D¾$U¨|5Ž¢X¥ÌFðp“ü@Œ0züÐÎøéÂiê;í'&ƒãendstream endobj 170 0 obj 1449 endobj 174 0 obj <> stream xœ•XYÛF~ׯè7SÀ²‡}lî[‚‰YÄ$£ f‚E6%Ú)óeòëSÕIÉÞØÁ <4û¨ë«¯ªø‘D”‘Üßâ´¹û9%‡a‘Ãæã†™Eâþ'òín#È®€]ŒøÝU{’žr*$IEBv§ÍcÊ-£@…Ûßwÿ…ûÌ)E˜ÄC!"IÂVÊ 1Ù]6ABÉÛ©-ƺkóf»{¿Q1E̦àûvÔ}•WV*„nÜŠû8Uœ™ëvÇz ƒ6÷‘RE_ïõ@Æ£&•3o #j c¨ÅNà‹Y3º3F#®˜[¨›|ßhR·x—Ó&rÚ$Š2žºM½//y_Ýh,ó¦>ï_½V÷b#åŒ{yô»E‘Œ²X¸4•Sóâ8Ûd IFcÐ#DãN+ÜùXGœSê¶h&xAêqU[A\2ÔmþEª®i:C–¥TeÜKqj$_tIö¯¤k5ézrêzMÎyŸúü|ôN¯Ûƒ÷Tè¯qŠ^ë7¸j‚ Â;gèÓMf0œuŸã1j.]Ba‘;Œ±QKš)¥‚ *áÀ0Ìh@µ†¨1uAª§ý°Â'#ߣgò¦þӈ߾,‰i»­^?zņ[”ú}¦`6™•® >,º¶Ð} νÔ㑜{ ^Eò–tû÷`±Ñb ¢Õ µ=¦ý ?NºI^z02èx?‰¦pˆ¯ Ü"¯F3Ö–¨(û†cš¨8ópˆ¢Ä±u÷ºÑù`4†0ù¦ôzè¦#—£n½Ž¤Ew:7zÔÔ É§etq`ôxFl>Ÿóñø¹.J<Û¿]åG½r½õ W¶ÍaëÚÔvm!¶µ–ñÀÆšX–ž¥)Í"ñ•‘\/sUŒªd&ñ®Z+šesÍE`¯oH&Ih¤¤›H<ÅÔëL‘~öíX¾-!z ù'xÆ×@AYÊ¿{ÆÒ»|U-æem žM#ŸÌx+³®®tŲ*Ó€UJ©úîDÎM=’ûË6u…ÌLZÃ6‡F•Ñ$æ Ñ%ilo}—?>òá·wt¦ÀmÜd/R± º©AaúD¦¶©?˜÷€ÜUFºsá*̾=>œ I‚lÅ,n|(¯ibZÁŒÀ¯ÃšÅ…” škä‡2RséÔkýÏ€fK KàŸËzJ¾i 72Å$V3Ü!¬ƒÀ?º-A{HÃA`¤àó©4F÷¶t)NL3™ý}Ê£T ÈýjBš»êÞÛóŽúÍû£ïÞ1ƒi$X´ÆüøÏÆ] /§³ç°Ïa–›‡3 ®ë¿a(¡àöxÕ‘¢á<¯Rñ­§J@˜ƒxÇóðï»;ÛEylÉ”¢s5[Ù.°É¼í½¦Ð1¤¥T‡»C¹¿ë¢€½®Ì\Ž„÷ÀQ¶ñ—0®(ß- ) 7¦CøX| ÇñÔ˜ö³náß“m„Ü‚ca*Õ Îì§2Ï~˜èVhM«¸ß¤“)HÊ©nʰ.?á¤>ß¾¹n ¡…\æ†ÞP6ƒ6ÑCÅzÎ(öRã0Ôv.•™L‚üÕTú+)3³þûœšnŸ7¦[3¨tîâq &ûP.ŒéÈ(æ‚ó…° Ž¸Òy_!Pòí4Þt¬)œñ?îXñj—3NÊc€Ý%wV c+òÞ(Ä@±K3â¨.8L'Í…©¯Æ a×L}R™÷ª^ܹte‰€ª€éi6e;ˆ‹UÏäða} ãƒ-% ˜Ó†ß#_MšôWLEw°ƒ½»`´ŒL…ßù…6t5::¼74ÀÉÒ;#V‘DPÓ n÷ h]â8ª2¯iŸ±à‚Ÿ×Xp±_Îù`ÆÉº½ê"Q±w‡ÐÖÛ«Ÿ´M’nŸ÷S½Y^ÚnoŒ3#›SÓbj ê¾s“©"L˜FFd`~Æ©Mf>" Œ”Îæx®}ÁG×ÐïÇO$¶ÃÕs7YÍßD^Äßx­+å)7xÄÙr:…,J¹/×ßæ¾Ûm~‚Ÿ¿z?IÆendstream endobj 175 0 obj 2152 endobj 179 0 obj <> stream xœ­XÛrÛÈ}çWÌ›A•8fpÝyESw=+vyË®æ û¾G¦×z2z?[^ÁÌ$};(íð¡ú‡Õ°Ù¨Ö,ˆCø^fÞPwå¶Vkv´5v•ª¯çof"à±6¼ÑGüÉ™çE¡ºŽ,.]mÛfØ×ÃãŠv{câ8ºøk^¯+Õ2Õ¶;|$‹(9Ûä‡^¿ÍÛ-½”§¯nÔjØ^±õJ¿òéŽú29­êTûM­pÂÅsa\ÁK 2lïëb¸Uâš*°0¯l .×Âä¹Åò™Å“<Þ¶mÓ^Y2F‚Œ EÏ?Ïÿ@ÏO ¶âˆ| m%x”$ÚÙ]ͺAW‚õ;Å6C]ôeS³VõC[wÖ‹ƒ^Ç<Ýêæç‡›÷ÿ|¸û;YEÆå¾uaíuNFÊä™9'õÚíÅr¶o€eT¶oX^3Bs™Wåoj­Ó!ˆ }s˜>÷ƒ(ôliu¥¢˜‹$KÌG º¶ÀÚît¨@Ë[>èÆ<ͷãª{ξ¯*2Bú¢, &N?yý®ì˜9‡Ÿ¥^Ó~eå Ë"¯ª' ¼m[|Fž÷û¦í r!PÜ0 ]4¾q׬¾¨¢g›¹ ‡ðÊJ±þi¯:®—QýÞϼwÀî´0’Q4)ÌÇ»‡ÛËû_&PÈ8–Ì">R¼Ã‚Zy§ZÅð¤n;œ‡ò¦< ŽëB³D©¨·LU^ºnjÅšÖT.‰¸/F.òÜFœÞ^ðHŠóXnïïïî'¤Ïdfæó(4)< $gÀÌÒDfÞØ6ì<Ö#&tó8šÓn‹™çÆ®Mù ˜ñ8±¬£ Q¤Óªz/¤†§ácC\eÊØaí“w8èq úã8Ï2!œ¼PÏP€t:Ihl³À Jié"Œ¹ŒPtËÞ'Ñ< ²Ì¹pËZ{­óGœx£?ŸC4 5¾•9½Ô[–2Myh³C£aRA„‘ºÍìÁc×z“s )¢ñØnÈYÈ“T(è&—¯ýpŒ m¦®oµ5J’w?²}n"<%ž)ãIIÙ²nŸ‡Óî¢&I]Ì«rk|Sù‰ÕØŠì³(Ç<È%ždAæm,¶#=x•å*„:høhÇÀ°[7l×Tº…u|j½@„tfVRýòž¨¹×Ͱªÿ}5€žÖk:`àûzærÑq;ƒÌ†Ð\š—;U›jŸö[ÚBÃå"‡ j^äp” )DÍ—™°3’Ní3éÎà(ú¦'ó¸ úƒqHå›# ²²cî¤ÍÁM¹i°ØgÏž!£ˆ£.ð˜'R‚YÿøË“Q¢’ 1ŸI‚ܖu^iƒÏs3UM«$ÒßÐŽE³/Q £¹è-ÇžÇé À'˜ŠÉÐe˜¿3)³6h€4‹3ÇQºÛÇ®‚ª"µ/!qb““ú‰cÞDÂý0µ-íBy§®Ù’Æ~šÇŠTÄ¡DpuS/>P‹íµ8xD#¦Õ¿Õ±8ÚYìæ+ŽlÙ¼ú@í®Ñ9”E„é `¤~Ü…>M3(bh3ÿåãOkR~UY½˜‡ÄÖÐÛT÷,0fŒä¶'XbfÀ¡„ø2@d>æ}±›l€ñÇQöSj lË;Ij„á„#žÄÁ3´x{Ì7Ššfã4Olá« SgþÁÉÂõŒwZ/h G«´Ü`ÂUëm@€zl:ÙÐ_¦´foWe[ÖÓwHJùªÚ­f#%25]OAâ°R¬jpÈÕmšeQ@ÝOŒ[•_êbOAi“•ž"D“smƒç4pînØnU%Î:\.t?IM¸àÕÈ ægoOÍÀ¾Ö$Ë"ó¢˜% ©Øwå><Iõ œNÀºƒ¾€Ç§¥lê7¦7­¯]šú£ÌëWs# Ô³q©e;ŠAOåºd†öÎ;5…»QT¼Ôªc‡jÍ®™$ü8a~&FÓ,JÜt™¼ìvPhÀex¤Ð XŒœv—/xìKüKó‚Î$ψu{UàòÈúVå=ɶzÒAéóYÞÙËŸˆBî»Ë"ù'Ò¢»$ˆ…L€’,þ]£€úaœE¹¹&œÎ*yJ/¤L»˜¤çäâo¦>´=F½ÉÏñámúÓëw‚‹å(¥bÛäMG—Å~SmóŒˆ[H¨² ·^÷8ßOõ¼k€·“Õ1ñA¾Ž⓹‰Kˆ-ä¾m,²˜ž¥ÄMQ í<"í&ÞôÂ6Á•’á½èàZ˜¯VÌxÐÐ:æ-ëƒ}ˆùk‚™àùÛ9ýº¼Ø&›Ƕ¾ÿéáþöû›é8<îu cSåÛkvØ•¸¹75¸ñœ(21Þɾ½À­:gªÇg)ÉVLœª\©jsM£€rf®±÷j¼ÆJî“ñ›<îä& Ã?ò'&|h6ÚMÆÛíùס·ËÙ?ðóÙ ®$endstream endobj 180 0 obj 2156 endobj 184 0 obj <> stream xœ}XÙŽÛF}×WÔÛPV¥Ì““v<3ˆ—ñÈí@`K%‰1E*\¬é|ýœÚ(‰­Ú€¬[w=÷Ü[ýa”f~üÿëÃì‡Ï)Ùu3Fv³?fÜÿßú@~\Î$Y®!ÅÁ¿åvænr"RAeLR™åaö-Ô\(±Åü·å¿ ·‚IÊXL B›Y´Üëùòw£-÷Ú„¤YÂrh4ç»¶ŽõpxÒ­— V³˜Æ ¿:¹Â申4ãî› ‚q²Ve¿ðùJaùrHÔ“K9&Ù%ØIfY|3±Äänή˜G>‰ÔßQRE µÊEF–¿Ì8MS‡[`”}ßj”½Þ}¹Ûë–­&Û¦%?}|ÿ0ÿ›IŠ”Âf…1ÊòØÜI[ÿèÍ’ìÆ8…Âw•™4c9:Jþ¹5‚Š…Bò ð5iž~Ghd;°Ãy••&{ØÔÕó¶K”HMÏy¢JZ;Û¶9XÌ6[¦¸MŒº&Ç¢ëÊzGþÔmCNeUy¬ã´è$µÅD‘ótD”¹UýJÚSÙé+E¶3Â˪E—l»ÐPÖJô­‘ÝË–GD,¤5G­Wzeï­ºòOÝ}¾Î'ÀS Ûª(ã”HþRë¡8ÞÒ©rªRGÛ.‡¦Õ.f 5Oòë˜=—`S-ê‚AÒ€#Z>#d× É”ç!Éiì°t5UÈ•I1ôs?36†ðëêÝg[&IOüÇ_>}øòþÇ·ŸWo>üL6Ih+¥n³iëÅ5.»?f>;ªiê…®¶½ÙxL€Þ@…“N®›ž €P¿ánmÓfyTêjã{”™µóàœæ2UÖm»?W:ø¬$M2Æ_h»ìzt¤ Ǧ¬{´=è¿ Û¡¶]æzÂB3¡¬}…cG‘ÒDyˆ¾7þ[’àèé„…ä}ÓŽ­a{(ØVÇ.³)Íã‘7Ñ­:(ÍœE*Õˆ€ï/”ò8 ÔÚs–@"(G.\<ÉiÛÆ¦g^†ã¾JàÃ’ÈR³Ñ= ŠIX˜4µºªÞðJáóθdBÅ8ȪòÉ6Ù¤8±2•©S¤:Gݺ>!/W€4£™ ]hj^´»©VB¤¯Wœ–Î7­åƒª={%`5A*´™ÑŠ® wPàtŒÃK~.é«È h £“`\rªúExp²¤L]C9>ŸÐ̓eΡF&ç©÷p»zk:5 ïE{`“ágà5ÓÝXæV׫Ýñ8vÅ–<7è®ÛÛ¿sn6éÙc~ó±‹3e¸ÁôYȺÙhíŒpiÝH §ƒ®Ü¸H(Hl.ø§Îõ³“Ù@xu,úýjS] æ–áŠG¦3Ž„’Íëæ²‰W£5ö§ž¬÷EKîæ ™0é{™úe¶¼ƒ˜H±ñE};h§³úÕÓ°ÝêÖ]° 5 uWîjÓŽ£¬“«t}@1½Üx°^~ ân;2/U] i«"óNÅ?@2PäùÆH¨ôÊȧޞ‚3Í¡_C]`wøÀ±â‡åaW5OEeýîîÝSÇž^âèÒíswyqµn˜¼ÈK?̻掀Îî]‡œ\Š_Vbd—] ¬[9›:?RË Ï_Þ5Ývã²¼qyR4Û‰w^&^vÙx_çŸôÞ‚'êÌ èoæ”-íâ¶ ü^nÐfë»±µIeöúËÍuø­­«®b!4Íõ¶Œ“üz‡`7ö‡g3êæ!¢çóÇIô¿µ>Ž4ñ­n\¿H³p…Mçäö ¼Û¥LÎûÏ”ƒ]¨ÌõÃйÐÁ¸">†eÜÇ¥ÎonÍZl0Ø:³0Ûyæ¨ü݇/Ä>Ÿ«²þ6IJŽ—IjÕ;ÄîÇñ™uio®SÙïÉäIœbtpØôõ'±_«R*±,N_—1¹÷²•Üê;Foó€Œ$‹è÷®Hû$µ®Î扴™Ý>»²Uy=­ 6ÅøvøT\Bá<»ÜÈš¸+™ù»Œ¸ÁÓÄ·Ç…Ól[>3xQfx¸š©`ævY?í™ š¿Ë³S~µtdO±ÐáËûâ™&øùvŠ÷X:þqãú¯No—³ãçÿ°ïVendstream endobj 185 0 obj 1970 endobj 189 0 obj <> stream xœ…XÛ’Û6}×Wà-Tj„!.¼=z3NöâØÞYíº¶f¶T ’K¤BRžš|}N)QʦÆU*@£¯§OãWrÁBúë‹Ãìþ1aÛv²íì×™°‹¬ÿ)ì/Ë™bË»„dø·ÜÌÜIÁd"¹Ò,Q1[fOÁ"šË( Äbþ¿åß!§2T< 5[DØ´žIIÁ–¯³àX—UgÖÕ,¯XÞ4ù«7¬ÿ<_þ2QÈã8ÂU8,ºzQìr»9)ÅL%ܯßZ±— ÅS¦ýB^ìœÔ²ÚÚÛØv_¿ä{vÌ»k»ß9]À'©=Ÿ)ž%º?ÿ9 žŠ,s dе¤mYYѸ(ë]´ÐaÂÓ0a ¡­wçŠîlWE}ªºþÄàT¥xÔò,²¢_K¨Øí «N‡8 246t¥]ðn´$‘±=[̤L¹€hgÿ<s­¥_È¡ýK[òÖú@%8FñrzÇ< ©òüfšš•ºµ1¸JÕlm^æ2D„• NÛ}Y}=÷nËjÚ#¹Óvm6óŒg™ÒYŸöÜŸWë¼YÛŒ9óÝþaÜŸÚæ~_¾ÜãžÓvþÝ…ÃÂûsçÌ” e½ïÖ` ­*.7c.¸bkÚ«2)é¿æÍfUVe·zyžçÓXúÍHf+ ng닃tÌ~Þ¬ï *üŸá°;ÿ]µå¶2k–…iÛ;{âä?n›út\¹H“€þÐ_á¡=œhšn\Ÿ­|îì×¼Ùž}| O±ïÙúåüëû¦©ö½¡xáÈ…ÓÔ'¼³¾ìLÅÊŽ5¦;5U;ñI*¸}=|Y=|øÏêÓ?h“¶.ð"ÖC îº1C¥Q_L’csªŠ®¬§¥e<•Ê Xߎ՘#Á[ØôF áãínrC’q%à /Û‰Pñ4J)¿*uó8‘“XÛ8L¥W2î).œ«Ÿ‚µi‹¦"Ô ¹Jrõpqìr}O¥ëuœzOg<(›õ4"šëË*‹\Ø.’èã§ÕûËÇÿN¥ÓǽeÛ§%¬pˆä°KÃj{£C®âÔê_¿üb ”k ܬêŽuÕåÐ{ ©¬mBJÅo|ðåݘ©)YzhVqâ¢öøã!´CY!R‡œ™_¡úU:t´Þâ÷Ÿ§‰’A“DÞ4×™Fõ€/’²¶ÀY]§¦1këpªk@éNúî\™p¥Âlè’”Z5"ô»D¿ÅFµ&iÿ-²‰o½±=°0]H¯–½R&;± äû}=—àŸ¯0dc“ݰÖ£¯J-TÞëE­!”>«5òá«Ç÷ï®kMÄrèÕYlÛXpÈ ´±o©‡²¦½%ùþdHcÛðP|ØMj -±T:Í“{gÏA]íß.>•} @C*†nPÿ³Ì†‡©ö •È´ï(p d¯Ë¶8µ-›º&4Y×…õîóÜFT¤àT2ÏgNñu¯j(gÝ×ÓîêÓ~Í^@òႺW5£ÆŸ]dÔS­¡zi¡@sO6B¢Gê–ÏQR èf7MRwõxôG«m:ÒM72|-2ѶA×§!”„#_§£ä2t€#Kð@+›4„\´ æOö{]QÜ&TGr†$IÕ÷.¨î%Ìm6>‰[Öž K¥®èLÆUæ ‰[6³"¤pŒÍJ¿h™hIuûéˆÂQŒÕ¹{µtÆ‹ÀȱUÕ¥_ŒÀñD ~n'è5tú§à—¸ŽðøcD>8—®°1‹½ru;JÐ<Ôº_x Žû²[à,ñÀ$ŠÉ.â+”œd Û™¦ú¦£ùr.H–AïTÞŸ‰TÔ.é¨Ä>€$®pËŒ±5¾+·;K£]§ýáÓÏHRxGA#¢Ó¡›˜ ²P9/¼[²í`& O+Ïgôp“½ˆ³¿ÙÂÇD#=7ñPœ}r[0{D^ íC ÞÁ^ 5Þ ®ÈŒÇÙè6pUç¹MSlN×¶Eºä'›Ñí©<©[YXx-÷{\–ØTÛ‰²àáÈkÙš‹sֱލ‡ý´2ʱzn}Yqˇmú—™V„#¹ w°oåØp[þfÚ[4€5ßVÑ?M‡Š¡¹‹ÜjM£'ªÂSùpàg1—™çg˜;mâL‚’)|¾ dâ(æÑ4.øìš¶`¦NÕ­nd›JE dòÇÃMcÄûKF¹°‚ü";£ ‚B5Eþ,„8ó¤IÙÉ?ùÓÌôÙâ̽2Ž3² 7ÝNÜ`ãZŠÉ$ÁnL#W­3… }L®Ç‹SäÈbo•Šp¥2PÔé¥k3<>al*«¼yóz:5Ÿƒ’N󂣦à(Ú=iƒêl$uùqL~äF&‡niOÐÍåÑÜ1˜úÕ²†0IÓÝÁV2QùÈ#rLõ[YàÐý±© ûèóæJÅ.– Œ3ëùã—„ ¾:º‚?Ïï¨ðiÆ;Ÿù€ {“ÃÈžõRä»ù{! µ€ ¡œ†aÚ£)ÊÑYûòv+vÊi|&¸9b ï•§²·óú<|w¶]yEƒ +öuëxói(F)Ÿ¿cÊ÷47’˜YԼʹ•øø‚·3ƒÑpdAaêBôÖvæ]öû¶÷Ô)éºSÕ•è…›ÎLÇepGà è:Ó¦¬Êvwó9Çe="¢æé2bÒàݨueË«5æ+À¿-íë‰5S‚Í«É|øôD \*mžOjðªþ0„Ã(z«þô™z§ŠFû2‘i7ÑœŽhBn~æ^Ä„ðúÂôºs‹— Áè Ÿ ­ì×G×Múxsä7uV ^Ðÿù9c2”b<˜Pƒ—Þ¤Ë'í÷ËÙ?ñ÷;”¹'÷endstream endobj 190 0 obj 2443 endobj 194 0 obj <> stream xœXksÛÆý®_±ß eÄ5vÀýæÔNãŽImuÒ™¨£%‰˜”ªþúž»|¸q;òX±û8÷Üsñ;‹¹`1ýøßÕîæõ'ÍÖÃMÌÖ7¿ßûù_ÕŽ}£Ø}…UB2ü»_ݸ‚I-¹J˜V»ßÝü-Ò[™Æ‘\Üþóþ¯8»2V<޶H±¨¾< »Æê›aìú¦*·ì§n4b¿Ü&1ÖÊ$jÆ ûü—÷ìý§÷ÿ¸cËV›Õ­ÀC¡ò¨Ã¤¨ÚvƒyˆnÙª¾½ÿmîò"ìYùä‡Ìr»©ÙíLÝ”£Ù¾°r5šžÁ£mÓ®ý áR!5ORé.êç²_=6m3Ò}´4q'ž:Ïxâ7Ü-i‘©@De.üƒÃè|mÖvãÉI:æ:Éýºr< åi‘…º~,—[¨¾+« {ˆÜö°€"m&î•2 ˆž»ã O“$Ø¡Ïu&´û®à±V.íÈͳÍeœi›¹–•UÕÔ¦„’-SZ ¢•©FÖ­l&b‘Eeå a‡ÁÔçi^ ð7YüîÃ~üôîÍÛÇßü|–b/²ÜÇ[Ù6¿-"1°MSÃDÖ´Èp C)ÉlìΓœf\g!äf»z\šuÓ†ÏnÓ÷XȦ«n9»ß›C‰«pÐÞçÈ&D’gzB"¥|§ cǪ®¥hö6Rçvf1W©¯€èíRòDg«»Ã0²¥a[³B.öˆÂØÀyvJLÕõ½ö][{Ø/D.y®d°1v©¯]ÉæIDàG:é¯ n†-;Ô @Ñ›ñз¦æ6§û?ÜDŸ›¶2·¯N*Yq¦øjQÍ|*P5E>e·Ð6fÀÍ`}Ê€×÷]Úš ˜!œ•ú›:,ëý¡qT–ð@$ѶYZ .¨£ü Á…vw¯m56È*n0æìhâV¥ ö»Þ^-2Tc~¬\ö£·õìN˜¥R=•þ² ¥lyAh.&^x2Ç2³ïnïXµmP–‡u_îöLy_›ÖôHÔ û=±^{†.‰Jʧ" ˜^†dÂo ¨9xìK\b,¨:þ¾\j.È¿ôa«=å†Þ”Ûæß%}ÍíÖœíŒS}º³ìE™ðÁWξ'ç`9ÊâKÓsð^j3†èƒk,QO• >^Ã]qôÕ-]Èxª`~ds¸Ò&™ó|â*Z°ªïlÒ‘oíò¿£¨×¨ "M¸y[ü 'Ïžü<ÚoË~=ûò­YÖì;V/çß¾³ðM\yµVÉo©0ÁµT.$¯TÎÓYr·þ‚058WéË~\† &ÔΩ:¦:­Ñüë*‚ÉÇ«•Ù×X0Éqyà„oñ-,mkY"/Š™&öº]ã8ƒ¸î»Ã¾=ì–HLéJXå`lÏ­œT8ô¯;ªµ¡ó™¥"@oì–¿Q DG¤ HÓ¨Ùá¢YÂR\²-I͉;­-A8;ºrÞùé{rÔÖÎ ¢á∼¶k8Ð ‰8Ö´Me€ð¨î­ãxž$öÌœ+‡Ë~ys¼,çizt4v¬÷é‡485_Ž–W¼Û] J±aÃGj–Ýà¾ë+lkŸJ% ™`–ÏI oŠÉ›pz«­1×J¨Ëž4H…Y=;(¬Íøˆ~ RÊ3à,wÚf"tô±Z ü—HïlÐ3ÃMh;÷Pr©Å”Òþœeôl(¦Éïk¥tRAðàk‡ I°¾R”ûrÜ\; 1÷Åè;=°k…ÂÀ¶Û'˜{©hJMrA•D„[ŸnÊ,N¯0î€Õæ‘´õ¸Ú–ëÿƒ~¯œq•‹Ÿ<]¡ÃÿfÆ¢œ”Š·>¶Él%\{ÁƒÏŒ`O–)P­b¶¥p*o{°Z}ûb9¦s ìÖ:Á. Ô]’û«võ‡¶uýrKH)èê³`agœL{®g2wÊ §š‡ÚãïçÓ‰.’Ôñ•Í]Ø ­«ÅtÁP^ßE&çH®ž|˜ŽêûÉÎz…(l8îlí@à¤î6ÝaëhRPˆMAÖâð×:æ•ú5+öÒ@8Æ‚[wö\hÓ¥Yû8±c'b©Ú8t¡—Ù8”ïŠñ¨x–ÅòJˆçò-ž"K’xàNøË(H&$s©\ÃùÞ Èd„;äfÐ}<—×K5‘õüúiÐ;µ#?®þr¢e¬'l"~¸Û£oõeõ…f6ó4:MY³bE5W­µ±f\euaŸ€€²ÊŸ¹/‚‹5aåØs!ŒGÎö¦jVžJ‘…6˜¤nXk*6é ‹LŽt»†4fÜKt³ïŽþk¿òfAÅ’ë0¸z/WÓPu!½rwZ¶»V[ƒ C×µƒí¦Ì<_nø;´5z²E#âêÇÎ÷®bȶӞšæ\&YÁþ€+ãËD Ù †:õ]…b`1Ksd¡ÐLp¦Ôo¿Lc‚1û ‡H2Å !ÏŸ;á7æ®6ÌŽ¼¨}òé Q:åYú?@Ê­üÕã s¤JB/$%¿4ÛÎ x[©[h"zŸên¡ÐGhö—~ŽUùeN Îh–ÏÅeA\É‚âi®Ùt“Óo–f‰_cæA‰~~6ãèjÞ•Dšñ8K’ÄqºšŒ•‡E‚¶ï ÚÎg¶ï)°N›ô\û’´ê»ãú}G™àÚZfÒn-Ø)#M¢×Y« ‘Q„Œ\¡%‡%4 û¶"U)½³B^¾_Bi‹¬8Ó\_-½™ærðƒLôeGtNØÎ¢Ñ'§·Hó÷lè¸Ùôž­Eè{×E.è%ƒrÏ>£×…*4œ'uÙ¥ ,þøX¾0Kq܈ᬓÊùÛÝw÷7ÃÏ?/ú?endstream endobj 195 0 obj 2312 endobj 199 0 obj <> stream xœXmã¶þî_A"V,_DQL?]±W4Áµit,d™öª‘%G’ooô¿w†%YÞ Š½ó.$r8/Ï<óпF9aø3ü.N«?}Ò䨭9®~]q÷’ ¿ŠùËf%ɦ€U\ø·9¬üNN„T&DË”lN«‡(Vk¡X$ãõÏ›ïÁ슓”±„Ä íW‚&&!›çU´y²¤µý¥­Éçõæ?«4uÒ€áa™rËòêbIsÀàyJÓL$³vKSi@|Mv/Ø5ÅÛÖ7MÕ‘îR<‘`T8>tñ¾üÍRèª8•X 5-ö4}]ŸWǶ„º mÝ] -|æð¿n\;àù};E•ÍéHY£¿-ÉÏçªôx‡¦„xá5 úX®¿™2Ï5GB¹.ñMæë—©"|xD-Räí¶kßRÜhÊÓÐR "Yõp©IŸ,±ÅSãIPQUØìÀgù¢¶BjªµøãÚB-Ò@ñDwkÁ€R´ŒJ[êê%}I¡BŒ]ß^Š¡¸YF5!tƽãñ{»»»ÅÙ&ùÃÚ/ü—Hß"ø?޾µviHކ¨•.ñM,€¹$–ßK*ü J)‡=Þ»¿AWžk¹Rê!ë‹ãâ°j(J<‚7Èt%2±kŽ´œ©èK~:WnääP‡<]ËÇN: ÆrOlÛŸ¼Ocá©'·™"¥¼ßÏDS#A>D«'vð:VÀŸ†éh‹’×nÀªüÅÏ¥¹m5R‚-ç„2Yz?ˆã.MÍÕpŠNù ÌrλÎb .*‹³‡›p„õ¶:<–ÐÔ»×f¼c…›vaCT&½o[æÎ®±2Š¥äTO-¸ÎqŒ|nJ‡Í¨+±®BC…¶Ä?¸²¹Ww®þÙ»y{7¾YE¿ÃÌ…±9`†Eõ‡môUèNoà[òõ~ (c,úºÛnë¯î\‰æ{CÖÚ¶n¶‘Ûµ]ß‘ñé©;Ž·ë?û™=ßo¿”½Ó2¯¼ûï"i˜Ž0U’ Œ.¥›ºr•ÆáŽãéàïRKö¶‡ŠÏë®Ü[⢄$H–QÁ’0rU¢=üÛƒµHl÷Ïèƒ6Àˆ,eLóÀ4šÊTNç­×œ*FËñâFàˆÈÁ4Ç•qGƒÃÿøñãG/Ó¿P䢸Þ߇á+A"L ÷œÏGy¦yp|„‡Ë¦«µ9æå¹ìŸ\¸v KÈ Úl¡õêËi½ ΃¢‚}0#qÄèzqI›"íY+T¾2ò‘¡r"ióîÁÍ9 €ü!d†‡d!‘¢9 qÛ ´Ôh¢ɼ4k©ÂTúé’x< ‹žì0™ 7^îÂÀí›mÊà„ &þ?z“ˆ·8J @^ôš{ŘAšå ‚?6ݼ]N(E5Ô+P¥oõ[‹©¤xgoc ?GdŸgĦðjf–> &—ýO?qnº¢Sžó.  óªi°±”ךûö¶3äT¤ÓpØ]ßš ÝÓò·ÌÜhIà4¯iIMœDû4܃|¿¾Â_äaoÏÀ·Yd ×_‚qóó’ã`-èèRrK‡xîÕøþPÈ;‚K%È•¡»ï¦ž$Ëõ0Nò¢€[ùj”Kxvl›ËÙÏ÷âJ*c‹bÎÞLbgöÐé~ðe¿›?õ³ðÝ Nü•ʤ‹/¤E¾_0Ãò'KÚéûhdÅG43å×À<;ú;{~ñé ̵Ti |¯®†Í¨Ç„¿ykÐé0¥^Q¢ç¼zÅ\,aÒH¥ßðiv…””M0—7WH/³¡q<ù;¨mÁŸvk`¿ÐåËïð>lVÿ‚Ÿÿ;·exendstream endobj 200 0 obj 2175 endobj 204 0 obj <> stream xœ­XÙnãÆ}×WôÛP†ÕéÛëÍÈ2™I Ý\x%¶$2éÔ8“¯Ïé…-Š’Ø€lªºÖS§ªù;a”f~üçæqöÍ}JvÝŒ‘Ýì÷·_ÿ±y$ÿYÎ$Yn ÅÁïr;s'9© R‘T&dù8{ˆñ\Ä,R‹ù§åЇS Á$eL‘E ¡r&©RŠ,ŸgQUw½.JJ–{=_þfôç^’ÓT)c'¢ò¹h·+}Ø®ªºê?Fç^<¸Ã3š@«/êr¢N(š§øïšºÕúšB ŸƒÂªîu»5""¦YPÄB$ÅFwdW‰Ò𙏡K1HfÌI~Ö¤6b65‚Ñ8^&jìq%²àÊž2'¢µ®õvÎsšç,Žªž46¹Áâ4gJz-Ÿm*m½8§\eþyÛ³œQ9xöí5iú½n‰v²D¦.¦‘û®ß5)‡奌3=WõÎú1J3Ï9Í>Í;Ý›T_-ÚPß¾!Ýq³Ñºü8§6 2‰iΑ a%8M…Ë B¶ÇzÓWM=ÅLF9“_UdE¥EîHW=V‡Ñ6SÕŠf!“Nó¹VÃ8xÞ#,¦qP¿>9å±µIŠÐs™Kš¤iT7§Þ‘¨1ç©Wñ¤§!/W8ÄÄH*³Øæéî°%7“xU ›y>Ø|jlÅ *ºN—Ä7$i¶¤ rYUMJÝmÚê©oZÒ5Ó²‹8óW—]Y/ô¦¨ìy "QC ‘ǃEƒÁÀ;`éBhË›‹‚Í¡Òuo¼¸džðtì4@«/甃‡œñ«I‚™gÓ$myÕwdd¨&OÇö©éÐ&ÏU¿oŽ=iu×·•§íQÁPÁPÎ7ã|/œÃ.*¬&ÿȹh'–f¯žÓ˜xfÀ…šV% X¡²—œ›‚&TÂ/H÷aµþ4¢]7_´¡ÿ8½ñ8´-á¹G*>qOsI´Â4Yæž—9–S1H1p­Û¿Ç´˜X _Í´ÂúpiÅß1­°sË„ømSjp©™õoÆŽd ˆÀMçe×gì ˜7LCkÁõ©§¡µ&Xt³wômzÝŒ;awSO]Åg˜ ôMyÃ}w5ò+¬½ê—(ùwà…pò‚ƽj;5ðtb7sìCŒ¾µˆøÚVf”eÿÜÊ7â¯YÞ¬Ò ßåÏLŸúð…<ê¢Fý¶Ç©ñ‹Ñ&쉯€âI±ça7¦,õÝ5ÄCžíîš©¨èÌü·@2*«âPýiGì0›.úЇBìk ¼Ä™8#ÁéÀ,ôý‰YRÜVä)ί¦Ö¦¿û°`—ÎÁ\‰ß×nìè"èüÒ”+¡N¡ «›z«‰>ã=T9kä°û[ùéúK‘!/{Û'i"†Û›pÇ,>_äìb¹z=·H«Ó#×…1žC‰LÌå(éŒ#Ë ƒ* ]{[™äá"z±… ‰ëÀ008“üåÑŸÓTk-DS—»´>rK#Wïk§î°A`ýåÊEâ~Åâk#cº0 nßa˜¶ ;Û¾=×ý Ï}z¡ @Áa%ëÛ«o"»s«Rà縻»¿ÿpÿâÎ?´EMì„›Çæ:Ã#êÉûtÈsÜÎÕÕYΙæ*•Ñ óøë+]®‚kg8²0%Ç¡ûÑ‹ Štå) ñø.–%xòSñ×ÁO§Só6*\ýÏ_™Ý-g¿àç/dª^endstream endobj 205 0 obj 1829 endobj 209 0 obj <> stream xœÅWMoÛF½ëWl/ e”ëý ¹dŠZÈ.Ò:qê*õ!.„•¸’™È¤CR‘¢ÿ½3»$EQRZ ‡Â†e“»óñæ½™ñgÂ(' ¿šÏÅÃèüF‘U5bd5ú<âö%i>äÇéH’éNqAà{º¹›œ%¨ ˆ’™>Œ>x~8!óBüÇôg°çn%Í-_0I ˆÂùtäeyMÒ­.—³ÊÔ³:3é,¯î¼ñôãHÄ4&>ìÁ‰=41óÍŠÀ‰ïð¾ºÚ…ìëíó‹²,Jrfðãn Ï{IøÎ…`è‚Q¥ ¨íț޲Üä‹:+rôÓK Ѝ`*&ö†w,rðá®tHÊZ։Éõ|m*²(‹ªò‹ùG³¨‰^,LU‘bI&hÅç4BÆ”‰ÆëíøÎBËc†íó›K’êZS{S& ^E-~ P—Öïë%ÑëBÑH2þuóÀ~HÞy@“DHO/>é•!Mà÷º²ïAŹ¢1oòö&·³Ëë›73¦åÓ¡$¢“­ÿ¢`ÎxŒã¡ŸÞ¾·ÆfYžš¡E_(I{Ép“&¹A|k¨q?J‚÷- ‡Øf )†Qëïɾ”ξ¤<èê¿ÜA…'‚.…‡ ì`buxœ@CUªƒlhø†4‘º®Ël>XL.¼Mml6¹1iEæ feËÐåÜŽ¨Œv:z§w~9Ô'Iœc™ƒ.­gWÙå˜'p÷²µ(R ÙÀ<8I´;€i±©‘ë¤.ˆ=¡hqϯSÄS]j ºÏ^w‰o³ú~@ _Paø½MÌiq Ðã­V‡Jµ…ë+’‡´ v1Ǫ‡‡âi žM­³úùTWpmm‹e'4Ë*ÇR“Þyøà G‚oé\ pé*‘AÑA[yúL¶cnëyú‘ü”¶!œv=‚ƒŒ¤lÕºÍÆAUˆ¼¥v¿©ÈËõ®-ã$hUç¶| Ç–Þ‰'®-bä$«&4è倲3“Rr;Q%4dKüD8¤…Á¬s¬äz4¨š%A²×~Íz èfõl~¬ùJIC0|ªµ`XœïÙC[hi66)í.®¡äÄèÅ}Û™ä8‡,‘ë­MÔ¢1H·…©¨w0Á•aÒ®XÛ—ô€ÃB¯×c?dÌ«6àHW/›F·aE clßÍó.³Õ¦ì܈ ºa’×€J·©ÓaKn£¹xÒk#`J;*åµC/í½A÷÷9T—ïhä})²”˜ÆÚÝÁ<'G¦¸«¦÷' í#»€ìv®“W„}oÏâ>Dvðn ª†Å:?#“ž†ÐeÖÙçX¨]íX=Å/_ðÝpñ°@* ém%6©&èÜÀÎcR Fþ’œC,þ^f.ôckšk—›o›e¦IyIîìÅo^Ž“«ßg׿@°Aú¿@®,_‘­¤¶e‘¯ ›Sÿè_'íX¨­lZD}Ä6¬[$ŠSÉÒ×% £#-¬4œÀÛ1$P»¬²±¦ÔØfaÊ ;-ÇÙ]ÆñöÙu¬æY+h¨LM9aU‰£È\Å_×ÄV£ª²f0mò&,ˆr/7|^ôÇÐ÷Tò¯ôÆOè ÇÃâä1Åõ×Lè9U±6µ9”ð3‰ºÅvOzò@zŽÓ kÿƒÖþ¼oß_]õ˜ûâÿ%®hÀvDÈ‹¶(\½uùüu6Ì ŒÁv9Jx´¹½0 »£ðÁ½1™l¶E&[’|‘;’´“Š Eà70ë|7DpZu+ùþ[Óѯðõ7Ⱥ¬Dendstream endobj 210 0 obj 1397 endobj 214 0 obj <> stream xœX[OãF~ϯ˜7œh3ÌÍûu´tQQÚª‚*rìqâ­×Îú¢¿¾gÆ3¶ã±Z ‰Ïýœï;¾#‚)"ú˾&ß×í›AûÅ÷5‘}I¾¡Ï›G›¤(Cð½É½&EL2Ì’<@›o‹'oí/™O¼`½ügó Ø3Z!¢\+­á˜Ö~„6é‚cæ£Íë 0Å”¢t¹ùº&œ…`$¼×¸Î¶{ÕnÛ\¥Ût·öž—Z b‰l,k§öµ16ó²Eéu­ÌB ÒThi*°0 7FøFíº=º^ìêú“Öb÷ÖèTfRÚ,Hn«®ÕÒWNâ¶®«ÚH(ýÛꂾ‚üß>Jï<8›×PcαD¶µj»ºlf¹s‰YÄ­ÈÍ_Û›û?·¿Î !–AD{)‚#°©“‰Ë5ª›Ж °&' ÎŒ†ÓÁ¨×V¨=(t¬ ìªÖ¢k@[À­³)à“¼ZR‰£ˆ3ãá ݼ.)ÙÒ³6D©‰oƒá&ênÑ]¦=p Cdjþ j…ò••ö‚ÉHXÕî«JZcw’.… Ñä˰uåy¨‚T¾üqûl¡l\ˆ¡»%2­Gy‹.·.Œp$vÚ»ÛÇLJǹç&´—ê}Q`.ƒÁ×]‹Jež¤C9F1ˆ³ýbSšpàªM£ H¡øc-½Ë£Hg!=÷ËÃööËæñïùè’pñ„(ÌMÈ"´æòœØ xê9 [2!†€7C³N~ę՜3À ª¡ùõ§@6­4ž$yg†#"à ŒwÖ•I›W嬄’`DѧQ ´6Ö0Àl:ø*nTƒâ¢°‚ÄÁ›b טû|g Ϭ ˜6æˆÂ€´Œ ˜Ì¦êêD›mš*ÉãV™@j[$ðâöð{ÍÛƒApªš¤ÎmUÏ’Œ|,˜ Û²ïõOV̨CݧxD:PU¨EÁ+0U^Ú 7v`‚ÀÍØËDb2i‘§ÑÙ ûàb¨—0è}½!¾si! ¿éü·õÔÿÄöeqò(ü÷ÁŒ2g+ÏÐ@nqiš ²§ ÛÓNÚÕy¹7èhje¬‡Žþ¸:ª:ÖŠ—kŸÍ ޤf bPiÉÄGFb—PÎcÔt LU“uÅÔ—™¬ˆaŸi¢ üg•Ä]£fEòÌ>µ|aIå ÌJ{ 4°.F½ÐèA ¥.º-²É䢪~nP–³t~VPhçþ@â†Bønt‰è‰-­”ÞF-JŠªQиan"Xfª" ´ `>Ç ¼2Ï)æc)¸Ýô×ËñˆšCÕ):/&Œ åì„uôÙ¡Š9I¬9± t¸0Äx+ôö“‘^‹0ãö(²­Êélûû#K 4b/;~*…ëªÛ›‡3/4”.k¹ZÍ9Žèx‹Ä\(”Ôj`5T “äº{›{pÝûÁaƒë„½·ç8 ÷ò–ãïºpUl›V79¨äߟ¸uÏ,h}01$­e§ó¤Ö½tožÂ¾m5¿Šqµ¼Ê™+F+ OQ`Ž}Qí`3eE¼× t¼äæaÍÀÝ9ékhÁ„ æ½äU× óžHêÅE§PeèsjLiº‡<#C0›Õ“w×KNB?‰ è÷?UWèÙë·`¶ޤxqW´ÏKTè<~Xáh èí¡B•{ýã  cóa[å­ɵ}0l_f·¯ §±¾í›´BMQõDÂú-K™æX7YŸ|½QÜýaâÔ·ðVH¨ã>⾚÷^KVŸápÀnygùþÐoÏKlotÍZ!1»²?,£½3 ÑY/˪\›•>+©ÉT'=+¨iwH]myúÍøÎº¼Poèk×´(D;½ŠªÜBÝ6–yúÕÞà'O€›*ÍSIU§*Åætp÷©ž¢S˜ €ùÕÅ[V#£6œP]VÉ6>‹<1kògN[cñÜÐEðk‰·÷`/#÷8ù‹kÏîÒâ“YrÌǼù-~CŒ0:*J8Ø%s™Ÿþgàv³ø¾þ¨öYendstream endobj 215 0 obj 1606 endobj 219 0 obj <> stream xœW]“Û6|ׯÀ[(—à÷£ïìÔ%å$GU÷°{¥¢HH¢M H®¬ûõéHI«õ^\»[ZÀ`¦gºgø'\2A?ãgy˜½ý”²]7l7ûs&Ý"?ÊûÇj²U‰]R1ü®¶3R2•*F, ¶:Ì‚eÙkbž$bÊÀÅ¡1ÂâL©¾K'Ò‘¨¿Içå³Ò›¹DÝæ± †Ý”Þγc)sÒ0 ­¼,Üe ùmàÂç¡ëYÆ65Xܘv·`ÀJ[÷ k‘üÕ%*èZ][Qºà™Ï—ã^ô¡cCÛÔ_ˆO¹ˆ"D}¦Z–Žá*8;\ñ·ÚzIÙê÷pg-ÀÛO“!©Qà#äF9ž G>bV!=#NX=NËì\fsq]ªE±6GŒ4oú¢ˆËÉôôšß«2ÚW,ùØùEØ‚÷nû?Ç}¿ù}lÚ/¤KÖß)=þÿÚ'OYN¢sÉÔyŒcêm Öë¦é®àç*J |ÊÈÑRÙtæ@ͯ/êЇŠ*¡7÷X«,û¦þÓõ•ú;gÁ£(cy’;cq‚ßf¥¶¸¥eÚZcǶJždɳJ Hnà”lÔ—©:Æ£7¹ͶP"—’'?=¤~XÀƒçiHÑæÁ»|@£è qKÏ¡ÉBŠ$øÚÛâ2Ýk|¤‡°]te»qã×¹ºŽ_ cMžÈi¼#‚ˆ> stream xœ•XÛŽÛ6}÷W}‰l¬‘º£Oi³ES´H»q‘‡laÈe+±$‡¤ên¿¾3¼ÈZï&H±¼±HÎðÌ9gFû™„”‘ÜgÕ-^Þed¯!Ù/>/˜yHÜGÕ‘6‹ˆl*XÅ8›faw2Â3N£˜dQJ6ÝâC°N–< ƒ|½ükóËbRãÎ5#†1Y'°°^M»Ü|„xð,£aÁYÇÁƒÁQ(Ò*²K–ÀC_}DUÃI¡ÿÀŠz¨ÆNôšÚPþ…4J²9/‚WŠ”äÐöú†ôƒ°¹Ôö¸a”• fÂ!/™ö¦fo‹Ùœ[} õ—eåyÈ|®¥l¶âØlÛ¾ÕÛfÉ ZänÚCpî…T‡ötÜ/m’¼à4ÉY³ØÀpØsYN“¨Èí¹œ)Ãð6À Û}Û—Ç)­î—¤L`/ £,›2vE¥·eU ¥Ìj NLÈ®H>­µ‹ìiRØ}".Á˜†qdSAĆþøà`SG—AšÃx¬I/DM¤8ËJ`mH3H@¿n›%œ¶;¨=žÂ²Æ¹ ‰Ù’!ȨçN 4rö‰2ƒGX-RÈ .@Å4ɽlC Ťû8L ëb"ü—tÚ¢¢Ü”Ðd<Õ p—O=j ̓ç¶ß“Ã`nÙøÍ|b‚³6î3 Ô¢Ð%w¹u€2R“%ËCšs(X[Ýñ¼0¼—­ÆPˆc3ö•eÒÊK§Ó 5øI¿FRœÛãÿ<¶lEõƒ§ ÊÔ–ÁAøÕÞ5x$àÆòŶ,¥,K¹'æ0'f–zÇ¿ñAAY’ä#Ö@Ô”8Å e÷e=œÚjn²qòm&ûò.',Bÿ_³¨ !B—Y]rk¶8¤Nj:¥aĽŒÎÆË¬=y_ÂUÐT ×TÖ~‡óp 878Ý“ÝÆµs:É-xmÖ¼Ý}ܾ²î÷¦×B6à+Tí np‹~†²…$BÊüzØ›£0œ]ñ»6OK¹Ç‡àú³g¯ÅnܯH½3ÏÜ—·Rr…{ {1o–k›§½øYœC›èuEÁhʦB‚ À©+ M§pÈÞ©U¶´e'H©®B1Õ›Ä ¡œï‚YLØ> ¾Ýùð“™Îó'ÌB_yñÏóÆZ‰“¾ÊšDâ²§I˜­þO/Ÿ!fÓ=éZ¥œŠM¢Q 5ã“?[1ìå0žú±ÛJ¹d¸h̃½¡=4;òÚuFm²(»XNðþÕånÐ:“Éžï~Jˆ:[ÌÝt^§Æj]!UÙÃ8 ¡ 'ë§BKRð¥/(-Fi¬ÔöBoíuò$ Ì®Yl{ Á4’üù™ŸDfª°¢¸V&ô]èEÕàÅŠšî—§¾û«KCáPC÷­®º±–>w,Y­HYéÑæf–o¡wÌ%ÿ®+Á£W¤+å'Qo«¡;A‡T¢žiøjÍ¿Ð:¿i¡:4ϯû³Wí¾‡ž±"—çÛ£è÷úðü2pƒ¯,4&C&—ùþk6CYh]ÛRá œî„n;hµ—XØÕ¤¨ÇJ§¨[õ ZÓ Oëo;Øt µG”Ìsî~±L’@Y±ø‡®T0ô†©•Û%x‹ö CŠ‘è€s ØíŽ"ò2‹$Á‚ºQ“EyPâfóÔ7Ñ%7sp„³7ö\Ûÿ¡­lV ‰ƒ€ ’´ÓÌÊS<èUö5>¹È¯fxÂQˆÁ·Ü:fdºT f–±:Ì@õM½­€%¸Û´sKo0‰É雋yD°ÄC`iÆ/· °ÌXîw©~¾+ãiürÎÍ9`?²¹`T#&3 ¶FÄ ÇÑ ãXgÎ`P›šµ¾ÄH|‰o-Ga«s}o¦4¶ Œå'6 `áÞÍÏÀ÷¹ç& Z–¦"JP˜Si„Â–× ÊÉ—dæ6W )Œ›ŒL1¬QžÃ43Š•0Ág)k_-{S?Û!G0Ülânð­ÅÎx¾Áøæ ¯ˆîEdÜCGj†ï]®S†3s¼íñH„úÑ lÖ£†ÜÃëôýÁ²Ø0Ó7ŸÌ7c½v »×G›Áô‚‘ÀµUÕü2ö¢Í±ÜƒŒÚêpCÚÆŒªÿ 9N”½šËÙëÞžéavŽU®1ˆ~Ó©‡ÒΓ3û±9½ûù§íoûýîöÝ»Û×8îSð1èk<ºæD7‚Á‹^röÚÞ‰nþÚ²ãÚ=X#œ¦xËfþm:x¦1\OQJýê§¡*f ¤ÅoïÄE(6I?šGOtbõ "ðÍoåá!g—ÝYlf'©Ç.¹Ý,þ€Ÿÿ‘Àù>endstream endobj 225 0 obj 1958 endobj 229 0 obj <> stream xœXÛnÛF}×W,ò*ˆ¶Ü oh^’ØA]8qk -Z»ÖäRbB‘/V”¯ïì¢ÛI °lîÎåÌ™3CF>&ÈW_ögºýt¡u;óÑzöyFôCd¤[ôf9ch™Â)B|/ó™¹I(fE,DËíìÚ[sø^²˜ÿ³üì™[‰½µ >þÏÑ"€óÙÌÛŠæ“ÌV_Óz{×ȶ•Ù|ùqú˜)ƒÇi‚Cð©®½꘶Æ8 9±*}äQ…Ç‚Ä>vîÊâvuìrì(ˆ1wŽ&æœ&hAøØZ»ÉŸ2F0}ÄX‚™}r¸¾*eµî6S+”>ÒÁJ_}× q<¶s”OÑ¢¯²©‘èP·‘è®.ªÕ9JEYbušÂÍóÅ>‡âìfÞNå¥XÏŸâæ„ºŠ¼°(#øÚ{YÌ9õ1Ob/¯\¢!æ”;@ëj¡~‰¶RT­º•iWÔªÄ~éDÓÉ í ƒ„¦fÙŒ}•ŵ‡¿fòvNœ$qäõktãUV¤¢+ª5r+«»9ñ=Ñ¢¬®äÍ븨ºöP ~—€1“>ÂDƒH’à˜ÇˆÄ˜ÑØ¢­b‰t,š2EUt…(Ñí¾“­*+üÑ€¤ð9Ÿ€â€4jµ™×WoÏÎPºH;Ù´èïó³7HTÙü (ht*´‰Ä8&Œ>´LócľÓds¬(rT}›þi™ѵ›•öj(u'%ðËpõË»ÕÛ‹÷¿]ž^]ž hŽVv$ªhCø4Q<_„D•&’D÷:{àÃv!¸ƒ´¢ìUÀ’e®Cs'Ç…겑"“ ëÆ#¯^r3‡Oþ—Ø÷3•<âˆ%Ì÷€1pÅOb'ÊãDK(ƒ;~òêB%ÝiˆäN¨ÃèV¤Ÿ¤¦î×›ƒ’¨`s_]•{õÙDNÂäá<‹1¬üƒÅV׺ê­BìGlš3gô©œ9öCÿ¸†rÇû¿Y›Œ†YDŽ3Óê¿fÖzgù·*hã+*s¯C½w@„²‚(ü9wŒL83 šåuáb}ûŒ¢|ªì“ ðŠRj_9@¦œir/œ-7SÙõMÕN0Åa”9ÌOþ\œÿ±úp±:ý°¼ük‚÷Â^PÿÖ´IÓèà! ‡½©Š%!?övzyyq9q‡Ã”ÅFh„Ü´®5©Ú®QcÁÔêR”S‡d¬G/@({Q® (+UUÝwßp*rr×·.Ò-¤ÕHyãÝÌ3lŽÇˆ0³E0(û ©K Ó@ƒíˆ!-D}àýµ·ƒb®î€¢b-W÷Z´Âz à€›r¢Ëw´éXG°§uñ)õG/PvlÔÙº¯‹ìfþó$Eˆ8>ŒI{Iwhìã ´ªS‘aŸ1çtØ ¾s3¥#êk¼½Ë›z‹Š®C4P›%„TWdõƒã}#±Hu+–«Ö±£êÛ÷â“Þr`ÈÆ>qí@¢Øt^´]‹»/:ÝfuߤЪNs·6™M"N¼¾(t ¶ªßÑìµóÈØ…ùP¸êã×Ã^ RìS2ŠÂH¹“ P³¹+R3+8ÌŠ‘¢À\!FG ]FÓ¦õuK»¶1j÷uý0 ëf ¹©BtŸh2tvu2ѹg¦YàuÂdäë½Í¦ô®V™6˜ÂÈ€GÔuF#‡táA ³ä‹ØÞ•f8°$Äaäòbj¢êÈžQŸÄ~DâguÏý0Á<‰âÀyi«ƒìa.Gg ºMV]ÑHè´”ÀíM}d/ýˆ#·Ñ½@ì…†) \Óô`q#˻ִDéæ›^ó¤‘ QUùÜKè)'´†š$Q£z²’)îî wšzN4Ùï¾ÈÀ¬%z££ ]¤]} ütl{tƒkÕÕúΰ Š.´¨CBñxÚ÷)>H×r?N5ÝVoÄàN¢Ùºi§¢sL¨¹S¨?wŒj%¾CÓ×¥Õ¾ @(P™‰ùæ<^ú.[±W’ €Y´–•lúúm|3S}È9~yÈ-ÄçŽ|f+aÃ-è‹a=Øo,Õ)· À«Ž½¸ ØìÞ∠/5Üí\¾1 gªZ TeçtW®ÃæKb6(’ÐÌ} Š×pT?‹Æ¯À;1¦;Ð6ÕìÚÅ>±o;q¬^v …âϾîAiÕÔIUr%š9X%#ÞºßB‡´‡UbD-fß‹q«AÉ&‰bbKppXÄôè0;Å*³$‚QÒmô,šnöêBA n_Ê0L)kõžø:¦*¦‚¿¼–PÕÃíˆc'nJÿ÷ât9û¾þ¡ñœìendstream endobj 230 0 obj 1802 endobj 234 0 obj <> stream xœXÛrÛF}çWÌ[@—8‹¹`Ô>9‘²ÑÆ–¼2—ËÚbÀP„C Š¥|}ºç€ ¤Ý’«Hž¾œî>=’2âŸûÌgÿ¸‹ÉC; ÉÃìÏ3‰ûÈÉË™ ˤ'ðo¹™Ù7á1§B’X(²|œ} jΣ0óÿ.ÿ úì[©{kÁCAÃP’EòÈ—UGŠcÖlVõú»Î»U¡;ø¨›Õ>ë¶÷A^WmGòmÖÌŒ‡að¿0ÚyB²`5(BÞÕ‡Î>_~Ÿáƒ³àPµåC¥ ²««âV;]]Ì=}·éž÷zò›®Š2› Ö›M«»¶üËHÇ<;΂KãÄoƒºr§½Lh$ÐÕwD7M^ú~þOx0 èÂzÃCôFP[µ·iy®Û–t[M6‡*ïʺ"îMÕ¢Ÿ£ø2•R™*b”—_V—~_ÝþŠRʪ¡P”RμР,ü–•QVe`÷Æ|ƒ @c |s@ÆS™ù2eŽ’‰·;À^:IíBB¼ÙPß°æ8 (wfS(ThU‰`YÛ&y2+XPŠ<–\ßžœ õÁ ûzØ;Ç3².!…•KM¶õÎ AA],@•“ã“uäˆ%TÔ‡õN[X@[Å\yd@zc Øý_V†fPe9œ%¿ˆ ;–Ár«+s”Õ£ç3‰1‘yÍcEyÞÑ´šÏcºªðFú˜Cƒt- •BësÞ`Ž%t¼µ&y½/±Æj?3G1’$¸¶ Ê³Ö€*×M—?³üö3)>ý8` ý@B&}šdä1憚%–zê»i•í\;•@¸7–Ñ$r¡wVyP›S7sÓ}#f|K°V‘𨃡PãœQùŸôÐ…véûNÛlGв1´¤Ô&ߺ¸Ÿc;pAÕ“:YpÁ© ã¾qŽ,anLFqañ-êË` àÎ0f^‚¸™.[Çvu>²ï™t6ê±l[„%öÌ*¯÷;`V#ÍtNÄ›5¶ ²Ó¾èQ²Ó›Ždò—nêb{KÚ®“©›Æ¶È%´1›÷eM´¯w-GÊÔ&á Qo4Ìàör?rµÝë¼gÁŬCPÛª ¦pZ±„ úÔ ±8Ë’‚ùŸ*öv“‰h,{™ÌNŠq¦£J%ÓL¿Pµ1ôiŸeóƒ#}Áò¬Ùò˜&±ò¯†:Ñ(#èüÊOüj+Ùõ=×zC%] zâ8é;L†4ŒGÌñçå×OW««?Oêz1eŸ|°ePññýO¿¬nψL<’*‚1<¨^ѧ«©)bDäΔûƒ‡rjÎû»Ÿ~¹þ}ªŠA¥.ƒfêLôž® º~»ùõæöËÍ[ºZa0è¦:’KmôÇöQ>‹ª’ÐûA—CùÇT é?C²ç¡9 x¶»$¼Ò§lÜ÷€èy^llÞ4i³ç¶gˆG`Ú³lÓF°`©“6*ÎÚh3:Ê’ ÿ` ÅbãR`±F]?Ïš|[žž„ä¿ÏÑk ›º±óQ&o•ðžÔÇÜîyÓÒÂ]#ìI/—ÿ«´€$lž«›Ëë÷7«¯ÿ591¢ú ša¶‹0Yû$7akÉz¦\WmÏ–lÚH'Qb# D Ôþgãm.쯄ËÄ—¡¿ã™ÀC!©ò½â$} ÐÛ=†P&•>Dh°¹DÂmaýÜéöâ¥%ŽKè©~U’½2 -xŒ /x~ݺuW ]>¥vv" `æb³Ã»§ÍyÅBsPÑhÕiòpùÆèÙ”}‡êO9ó\|gܬä–ÕöòÄÐéºÿ–ƒØß\¹k¶ó}Qõ£ÌcÑyO±Ø4÷ñ^Wø~iÁ}&RýªsØ“¹ù°7)U2Ži·w'—ëg»•“SÃŽ‰#ÍA~tíKGVá¶¡ç /TðfÛ»ô+*p*ï±à ®|Ô'·B[pãy¸IÄ®in`´kí½)LÝØ¶ÕA»Ùs°e9~ÿƒá:,ðØÔ-ˆ»r]Ø„U/qH[š\“çú`Í­XÆaå+ì~ìN2 \”îö>µä«Õ;µØr‚SƒweÛèDöÞíKÙ2X:úKª'1ðå1ÿ|Ìž 9(M =Â/ÝÓ»î«åì?ð÷7ƒ!‘endstream endobj 235 0 obj 2390 endobj 239 0 obj <> stream xœXÛnãÈ}×W4öe©Õa_xCž&ãI°ÙYxwG“y°[6©%)k”¯Ï©n6IÉvl@6Ù]]]uêÔ)ýÉB.XH?ýçf?ûËï {lg!{œý9ö%ë?6{ö·åL±å«„dø]ngn§`2‘\i–¨˜-÷³û`Ïeb1ÿ÷òŸ°gw¥L(Ú´¡âa¨Ù"ÊØ²˜).#¶<Í‚˜K.Y1_þ1S”La ‚SÞlWõú³éV…éðQ7«mñ<Ìi1Êz‡~#¡­¡5\V+Þ4Bo·Å Y’)ÇV¡í©Çª-+S°wÛî|0v½ú4}eª¢Ì«›ùÓ‡õvÛš®-ÿcèE‚K‘·Öƒ/£ÕrgüšÑÏwÌ4ͦ.ÌÃü¯x±p.¹Ûo_bˆ„OTš‡qæ"¨Oñ·=£eÝ“am¾7,o¯Ãçwù¼~à!ïžü‘ à'½‚…Š $Û9m¾Ñ: !¸Ð}VSàÒÆ:8•w¬ªÙfm×”ÕcËòÃawf]ýÂM©¹ŒÅwÜ|5."¥|8ϸ{`jkÖ½[DÒÁÒ£R±Ï0XÖ-O"ÕÇÕ¦í>øG3) %A}<°»ƒirZßZøO_øÝ}B5O¥‹Á’râNa Y)ò.gÈ–i[Sue¾ceµ­›½µÌNO¦b‡¦Þà5BÅòйë³SÙ=‘£Á‡»_n A‚+%)ú*BȳÞuÅ3™Ø£ß/Y;dHâÚ™î×Ù¹wáÙ­Í»àZÓŽDs1$øú~L62ùPÿþw½–Õu’­kJõaWv‹âd«+Žù`Š×öpä–=Ü­Ñîñ†(BHå)¢¯ 4Ï”?·?óaŽYfY(p•±ÇNŸÂª®ÖÅ<ãY–F©=Ø{Ím.)mŸ;¤ÖµŸ:Ö˜]ip©Š}Üm/sØÞPž“·¬­Qo›z@Ñ7-m:#Ÿmgò‚¶âÿzc3‹Œ9’G*üå»û`šú®feAØž¯ŽãóEIžDá©5³¸œÙ”[{ %[{„Ê…¹)Y;®ôƒrì\Èú Óî ܤ«ë‚åT¾D,åÞp—$MàÚôñ Þ·Žãœî Ö=;$'oŠ+dé”'"ßE–$D]mMxªÂïoUÿÿVí î!¸Û쳿Ã}zC†ï>ßõ$)éÞ™öDÐû›ŸÊÝŽâ lT]^V€)mˆÝ‚Í,á±§Ìûà\Ï£]2ÒÁ¶›«B§>¬ÁSÔWæÂª%Œ„÷þ4©–Œ+¿3Üò gÀQÏòÔÛQí!rz;·_§Ñ™”¨<¹P Ú>67ìýá@óûÈ… L’X’ñÐâ:L]EþðÅÛ[3ù_ª²k`õvþÏ2‘[*&â>‹¡‰¬í£<›WPÐ<—ör‡Ú;¨Ø_î>8Õs™¢ l?L‚MåŸ%½"YŸžee–‹+‘¯,jTe½Õƒ«Z¾ìy Ù4L¼ë»rm{ÞUs¹¡ô|0±ÃÎ[Ò¶ñ[PH©~‘ãöê¸_›”dÖÙÅW%"È‚¿ãÿ(Û/­}¼RŽßÂß_H`0Òº/9 ÛñQuž† ñÓÑe1…©ÄX…S7¡=™÷¦ÖBÃÇ8ñFC¦Ï¥I#B)Ї‚ìûŽr+é"Щْ ‰#ž‰8hê$m*I…O±pâ«2¯Õ_Ý`”VG ×*É^éenQ2”?q8„Àí\Ú•_…‹…q´ÞK© ”oo›vƆ¤ “¥ŽïÁ'±NF ­_bÄ]! '§ÑJ§šê‡@ÂôúÌ,T-P7ôɰyáìË*ŠG –ž—Ò0{¥Œbbr}òE]Ü­æx‡údª/[š»XˉöT>¢yc7¸Ô¦°rÙ·~Rl/$%r±ä™~½úãB{÷—ëØš¡³“A“( h/DÝ¡»—¸Í [Ûÿ¡‚cÇõá¸Ë›^c8ùÉÚ3ÆÞÉÐEŠÅSäÇ>§ØÛãæi¢wúÊ|ÕÒá\]’ª!q Á¾7y…ÝÛ#\¬7Ç=”I¯S¨(OP=àgçz˜(¸^ c¶5sZDf1Oâx(Ò¾_º*•£³¡rQ‡Ý§Ú•Ž}dQŒµsêF¸GX2¼ðÙº@™Î@%¾ûáëéR±WÍ£#/a†”!)íõ°"ÐÜ¿EÜ1‚;øJ‡$.Ðñ:‡]Òˆõº5Í3k`@Ê Oqíâ¸Pb’^§.(£ê|4M&fœ{ì@N‡}šŽá`Œá?^Ná÷n >V˜wªO;ï¬hˆmí¨Õ;ã4.)ÒoNãÅÄâÄÄÁ@Ãxç&ç[³>>²bý8į‡jßÕ¦>Vݪ>vv6±ÌøE­ÙÁš)z÷Þ\·Ï+À¾9_´w'ÿMMøŽ>0¥= ÓÓSêBD‚FQÙÊi/§ˆt¶Çj˜F'ÁNëQ™½Ú—ã0ô©ðá‡î}~fk*ÝÝÎÏÉR!Ü ê%PR¡Gõ¹žXâå3ÔÞõì®1ŸÅ‰z-¹N/€@¯¾OH²qdÿ©Ÿ/Ü"A)Z×L…^’³ƒéŽMuýet\2´HÙÕí§­î~¾®Lœ%ÃÀÅ®0Ð%Mß¶W4îö씩ʂ|wƒ?—¹m÷‡¨7+U¦\SïQÒ %§Bû³ë³špÙä ‡=ƒáÉ/H’ ¥wCýeÉ M.¿…û¸œý†ŸÿÎ> stream xœ•Xkoã¸ýî_Áo#cV$õü˜6S ÅÌf›u;(&…!Ë´£]YÊ葬ÿ}_’,ç1ƒˆ"‘—÷yνüN|ʈ¯~ìßü¸øË]LíÂ'‡Å÷Ó‰ý“É_× AÖ9V1Nð»Þ/ÌNFxÌ©H,"²>.¾y«hÉCßã«åÿÖÿ„<ìZq_PßÈ*Ä¢eÍ’%Ôgaèú£¬º–êåë?/|©…Ï ï¶Ê%éäòƒ::µG1åi¤€0ïæ9kö›¹íËõïSN“0Líº¢%õ£¬”8rhêþ‘Õ¾nŽYWÔÁ×Vv$«v¤èÈsQ–¤ª;’?dÕA¬S²WLÀe!'+(™¾VR ,‹½$õ‹Öjá´Ršþˆ¶qJ¹]DÍaAJY‘7o×ðùhÎhÂ…ÝtÕÊ\™²Éë¾ê6ußÍ`‚Ó8²Ëa•úÖò®Öž©úãV6Ê+®…›ô—zû;ÞPò%«”`\E—> ¬ÔoÞ©^òHÐ I½}7¦ULªÆUÀéxæÍáXƒ­$EÓÈÒlð©ÎBæs%ö”©oúƨÏçêJ5÷X€™K‰²ØîT|ýÕùÃigÒÄ(—úÀ 6êÆ^Ó-rÓ:™Üô“³Ü¤Q7M4^…0_ðÔûÇ^ȱnZeÕhÉ‘Ê@¸;i´,‹?–Ì ¦‰'á‚çá¿L§¬©l·+T!d¥öø$ÎJ£ÏçHòá öb껂 h˜27~j5Â5ò{/ÛŽ\8ñ;…¥dš0CÝ)†BõǦÎe«“ˆÜ˜Ú¡A EÄ‚†¾Ëίף섆¡{÷wã}ïƒ÷­pg§é‚\Wg±ŽÊ‚eåŸr”MØÂw’î}—mKTC2è*t æe½¯Žá.ßyâÐáyâ!A“XNí<€Aš EÀ|á’q”qVË48û t>&­&`KvÛÃG Th–'ÿ]µÅ¡ÏÐá#šCÿ¥uWô7ÚMÖ4ÙI­¾\è&Ë‹¥ë+56T­”›åJø¾ï]é ›*;Êa©î•]£"ŸTa‘+HahU\Qêr»€ ‡Ƈ@…ˆÇC½íûJ«7Ká3ó–*ÐÜr‹›úÓQ³“EuzîW˜U¢W¨ö/¡ÂwÉyªGÒÕ‡&hì_ÆP1`èO\èÖ'8w„ SGäØ#2ªˆò¬›ƒ7¨ ×:y³¤¹h0C-Þw·7ˆiKú¾°”±¯U©rÕÁqίxÝ€1t‡ÄókuýƒRÅiÉ8Ÿ%¦1±BZ¬‚èÇÌÎÙ#¦‹Ç¦€-(nÍ¡ŠI ™¹$@/Gž¥êÜ[½SiR\8ÝízÏ|¿¢ßï-iáíˆÿ“|„°Q ]ÁOy}Žþ"¦qxÿüø?›1Øpk ×âD˜z9l uCÆß¶Ôwî^¹ìÁcÝtw:÷ ö©&Ôy𼚕SGúÀ¬(|g¾T³¶Aá²·#ó®È;öç‡"0÷lr®óE—ŒüöíKÂaÙy³ .nI"KðYÞõ¨( Y®f]xï©È´F}‹oó:‹Õèåè•[t¨<ÝxÅÆ|—Ó˜v×`4µÚú¨±aeÑ~*A«|²:O£Ñ?1-–‹™íþ-ÈíŠFê«™Á<›ZwsWǨá½ÞQT³ ƒºöÑL…©å<÷ÅžçQÒÖæ&âÃxr§é;‰¢î\ÿŽs’¤í‘)l»m´8¨>HÂaø ´#væòBͲvŒ@ÿ ²ÀÔ‰š¤…?L£ObÒƒL[|“à͸§²q7r!‡NåüªüÓzñ/üüÙ°:)endstream endobj 245 0 obj 2242 endobj 249 0 obj <> stream xœuVÛnã6}÷WÌ[©¢fER¥¾m›½ì®QChQÄ!ËŒ­…-eI)Þôë;¼X‰6à‹¨™3çÌœÑWˆ)ƒØ¾Âg}œý¸”°3³v³¯3æ.Bø¨ðs9PÖxŠqÀwù0ów2à’S‘€”ÇÙ™gOc"æÑ}ùÆÃ»æ<4Ž˜§xh;Kh"s(O3¢úšÂ2µn6M»‹Ê/³œÑ,ÆÆ“l<ÙïlU_5ÝôûÆ@U×ÊàÏ¡7ÍV=RZ«¶·k°r.(ãÌÇ$FTÝ«íz§»á1ËŠSÊeHOv2öÀêñ^{LAþ¤äg¸…ô}êÁ£8Dlô#{y¸W4òÇ;rÍn“ñSe6ÏG"‡ÎQˆ"yEi–¶öT½¶˜ç¯Y#­Mýfèh&Y1:ȇ寓šÅh+¢ªz? fßyóÈ9µ£ ;­Ð*°oöU ÿ)ÝY›ÊPàŠ±è_É0™®©BÐ"ç%"bñf$xrîÇ=ͱ?L¯ÑtÑÂ[Ü;­ýj½%N’\ôòX5Âóö­®ˆ†Î9%¸`.úÌ„F{¿Ï8=¯ ¿„Ì(‹GÁ©‘~F-(­í€" ‡¡õhœ ~eLðØΓÉʸ].Ë Ô&—çÂQžÆÉ‚È/ã|^¬o?—˧å0ÿdàÏžöM½÷¦ãÈã ]Ý´ÛÆnc…RºéºÛà²Á²ú½_œÝæ Ré¸ÁåŠ_~G~³FcŸZ œ‹s3 d¸Ì‚ræ…*ã»Rd. Y*tj?Yøh#Æ}.^YåY.|ÂMÈcÎì0’‰s†05—ÏM·åì/|ýÆÖ§©endstream endobj 250 0 obj 1107 endobj 254 0 obj <> stream xœU]o›0}÷¯¸}I Ôæ£$šòÐ-Ô­UµŽmeŠqUÀ)fYµÿ>Û@ ÕXEsï¹çß‹Ÿë°¸Ê{£ó{ aÑ"ò!”· †÷.2Á x1€Ü9*2 Ž¡›8æ¸1zP´ Õ°±biêO÷Ç+²†e–Fœ¡Ž±šÍãgHyfÑ è/?^-iFƒ0eë•§Œ7~:ŸŒétÂlzªê>"b{ƒ”µ‹Œ>M,pˆ(É!¥Œ¿qŽÎKmP ò-É¢0¡3àèyÄ’IÀÖIÎ1dX€ rÁuœÙ¸XÔ«U ©¦ÃWªŠÈ’t+£+/ym:›ÈÀFiÃä?Z·¬†Ü“Åc5¡IžnKy• Í1õV ‡6O(‹àSö¸ƒ“d×NEdê˜.r{JÀ’,‡`á§Ðë©`¬H,?®¶MôŠÜÔºîU𲍸®-#ö@·Z¨á5*-¯´CÔðˆÃV›,£ö¨h¼™Äš ²è7Í<…·n¿³×w}³×½F÷ˆàf«ô¡sr{%ŠÒ‘Þxª°YÛŸˆ¹'‰`üc2¾ù>¹ûì©ðrTü¼_YLóE”„e0õgË-lR–„½sY$¥ù:MŽKüiN‡¹Nxˆ«Í)Ìñ`ÓG.6Q¾`ë²Õ2Ê5iW5YÑ~¤1_|ß?ÜÝŽ/Ý] l($l ÿ™J^ûFÁhDÎùg£g¹d§œ¶Tl›{mâ©Â_QPxzV¡I3»G^~¼¼¾ÑAèdsˆiÌÒ-´ñQÙ››·óì–4k¸SDç)¥žÒŒ)¾. û/þÍinG_¼ zû¬w ÿCºX¯÷E½]‰1gÌ驿ZŠ™~e((×dû¿þNc¿ž^ÙþmÇ·qk¶!’Lù6Rîå\ÈSš˜:6«ƒåÙܽψ]®é†üÏ­¿¤Nt,}è”™‡Gù•‹¾ðë/ÂYendstream endobj 255 0 obj 749 endobj 259 0 obj <> stream xœ•Vß“›6~ç¯Ø·ÃNñÞkÚ^:ÓLÚN/îÓ]† cZ#$ìºþï]Ià×kâ ž¤ow¿]}»ø#ø$__ýhœÅ} •t|¨œN`6a¸ |¿v(¬ D!ào½q¬eaAJX7΃ë%³0öÝØ›}X¿EÖj5XyAÈÀ‹_:îb?~÷Ó;ïÛ†«m-*ÈY¹;Á±kEE`¾˜­ÿp¼pI–à‘±ùW/éçwŽ»i»Gjøü[¼}U×öû¬aûŒ Õ²¢í…º…W¯êÇü3»q¦®R‚¬Ž†Å/íQ»S’`^¸ç›²yfv¬ÕöS:6¢èùPx-yqùÌ®_ÆLL€‹LÜMÇùãÄÍãìyË£?»8!¼Þr\xÎWª™J`‡ZÀ›ÝJ¦ù”ö] ¢U`£`mÔ–ÃhÏ仗䥘0ÓÙij/Òâ~ ú>Ä3Ì%±¡šÞóBÕ­ÐØ4 qLWÉÔsh÷¼c$­Ç³½Ñ ‹‘SüP”Hƒ †"*~©%D I’hF´x1ÞC®aFµÁЬüt9åÓ+S2¡îP£‚ó’—äœ)µO§!Ò¢6Ýðœ/ö[©ÑtEb¾Ý#ë6YÅU&m5P½eíf#¹’Y®gÈüÜE£ý¹eW å—|Ý@Éó¾‚2¯^kÏ—²0€ß…¬+ÁK˜ÃbnЙ.d¦Od¾0VÿdyÞñÃ{óè®ü:`[\…c—WaV\$õ9ì¾ÏÖ¯c]…Ûtèò*äWd…LÕi%xŠ´fÚ`VVc8¶QpZgØf°éŹq'ÂLRã„týE1ž…=F £øc_<¸Lènpwœ>ñý8uµÇ»¼&Jóñ¨½òµÐñ}Û) ­°SÍF¦„üû^šy>Ý€ƒi…8$ ö®!@3¶ëµ+þ4߇„Ðàbâª-îjk"í[lBÞI;n©¿$«¥®àÒÔ㇎3…åǹük¡ÚœwúAðl~ÐTØ.¦FˆSãæ+†Æ •}µ~ÏÍ$2£ŽŸI»ú4ãi¢$LW~f'¤OÖiDVcÍžÿx³v~Ãë?Ÿùh¢endstream endobj 260 0 obj 868 endobj 264 0 obj <> stream xœ•XËrã6Ýë+°3å Ñ$ø®Y%“,:•©šd4+{J‘ Ä4E*iµæëçàEÊtÇã”U%›¼îãœs/ü hHõc¿ËóæÓo9ÊM@Ž›?6¡~IìWy&?ì6Ù•° ÁgWoÌʰŒÑ(&Y”’Ýyóäùé–%—úÛÿì~Æ~fUaWù,ˆhÄÄO`_m¼¦IuåC½?Šq/E96}·?ó¯û¾®¥å³÷£~]‰Ãt$ÕáøÝv÷û†å4'~ë=ŒÁ¿;Ù;Q‘GòéQ[ï›®î÷²ù¯xü¤W)û_Þ±ç‡Ã ^æM'>fØ—²ãïŽB~ÈöÌËW¡½g{™?pc9²«lù!Ë¿<o—Ùøyû7˜ß!Î7Eg*z@SH^7Þî$H=u8¤‘dÄßî.UÍïÀFÍÂœè ¼wQ·?<{Ï[µÞIòöYRƘÝH|UvéaHÃØ Ã7Ð6çFʦ;*ïW^'9“Í^ëT-yrnÞ33b4µæ|P/ b‡Ð<3Y;NgÑ”ìNýt<)£<¡Qdc2>õÙ·bÆw"Ǧm‰œ.—~EEͱ9Qaèê$4@ð~”ëch¢7IñýÏ4¯•}Ñ,- ëÝßyÛxùE®"ð™+¶-4œÀ§ÓÒz§4Jmjž¼k£¥§û~‘•Š4¶‘{Óq’#aAiçý¬ B¶§($­rÏšiø 1Œæ¿üVòc¸ÙôG´P²ßïŠå¢«}. ''Ñ^Ä@Æž\†þ^IÒ6_´Æ%™RV ²•g~ÌRšflAí\5/+‡ÒœÆ ›!™Hò®"òÔëDš‡È•:Îáì*P§´È=ˆ¥b×Q oI%FÞ´*,DsÕ2›„4ËÒåÌМy#}×Þ4AÝjIúû*³0ŽiZ;ìjÈøq˜Ó4f¾ÐXý¢xÅ»%ýA¤4Ž2°ë¸D‘(Çy“8Sòä풀æ3œÅ“7ibê²×¤j¨¢@¸Æïl¢L¹K΂wFJ@e=qUÎs¾²ïÆ¡o58ý02‘UƒÈ„æ8$äzƒÐÛôÓx™FÂ/ÁI·~š#·iâý«']¯·JÌRD˜3š%ñ7BÏ`¸œ`ׇËLÈyuœÑœåÎè¡¿O\˜eŽAÚ€øÂ¥DLн »KȺd,e´@²ï%îÉOƒÀ¤´Ä_„ûzê%`q¾´B wd)¶ð ƒÔ{ik·ûÓ’D…Gu.‘Ñà¿ïÐ9@¾Àä%¦ñŒß[y›#Œµ.@evWU7%.@€Ô–X«·rHð@–Cs€‡€Æ¨´Êö^…5Šö¦ŒŠ‚²ÜeÔ(QÌ —,´Ì8ò¹^Áq¨9»ÒoÐÖ%G{%Ï^SÞÍ™º=oI=ôçÅÿ"B’”ÿW-â*Ñ7 ÈAK;fÆ£Ýã“§¶Š±(ɽ›ã«ô*|¸£4¤yâÒGâ$zZK£BRaÍb´Õ"7qž¯À•zË•Bæ5­@:k벺~¦Tw¥„€ZN£1ÁLåhúlþvH4hïÏþ³£VŽ‚ùZZ­ uÕíµ¯´w?ˆc#!k¦CÔ{òÕîL5+³©úMç îÑ4œªX´)”KTMžôx`8ïÛMfÈd‰ÅÌÌ ™$Ê%è•1‹½Ï+p^ÅŒ\r2»ÇØ.U aY¦[ºU”;M( ®‡Æbж0I¡FâµÆ`Þ ®Æ³1/…?„­ºÙœO`²mJ­oª ¢®:ò7š^%ÿÓòeËßlÁÖ{$w³(î ÌûÊUŠuã²ùÒ£‚Œ‹y&|ÕxfáEuÏ肦»*Ò¨ŠÔ°¤ûibz›'(ÜÓtQ¬³eàѰۆ¹÷gÐSîÝ#×m`GžŒšqÀ°†ü?ŽÜߺÌLö>òÝÝíÇWw7#3åèc @¦±Mçc7§˜…óÀ+®/¼0šáö°*# 2ù{Ã^Œ˜ÜÃâÀÞ ~,ÂÄ›:ÌÐ0M^~ªoèñç`{æ¿zT“Ÿ¥Ã Í]à ©Ó£E˜ÄžÍ¡i÷)e™SQÀ> stream xœ¥WÛnã6}÷Wð-òbÍŠ¤®Ø§^iÑ.\ô!) Y—D][òJ² ·è¿÷pDJŠÜM›- p<ÎåÌ™ÃÌ傹úÇüM÷‹/Þ‡ì±]¸ìqñq!èKfþ¤{öÕz¡Ø:…• ¿ëbÑŸL†’+…*`ëýâÞYKé»N¸Zþ¶þþpj%]Å]×c+FÙÂå*öÙú ë&ïŽM•g,irÖ=åì´”£ r’Ý1oÙ6/êþ+ò‡b@àãb‰ àÒ©òó‰N,׿Oà ".b/6Vú–&Oë&˳‡%×¶¡âžð„1¸-ÌùáÁUŠWÝR¶¬:îv¬ªµÙJE÷•b+áQö}æéSR=æ ¶û$C‚5¥¿+·Ùyó8^€p VV]ÞTÉŽ¥Én·MÒ,Kº„›jDL(@³õÝBqIuup!—ì›3l~jà¢Ø|mŽon«by³*6âzÓÎò^Y4oˆÚi»æ˜vŸv ?ìOíIF<² ß;§ºÌØ›%>{®ëd‡Í±Í›Í¡¦ÜÞQ*ÚônádäùÐ{¶oŠc•ve]mºË!g8_:œ»Y¬ßP!›gηǢ°nµÁ±jËG18…™MÍ6»¼2D!j¦³„ úX›úT4úR*…v|•V“Ãö¤­´ÃÕ´Î_ïf˜Ñu½[ÄÜ•Šný®lÚŽ‘_Þ¦M¹íçzåIîÅAß+}À„™ï²–%ø=vešlw€SÅÚ¼ëÊê‘ £ÃðuÕ`ãÕØ—¾É˶£ŒŸõàÁyXÎP.÷ €h”Vý,bxìQœkJCƒ"àÊ÷‡)Aø³˜¤à±Š#c0ÃÉìvÉŒÍõ÷zäš|Ÿï·yƒFo/“A ý~’*c‡¤mõ÷zŒPª¤¢F)Š4]HÏëì\R}#˜À46,„’õæó‘ïŒüˆîÜ'è³ç df†\guÓßLÞuÕ\[Évr­ÄÑ@ØíüÛiàË•ÜÝvšDj8nÎe [IÞ»°2×W2W± IAÆûw9g^{þ™ÚÕ†Y^0ÒyÎöÔéÃòÁèB6/oç¢ØIë dÝ‹WŒb…W «îa9ŠFGö‘9_gˆ¨C¡ÃðÈ2öe켌Aªÿ?ô‹yq9½TÔá">Mß6ì9 (é”~/äÃ>¾ZU8&ü?â¨ÀrT¬Ÿg¢<Öä*ÁÞ Õ¥O&X#4ûÓöúd[›‰%Ä‹ì~4¾OF/ôƒ›gŸ}†{ìuØ]MO¢©÷ž‚d2ô> stream xœ•XÛ’ÓF}÷WÌS—õD3ºçòàM  ¸ÂÚRÉòȱ%#Él–Tþ=§ç"{½*j)ÌJ==§/çt›Ìç‚ùôc?ËýäÛ× ÛôŸm&&B¿dö£Ü³Ÿ“€-JX ÉðgQMÌIÁd"y²$ˆÙb?¹õfñTF¾—Φï¿ÂŸ>•2С™ôîû!›E[¬'—[ÜM¼˜G™xú_y§6u?¨.¿°_zëÕæú3 ÂK$SÐO}ÜSN‡­¢´w¬¦ZíU3ô¬o÷jØâ-!÷võ_J›Uín×ÞÑ¡êØ”º.(ÖgÏJõ®¢;ìǶ^ã·¡>º¥¶eWDç´l›~`å¶èØ• âÿ¡1]QÊö8°~`cÉfg/ÿ¥g N ñbâó$Ët‹>XݳíQ;„W c*žÐ5ưœ)y–DÌöSIn5 ™„™}á:xÌLÙjÕ³¶3eíµwBŠDïÕº.µ»'gä&%‡2¸±ŒCþêtÈKK¯)5£f!aäöyÞRdcEËG :5»Fc±éqÌiÀSÔÍÜA8/ò@pïî2D?´ˆ Wí‹{ªV³QñJ•è ÖÅN±»zØ¢P3JRD3)b.b9Vë®8Ïkš—×®A¿qƒ²j–;“Y$ì8Õ‰Ù\­È8Ly Ó‡zsÜl¨wÁzHd+ˆ¼¶Û}¹i†î‡wµ–j0©äq[0Õ9J?Aå={uPöÕ_$n&Ãû™“$ÉüÜÅVAî\mzVt ]ƒòvZë´±¢,U¯¥omâ’‘ä©oË@®Lä6´‚æ"‘;4à5»Û‚˪ÓùwÇ]ϘÄT]»‡ærºCdÌ] a8tíªX(a¦ÑœˆÀ)€f² #ì‡âäL¸] ,Œ-}â[ 6¿‚CFŽæHÌ“ØìcÂE}?ŒQKˆ¹kcN"©EEóR§Ð0û…ˆÝÔwd5:âŸæà‘Ô½°«ÔŸŒÀ#¶5”ŽÚR¹ /Ñ÷½Q¤™}{1ë!^Ô×Ù×—Ù•¯>Ç/á"74Áï–¨(–§Û˜û‹û¨eš¸È¾ŽÚØ]O—™vnõð¥u«Ñ©U5¼‘'2EÇÆÞ­wLiæÆ×­LIʳ(K]“$¦GÚw#9–^]]„g> stream xœíWÛŽÛF }×WÌ£´ˆ&sÓ }já v› ®› H C–Æk²äHrÍ×—œ‹ì5ri‹ô­ØÞõpÈCòð óž0Ê Ã÷Y탧ˌÜ#÷Áû€›Câ>ª=ùaH²ªÀŠ ÿVÛÀÞäDd‚JE2™’Õ>xÆi$qôÇêGð·bÁ$eL‘8£:`TÀç)›‘ z:®i´zÄ(Ç)£ Ëræá³¥¹U\PUáΆÏLIR؈¿b¾‹oÛ-é7ït5¤™„=ôãØlZM¦&ã44Ý=|×t“fHäÔ´-Ùhòâ·»;ÒažÚ 1WAeæMh¬2õ¤ìˆÞ¦çœFq…iøÜÄ?ЃWeÛbôòph›ªœš¾Ã£AWý}×|D„Íhj‰ï0ÕS°ºyÚš¶ eW“Z—-@žv˜"xúÃД“n¢TÑ¢P2¤Æ`è]<ßÚü¡0¶îõHº~":âx#•á‡fœŒÍöØY#[‘,"QÐ"ÏÓðõzqqÆ(ã*|µ~ñr}ûbµ4¡bNe:*£JøŽþNç®Åþ$æŒS)Ó8‹nÐX/(§iN9êaèHwØÐ¥O¡CïÀÕÂqU䂦,uÁøÕúv¹|¹t†žÔ£y¢ ¬î¨;êÊs,3‰ôwto ¸+¯ 8c}b×LQ’àD®%O—9áÒ84ƱŽ]¶)Åok3Mä\ÈS9l×÷zZ×^»>®»r¯×›·áÛè Hì/»Z‡€M®˜UŸ"ÓZ~ÉûâM‡žóܘ-MÀ쉥ª˜+RõP¨Ú•¹¹AªO0,Æò^ìÖôöÆöømô«Î¹ÞèÙ¯ÿYòBš¤®ÒüŠ¥m±±ò¸×­ªôh:íÃO‡™~ïÃ%ÄM-E0*9ítGúN“] ŽÈâù­¡9—U\x]R©´‚±‚Á6Z0êí±%[HüBFrQßnB‰Y€‘îì@š*’脊"j„rVE(¨|žúyN i…/t¨ìx$¤Á4 VÖð³”fʽ%áÃtùÈ"÷ T«Üâ£á¤!–iNy:gÀl«¯X¾Ð›HàßL…Ç{(N35eÛ|´êYÔÀ"« <Ë©È$Yø¿jÚŽý•©úÍ|Í??Ÿ Æ©WGêØ“€r+?kðäB—Ï¢|Üñ£ëñÉ.!¿™7~î¯gðLËÌUƒ~/½5Ïèü*›?ÜKm^¹3{íhÂ$Š3ݹ°ÕzÄlTò¿ñ^ð\Q6ÓÚ½/B«Ô:~´ Áóêmé®*Έg4Ë3OóþbWIŒ óXÝhNd;èGKÉi×äúWÃ$šs f~ÎÔ/:_Þ¦übtÞ¦ðÚWש3öo¾EI~¹EYz}e‰B5ÅeÆÃš×¯¹V-sOìÿÛÕ´]Íšðõ­Šóµ ¤æz­’Ÿ]«:ýaZWÇõN—µÖõ—*îÞ:“‹tĤÏöOy1ûnî *2ßü\>Á?ß΀$ÙœàãÿVÝ®‚_àç/Û‹ÉXendstream endobj 280 0 obj 1309 endobj 284 0 obj <> stream xœXYoÛH~ׯ跡©·O6‰yJ›O‚ñh6Ø ’(‰»2éð°Góë·úä!Ù ÄÙ]çWU_ñ"˜"¢ÜïíÃì· šA‡Ù·5/‘ûµ}@ïV3ŽV[8E‚«ýÌÞ¤ˆ)†¹@ŠÇhõ0»‹–jÎ$‰ÈrþŸÕ¿@ž½•º[KF8&D ¥„ó»YT”-Ú=gõ~]æµëm·>æÙ.¯×»ûh¾úïŒ%8AK*Ìá÷æà.ßt´Ûú€~uã_½«ª*šuQî«Åü'ÿø²)e¾Cozù§¼<´G}ȨX=ûÃÿÌN{ôæ)¯›¢*×M›=<êSdp¤——m6uþ´®öû&o_–ívuÞ4ë¦ø;˜e_Ú»×ßAHòÒÚ1~ý{qHÐmEÖvuþ²íù1·®…cóíw!ƒƒZœ9Fq<8ö¡®«ÌÕ¿îç?ÃR–6‡ŒèRÌ)57WÇí»rÛ‚{:‘”Ä 3•h„鬿û¹» ©¦Ô_«ó:kóU%jAW^Àÿµù„ v$E©»Ð nô‹%OŽã€<†¥`Æê&7£û¨ØO¬–1D%NšCáÄD)q*³gîà*«rùw^W÷s!4–1‚ •R¤ãÝ ‘R]V­ŒÄ8?®Të´ú°>&R¬¸ô!øÔïyÕ9€¬l&þòsƽ¿ï¿®ßßü{ýáööËíD’bg Á(¸½GE‹öó§)i”§f²r7u.Žq¢b6Vñå—‰|€Kˆº‘ÜtÛmžïãá’Åô;üpÌâïÓèèb✢˜¥ÂÇeR(SÜQj¤öI…rCme°VíçÍ4‘I¤«eAí- %Q°Îç°2_íõ- M&1á4$§4Á*/%%ÔFú¯m«‡Çâ”i1Ë®—­hª¥T 8£/%ªáHQŒ¥§¬yQˆñ`ét;ƒÀ&ŒCWÁD µ ¦OqkãÔ×B«+Û¬(s_·>€¾>çá"Ô~L5œèEÕ`k¤×îÃöΆc*¾ Ò˜вÔîCͼ}¬‹b„¦€Pš`F•Èëø 'RôZ„uü¹8 þ[´ÉQ×@?ÈØR"'¥©CÎEí/‡N qì±ð3Yø¼ºýs"Š_ôu& ×g˜lU׆ªÍ.ËJ ÔÂÛ‰rÅ”¼Òæ`¦%lJýˆwÿ>L+•> stream xœXmsÛ6þ®_o¥Ò%^HsŸÒ¸ËÍuæ.Q&±o<”Ù¼“H•¤ì¤¿þv±HÑvê¦Ç$°ïûì³üƒ¥\°ÿøŸÛã⧆Ýõ‹”Ý-þX÷’ùÛ#ûy½Pl½…SB2ø½_ÐMÁ¤‘\ifTÎÖÇÅu²2K™¥‰X-ÿ³þȃ[+™*ž¦š­28´[¤\É‚­ÉpoYµÛu¶ïY_ÿiYÝôõÎ2|n—ëÿ.V`b2„Ò\+ *A@òÕ½tÂ…àBôü:Ùž‡js°lÛî,_®2i¸R2Yƒ¼vï,©àyæ¡%¥³dßÛLØV ÛX¦g”pMëÒðà^*º>7¢©—Ò®e™ìí™q%ü¡ä¸±»ÝÃ$HæNÐJ8¥[ íÎUùè©æY™—ÁrwãÔéM=0{سýR”¼,t™Ô‚›äñ¾ÞÞ³ºgMÛ«Û·ËÃé›å[V5»ànÁÈÒè¯4%Ïò¹¿ÞÌgü•\‹¤©FwUÊu^NÌ-È\%G{eÊS‘eS{É ¥2n ººvÙýÆëÃ5—ù1Wy*/í}jk·qåiû‹¼”¥ 7­m )ìÔUÛ¡ÞÚ›%wj„ÈxÆ ’Ý!¨'| íPúv‚a¢¯ƒ…Jn›[,)4vtC‘™˜4£^8µu3ØóÕ6àdgÁCçG ž–¡|ªi¤²þE3°zý3³O§Ò 'w±8x´B“ ÷]{¾»w°LÂbÞ¶ÇÓÁB¨?|š¼¼h™6ÚI\Wg‘ÉAmš‰×e.ãÒdÁZ ÿDÙ!:©={ÿÍÿíÿ>ýôáã‡ßÁ÷fÕÐmU·£$cóœElõÝ#>Å.×Z„ê(LN‘­º=´È(“î@Ë—wàq)°£T‘T=Ûv¶ zßlÕõÐã1Ë®¨¿ÀxM]®yDÕ/ïÆ¢*x@ò:ùø«b;Kíš*•Ô˜”h¡ªqN‚À”›¥sQƒ;ù¤¹)= ö„Àé8ïNžiç”Jïž_  Ä–¥VIÈ„ÏiŒ»»@Äm¾ "@?ØðÏ…äe¦ãôI¿î—?ÄS9@t¾‚ÐÁ=ýÇjô)£ûp8€“cãÁƒ*)B«Fu×É=šT5@ñÁ6wýGÀÔ@HíaÇ<`7»z[ Þõ}{8´Î|©cÊQªr¶=ÖÍ 79 ûÖ_Áˆ”ÉcuñÝà TX˜–EFÆïnëfß²ÞîA@«ŽÆ0Q0±p• ÃK‘'Ÿ,½Ÿ”Ô8'¿_Q®  ¯¨ üU ñ!êå«:–ÃÛ`­÷jPËè1L`NcÚfÿ0ƒì|œ}}×TPŽóžÏ ÷™L_ Ó©T¯Ãir¿0<rl©³Xž€$÷Ðʾ°ª½4º¡iæÚEQð\þ…rTA… V *Ÿ™è÷2Ž(r£Õ‚§{ <*Í‹‹a} é¶ÚQ¨ªå>åË š¹(ò„»Rz&QŠ •†È¡^š_³L™|B8Åë†ÄÒˆW$ì; y>P@‹_%˜Ð˜AŒÒF1`3úph·Ð…­+UÀ„Î"H%(ÞŽÁ>ÖÃ=Zê3èþ¢¹ @"pª’NÇôÞÒÊl3tªPsø7 K×îMÔ€^D ¿›a,Ÿ”Ž"5Ž0û|ãФø&O  €óôr”NOê­£8V˜Cp[ÁPô]‘M€e&L¹/·ï–Ì,¡×.Þe<_O8E!< wvo;Ûl‚cÏñìXaôè-¨CJÙ@ â­3 <Ñr•gÀNó…"ÔOxnhlºýÌbh.5‚§/­9Àª€[׉ûRÒ¬þ´]{³Äý(r³ÒÈ‘›]hœ7t :‹×ªD¤mò]WJ ì%´d^'CÛw˜óùkµ€Qêÿ[‘9bQø’2ÇÀŒE`fÏçoò·ÂeþÁ¹§ÍæìI%n†„ô&.s×ÉP/aÉÚ–'ýqüÔ‡´ ŒÏÐ]’¾÷ŽÂ` 8–K>N>&ÂÄ‹ý &+ÿtG„úaðä7 2•b¼m` ˜häå§ò_Ö‹ßÿLNÈendstream endobj 290 0 obj 2347 endobj 294 0 obj <> stream xœÕWMoã6½ëWð¶r±üE =µèmÑ¢èÂ=%…!Y”¬F–¼’œlö×wHJ–¬ØF襈áÌã›á¼Gæ3"˜"b~†ïíÞûî“DEçTxŸ=jÑðµÝ£×Gë-DQ†à³Î=—I“ óI¡õÞ{ð¹b‚ø,Xý½þð\V9¹e8t,¾Î–½‰,’[5ÞíTq­r~ÍÀrÎÀ»™ƒÃáÑqðè)ȸi©‚ûDN«ÌA\tt—.*$ÐΓýÍ ¥ ÝÖÇ# °Ó3?wztÓÐiÈq¬Ô»kæècñKÞiéº4t˜K>(ÈšASU Üèæ¢dþ‹™:¨Ô(¶iË¢¬“Êôyö³™4ó;+˜…„?ZÇÌ@TÀ*Ɖ»_^‚†•åÜg—Ž«®À€_(°‚øš<̹¾SRpzCéä1…_“uäy ²^ìÉ%T¾Ï®$`½±+xÇÔ°ž*…Î 1ãZî¾ ¢VPAHÑtÏ?é €È>¶QåšH©²‰p1Æì­J™ÄŒ³K"Eߢŀ à@#éÛ»ýڷ·ÿùSç?|¯œŒËu$äo\K^u­®L+8Ê&¿ø¦˜, îL›ôÉž«½ÚàŠ%§ÁxæÓsb&üå÷äGŒNÙðnŽåéZ>ÿgæãÚû~þ‹‡‰Lendstream endobj 295 0 obj 1152 endobj 299 0 obj <> stream xœ•XmoÛ6þî_ÁO‹\Ä,_$QÚÐ-’ ݲ ÜC3ŠMÛÚlÉ•ädÙ°ÿ¾;R¤dÙñ6$€e‘<>÷úÜù a”†íç|;z}§Èª1²}q³HÚù–¼›Ž$™Îaþ§Ë‘=ɉP‚Ê(“évô9˜¨±ˆX 'ã_§ßƒ<{*mOM“”±L"Ø¿yÑÅSV-guþ°É‹U¹œ=Üãéo#‘ЄLxhö]™=Wúa¿"‹‡Õ%nÀ¥¿”k²ÈõåøÂ½yW–’׳¼X–½×¸ñU¥›}Uཕëª*+òJãÇýÞ÷ÔX4‚!F“î~Óµ&Ë}1oò²@H=Uã˜Ê8D3!þ:Âö„7iÈh ‚í ±H•Šr•8©WŸfW7?Ï®ïî>Ü „¥ŒŠH¶°4€³bAjÝÔ¤Yë!`N£­hc…̉LcçIÓP‘»œ¨+RÄJíê|”…±ÃKßãbì9>ÉvmÙàš R¡’´]XëJƒIQ’Ö~$oÈióð(¢l`Û³ëÛéÝ/¸úfg‰ƒ÷ÉC!ò ¸×&!ã”-]\Öûù\ëE}9¦”G*ùŸÞ—,=ïý˜&R$‡ú}øa IñN£<ö=?ŠéëÔKŒPp¤òèšÒCÇ¡7ÆqLq…¼C\dÇŠ¶:1u¡ëy•ïÈÆr‰‘ê_.‡H°š‹ÙÅ‘dÁiìœk H ™d°"¾},29‰mùH… ]Ü ÊB›Z&D‹ÉŸº*sq"Å8ð87¦±O—Õõ~«¤)!Þ—cðºÐ¶þA‰¢ÃakÒ~e0“«÷×Fg%iÈ…óÁ‘ÂàÅJ²ò^|AgIc‘øz"Ð~Vés «”&i˜¾¬pH¡:¡¦¢|þÕ9dq¦¨hó¼ÓµÕtñ„¦" nËF”¬1x…& :Ĭžð(¡2òª.sŸðвTð)TBf‹[U7džm6ä£Û>Ù«¶ˆ’y¹Ýå› `²/ 2’¶·Bpå~Lv ÆeŽîVèöãÍÍ0ç#ʙܶ$ùTV¿×´%Uæà:«2éëhTy;æÂ» ½õ•± {€z³ÄE7e±®Y&›²X•ìëìa£ agÅs³«_’'Ë ÐAúòè¢ÞÃ0ø£~ ç8©‘ž²ù<_íògò”7ë¯["<Z‡þ~áÕÁ¡'”;í³ÔŒ .Kå1ËÁ8IàËÙ3Lðî öTÂQÙáÏ'×ÓÑOð÷Þ¥"endstream endobj 300 0 obj 1715 endobj 304 0 obj <> stream xœW[oâF~çWœ§‰`27ßZíC«PiÛíFE´«*TÈàÜ%ö®mÂFUÿ{ÏÌxŒíhUðÌ9s.ß÷á P€êWó¾yÝÌCØU# »Ñ—3‹Ð¼màÇÅHÀbƒ»ü[lGÖ’9BÀâatïMÃ1÷©'§ã¿?£?cÚhÊ© ”J˜ú1,Ò‘ ܇Åiä$ ¤ãÅß#_ðãï””ÛU•­Y¾+¶Ko9Ö{0ޏ‰cêö£omA¿,¯!ÚjKá9S&ó[³ãV­;H×»‰Þ —Þ·K™‚4S“ñU÷Éu©êc™kוYY%\+ý†Q^a²æ, HÊ—ckójë…$”Mî½â³*“ZU ÆÌ'”ÑÀûšlêÃÔ{Uò  ©LÉ;µáœ“ÀgM)ñ\}ÆT2JD·UIJZ»h#¶]èFY‡“µÞeZÌ)ñ#êN:Öƒ&qF˜-7Ë‘ñúí…1 Ùx.ÕV•¹N¼0éÓ —Žéÿ½GRµcT”F±wÜ­²|[Àí»YEš"9Hby°ß= ÆÄ«K8Üì³Cú?0ØØ½„?²KèsXû”¥¯a­S¯>ìˆ!&F³@˜lù¦ÎŠ|~Æ#×¼ôbªÎ{!\'=\5ð'"BÊ›=·W·ïÿXÍæó»ùÐÂâì,ÉS¨T]iD#”„Sæ<š´®$ÅLÃ&uh²Æº‚Íw*)b4>¿õ‚0×tÐ(Ötiã!ïôjä™þ$Ýâ¶n±| m|»Þ«RAVA^€)&d5\®RƒPôëõán5û°˜ÿÙ°Ë ê°I>žyˆ±ð°y¾W¹>´:n6J¥Õäj¥O|ßÁ+ç,z½ñ!‰%4þî—£ &Ò9b$Àº\®û—R?p2èuØ0p ±˜½Ú&ÔÅ4 d»]'[® %ƽäpT—RG’)¿Mb‚6}l_‚à­Œ&@ÿJ[Ý¡§ x$ѲUìôYG»uµKQ«™¾™uH ³üS¶;m0·Té·âÃΑDœu““aa}7¼g_“‡Ïåã83”0ôú”kÊŽÒÈŒ{E–‚jÜ,;ó!ËW˜¨­¡÷N‚Ì™8ðè÷f{w–5´KWvt•xÙh¾cMõT²OzͳÇOÞt¦¼iÆ’¶læY¶…¥5 ­,,Çð,à›kø½êE«e”Àõ‰Øžªäp(6&qï¼Õž¨9«™žpäá?t]·c¹(³]–'Øåƒfpãª:;àT”ŸŒM{õN^zú¶ݤMV?¬ð†¡ÃбbÈW}'ÐÓ£­”734E¾C¸«d}P:XHò§z4žÀɘMÃø,PžÊ«#Nœ^& ´¯5‡µü#²Tå5Fþš¸ß5Õì'x ý ÿ¾ð¨wõÐ7{»6W-Þù…ãÏ£è NÇFYøå×ä 8åìlˆâ‡ÜѨÿÓb¶ý†¯ÿ6dT=endstream endobj 305 0 obj 1268 endobj 309 0 obj <> stream xœWmoÛ6þî_Áo‘‹˜ã«(îÛŠd@·®ÁcÅІ,ÑŽ6YJõ’.ûõ;’"å(I7$€aéx¼{î¹çÎ_Áû7}§Õw· ûAÇÕ—u/ÑôQœÐÛ튣mV”!øßVþ$EL1ÌR¯­ Ä¡§86Á|ÛÄù«š•‹£ö Ë0XRá\_9ƒ+³¨Ü/­}õ>¼º9œïÍp¹¾ß¶mª~W5‡öìñUeЛΠc×ìà³7×]×vè±þÅ9ŠbªSþöÎ ÃØCÕ6‹|S…‰à,SŒèÄ*Q98õæ>¼~á‘+,©Ö“ÍÕÇÝÕûßv×··7· gš`©S:æM‰™ wf#Ã2#ÁÐ%¾p%ˆÍ5X@ôöýFP…9i*Ç™Ìmƒ¢íŸ+A!n|àö¥ã˜f2$tgT ¨‹Â˜²¿\Ä I1Féÿ”1L¤ú& 6¹Œ,½ùyáIQœG6Så2 ¨.YÎ3È›Fh’3ª-üf N·CrÚ;Z[¨Š%2,eD+’yá5Í0ÑÙìÔÕåSRš¾èªûÞÜ¥Ù¯tZsšŒÇcÕ‘í”î”[2#Ó Ý#ʧç 1•4&èûnI› kÎ| +N}Uã®îkT´ÍW½ÚFÃHޝES™UØ!ƒ°µ·‘q!Á½œ@®ÛG¹8MÕÌQ‘yŽN·côƒµ“§\Æ*#_5ÀjY0g}J™7»ëÛÛߟõ4uþ¼íÉäíÁ|x¡¶Šc•éàöeHAz£‰ TOúÒª·õÍ=d›ˆe›;²Ì9öy]ƒ×}5ô—zY€9<¡vÆzmZ”ï÷ñâL°V,†¢ýlx¨ò©¬¥ÁèÈ×»ÓN²yŠyš½¤%âŒN^;R’X*¹'Åå‡ãb³bh#©{ç’GÉkdµM¤R<{¬júÁä%Ê›p’vv²ëédŽîó²tÔ´_AÒ,Ý6!°ªW½êÛ“AˆB{Bÿ˜®Eäï}òý];Ö¥ yFŽY¦„Xà¼Fco°Ã•Ø™F°¢ž„ï\Ì6M°è.`"qÿ®X¥0U é»(©†||núû¶é«}UWÃ#a9åYËèEgÐ"d6ŸÝX“(ÙcgžË§šO¿FZM£)ª&ðYõCÞMÀ?@1’¼®J:›2Š•Hcg[M˜ÛFÍŸ–à™tYÓÔ¦’q,Å<}¶sŽÀÆ Q0| 0ýX»pîó¾w 4X¢Tn²oæ`X„˜Ž=ä³;ŠIT†O‰M%sbXáh(îò¶ÇžPŒkH3®É»¥â@)$CjÚg0ƒˆi´f:Ÿ´ÁöI³q||®9µ}³|ˆk”¥ÓØ€ÒÁt–K¹aÛׄáLGµ—Â]>iqT¦©±¬|ÊF[{5FÏR‡RKLù¼¾’=·# Šç^Ž^I¶=/¯±VrÉB)_ÌÛŽÎLh›æðx£é,OGßLa·†“Oô:¬HP7>·G0š–äm`£+!Ÿð‚ªú”ÌÒô!°,¯Gä”?.WnÔ/G8UpWHïuLÇu~„X^€R‚ØÌ é eè•§²ÿ虢G¹6MÑvÀ‰ý}YÜÁ¡(ƒÝŠ{:üXG‡‘» SĬ /˜Ï—p¼œÒ2Ôùúïüt_›~¬©*ñ[æ6U­³älÛtÍK•Â8¼q¥ï·&†±’(/|',+˜)_~r1Âè|P‰yº.§]oW¿Âß¿ú^­Mendstream endobj 310 0 obj 1463 endobj 314 0 obj <> stream xœVÛnÛF}çWÌSLæzwyO‘‡òCÛ$FµAa%.¥mhR!)«FÐïì…"uiQȰ Ý¹œ™9sÈo@ ª>ö{ýìÜÏbØ´…óÍaúì×ú>Ìæk´bðo^8Æ“9ñˆýæÏΓëÅR7ò&ÌÂxÆ+µ^‹SBi^ˆö¹ã¾Ô2ñWö¼+E´p§‡¬)–S±Úo _mîÌïÇ¢€\Še]­èìᇺ.A¶KYõb2™ÿé°æ÷ûäÆá IÀS˜ÃØ?4MÝ€ÐÿßýAyôù¤€Ftû¦Zbs{㸲êð¸íóD‡7'¹vD@ ×já*°#ˆ×Ý›!ì¼ÑÉÌb•,LÄw0ý²œ~ümùøób5Ü߯í Ê­hÛ{]‡“‹¬,뵺VQ{S“1&8ƒŽ4ß <cá1:Õu#7²ÊJ(êæÚN–%êækûV¥ðNàœä3ÕøT]ËûåôÇ•üÂÝ !|Uoh2Æ%[¨j(ëj#ط٪ "dÕk·•f>©Å)DÕîW×èß¡§ÙA¶^Ë\T"…ƒì¶omOžÓ¡‡»>³û[§Ö4ç¬ï§[b®ï½5=©¶U—çX×û2‡•€Ïððy>û°Ê‡Ùìqv­*âæ“kG•X‹¶ÍšW2ñ§TµX- §“Ñ^ªîg 0_/(ÇÝ |uåj\‰c+Ë "Ôçv>îh ®YÂñ²÷Æ·*?qTnWvPѪ*)°;¦VtØßÛý†³ô·vñð|¤`¶I#¦ñár@±¯Ö¬«³‚¢ˆ„qÂlñùõêIG½1’¸^µu):ܤâYä¡$ôZd%.—±YJXĹйmmÛ‰,'zÁÕ¤ý(%>¶5è‹Cñ´[Þîw»ºéD²‚ë/åªA.©Z÷Y‚•‡6Ÿ{·:rž1¬‘Ú‹'wßA]á^5¢@uª’:ÉÅjÂ) è»û–Fh…FA4MGdiB|,Ó Ù% ù>¾LR’¦q¹Y)ó¬Š ËV®JÔÝC“èÐóåj„£)’ÏÚœõÖ0õ?‰ÇK#ùËVTŠ9¬ë¦Áî`#qäb×m½B?â"ŸøV4”§nÍ“+›¶ƒÃ„Q¬ý+î:¡ôB×À9gþ2áI“8黤&”¡,Vº=<â$ úAkxTeTÂpl$vúeàAJ"¿w[¾×PiÄ|uÞ7²®k¤åE‚¼èl¤-|1ItXÊIÊ{U}ѤL,Í=ôJÔvŽqé×fÏ›¢%×' £#TY œd†¬¹T½7½;èB µOpôÁN«EËtâ’8‰Óó¸Ò„T;aöQIŸîãnßìêV!<1„Sï Œ„Qt©N7'â+§rÈr©ª0´®FHÛ3…òcT¨´|W9‹¤^£~( µÙ]YYÉ̘> stream xœ…X]oÛH|ׯ˜·Ð k–3üòÞvÏ> ‡Ýëv±HM$^$R!)ë|¿þªç‹”ìlÀN$ÎLwuuu ¿²˜ Ó÷»>,~|Pl;,b¶]|]ó%s¿êûyµHتÆSB2ü]mv¥`RIž¤L%9[Ÿ¢¥º‘Y©åÍ¿WÿÄ~vUéV-eœð8NÙ2ÃóëE´>WýæqhžöM»í6Ÿ£Ï77«ÿ,r^fÅõ‰RògÒ2þ+=ev—1Ïe.í±]w^Dºj±#wÕˆšÝÑ‚"åEâ÷øãñ'úL¦<ÏãÙzEë?E+«Æ±ožnDÉËRÉè4jö|ƒee)ʨڟô-k6¬jMÆË˜+¹H ®rw˜ä™0ûF/·ì<]I!\@Õ@_,SäÇ[ŠÔ|\w}¯ë‘›`±õ/ˆ2A´ÛûI®îÚu36];°ª×¬íFvÐ&[©Ì\,ŸùÝ/7"Žy,Òè÷Çû‡z^ò;¶ Äj¶'¯;ììY[w‡c³Ç¢u³fç¾k·ÜóãCÁ(ŒÍ"1ŒH¸6çŠÝ†w‹”ªãs±ž¶[âóûvc‚‹“,êúƒÍô¾ûöÛIãçÇ£îͧƒ;,Ôsé·E#ÓÆ8WJ×/;=hö4Úó† G]78-ŽššQAüqÕåé+V Ûüh¯®g• „2&öçÂòc­‡ºoŽ#0}^W-! ”× ë‡ÓÓ P;†°ÎÔÛø O…éSY ‰ÔQ4zÖD·Ä&}ì¾k«Ð¸³6ÏòÔ·Áѳ»F_5BòˆÂ7àøMFÄ)òÈÖu™‚çJz’¥<‹S‹ï‡ºcÒºhjdZ>MœK mP‹à¥]eªÐz¹=¶´dù ÈÍ9Ø×ô§_îb8…UŸ^{½÷Ó «®BâIU~%xZ¤¯‘¡–­|^†$‰0y½5÷R몔ÇSR%<ê>•ýêÓ°²;§08˜ˆìH^7š¢ðy>‡ ¹Á–{6 &ö«­SIÍ%¿ÇB1ó¥¸nëu©.;³ûTö$§ ú@ÊÜò¬ Á€GB|ÍËéTÐ-&®*4j Œ/‚«XÚôP§s³ß;e»JSåXäuâŽæëï>>ÞX=üI*»Ï¥Ÿ‰ý¾šHYð88”ædcSqtßC/ð`ê7+1Q…§ým3m‚ ™„ÆãšC÷Öʰͩ5Ñ3-Sàp?‰ŸjÀ½Õz=L=h´%˨ZôIœ%›«8Ù†TcK_ÕÐw‚U2»3;• |¤'JS;ÖÚ]|Ÿ¢YóiJ[) iD“¡pîâh„QÏÅB=ÖsÄ&ï«=Ù§]·^ÏÈj÷ä2 HŒ’¨ÄËqÍ`HÎЈØE죃 \øÑ¥ŽIÅK™'¼ÖA“OºÔè¿aÊü\6!D‚³¿;˜·dƳì²ÙwÕ@!¾ÙìÔÀ…ïú§%M—Q÷‡¦Õä~ ’GLúoÈà Ú×9)‘(.¦q’ÄbòRo˜m`†‚»Á‘,tàÛp²ßšŽø×ßϼÃê‡K‘SôZJÄ”¤|’³`_“¬à25¨®šÕЪ3$“’ËÌ›ëÊ|[r«àÑðunqØž@ì–<7«wºþšqpw0Ü2«ÚkQc‚¤r@4¸ À¿j6Œ¾á>!ÁP+” æ©N5áÍÉ+Û-»¨-ÐV£q¦¶Ì°Î°®s¡ÇôöŒE×]Á‚ˆ³‰¹oÁ²L¨'c1)ñ[и Æê°Ï’<Âê'ééêú„+Óú–u '3Ôª%˜—„ûH®\¯Nš6ëQÒ?½-j$w™Ä9—iˆölFRbÇ/¦Á;¦îUäµ½_p ÁöˆSÇF8—™Àtšó0áì§¾¯Ú­A7Ï yé;²pW*íjGƒ~ÅM‰ÄËòB›¶ßPÁ"o>ߨJ YròéóB¥oë-—á‚`Ï!²í›á­³½ÐeK‹Òõê"@–ŸZ²ïNÛ¡v¸ŸÓn†ÉÈ`𤅛KDèáÖ}G„ ôü ÏU™zž›qÇtUïpSº ÷T·-EÍÍ3qË–ib5\†û'”ݼ)€Þe‰ W“öVd,éjn_ À> stream xœWMsÛ6½ëWàfÊc!ø à˜Ôî4­SO¥9$ -‚[‰LHʪûë»’¢­&Óqfì!°‹Ý}ïín¾"‚)"ö§û½ÞÏ^ÝK´ifmf_gÔ¢î×zÞ,g-×p‹2ÿ–ùÌ[RÄ$Ã4·¦´Lß…./›bS¦í¡vG¶œ¶þÆ]><\å«)7íväáCiM†.ÛªMw«‡§ÖŒn‘‘«›º®jÆþ.ÆœXøzV1u†w%jë5$v…Ú­Aù¡\·ÇBÊ)NdÒóÁϨÈŽãÎî1µ·ï(Å„)Šúp\4uQ”¥mŠŠÖì”×ÕÞÅõÃ÷“ Sð×Q`¥|-}<(-³îºeú’6 T®(±ãG¢±"!‰×.Gî=@@1ŽUô©…2À°\<:ËsR!!îIwx·vC8ûô =ŒÂ@iƒ~ýp{{å“á 6$cí?.²b¶E¹LÒÖ¥ó8g1Öškï¾hPYµ¨4&3vb¶¸÷ßö{°ôÐðÅ\Ç]¤ÑˆãÈ+ű¦qP7”rBÆ0‰y¨Ä ã'ž(XPÑ]Ý9¨²Õ˜p¡{N8ÛK¸îy1„д nèêo;Ø‘—ªò¼ÿÐ= åëÓKIû’½g‰‰f4àè10»ì ·Åzkk]ì÷&+ÒÖìžP^ívUÆP}x {Ϊ$‰<0ã>žêTù.t騈q}‚üg¸6Pt,v;qmÃKw¡ÔŽÔ Ü9ôëSV/Ÿ¢§ÆÒ”XzfÇ9%0„ŒªWÙñ ™y˜3ûIÇÑaãú)Z§¥e 5Í5CŠ‚1mUB%Ÿ:[b.YŸïrk¦”¢X‹eß$Ïô’DÙÜÙ7𠤬}Oè¤R;ÑZý9ŠÔ¥¨ÊŠÒÂwíÞ¤¶WCüe,Pôãëá%…Eïýb€Açm}~ üP±:vä[’kD®iI)OÚƒ©¸¨ÆœÊ  :Òy6.¥*‡i Ydý…äLÁ£¢nB'ᨓRî;ŠXj1<“ø±m)®]žªÒ§yz1œÏ“39h·/fÊL’8àš$^ôÓD‡à'G¹®¥k¤aŒœ6h4˜+õ}M!ê‹•¶  jO¿o£'zYcÖo`öµäbóœ,`üìÖ¦›ÿ±s9«3›U·w=ß©ü®¦én´¡|÷ÚA°Ðʲ<¿j$«^bÙ )öã 4£ê=Ë9š€ö&(8—w ª“aJ>Û€à‰0üº­ô¬u»­«ÃfëxØíw ©z }I'.¡ÿËÁ%4¯ÂoêÂuš_;Üg²£·îVU‘ÀÉ®(“x2ãõÇÕõíï«»_&a$«“áè"Aýƒó… $zÛ¢ðÈdêQ虜L^¹¹¿¿»Ÿâ©qŒG§¹°Œ÷³´— —0ÁÀþx¦•ø¬V7/Ïè4(FKßÞƼ—„÷ƒ‡ã@Œ;fÁ—w°ô1Âè`-a#,ävú¿°›åì7øùǫ̃ýendstream endobj 325 0 obj 1391 endobj 329 0 obj <> stream xœXÛnãÈ}×Wô[(Ãj÷…ì öÉYyIf×­&F`-Q‰œ%©‘ý÷©¾’¢íÁÂl‰ÝÕu9uê4ÿ@SDÌÿ»>NníÚ A»Éj"ÿg}D]N8Z®ae~—Û‰ÛI“ óI.Ðò8yLfrÊ2’èÙô?Ë¿ƒ=·Kû]3F8&$E³ Öo&IYuhsΛíjSõvÛÝS2]þwÂVhFS»jnWÌËÁªkóØ<øÜo·è 5Ewjª•3r=ýKxz×4uƒ® óçi ߢ˜¹c1ÇPœŠ–çIò°/*Tv¨=­×E±i¯Q·/ÐöT­»²®Ìùƒ˜h¦0MM>Œ«o‚#Ýú˜9&°&a½óºÙä+&˜_3XÍ¿ükuÿ‘%¡1'~‘qžYçójƒàä±É× Sszu‘¯±DáLeÎtŠ%ükLwµMÄ·º-M"P½çÊ«hÌEYŒì2ðX¥½ÙÔš-+k¶-lzѺ®º¼¬Êj‡6ų­v&° û’ÓnÏÌ÷“ÂB¤!(‚‰àÞä¶n޹µWT]S-zJà”±ÃT@ⲋb¼Ÿ-à$¦ýʲEypxÖ8É:-¥ æ…<„Úœ2çÖ÷Õ~m(F0£$ÝÚtÚž‘XhFýÃ2ˆšbôÙbkœf4žA„ÍæcRC˜ :O)|G¨HêÆ ¸ìlG耆å,âà¨0Ž—ôÏ$EcW2³Ë¹àø`8!hb6ÃgWè.oâSbf<Õ©¯,ïÕyNÃJÆbHؤlŠvÝ”ÏÅ=¿Ž"‘Ë4ýœâTÅ^ü ~J\ ì µÁ„yDjðÄÇi·2ÎC…l¦¤©|lã÷[Ýa¸+tûÝbq¿¹« â¾Ü¾Ô ÃkÓ ÒLi‚m¦n QnÛ³Œ:1ׯKœ¡ÇPÆ™rFK^ùfÓ¬ r)ÖJI€ÏqU¶צx)6–ÐÜ!ÜO¤žñvóÅNd<Åi©Œ¤.¶ËN]y(»×H¿ÀuÌÿg,¤nåzB9ÃDóFQN9‡(Sž¸ã ‚ˆdhõòøíP€)O#3à¸H#ÝA«+šcY¨Ü‚+ÆwNÕUàkâºè|*!å‘«^ìCŽ©mwJaR¨€Æ¾Û),ˆ8!v1‡yÒj ”7˜—“a9¨¥77<¦ÉfŽíÁS4·ûó©Y&(* ûnûý@þ Üã½Y|Ê õü^'ÌÄ_CîÁJˆ|‡v¨fl€ØäÌÄâlÔÀ(œG§~>äm ­gfÚ'“7³4 a€…ŽuS é[_YʰîáùèUÇTc­U¦’wÁê8'V5%Ф⢪orý˜¾çžx¥´vÿ–¶Èaþ'OcÌ ïÀÔgøsç5L‹–¶ó%Ç’KŸ ³Î ø¯wV‘ü <2’šYrá¹v¶Æ€ÌcT@È)ðRx°iжµ§@Z4åí&hªÞ…†ÁÀ.xkõé~ñ‹Íù }šºòN%´3e<¹ýòû²Cì\¶ÅJóæffÖŒHM|Lj†·©)8g†¥m¹-'­ºÚ~û€Ø¼÷ïÀ'L1šeæ§Ôs&“Á9s·•§: ²öæ &ÌÕ͵u€²ðµòGbF¤ÇaÅlüZµå®‚±j,JöríZÀ˜"êGöt´w Þ¡+³@êcñ1(ãý4%‰ór¦@N*@çl‹hÛ‹pkÜ脈-/˲îšR)ã¹í@¹=ûë@Ê ©Ö}LN°Ã¹ìö®æSNì | Ì©÷ú[Ñ8I1·þ3hC#£E—؇Õýoax¼.£|w96Â#z  ¾ÁxšmÎyŒŠ o9ÉE‡zíN?”m%éîR5RZZD},¤ ªÑ¶¦‹®§t”5UÙ·ˆÔŒöô°ˆÛ 6}·¿|6¨iÝèµ;5?œÌ€„±wÌ×{3sON'¹dd̸“õäHê‚ÿ3ô‘1'ÀSrÞ—f6ÅB*3ñžÙÏ=1Á¤T2̼ÇäÕ:ƒcsÓxˆ¿5HÚ‹AÉO# ¬ÎýI C)s „{Ó#)·ÓÆš³$È´§vŸ G’ÎŒ -è à"±ó‚Ûy±œ­çÖ 8>Ôí0 BIJ©„ÙìZHÔ´n`,àq×…÷•»Î¶íötðƒb‚Ì÷ÂÊÎGïUd&2‹:™pÝø)‡±IIcsÚå&¾Ê¢Äþ’©Tg—€€¢ïîn ¨GÚ¾©O»½+ ¤‚ÌÝ>íÕÈ·hF¢!ƒ^äRg;ºég†Ã"—-ÓpJô/¨»C%Ÿm»›êíá4¶KÖ1 ɳjŠ‚MMRV㫈­(~$í5Á™ˆ-m"`ã\hŸ_p„0ñúK?KE4Ã~摃û ¬×0.òʉ^ౌ]¦8êJq ,b£¸×)£R>N/Œ•ö÷‚aZ«…ÀÖ„d¯f-÷Hý0|ùóÁ_Ä콑ó7´2ªÔø¾b$‘䣢üz¿ºûu¹ø÷Û7!Ã:ļOQùŽI›¡ÕÏ_W¾ê%‡¶—¶dQD~¶'Ñíï¼ÏP6”ØÐ£¾ùÂg„Ñ~7è+Úwü¢în9ù'üüGì0¶endstream endobj 330 0 obj 2034 endobj 334 0 obj <> stream xœ­WÛnã6}÷Wð­ò"by%¾n²(Ún±Ø…Ó>$…!Û´£Â‘¼’œËßwHŠ´$ËÙ-lD±ÈÎ圙áwD0EÄ|ºçúqöó·íšA»Ù÷µ‹¨{¬ÑÇÅŒ£ÅvQ†à»ØÎœ$E,e˜ ”r‰³»(Îæ,!‰ç/~}NJuR1#"PœÀþÍ,*Êmžóz»Üzy}»¬¶ÛF·÷Ñ|ñÏŒe8C1vçÝuSh;¯Ì²Yøì¾l·èC­Ûc]v:®æ?ùÅOu]Õèƒ6û9¼ï9»S1§,Ó -žgÑâA£í±\·EUšÃzN¤ÊLŒ]“ÖÃ!N&„+S@µ“)ÔÅ>¯Q[µsœRÂÆÚ/kf ‹n· K iÍLÜcÁTŸ~1k6”b*:S(&œ‡ï¢µ>´¨}È[T´èplø¡Qµ…|BÊ2à·}}óë'TëC­]¶zƒV¯æµÍyÏ–QÌeg]Ì1•.¸ƒ\»„3c€0E°à>WÛ¾ùìêêÑš`"ÀÇ*eÞyŠ¥ävSÓæuða]= &Ãñ±,Nίô¾*wà…êvÖf¥´2AÞè•9‹§à¢H½5R:kŽ»eQn+tu6õIàe|n°¥WI,rbtrt}×ÚX>È·˜'‰êvcÃHx‚vÛ,‡9e?ڞšb©í¤#ƒµ9v¶dˆrk7Í2œ*‰À³‰c–Ø#$NB…μú@ çZÓƒï)DÇÀÎËAYÒï( ýr°ÛW«|oÄ{µÀ®¬£·ï® Â~T!dŠ…<çðD‹Å,HØ$.#<4K°LN¤pÇ9À‚’—ž!± ¦V'ÞpÊ3Í Z•ÿ=Üi§r8ФX)Ò_èQؘðœ6ÁÊ¡”»=Ô£|¿?§Tw°'NèåÔEÊÚz²½—t#ù ´ƒ×Tÿ—HÖîß> ?¾¶ÚèrÚÇ4 ߤ[ôË0‡Pü=èŸlX%¦$wµ¨ÌŸBæ˜ÂLx”q·Ýô»|_l)È>8)EyÎ*ˆ}ƒ¦<ü‚¿•öP& seaªÁ¨ Æ ÃÄÂÇo2Êì‚,gÜÎp’¹æIucgŠ%ž-o>[H0L÷Áøsùåw댩=#$dÐy¥ò³L—‘‘@r•€Ù(XйV›Bú­ìŒv€vŠaŸwX®§g<Ÿ#âò³¯€÷ó0Ènñõåúwl%"ø$[`šµtr’] ¡v.wÁz[`ÐÿøsÎdˆ±$/†)¦ÑTA¯¿È´ÑÑOºSôF§ »ÎúÝ! œóu7J`|aÃîvÉ3P3žÂÝHhÏ~®¹8ÇœgXÂaÈŸÉ™[b–Òñ]zH${Ð|T( V,y™„»Öåš• 'Q+Ù¡HÀŒÜï,1 vòàEõÜ7ædOÃúÁ¸9Ãîg»(x\iæ°>‡ü  ]Àe4–ŽÊ”–¥Òê}Cé›Uºà4zíÇCY¸šØ˜˜IÒœ3ÔE£M¥È-‘pêF6Ðr…r›OÇ‚0° œ®toºt¦Ê'b §¯4:äM— 3à*¨jxQ¥·«É›Ìt~Ä›©‡Ì-Ä䜊 5_@3¶ÈEß, \±âö:ÔÕ*~‚WÒŸ[ \áÍù+‚‘“ž¤ábknM]b‡7ùO‹ÙWøü dÿJYendstream endobj 335 0 obj 1461 endobj 339 0 obj <> stream xœVÛnÛF}çWL_â¥!®w——%QäÁ‰À©‹ Ò>X…@‰+š­D*$eÅ(úコØM ÄÝ9sæœY~F90ýqßËwõYBÙy Jï«ÇÍ"¸¯åÞM½¦KÜÅàßtåÙ“„4Œ@† L7Þ R_ÄŒðÀÿ}úãá©@°2Aã¦ÂË(“¦{ܽmªºW-ô ô Þ¢RЬ†_ £ŒG‚ìëª.õcdHÈ8•!bÁȤ¬žT=Çþôc´2¡©äÜíÚæ]§ Lêv ¡‚P¦4a™Å>oWó÷_tÄfµêT?3ÌÈÌ×ç±´,:#GðÄ¥¢S½ÇÐÀC‰DØfOi°ÒeSw» ò°ÌkP>ÇšY“o}›/{¨êUÓnò¾jjXµÍÆ0‘éxV¦ƒ‘#óº0t–˜ š¥2ûºIS»åÌHU›vÔÄö>Gð,–$žù&ͶÅ.BÕS‹Œ'ŒÊ4…@¤¶T?4ºk]f!u­ǵoùf»V0#¹ÞGTˆ”\¹M¤««íVõ˜5²l »Îê¢ê`µ«—–¤f½¶Êa(œŽÂ]Ørd¸Ãy.!‘q'‘#¥z‘(¡Ñ7Lf`¶*L‡pOfÞÜÝb߀já ÍdWÎu+ „ ‚l¡k6 Z•wM=çf¹¥™j͈HÒ0všá4KLxò¤ u%Pÿ±¶8D-«5^+UtZ(±ÞÅyD³˜ö;þ{ÛFeaQ6Š E`øCªÏô£ûC1øJÐäÍ‹¼ÏÏä8œ¨¬V‹ÛqÄ@¾Àþ›˜fæS{>¼)#dZ@ZDªr×ÿR 4ÅžÃC£ŽHDÏ1ŃÊo­þ$Nßõ}ä}_ kYœ7NÛÄ\=ÿ¤ù9å‘«šœŒã±cô‡ã¥ ÐT(‡hFn̺Q‹] Å¢œ€{€&·ZØïšf UgDf“èîÝ{ä/ÿB34ê”h»¶Èþ[`?ê}.ŧšjgg]»–t2³töü¶mQÇÊüw+Úõ˜ÔÆÿþuðß I'oL¤™¯ã8ðÕjfbýðn~›ßÜÿ:ÿôúÿ¼&I…QÕÕ%|¸¾»×UaSê/¯ŒªÍ“„Võ»¶6õ'ìüíÚ·?-ñii/fD7a„ìwEœTð± Á‘]¼Lo.cœz8ûöUÿˆ½ÑLêõU¨ÇàÒ2mÀYTGLMñ~¸ðbI“cc6mUV5Žz}í@×WkœúMûgG_ru’ꈙ‰-øzŽƒP§}qÐuäe}Gö$ψΌ€Ðú-¢ß̽¬ •ïu3´pF3t»k¹† Cñ9åµy]¾jÀá¤3 ¥A›¤ø÷(æ";F0Š®ÿÌV—Ø rÝ,òµ 39xhX_«ºì'çæºtŠ2\ŒÜ8æ`š…æŠ`GÇ{ð¬Ê$¡1ØùNa#=ã”ÌRòõâìÌ+ÎEí³˜ÆQ2^ÖYhõ¥c¯r å ™—J¬v÷Ifx ‰Ã=6kŸÕ8Ùñ­‰gžÂÃd%Kñ0>ù9Á?œÆ[#“b˜ò§/§·Sïüü¼öéendstream endobj 340 0 obj 1241 endobj 344 0 obj <> stream xœ½XÛrã6|×Wàm©) !@ðöèÄ»™™ZGÉÔ–½å¢IÈâF^|ùûm\Iq4‰75•šT,›ÀÁAŸ>}šú„”‘Pý³?Ëýâ›ë”Ý]üøËÝÇÎ¥!ÍC|ô©3ºj>ÅÌyu¢<4õ¶ ¿›8‹œå4c)wœ,Õ‘A+´bƒŠÊ–è_Ãn·ÂoûúPôh¼®oëÃêU²¢Ä£Ît{+[ÙAÔïú¼•;eZ²›@¥CŠî— ~ˆC/ѽº'7Jcš ÁF”Î×þ2s¥t—A9šÓýlf€%êa˜»ªÖsз‰}hD€áBú×’‰SÆLG)‰ìú¦-¤…¯RðA¥ C°®Û ;bê¡´æ8. dYúfzEú`³ºÛ6î"‡¦'÷õ(1,÷bF†7›D'…®éõbð:ËbÏ4·^ùÒU¶Õ®ø…+É^î›öÕ m× ºé Fì ´øèw W³Ý)¢?Œ*w¬—‡OcÉ2ÊrΧ’w~ý©Šå¨s+·pìlnøõó£Âþ}Ñ–[ÂC<Õ"Y5å°;IWÔ•a,&Ã˸„¢6%4SíÂŒ9èäH5éùÝOëë«ß ÍSs6Ø’ÜK3 zM Œ¢úó¶m†‡­~f»N‘4Ný¯`44ìÈ®þuÌM…®–ý4L’x F'Ý.-#`ÓBÌ ß‚gsÕ“Ó3/F5Ã4;z>Þ]~X_ÿûÄ UmösÅ]ÓØ‡:!Ý  ÷ôe™9³„ÌS-ͼ5+Œ9ÓDñ¤:ã5'S +cÀÇÚ‰_„¹FÉ•Fb‘‰cksb‚g4I“‰.jŒ.¯¯?^>ÁÅT$ë ¨fÕ¸)˽[Í ¡ÞƒVþÜ F¿çïzùÒÿ9;h·¾ÁÚ?ýPì6Öð?ƒü« "^³þœAä§ â9Ïnøžø"¨ð‡È¼CT¹ÿ‘Cd4z›CT^ân"C³óøk:DÓ‡îŒch¬ìkZŠ·´á¤_´¯lÓ*àÅ/ujJõ£ÀôË4l©°ó˜I wìBZbÎÂBלpÖz„¨;‘䉂Λ ‰¯ãálãìÍ|ÃP#—ä~ÀkëAI!Ø–†Ç#[˜dGvÐޭȳØÄƒðAÁŽ-¿1žgS T+ƒ¡ÿpaÌæ(žj7c×ùÔÆÎ§Î*š×FÙ«Wp¸V£ª9©¸h"d*G•¢œ™ïEÎ;ÅÒ#£=’]ÙÖªÇÉV¶3£ƒ•ƒX?äeu,FðÒYó;;r¢˜:î&Æ*Zk¡}›ïÍY°+ôSÈV(ú¼:[»ÉšƒéûÏŠSó–W<‘‰÷È)œÝ2åÒ·X×â3ãzÿ:׿'%ÿcê °n„ŽÓd,RÂÄï» ‘âBëãÍÓñ¾d&à …K> stream xœµX]oã¸}÷¯ öeå æ’¢$JèÓ¶ Úi³4ð´(’ÂmÚQ!K^IN6óë{ø%Ér²ØÅbILêðÞËsÏ=ÊÏ„QN˜þr?7‡Ù’ìÛ#ûÙÏ3n‰û±9?/g‚,7ØÅC‚ïånfŸä$”!‘"!ËÃì1X¤ó0fXÌÿ»ü;ðÌS)áB?´™ ŒEdgd¹ Ædù: *)Èv¾üß,J(a tìx ^óf·Új•¯çœQÆÃ$X7}²X‘rš%‘{&P/ÇœÍCʤtŸ¯6õV=Os½Œ\2—Ë‚G–1A|z#31UG¶£Ó×zqäÆ|~S(‚µÏ×F£ÜÍ ¹Ényõ,ŸÙªMWÔiTwjª–tøÐà¢dHŒ…ÁK‘›úRïÌŽ›O·t¾ˆ¹¤™NÞ‘¢½&E÷Œ.ŠÈRš$¡KÙê~éšµïŠj«ô N)ãöF£Dè°ƒ_¾#(B=Ž3¢Yg}œ]¾.‘Xݘ=›úp,J»rª!2x}.6Ï>DNrrÌ›ŽºX3fîààSgÂŒpH"¹“ÙX6yUÕÙ0p /JJ>×D5MݶQäX·m€t¹35?ÖÈ@YºŒn< NâÎÕW\\¢ÈÜòáÔvDŸ½Väó—»;j7œN2µò’Òñ7¦ô#8ý\”Ûf®é‘fQ ªÕ®Ì÷&¡IÒ¿‡æ´Ç:çûµI ‰öL²ËË˹zÎ[ûøEEö{xŒp Í>n -| Dâ:bÒ½!*Å£h¸ÌéE2§¾øÁ1o[µ¯ÔÔ§ýó;ˆ Á9•¡ìó’š`KI“X:ì¿§&¥á¼Úúœ&‡pšsß§7ÿ^ÝÜýkuÿéhÇXøÒà£Píi³QmkÈÛ…Í,A#3ùcÕS&dT„œ{ÎÔÕâ«jjòbû™gA^ž´Þ\0FD)ño¨CLF”:¨Ü^á$å˜# ‘~xSºñÝ""þîMŽ 3š…¸J“Å}åÔ€‡©Vƒ`PÅi*™¤iœ¥çå¾}x¸˜‘&ÔsÉœF4Lü¹¸„ÌÉãq_­0E2@ä[Õ7sjZ–é‹^“ÕÐËšº}²ÈÔ¯¬`„·TDµjOÕØ™°­!CÍê²=ÖMWT{M¶¶>(2Gñ¹„›¢Ùœm—W Ž Pc­k{U©&/Ë7R)µUÛ‰Ài]»›èZ]ûþ[Nê}Y¯órUïv­êþØÈž@]JY˜ÒÔ—ÊH”†²ÛîwP4½‡‡YÏM‡k¯mÁͲÃg_ª¶ØW¸Ïp6õ©zF;ªåVßö•½ô§ùŸ¦ÊjSp¥ €¹TV\p­KÁ3õÞ‡©eókK5Zh«:4â=6(§fTw˜þ©ýôßæ]n¬ ƒ¯ˆ1¿5£ž!yoÆäU^¾}‚¥€?Ø‹‰ÅÔõO 1Nµ ‘´¹SZ²ž‡ºµbœzÎVusQ–¬ßH~<–ÅÆ>ƒ¨ ­4Ñyv Ò ¦:Q9ÌCQÙ]$gmóSÞÀÀ„ -e‚uÞ.Êl;Ü÷RlfÖt¡KÆš'ÔËð‡’Ÿ¤ðDÃENô$ߦc$‚ýîÌÕ5'¸œEØmu¶Î6‡µ‡’£4Q?ø„Ìæ¼XæX©ñíмL°Iú$éV­O{׊Å4r€¶Ã­U¶‚Îþö4Ḻ˜»H œ~¿ã %Ö?bbŠ( §¨yÙÖïÕo!ÀËT ^æjÜ–“ˆ1DoWQ,üj˜êjYk³n—®k ˆ`¦§+X«~@?`| C¶‰ñg)ï[JU]ófÈ(-þþ%¢²7Éô“q_~&‚¥}µ»bSFezÛ:g-©RE¡¸µ+Î7_#0c‰NÕ©=ååõÈÙ£z"Áëðd†¼V,ëÁÛ%ÀræÇ‚>„ï ùÛdIçöžµœ¦zN–fÀŒPQä™yÐÌÒðÇ¿’!åP`ÜFc#âNr/!ϹC´C÷1Ñ#:b¿àMÎ7õã9¨ó¡¸ŒLÚû©ÑmÇæºÛ§¹}ÁYp ÍÉÙ˜úvÖ%ë­ËGjÁGWfœ\Ì “8ílj–õ´(·ÐÚ³âêDâ…ʹ1u5AÓŒ9™e¾5“ìÔË£Á61ÅŸïW·Ÿ—ÿéñÏ4ÄŸs½»*9 `hl0*ZÏåáG¡Ã+¨6¿î”x L³î¼|Ûf)Ê¢{›'Ú>§Q@©»³þ¥PÀždQüþ[¡üø­p¯ºÕ‹¥†ˆÄŒŽœ¯ü;êÔ {Œl› üº:{—sšMzùî|ÙŽ™U[|ÕÿùþCGË'ù;žyü²÷—/Úévjε"ÂMüÒáýÄüùBøW¶‹·yh¾ì‰à£žŽÕƲ¾º?ÎŽÕÎLH½ÁùN3a[LEaËó0¢¹Ðµ÷ô#âŒ5ˆâ=Ÿü”¿ÁD„|xZ+ƒìéuþ³ÛåìŸøú?Ä5»endstream endobj 350 0 obj 1902 endobj 354 0 obj <> stream xœ•WmoÛ6þî_Áo•ƒ˜_DRûÖ!)Ð-k°Ôk14ƒ!Ë´£Á–\½ÄKýޝVÔ´è¶EòîøÜsÏ>£”š?ÿYf?ÝI´ëf)ÚÍ>ψ]Dþ£< _–3†–%ì"Áÿr;s' ¢’bÆ‘d-³OÉBÍi–&|1ÿ{ù+؃S š2œ¦-2Ø´MÍvN9ÎsÊ“m§ûEW}Ѩh›a÷`Ï£Ü;Êá,¡ÆM.š­9±2'æËÆ©s¿«¨7¨ÕýÐÖ߬e‹ŒúmWWW7V·¿M, ‰•ßÒÔ¨ÊRw6›,X ¸ Uf=ÅŠ2§Yò¶FeÑiÔl‘nÛ¦5»™[-g.ËU°yÙ›E d¹{nlqkëÌÔû'g¨CǦëªõ^£ª¶1¤ØìƒÃ€!ÜÕÇæl•`)ÒpËýcˆÅžÊÁc¦ü©O‰.æŒ(,DRWç”Q‰êâxl›c[½Fïþ¼¹™€JR)^oSM3C3Ì) ëǦª{Ý¢®qˆ*†3Ø· Ü¡ ‡BÝ «“ b*IrÛnWWzmrœž† ¦«*‹¿P_8ôXŒ‘J©ò ,º®öàÑòA·zÛ´öBJà4$$Ëïý”ûªÞ¡Â„ MS"l”×&}è4Ïé2I3ì7¨nz´ÖèÑbM$¬ÑŒnŸlМI¥ˆœe.¬ƒ.jð´öè>éMlæ¦'’)ÀƒþN}ƒŠ¾/ÊTõðã~nÉM(Þxf¯™õ  íP—}Å0ª*®°õÍhŠsâ…²:ã›cÁ|D©ƒ JnžHHž|X]ßÝÍ9`uà 0¥ÕöÁ£Ó$åõ'—¢ÔY+g ¾æQ¿(±P‚g~±ÝEr,Uš†SÃA×=˜öÌ—s™Gæ»7–0Jq›Áhð°*÷E×Ý'÷s¸Íç¡ju‡½R*D˜©2&ÑòHL]Ú–˜(´™¿šq`.‹4;»þv_u½±8©æEغãJ,´™5©­Œ™·®*@.-§¸ Ê/¼†“ÕzèõÅ…á_»¶—ž_}_íLŽ.ÌJÙ u?Zs¥ta¹¿«ËÂ…à‚…fdH|е¡÷Ë}@q`TPÞç s&žu;ÁñKêM@7y•Q™Lœ  ò3E1& ¶V(§,¦ äe<Ô)‹ª•x$'F €äyg§ÔDòeOZ°l1XY¨¡Úâ úØTäþ *!e:&tz­é(«®\7º+ÛêØ›¦V6-pøØÔ£àY9‚î ¥hc¥PLž`¯YY9ƒv’æÔ;1:a­C´HK=4šlq×Ãa Átç½vU[ÍŠ»n>žß™rÂF@[bNÇ…39ðWµDA{Ól¤–iïnW×ï–w}…ÅDÊp3óÕÖÞHÂ*‹²qõÿ¢ÛºAÝLÓ3‡$âûá8 ÞŒ“b¿oJèñ‡Mådžq2o`¦ß0Fî`9O8þ– î·wŸ¹À9ÌsQ©¡,¦WŒMÀès[JË)ÂC´øÖ®¦a8Aþ뢋EÊ„õ³?êÈbg:ÓI[´m›Ã4y \²Ø‡¿Q¸_7X=Ëc†C¾Ôg½˜…áS¸cÊsÞeCAÈü+NZƒ^bF…Ö=عcíªŠÁ¾ü¬ ë›Ê" ¾âˆb¡\Z«Í¬xx4dfè X¿þ ÙsqÛhK¥—´Íhf”¥SÕ»fì™g&Œþé8‚@tg.[r½^½^.§Ü‚i*¢îõ.v×dÛ€+Ð#„Š7åî¦'¸ÞÚÝsa ¢2iösÂÆHÔúi˜••A/^®2PÊâàð„ ‚óÿ!!è‡F¸‹ˆe {”tTÿ|aܧ’>Ç÷æíû¥ëàÎRù-¤O‘߆ÆsS5ýfÓ}SïœòÚyK¤÷ÐÔ¦1,(3/‰jRmß!NU^æIx/³7É ¹ eû³3£FŠä4ŒÉ›j7¸w7{!…y|[Ôä\È|Ü€3< - oW×ÿ‡ã^Ãæ_ ¤L¦"b9çç\ “‚4ÑÀ,iLßé (aFéä‘c ôƒ"øñ;t3šRr>hÞ>Cv§/è×ËÙð÷d±(ðendstream endobj 355 0 obj 1684 endobj 359 0 obj <> stream xœ­W[oÛ6~÷¯8O­œZŒHJ¢„®)`ݲs…C\ŠD;Úl©•ädì¿ïð"Y–í`(±M~çöòWðO½ì{¶™œÏ¬š‰«É× Õ›`ß² ¼O&’ ­(üK–s’Œp!ÙLî7š²Àswú9ùñ̩؞r©ˆ‰çùàhŸOœ§ªÈAþ‘n¾¬e´p.ŸÓzy)¶+ÈV3° …„¦Úȼ‹é4ùmB}H®'ÎßÓב\µ€pÆüS±*ei›UÛ²…wà½U‡ìîEÛÖÅö•p–¶ë¢±¯»ý«º®jú·S ®%&¥#G–ÎçP®YÍÐŒ«-NX ³‰ Hû\Yú!ñ8vIÅÑ‘<¦*éÂ1|ŽHgí²Aóý“¦õôP³¢È7`ü÷éz êÐlÇò÷Uµ†³Z¶Ûº¼À/³ñœYªâú`îm!LlœPÏtÿöQ–P´Ðl³Lʼ™Aû(a¹-³¶¨ÊQŠ4 õ[üDAz¥¡>º¡ÖÚDÜŒyL|Öö34‰=ü؇Nuèi™C#Û1¤Ëc‚íÈ5(Ö9¦ˆ[÷mew½.Ÿx¾o·ïœ²*Ý¿d=õT€;•VÊ bQW,ÇÕcו;=Š……„w±P"ð£JË«;bæX Bøó‚“=v.xGZunäˆs¨ö[ƒ2¥Í0N.ú´»”i¦Ì|á-¢M}"Lc* ¸~.Iàƒ.6Ð »ˆŠVÏ%ÞaL]2.öŸp&úv-Sµ¯/ ˜0Çt(JÅ)Š|=N§΃xŸOWóùÍ|Tƒ($6j‡Œ4‰Q¸8ОSºð¢ð(Âà^´LügY $PwÒ@Ž—9b„”ÙŒ­o ö9B$‰µµ}s©G¢°Ÿ‡Ó¢z„G½ŒäǪÝ3 ‹:Ó#Ú€ÔvÃr½ˆd”™ÊHú}—懳Çh?›£öÈ#„ÝÀ«ªò¹l²ºøÒbǪ±‚„‚xq¿$!4]EõQJ¼HÄ;/B{y*ÊÕHWpH™¼¨+ŒQ:Òa ÷ú­)e‡ë¶ï7£$ŠÖ÷»„ª”PšÒr"¥ºÊê)¹sÖU¹’5”ê^ËPN(óUŒáƒA'J}¤>Jg{Œ9ò<4èþ“X€ÙÂõ=Nbµ£â|858ña0Ž7÷W“ù¯ 'o ¤}ŸÃ1§}‘‹ËØBV•mZèGÌñ á=·;ÂÚ=ùÙd9rS|k®Gõ6îôö®¿·uK*AZO© q,˜³Ún$ê#>]§¥}š¯²l[×2'ºÓ.å(ª8..7s8×ùè:”+¹µñ<ñØtÏoüòSú'0ÑÝAáôÞŸÿkè*™üŒ¯´¥endstream endobj 360 0 obj 1267 endobj 364 0 obj <> stream xœ­XÛnÛF}×Wì›)£Úì•»|tlu›Ä­,4(œB %Jb+“./ò÷½Q%ÛIP؆dqvvæì™3³úL1?þuñ8z3Uh]ZþQûù—Å#z;q4[€e~g«‘[IS sÑìqtMô˜IÅ“ñ_³_ÀŸ]¥åfÑ„Ž h"4[Ž8fÍv£(Æ 3Š–ãÙß#c™ï`qíÒj5ß–ã' Mx´{Z|Ž>­{ˆ'ññLÂ2ØÃ,$Öo^4hé=Ø…f¦1˜QaÌì{cye­®ò -óì'cf Þ ®Þó‹å²Bçã3€ˆ`bTeM[n»râžú-HoýuU•àeæ’㦙OSíB›m2´j‹E“—…_²Ž¥IÚÇqè‘ó0Ö*9ˆ¹¸ã1–”Qosõi~õþùí¯O±ÂÉÞSZ,Q5CW‚bEx0:ïcôb`M‰šMfQD` 6ÇHǘ‚1Ð*Ôe"üºÝ“yhùÆ|ÁÝçÜYï€HU¹®ÒG´(Û¢É*ôx \ä4J·m†Òº.yÚdK´Ë› b@1F5V<€gƒ<˜ÂJéÇ2«UþÔÀqç«á©)+M¿ÑS•=UYMR‹ W”.ËìÁòUaÒá¨1 `ÈÓ®×y±Fy±*«ÇÔP«êë>ËÃØQX÷p13‡6?>50ã$¦MSå6 jÂ<%)íÂh2Œnc!áx¤|™ˆžhÀ(îrô\üx;¿þ8›þ9†šdì]áMIŸa'ð†˜»ˆˆõdb^–YвA‡»©HÃ/)1E¹Pgý%CMGA8‹RzÜäp†T‚a)Yài°é!ÅNˆÒ¯•¬ÒdP²×Óéít¤Nú°;Œ&‚ ÇêPªÒÂé*‹¶ª²%v®‚Šse„ñP»h÷Ù¡t;åÞäëÍÓbþÐS¤o•ìýÒ¡j;}ýÙ†n5m·‹×mû¸ãœ]ûsº]ÁZ[`G‹MQ¿9±Øå’í#rnÞåür 2òïW/Ì¿~ùaƒýáì…ö ÌN¯¶¡»ó¢zÔ"(\Lù«|z­Ehhçl_Q”{fî SyÔ+\ ÃÉ9Åìå{ß3¬¢;1/W§ô*€‡zóÒfö8¡m1ŽÃøáË•Âø¡Eb«ÓúP-qîàT,%±¢¶ÑD7 J·uy*Q È($jH4Œ€bJo®™}žïn§|Š=5¡ ÷a‹°ÂŠÉ[«w\cÉCýw.¡9¦?@_G™MàÖÒlRGÀðÌ—@Ò˜%ùáÓ*-ÖÙç1Æ—6·î‘´H¹Q ”SÈ€s`%9Vp:/Ìà*ÂN#|yûñnvñq6„8ˆ…|b¸½)’| Â Ž…HöåÓ! êÊxWû¥­O0NâàØÎb‡ö 4­ªò1Œ†Å2éÏöïêæúÌf¯ÝZ3ã'XŠPæõÖ߸xÚõAÍÖÍöåýf¯@Á»¸»p_¦ûÂí“aô7áºY»#DAHnì4ÍŠØô÷pŸ.úžº[F4}'@äí¨ˆÀ+LÉNn8ÜÕ`x½,‹&_·Fi.ü¾SO'›ClÈcºFÌöñþºñêõí…«ßÁq|saR{þ¶t£I7ðÓ·5¡tÇ5/0\R¯Äß77²þÜÈhj76’ÐzOOÛ'Q|æv': ÑéÜ„ÂðNLW>X6¸6k!à½/’¾ð^ðŸAcDðχô+4\F÷ Œb!íïÿ®g£ßáç?ddCáendstream endobj 365 0 obj 1829 endobj 369 0 obj <> stream xœX]oÛ6}÷¯à[e£fDRIì©ER`[Ú`†·`HC–h[ƒ#eúh¿Kê›¶“¢H§yuïá¹ç\æ?äc‚|óÓ~ÆO³«•@ûræ£ý쿱Qû?¡ÏëCëVŠàßz7kvDÅ,@‚…hý4{ð–rN¹ï‰åüŸõoÏî’ˆ0³iI}†}?@K®Ð:™1L9Z¿Ì¼ LJæëgAˆ}F%D‡ÞKTì6‡txŽ½Ç¹YY¨6‹e·"›å¾–fJ&Í6*1¬# {m_§%©þh›·3HÆhžJ’-æwºª‹¬ m·.›Çmlà¦(rˆ ÍGŸ|á²É¨Éœâ@ØëƒF»:‹«4ÏœjC…¹ I›Gršþ€üS1ɹtâ1‰… ºx×÷›ëÛ¿6w¿;„i¨êÓ$6Ï(KP©+7&ȰÚ[LÀrëgŒÜ-lð« Mä¯Ìô\äû"zBq^g•.Ð÷9 °’BzѱÖ(*ËëM¾Ûÿ„Eºg¼ZÀ³ÅÕG×< :ò¸»Ý<ÒhÙÈ$¯:凰mˆw]^h‘\\=ÎyË+ª1Ë» •u¨.û&öP×¼ˆZOò€7:öiß‘[ÒR Ù .SÒæc¢½vÚ¡ÊÑöõD@A•]2Ù¸¾Ë'ñ[2enRqìŽs,8 R;ôˆÝćIŽòÃ*P¶ 7¼w"ƒj)ù†ªpˆL¯¸S ï`¬ïÂ5EŠªA &§@CÌ¥[ë{Ý>­´ï|ø>Ñ•Ža9õ®‡Ö´t;5z™›´Æ<¨º°È“:6ñ2ôEo‹:“§> »”;}0ªpë¨UøpNZoŽiù3Š0ÙÝÊÞÖ{”l÷'bã@èˆA³4Ts"Ÿóü˜mÌtó `n€…¹©êy·õ®UûýXEÚ­feº7g³˜Ã*ß7Ûâ 1HZæŸHŽóžvN?Sd  ¬–»êóÆÔNǼ?Ÿ3ŸŠ Œó·gwø„tÜêtv'&P×;Fö%S`¿Dô’´hðvbqèCÎzknA€i=‡‰Å°~–ˆŠ"z5n׊%L pã#VËîû$- ]P|H`†Ùð5 õ•Û¬æš 9p"9¹`t¬kËNÕ÷éÔmÀúÏ”ч¡eÑpæ´ôNÆÕš”íÕÄäoæóT›ž>7Ÿ h“ðÍ Â¾‹`siða®Ï.Š£RÛ×5Êsi˜)N+|‡àbr‘ ,<.¥Ò—týÈÖ¼Ñy¡ Gèë€ îßÌhìwlk³Ž7¯´Ó±ý.bóŸ±Þ~žŽŽG]”¨<äõ&õã1ŸD‘b<1¿Œ†oèè°çTgu“wzL«ÿ,Qô,kÉæðz¥¸ô^%—‡š/Cæ5ªmÀ»m8·^ü¸þ ¸w âo.q·0Îk£‘íMÂï™ú µtRa.ü🯑ñJ†+ˆ€üí rú7š›õìøùÝô´fendstream endobj 370 0 obj 1666 endobj 374 0 obj <> stream xœVÛnÛF}×WÌ“#9Òz/¼,ëæ! ©£ŠÚ °— ‹LHÊ®[ôß;{!EQvÒ,zwföÌ™3³ü”0 úã~7ÛÑÙ<„¬QÈF_FÌl‚ûÙláÕb$`±A+Æ¿‹td=ðáA(XlG7㙜pŸŽålòqñã¡×ŒSA(õ`æ£Q‚F¯+¥ò"ƒæ“‚2EÜØ8­U³ºÍëò’²P×–··%šŒïkòƒ z6—„ôˆä’ž _çÙ®š,þ°h¹$žÏÁn)¦× 桽ìF@ôF?3ßîÜŒ/ÿŒ·Ÿo•CÈ8ï!Lî'‰"ßçã¸JWÚÆÃÿåÞd9^N ÅLh¹fŒIPÙÁ¾+óT{X/ÀŽŽ}¡Ö» ’u6»p¦äÎtªácªŽy&œ5zU–·Èã*/Òr9ÑF³«¿Ÿðûµ¨ó¬P &Ý ¼z®MµÑUk¤œ¢Áz—ZƒgíÎeU•(ó·ÝÉ1 ®Üµ \šPn)¹·öòÖ¹îl³˜×à‹`zb¡NáÄœ»œœ§›§°t'¾€‹«‹«ßV×?a…¾ÉCÞQ0N1©åØ.àúŽ£sxþ<7¡ÏNaWk‰k˜7ùG8=;FöO]ËE¢bÔüÆò༧ôËÕÕ›÷ á³ÇÂ<²dºEÝqlÁé-A¸‹{­þðmé„bc¸¾0HÖªó¿”Ö²k“NÅ­¹S15ñ,wï-sÉ ÆiŸ¯çu‘+-k#hDÕÛéjqZ©fW+¯“ÃÞΊïÔ©÷{mí¨±`#·gø¤ Ȩw›RI=äɰ¯¥×²2L©£¥›<™äFÈØÂ­!½DžlCvbD #âµ ^[±¸H»bs&$'Ô »â÷©DŽpðËÈ @JBi9lJ3‹Ýv­*”˜4¡@VzÜÝ”EçÄHXQ7q±ÑÚ6Nq–Uæ˜%4ÐSVpFd¸$³x?~*®M¾±NDÑOÔÚtEH¨ #kˉ'mÉvY¦o=ªmÜäeªhª¨ÔçJÕøŒx׆8ˆèXG¡é}iƒ\m¼…MÞh#¿5bú‰¶7GSísâD²ÖéÑš Tãì°æï®W—ïó߇bœHÝä:ê<”dìûÜåÒ‹ (ñ… à“HXÞ’R—³lºBêÊé"ƒ ÄMSå†wN}¼Ô[»F ©Äzú}¹0-Ñi KlÎ<|c ò€UÙÚ0ýô(«*嫬Î<ÊIòýì¶Ä^Îç×ó'û z£ o²½©ÊÍfWU*!ƒ‰i|f"<ž™áÓ33oþ×ÈÔ·crèùÄ•ô’~×tDN}ñ§#Î2áNÇ#öÃQ˜È_ލ†0üÆl”xsøÂIÆÀõކ#ND†om˜•ÇM°¹ê^ ±Á°î;±WœßWˆ®2®ü?§œí½C|Õ yûšxøÊ{¹ý‚ŸIý°endstream endobj 375 0 obj 1141 endobj 379 0 obj <> stream xœÕXÛnÛF}×Wì[éÀÚr/¼ìcû!mš †Ú ° ƒ¦V2 ‰tH*ûõ={£$J²Ý¤/ XwgfÏÌœ3ËÏ$¦ŒÄæÇÿ-דŸ¯2²ì&1YN>O˜}HüŸrMÞÌ&‚ÌJ¬bœàw¶˜¸ŒðŒS!I&R2[O®£i~Æ“8RÓ³¿f¿ÀžÛ¥ü®)cI¦ ÖÏ'Ñ«V÷›¶¾íªôÙìï]¹¢Y+xÁÂ˜Š”‘ÙWxèÒßkRoÖwº%Í‚ÜU}Gš²ÜŒhÓÛ0§’eTˆ„L™4ß3šäÊB<Æý²²Ë€pn œæ™ðN£/Ö†t{Ê c”É𬞛g7–šÌ=ƒ‡JSò¶7«p¶µêì<Šq‘QÅxÿâÓíÅ»?n߸½|?»ús„8cÜzqk«ÅÈâTœùx¢y5NOqÚï‘y£;R7=)›º/ªzHOÈù”+äAeÌëÈ£o²—KiA7©Û‰€fI*¶Çz=»…Í¡ŽÒq¹Æ1 @Ñ·< 1G}¤áH}»Å î¿?,êžçlØË««W‡u,}µ¹ü-Lé¶mZ[µm«çÔíÉ ®Mòœ¦ø<™Ù((OìÞ”f”çÄÖˆLiŒ|_‹vah‹N÷7ÑÍÙ(ÞiXÜ ¦îÉ|¼×ìä9ðò ‰.슋JdýÜ<6ÞMŒµâžÿ^wÕ²F î6õùÙOÞ•[tiÏýÊ1þ´‹ÔÔ9uñ!‰rÍùé^×Ä̦,µžwçãÂähéT†Â< ÅP "1i²o€–bjÔ7~YÊrîP?E='ð8659H/K8Ÿ =tBÆEh!ÁåSœç¿]éEO<﬛Î4Ö²F÷òT+DT•²l:Î/ÂGÛO 'ã œL½Ûà¢!£1š~`a—oǦ¦JMRéÏ/üSÃ¥”Ìî+ D"`:ô‰7p¹h ‘G&O†x KÔºÔ]W´ÕÊy­Cì6f¦Må@ß&EƧµðµêï=¿t}»)²&¨¶rUt6D›»sdÝ0œø¼Û¶>C·…Ö¯êRÒiΜ¥|zæE_Ü®µÉÎíª)‹¾jêqÑŒóÀ.¾.Çb!äv¡’náM r7DÉ`ldî:zìµV‚:³ÜábëÙqh §x{9&óÑȪ6JÔ;•(§Œí§ÔxVÂyv…®Íî¶Ù,ïmn°Êx€¼ÚÌu¨ÍŽ‘ð‡1q·\øžElñ6ïA§aMHê‰Î†töIĘ˜âPSšóA0«Ô?lÐ8 ÕII -!™ÃÏ ¡[bc!#~Ùãw;’lO¿EG„Ge‘%”ÿ@²˜‚@09•EuD¯.víÀÁ‘T.¨—VFÝðœ>v­ßúu|Fo×ENÓD¾Pqh‘íéâpŒCU±¥‰xZsª²ìQÌc*æ@nZ]8)h~ Ž&̱:‚±Ô 6B9”Ao: RÕóÊo½t"ÐlÚúC›b©ƒü•Íú¡ZYŽ&›ºrÜáM¬&­‡‡Vw„5\-æº+Ûê¡oÚ1Þ £i,÷é w¦öÚóJº×uIX„~”qv¤ñžO6ž¤™Pì…´&¬ÃS´¶ëìÈœ™€…‹™AjoÌwLŒîæÉÐ"¸ÈÈÔQ߀'ræóã'%£jeнsÿ3m–K“˪^4íÚ% ;ÛGrU3Æ.}îPe`ÂÿH•¡NÆ`m¯®Žo΂â cvÈîÄ,Åšá’ö¢T¸ò£„(âÓ„X´mñh¥†Å"jÚ¹n¿…­¿ûûiÑúf^T˜Dó—Ñ"Ãå*ßcÅ݃#&–fOcBóqóÞ”4óòiâÍžáE‰9'9 F§UsøäG.ºR‰.Ê-ƒdhÂPÇn£y]qÈšÖ¼ùÇӥņò mtƒe< ƒÑIj3J™çûœ‚‰(}–EXd8+9F˜«ÕÓÔ>;ÈÎIjdÖá)jÜuv„ÑQ;ï¬dºÏû„eq’‰+ fÍX|ï[¾ú-ˆ½É]ÕrËÉëáý\ÊP×ÃEÈ.Räã(ènÅ4¬„†!‘ú›¢Ce7{ZbÞþá2˜òíKH%ƒ‡ŽQ:7ë;4̓n­@uÈ«1po´s'õ× ÓS˜7Ìݽ„Frƒ‡÷à)<ºÒÛ¼{Gõ/ Å6-Éîi)Ͼù ÅÄcζ»3ÜÄÛŒ_Ì^Î&ñó/NÕ¸dendstream endobj 380 0 obj 1779 endobj 384 0 obj <> stream xœÝX[oÛ6~÷¯à[ä"æxE>¶H‡]:ËŒõ¡E¢km¶äJrŒì×ï)YI›¬}†‰ažë÷£Oˆ`ŠˆýþûÅw×úØ-ú¸ø´ î!þ{ôj½àh]€e~×›…?IËæe\¢õ~ñ>Yé%KIBVË?Ö?>8µb„cBZ¥ T.’¼ïÛêv¹þsÁRL4c  ¾'˜ÀÇõ ´{ƒÊ¼Ïñr•ŠÉoU]Tõ¨êPÝô(ß¹Và³·P&àåU%§Üªw×SŽUFµð>¹ïPs»¤k%YrW5ÇmÚfú­A­émîœjÊS¬ÓÑ6jmKòÝÑ fcÅ;ƒ6Ǻ諦îPµAym/]1­°ujE…?šYö¨iÛ¦EMQÛÖ”—¨© ê¶ÍqWZoìÑ茠O8bý莇Ãî~¸r£‡ÜÈÔð wë ²Ç5•‰CÞæ{Ó°­EÛ,Ïn˜d@œ²±*?,û%§D%M9öËpš¥*ˆÙ$í+([¬wK(y­©†š¬Êª¿‡²ô=Á©ÄB*Ð7ÕXà•ápª}ACTÎ:‡ç®¾¡ª¬.×÷],dˆé½™†3<· ê@MÞ£}~?Ϻ¢XÄðlÃRsVH"Äyhì”p'àÑŠ)÷ðå<S©ƒ!W./̔̊ŸRqNCIÛÖ’ÒtE[z(2ÿñÖt4¢Ìfc<(G´²CÝÁÕf nJER¨¬ `˜œJ%ëí±»D&/¶.¶ûWL*(`Rö¤ ƒ«Cj'¶º>¸…$èÙÊñsh]Àg­3æú´5‡ˆ»¶q{﬘×(ÕŠôùÜ qìÙo$yÇš5'd ­HúÄi´±ï§ŽÀiÙL}oZ×&q × Yd™$Hì,®º½þѵx²ÐJIÔÑé%–ö"…Ç[e~ˆkL7pRʰÔãP£Œ³ÜÎr3¦àÀåZ耳ŒÓ@“Ëæiã´Yî™Ä!7”qÆE°46éPØÓ@p(–pyh ÝõÚ7óŒB_ùD¹Æ¹Ï´h¬¤Öì¼½___¿½ž©€yäè¯GÎ.2º§Ie”ψ¿†§ej¦Éí-ο9Çy8ñ(ÌŸ Ä€óé×B¼;ÿUïdG°vXâþMh-,™o¸w[SÛ%£;…1ew9Ÿ3€àTQæ=Dw fé^dXÃpðÂg0cEÎÞ4}gú¹N(†‰Èbh§qšW–€|‰¥”‹aZlæ:´´UЦ [P±uÀ—„[]<‚Ó#¸;7ðDKño' /`.±6ëèÊ'Ïo“€q¤÷'èEšLgìt:©¥KÓc}ʇ>]qØh”aö%|꼌өç8w¡>vv?ºZ2K{"KÞÝ|ÿöúØHʪ5EŒß‘­Á• <©ÎP˜YöŽ7ÙÒ,ã‰8ÇËaCÛÙØêäÉCúHŒÃì'“eV†•ŠG%PZFëm傚*œN¸.ÅÍoÒO@/³T›#Sl\{.6~(ß]ø"†?sô‚Õ]Es¯f‘ó»œÍíì]Mqˆãe=u‘)2Ò˜ò|÷°ú9l6­Ÿ¿øì>ƒXaUß™ÝfŒŒís5'q_îÐÉ­hM×£ü`W…Ü¿Â8U»:-m ¨€-½]Þ‹|·{cðg1Æ 8´î&”Ð<û¹ñÁù ûsy„@ð>Ã#ѯ‡t’qèÉ'è„àìtÂ`0 Ç,_f Öþ¯Ù–6òôÎÅו‘Q´;ú«È d_͈/Tü+6Á$‚ætß\›‘+¡(#ÜñѧtÂn f‚o~Éï#ŒŽ§3a9 ˆqþþøõzñ+üü«æÖÂendstream endobj 385 0 obj 1926 endobj 389 0 obj <> stream xœXÛnÛF}×W웩ÀÚî…Ë%û–Ä š4‰QGmœB ¥¥Í–"’²á~}g¯¤hÉ °#gçrÎÌY}CSDôû½ÙÍ~¹’è¶›t;û6£æ!r¿6;ôj5ãhµ+Êü[3û&EL2Ìc$y‚V»Ùu´ÈæLˆ.æ¯Þ?xkÁÇ„Äh!Àh;‹ò¾oË›ùꟘdŒ'øœà,ËÐêaí{…ö]Yßj84s‡Æ)N’ÄZGŸ×o.¯>¬Ëz[¶jÓ;Û Í0Æø:RÅ\Fc`\šðPT‡È &±”Îó½Ò¾Lì”b§îóêÝåêôcÑšwc%.‡¨)†wµILígÉ5í®ÃhuWvÚRd˜óQ¬M«ú}[ÃQw ð‚¶„`SN.NÒ -hlŽ<Û†#ÁY–—41®LmªÇ3TÖÆ]Y—}™WÆ-2ÁR–bé“äö%UmuŒ¹©ª XBG^¯£²;GeÆž9×gÖwS˜O]³¡Y*ug±-=Í ø€ f¼fXJfŽþÔ ‡;U‡Ô]Œœb‚é%²e¢â1Â$ÎÀ™5î¡%h“WÕ8«‰óDÆCñ¿‹Â³q;tJça¹¹ƒÐQ×ìT_îTxWÅÞ´m÷»¯hß—”SuØ4ß:rÕ"8f±íÃÛ^»Ù4ua!罩ÝÚÆó%ú2GžÈ7uHìbÎt?bMÂGeò…ÿðé~étßÏtË„­}Fó3JÊfÆ€BDPO¡fL!™~T÷úPSˆ4ñÔðN€îݾ3EŒfi–zfxhRý¯Å„l´)ÙÔ'è62cŠ'|%ÄmgSD÷v:0åÕ^¡Nu+4 \9Q]ß ÆàŽcîQoóªk\ Ú 4*kÛ¾®T×=à¬ÏAŽeP-É~tê ·Ûg)¢Ü@7¦1æàhÁ¥-;³%MpŠcd†ϰàÌÏ»‡¼-Ö(¦Ò28sK‹ŒºGÛÉ«¦ )NÚƒ—¦|zÚk³ó`¥ÝX‹ßòª@/l×ÖèÌc –m mz¡ô/ðl\Œ…=Ò0L\Ÿõ|áÕí7¥¶Ýù$/Êbœ(Os e¦H†SæGŽ£ØtsÁ  {zxñþ¯õåïG2^sgeâ5$òz ˆì§>à¢LݤŒj – E!ÔrÊÌ /µœlkL}ló}ï'PLÁ} ú©Ö'§°œ½ÊôGZ  ·^f&['†O`}›g–C œz ›Á¥M|Ú×ÑxU·+`nƒ´Ž^)šT>\ÐnËÚÜÍÁXKêÑrêκ»Q-b„’_Ñ˪š$&%–C¼Ï'–÷Jˆ‹\S‡1Ö8€D†}út"rëãu„ [ýÃŽÄpCõÕoìíĬ^ˆP,Kx< êXL £eÌO†t€ P\ó —þSmsŽnæÌ˜hÍoÐk;ÝË ¤¡Éø¶xñ~¹~¹Z]Y.^¾yói¹Z¿zy1 Z†I€n’¹ËîrG6Q¦09]õƒbKଗJÍhVS ;É\Öã [|¸¶E÷ùr$È''Œªr £ÝÜ«‹tèKd/GpÇnìN£{ Òo€*„òµÕÊ%G»¦ÕÛ¨ÏË ¶“pSîò[õe¾E€Õ¨¿EHMHŸ”2×®éÖ’WP«#n«æ&¯¼œ˜V'öAO!W™º{.Oü·:Ñ5K>œD«]¸DL%_rZòùliRñŒòDµW~)µ³P rF^XÇ÷|h–!™DðɇüÆ£ÃÛä§¿vN¿×[®fÀÏÿ³=†endstream endobj 390 0 obj 1918 endobj 394 0 obj <> stream xœ­X]oÛ6}÷¯à[å¢âÄoê±kR [·`ž·>$ƒ¡ÈT¢Á–RIN‘¿KR”dÙI:lH'?.ï=÷œCE &(±?ýg¾_ü°Rè®]$ènñuAÜKÔä{ôãzÁÐ:‡Q„"ø] ?“ ª(f)&Ñz¿¸ŽâtIEÑxù×ú'XÏÏJûY1MNŽbã·‹¨¬:´ý–5ÅænWßf»MQ7ûÆ7Ñrý÷‚j¬QL¸zᆽﺦ¼=teð×;;ʾÿìÇ®¿…qWEÞ6¦;4Õ¦.ŠÖtï–ol<È˦©ôÖØ›%¼œœ.ö;ÓÄî,0ÜMüro*Tv¨=ä¹1ÛÖm?9I$fL!7-:.ØÊO2)%Ö‚õ“|ÈílaN°RaÝ‹/›‹Ïn®~ž-¤¦‚4Í\ÐYµEpüù’1ÓS:¤÷8Yó1j¿4Á‰ð©îjÔÝX=ïʺŠ³ËºÒNZÚÖ>å˜Ëa'~Þ£Au?ÌáŠL‘öç+ ûÎAGa™R’Î÷…QcÓšª3[tûäâØš6oʇ®næu‘ Rl3;£p¼°éö9åXJä sÙ}l-Q]¸=3‡Ç%Iqªudqykvuu×"Ÿ×ÓP´ÂŠ÷;­.?^®.ýp9 G*Üç,ˆÖ°L3IraSå¦Eù.k[Óâye©ÛÃ÷ìy%–Œö{@i™‡JžU>Ê*;\ùÇùBp¬ÒÏÓDa"Ós1ÅÊ­cîP6ÔH¨»ì§ïæ•!0_¿’ ˆv –ú`íé}-v‡9¼SˆP %…–ùxµúeÉÛdÛí<„+…¢ø¨g­@EýrP“I¿¤˜P9§IšâpvüÉŽ’a±lG¾oì#å^Ò1ç×Q›-I°PiT™‘X Zé>ùÌO…Ä8^ƒ¼ «ÅªîzdÚÿêÊôvÕ$)œ/¨–b!¹‡û€¶l±" KÅ£O¶ =[ÍAÎÒ$?æ«ËÕêj5K|Jp*9 ‰¯cc;HûòO0d)¤ ÿ>â è‹ 6Û][Ÿò&°çù¸'âY 1cÎnë˜óÓG3Æ@&Ï]Zå ©$¡û(&©ö¹\C9òl·ƒfÞZÐ=Ó™f_B)¾Ý—ù}èpW¶ºXý¤À¹QáÙÎ&¨.{xؕƲ TBj¨º¤nåâP¹éóZ2;úÆÕÑÉЛc¦öñ"Y¶èКⰳxCuœgcȳÛÝ@ýþè~áàR ·Ò4:”×ÕQf5 E±×RÛt-úð:#0°% MÌÅy¡–6ô+3†lõM½wýÓZÁ¿GY‹.œß¨Ø†9½9(†#°5~Æ à=Öo †z‡Z3åj -æK¨aެ•õ7VÜÝ>0 Ù-”¥XŒ§rež¤×s7ˆ®TôLz˜@kC~7]¬Šg´‰Sx€{ƒY¡Ä=P ›?š³KÙ…äú?˜¹ÑÄý?χC{g!¾ËßY7£$=â“ç}âô(ƒ2¿èóˆ.ºá9£30ƒsKÀºˆ—œ·â¦ÂƯú<)DФï±w‰¤$ø3Jøsþ.Iè+ÝgÏÁ_²wùá\D$˜'üá Ú‰3Ö}ž®£¾ÑRÊ]£Í™Z• >çlz@ÖØ@V0Zõ*Yè_˜’ïñ…)öš‚º§#[:*Ÿ»?°²bÈõ9ëG¦KX!òn7Ñx4»P/å1eí Po¼«AºÐhn¢ Ïù˜;™&`F´ RûåýT¦…ñ¬>z†Þ,‘w+ûÏÌ®&â%3pS:¡“øÙxûémδ%¸K(ýB–ŽÃÉ5db[6Ð »'+Df p’X£úæqb~!,ZL|d3?˜Íöä Öo`ì×oeŒÝº7ÞºÇ,¥Môá9±Ð?ñÔÝ—Õ8!°mr*ÓžÞ‡b6#§s®N§ÁJ\žî$ !‘ß'dÎÞ°ußúŠŽ&iˆ<ˆõ­-´’K{eàÚÓfͺ]Bs' ¡ÐZhŸ=¹k‹3nù@TBÿÉ3ê71vsâ7¯J‡m[£Óþ}h@é snÎRˆ°rYõ7FȺä3µÏ³Ö™í1 ‰L£¹È r"òúT䯽Ê÷<¦ ÜUö¶œØÌ%3ŸQëb˜û¯Õ™ÀØQfßÃ"è-„ €é‘¾¹^}ç‰Â½œ¦æ¼JÏûH¦a_úßÄ@‚ô`ç>ý®išŠµ™÷rýš6+À~XÈÅ{*Í1ÓpÝâ ÅÌ ¶rÀôD2½ˆ>²°bêÍ1ÜôàÉ/€{šP2ÎV‹Àóïâ.׋ßàç(2{endstream endobj 395 0 obj 1791 endobj 399 0 obj <> stream xœXÛrÛF}çWLåÅ ÊœÌ  ö)Y1^%¶U+Ñ›9Å‚DB Zñß§{.ŠÉVJ®"MÌôôåôé3ø0Ê Ã?÷™fß>DdÛÎÙÎ~Ÿqó¸ì@¾_Í$Ye°Š ÿV›™Ýɉˆ•ŠDR“Õaö,’¹Y ó_V?‚=»+q»‚Iʘ"‹Öç³à¦)ºSS­ÓDùÊQ‚jÍ|Nm1ÛIXRS)|ZƒÛŸ×·ïÿ·^><Ü?Lb‹ªœ×xÒSP;ç!d”ó€P-¸Ž©ŒD"¶Yà:1®ÝW9Öm[>ï i·K;’AàiS¶ù”ð•ÐüÏÖvgÐiÈ}u vyŒK¸{ðük‘udƒO+"”Ü×\².—p2kŽ8’cšý–n!Ïsž@&9>þ<'^ ä¬1"Mh$&“¦åúÃÝããÝÇwëËåíòv}»üþÓ»5"cý¸ü÷êîþ#ú’P.“IŠØ'œ>Ž£‰9ëÁcv!0³ÝC‘V­I›E9Ó°§G9Ô!²pBø¸4â!ÚWŒŠØ•ð Ó¨„  ‚†t À]¥]æ„ÝŠ™Ã|mæÐ£Œiiòˆ=”PMD%4Ë$e\p³ÈG™ϧík<CÇx ýqA •,늒ŸwE…;"ÈrïUP‹ Ïï!qªã¾G PJô- Ã^,}œ\E†ÅU pòàZ±‹;Òí®>ís’îÛš C¦u³ºæ;ÖUŽþYJBMŠy ¤“8äÞ#;u)6JZå¶ÔA•Ä=Oí” äAå/i³Y·E·îÊ"_çÏÛÏÁçù$ûXJ…Qá ,,Rge ¤ˆáØlµÀBÀI]ºßC\Æ/“@G}Š)sLi¬t9 ËŽ‡[˜™Y…æý,øüfþÆz¼çª©•-„2øãLKë²Ê‹9GúQ:øÏøæ²wa˜n=yÏtÄfÈ™[C¦q"ª‡Ž7‹¿3SGΓ·¸ Ÿ¿ŸEÔ‚Â.ûTµå¶‚¡wÑqh)}FÁö·6}æ©ÇçÈÆÒôûi{[·…uHŒëûº÷uP\å!Ñ8ÑŽ[€ðþ+ù28Kâ Ý—9üDܸ çbK^ÊngÆÑevå3þpÿðaýîã§‘KSØiîgIp!À L5> $cmMÍ$²O,µQGv"ÚÑãæÔ Gé©2ŒBéosΈ©ì†i€?6ˆ »UT!`@†}·n†nûù4õØ`Ë‘#£qKòÓáX4`»Þ6éÁ H!¡éBá½ÄmÁƒd‡nµ§,+м};U œü0@¨þ%CÃõüá”ÀýOK£jp³“-¢A½yïLÍ÷{nÆ]0-©ö%uÅóŠÒâѵJ”o†Er¤è‚¶*cÒG„eEm`žD#ªuý~YU¤‰×¤ p`Ú¿n‚ö^Ù‰†$hØ<” `{¤wy½( N‹ò×òìš2ûö!&\š®å ú€z¡C+6„¨ &hBLI!ÆPŠØ›|¹¤aŽ4ÜvcÐMÙÁY¨¿áÞ‘™)õžSë+ Ì^e^rεof«›§sj/„b@–aÿe›ÓéQfÏy÷‡ÚjSÅ/ªÇ°@:!èXÆA•ª ô¨f‘Ç[8GZõ2Õ˜tWd\“ N“¡þ†‚'m•Œt–gKHçEg Gqr•u1¢pbI¼¯Ì…t€¬DÞ^)1D0h=ùBIšò\ ÁeqÏ®_F :ÖBmw¥¥=[û]Rî‰æj_œw%Èê¦Ø¹î¡îóÀCìzcç"O‚ 2q] ‡šk˜‘F?*Ô^à@wQG=dÀãØÞUï6–ÛÛvsÚ¿µw<—›i9P̱ø ÕŸ7ݤ.IL•—ùט>¢j€ã5¦_H½wVJà{OTìôÙO û>õÝ8ó#²Ü5õi»{…SCuyW½$“´§¦c ŒRX²c0ü˜Õ ü’Q´rw™;ûÊà˜¢©dKeú/¯A"àÅ{—žqÒ…ýU„Yæü"b.QÂ÷ìäBƾ¨0üÆ\¢ªÚË/€™Ñ_Y}8–ûÔ íT•‹cfê¬OAVCìsó&€EöþåÁ(&Æ…‰iŒ·~ÜL(õ\¨Ôÿ1ot/áœøà%°n*æ×‡Q3Àö¯<‚/rÈ“'¸øÏ‡ô+Lðј†À¢ž]Ï__-W³ÿÂߟè¬wendstream endobj 400 0 obj 1924 endobj 404 0 obj <> stream xœíXÛnÛF}×Wì[(ÃÜr/Ü%ÚÒ&6ª¨ »(iu)dÒ!)Ê×wöÆ›d'i^úP8€qwvföÌ9‡þŒ"LP¤ÜçâaôÓD¢u5ŠÐzôyDÌCä>èítÄÐt«EðoºÙQI1ãH2¦£» LÇ4ŽŽÿšþñì®Ôí iÄpqư~9 .?Í.ßÿ1»¹]ÝL'ާ÷!ú½n[¡¼¨Q©ê}™«%¶ D˜ «†Lê¥ ÓMŸGÀ †–z)8b4±Áî‚ç¬\ÍVcÊqš&$(ʇÕ.[ß÷c“u7a¿2×{#z›×hiƒ4{õ14Á°’p[šYpQ×åv¾¯Êà·s½J?-Š:s…Íæð¿óñÿðª,‹)ý¹½éö&´‡Ù´Á•ýi£r´­Qµ_,”ZVç®§¾"U'±ïë° 8ep4Å „¶ËmšÕ $—8容þFo’)改U&_nòÍò%ªT=Œ²„∷í<ë´h:I±L:Â,MMäº@õF¡û ÈÚçÕv ÈAóC­îÇH—‹žÌuÄ Ž¤ÝÌšÍÙn¯0ºÈõ ÷íbÄN¤ïÅÁ<3'1¬8J࿨²€sh °¨é°èAey…êN0x3³²HbÂYSðÅ—6¾ RŠZÞm\Âi7îjœâ4IÍ—•;!ô56ÇÄvÿ­‚»Wˆ¦è¦ÐÇ…À ‰>RÀøáJ}Rm*’l*M˜«ôa®JD#¸z³ú<&ÌdPìwKT仃ƒ8P@Út¥Þ”Å~½1—ôXÀL©Ò¶Ã†]Œ¡ÂCõ|Þ&AqÜô;Ø×"«}úÔt“G@Ìwó9³7™@<Aß$€ÍF¨²Þfý0vˆvv§=Wâ(‘iS½Ž¥«?T(CU]fùZéäkà[xÆ’`)â` E^º»Àœ[Ô,šIütÑ“à8¦í)Ôž2¹FÕ£Zl¸ts% ¶‹¬Þ9ÚdÀÎFoŠ€›J%èÑ+RŸ+`ŒÅNeeÛGÆc,e۾̀c!ø½Az…+‰ØÕƒAМ%ǃ –ÀÓ¨Õ>_˜ÂªÁO©‹²6@Ñ·›WŨ6×›Õ~·;˜òy™5È0Ür@·«#j('7p7“Ç€hhBqØ«—­‚Q‰‹}Ë Uý ã3]­ªà¨#‚ÔÝìw y5™ÜNŽ™ŒûSrdx_Ëv¥k~Êð¥jucOó³ÐMÖ›ò˜cNÒÐZÄŸõ¸‰tÀH¸¿RÛ?P ßCf”b©µò”“oTâý2«³+ÅnóP‹ ”iV¿¨ÉÓ΂߽Xœæj=ý›íŸ4-ºìcw9´ãôÛ¨L'Š×óþu…Zˆx£èljͩ; ¤XÚß_pÔ‡c5ç´öª‚5¦8†`=’ó„cÖzQÃ%fz$á¶}ÃÔ"Ž)kX3ÚñA`¦YÑcrpgßG~µ>xêÐ!éM¿f–ÂŒ›Çv>& §) 4\€‡JU)P*í#Lb†s/0‹KU-Êíc]”ǽ)yedŽ#Ö𧌘åOKH_í©ì$5éÍÕ®È×r=Ì%ÖÇØÃ¾½ù8½¸™šT|°s³ØeU…ѻڰHÚíP}+ ½àïqî½® ­òÔœdÓ¶YC{(guuXˆ1MÅ÷Pê]éãXÛ&8sÄ€Äò<~£z$ }ûr^ˆ©`Y¶Š:v-89d 9¬AÝ×Þ‚"îå)0­þ\M‹k¥sI¼M£¼´tå͇æ—þá æƒÚPp»“kŠô”÷ƒ€‰9ýJØË†/!À“2emõ×·“3ÍY|P{  ã@‰œ“’W鲬Òe¥¶žUµƒ0¾^g)È–ŸdÆá¡¢{wÝA’N,Î?ï1N»ßªtVOF¿»<ÒÿŠ?„îrs3» ü³çJ“„„P¿ÿÐI€w¸@KeM%‰cPÔm­À¯ÛÒc—lZÓñ‰tÊ>²©W@O[ú¡ú‹P¶ßj >vŒ¼öõ¥tVuyÜ3ž'ßê. ÷ZÿC& úO›€ê´ ˆ±ð¬öU¾f–|`>¾fR‚iûâóÝÀ‰ì‹ºªæÐóúM^³TG5™žQ ¬óG”.#ÂU!øæCv@4¢¤Ý-> stream xœÅXmoÛ6þî_Áo“ƒˆ_E}L›tèÖ&˜+¬š!Pd:ÑfK©$·Mýޤ(ɲó6`’À±EŸ»{¿ ™Ÿî5ßÌ^-btÓÌ"t3û2#ö!ê^ò zÎJsXE(‚ßt5s; ¢1ÅŒ£˜I”nfŸƒ0™S"œÿ™þö`WH#†£ˆ£PÀ¢å,Â4V(ý«u]W5ZÁ_{«Íëµ*«]ëuUÞ˜wímÑ |5 ž‡‚2L$ ޭ쎦ø¡Qåþ_fm†²¶­‹ë9Ip¢â`ÛjTë•®u™ë%* Šp”¾qÂ Š Ùdëµ6²rjuþ“q:ñN3‰c~ƒÁé·¬^]},nJ½œ§ƒ“@dž¸…æ áÜmïïô1*Ú}Sn ª [o5 ƒCoJ¤@B±¢±ÛÎüöà{«Ë¥^bô®5ç …ÂI‡¦Öí¶.›ˆ²DaK§ èOW§ï¿:[,.Ð*Ák‘C[“Ÿ¹8"$À\h×…TY{çÚX Á_eRM– ¥¦¯ö¡e!˜på±ÖæsË ádØpУÊûÙ9p~quvž.þ˜ø@"ÞÁ’XÞô¸ßV6„˜ØÂ ˜0êS»™`ÎíÃsû‡ŸNð Ñ}N)HÓâ-EY¹D»F„Ä‚Ó'ŒÀ^ví¬wÍÇ™8³úp4‰Š"§ƒ+>†¡×ùµÊ,ˆÔ(ʶÌÛ¢*'´”såñìù 'Lº @öh§5ÊÀâI—ºøubI*L M†"En§¦8ÞÔÑ8^s!cÊ4c9žX×A53(VȦá9¼™œ@"k=ŒQ¶¦’\‹IÏþ¦­·9€Ñ(¯Ê6ö…†0ƒšDD ËVÍ:Aî´Ød‹š.¦<Ó36ïÐU1c½8S×kj}WëFü%º¾wê®›¼.îÚªžúÂ!ûÒ‹²9sâcXPé³]¬†Qc'ì"Ð.⨃iฎn8îæ‘Æ $z‚!‚‹˜çë÷o¦‰7ÕìýEvþq-Óë9çTŠöCƒˆ]%ÀluJü¢IIÂÐs[ „-»Ñ%–f-„5szîÏí³À‡®Ùæ¹nšÕv!`ˆÄeü‚JF%‰0‡íI·Õv ©Çj ø¶gLfUž™FfxšŽ7†WLNÆ›“«>PnfxÊ'¤öl9þ64z˜EâEv#×­.!ÆÈ* øbKJ7-º =…C@äyDv¢±ÔÖ…C±ð³ 4¿n½œ{2І;ùhÇùf»‘ú¸)ºÐžôðgJt ÈâãÚÃÔ¿ûùâ# õ»ªºÍêeÇÙ}HwveÇëͤ”Çr˜¢OéMzC<íƒ}'÷¹Á!ÿŠ>š *ÉŠ£à¾Ôz@p`Â0…Ò‡øh'V{´åÐÊû»M¢’în3ÕTn×ëÞmŠ23]Ç™i4)¼8 : ߈ºë—íPþHohØFvú¹úI×Wݽï"¥¹K=ª!TÄ=ÙR‹)ÿalÆTöÂ|LïΞœ EÒ9ƈÅRFëç_é„©eŒõ##¢§ôÚž¡Â«}ux˜öp×Kàl·¡S‡Ý]9 OqÔ—¬„¸„[ÙÀ(uÊ,!8ýUn¤²£¨g§}mL/¯àÆMÌè¢Dð½hZÃÏÓŽtþö'¸¹> stream xœ­XÛrãÆ}çWÌÛ‚.qŒ¹aÊJª8^¯b.}R*)8$H dåëÝ=7Vr\©Ý*‘DOO_ÏéÆo$¥Œ¤øÏÿ-·“ï皬»IJÖ“ß&Ì>$þO¹%[LY” Å8ÿ‹ÕÄd„kN…$Zdd±Ü$³|ÊUšd³é¿ÿ}îTîOÍx*hšJ2S ¿œ$uÓ“åSÑ®îV»vÛÕks›L¿N”¦™1i….¬Àyß·õý¡¯HŸÎP Ÿšh ºŸ‚ØÐA¾›~/RjÀFÔÐVý¡mîP¿=8sý)¿ñç/Ûvׂ‚3išTøívj9ò~æìãV»¤½ Yš²¯w ^sä¹–TdÁœ±Çp“ŽÑå&Pzl}7Ò(™—¹øzwñé_w×?Ž4Az2¥r/U4KRîöuÕ‘l5äþ¹¯l@c”ǧp»².M×W¤ß‘bdB¦©á,šã?¶A¡º Öõí¡´÷í%3HE°/–.õ²Z‚ÖÒ²Ølª–Ô+û #GvîsaËbÊá$S*Áú¨;›/[lZ¨Á))„u Ž¢Šq@¡Ln†€^]Ϻk«•­NÃi#0C3øÕžše áªñ6)ˆ½ÁöWTq|”Âú˜TÛ{pÊ92­¤¹ò¦Ì/¯.ç—Ÿ?^ŽâšÊA“Qi¹)ºîvJÉ=ÊK 7 3¾ºîHÑ[Þ W&J‡xAå0c…cÌ¡î!䶸sN¹Î¸SŒ²ÚÊ>÷u³&÷önNSiBDýÈG†> öFÀS; ¸¢þÖ„þ`Á"H1üÄC±÷m ?ã4 yµ#e~ÚN—óùõ|uð;e:Xà}&±þRBwã€cª  `oBmA"\|rhP°1…¿‡*b ®C=`£‘þy_‘CS÷ ìû¹!LX+5ª”»į̂¡,#K‘M÷.Þ$a¦¼Ê Kà¢ê÷}»Ù•m<œEX‡=¢9O±9ÿ_áÙ?ÿ¥A(?¿#­Æª9ãO!üŸ}k<4@à=\ýŸ»½W<³Oþ?èͨÌÔ{è @§"F%¯å%‚KÄSõ&‚ MµÉßCð,EÒ'­u\ƒPÞU½òþɶ›{X"àò,æî‡>È \BL‹Í¡ê\õ¦Hœ @©µðßìûTCÕvXœøò¶îÒ4¾@}\"{`J|[[€Ë8•F,ÒÚeÝ‘TMß> ÞáR Çò®©pæÝ$#Hµð@Ä*1D*1‚Hc…&Xöw G€”´…OYÈ!TO¹bV&é ÷ljªaб,±Õ!8L^…ZÆsBo{„µ‘I)·V@µ ì{òþ0äœQ¥Áü1ƒ»Båòe@b<ƱHÍi$¾æ{xÁEÁßÄ]ކ³÷q×ä4TŽKþÎó—GY²3®1þ|èocŒ;pÝîP–UçšæÑ¡#Ïm'`3ÁÏíî°~°|<®œ<¥Jñ“†6îýxÈÄŽ5Æ1£ï!¬Î£ØÆó ó9ЯtÅ™(”ˆ“‡8Ñ©(–€c Eɵ5Hkä¼HÏÒU£`è8ÿsXQâ"‡=˜1¤ ù<ò¹p½¬¡aŒwóèr)GÞ3Ëfrð•Ô}WmVÔ›úKêo²äºê‘)1 ‰òÎMPš'«æ°%Ž~®ðøG<î™Óê>ÒiáÑ «‡§­¿›œx„¯^’§}Ž@W!_ÿ¼[­ q02ý·?›Á‹'äç®÷@]¼$?ÌÖ¯‡®€Tú)d7g1‹\.ÇÕ1Ö°PsISWMYa7õýÒ2T, qÖµ “râ–ΊžlëõCOžêîKòo¯`Ð~\¢Ö»\öü…3:G+W44¢ û¢íëò°)Ú@^© ¥âI J¾1Ä, *ØTޱjð ,çqÖÊóÓùüŠtûª¬WŽŸOj_ÍËÚÂ,vÓé¬>Øyd4Š:ÅÖQ…räãC±Ç¦Ñ–†{;P† úûr™ÔkXµ ™½OeÛVeO¬›à–Éñ„ŠÅàŠ&>1:8 u<©â KãÚ77Z¼D‹»XãÖШf—¶ÜæÿÑv·‘,qºCû—»í¾Þ¸˜á< z\|÷!jæ<Øö¸ûñmì”5(“ 6ºa Ì»Mxœ…pYõag@¼®C0Vîå•îf Ïaýýz~\U̯øäåqXñR™åïgDþÕãh¾s*QÂVh)ÛPWÂdñb÷„i#¦];£\+6yØþ¾‘bø¬y—Êdè“nÄUƒeXé¿R.ù_k°(Q"8ÿ{±Ýoª³ñ› •s4Dž/îšb[Bd`ÂÍüì^ L#°S‹È%¤-†éÕÇjÒð604Uo¶Ù0fØSnæžCõ(l{ì ÛÞ¸×\ˆÃ…qüÎÜÜ~“Ü&®0¿¯ûÐЩҶ¡áwcŸfÒ?Em8D°4¾´ðªðÀëqiG°¸Ê½µáÃü(õ¥Û¾ŽWJ)î 3®`TȇÍÖU¡{!”tãüã¦ßÔ¿vÃÛ…ÕȃÜ> /ˆ`”YÀüÀ]7Ëqy> stream xœ}WÛnã6}÷Wð­r±$%ŠÔã¶IÑv³ êxÙB%ÚV+K^]’õßwx‘lËsãÌ™3㯈`Šˆþ¸ïl7ûq!Ц´™}QsˆÜW¶C?-gZf E‚¿åzf5)b‚á D"ˆÐr7{õüxÎ8ñ„?ÿ{ù;Ø-Ÿ‘"ŸƒP># ï3ïe«*Tt¨Q]ßTí|ùv;BâHÆÜ€’w÷’üò´ø”üüðáù9ùüøññéåÑiŒAñs°m5º­Bë¾Êº¢/-j‹Ý¾< 6=ÕF»Íê¾ÌQUwڌς3¸†OC¥”¡‰2WjvE¥¶˜ÕM£2P.Ó¶E›ÂèB&¥¾* ,£Ðð¦ôa` Á!Å4®S§&?üÒ8và"mô q0¾ÖÑpÍ«·éwªêZ´oT *ÇsŸ‹‹zÏõN¡¾UÉ>å1w†ý\­µ]c" uoáZ9J»®)Vú0Œqg}§LMü2ErLIË®Øl;´MÏ2LâˆA¶Îoºãu¥K‘µ´-ômêU©vØXã1æ:DŸI-Å1hÉåII§h)Î\äù{Ú¬“ê’7Õ´ œÔë$/ÔïË|Š™˜ãp@Ù«·Kh¥ÐV•ûu_¢¢Bë9#˜PzEYjäÔ}gÒë3A°àgYyõ xT‚<çc¥ÖuƒR”¥e‰ºÚ¨žÄM)‰.â]b0v-f.ñ2lÏ$¢>òYc („>hØx–ºD¹)r„IÀ$—yÑfMRmwânÑ “U+ªåʹXñîŒÈZõ”¯6·‚pô0c[xX‘çNÐÍü‡el¼Þª¬³÷58SÑõí©3OCžØø\µÅF#Ú¨•ªºu°%îÚ,ùU¥9ºA9N, -¶]›V9jU75é2Ä”ŒyñnN+2± h5G†À£ð¨-w54–Cô–!hsÕø:€•n¤ÔŒÝ†:%¦DÎÁ€+=ì{Á‡!ŽŽù¸¹†”‹¦…ÊAà #‚¨×çAk4…jMkSµóáæ‘ F&¬«ò`b¤Ð³bÂDY“ ¬¥û}Ydéª(‹î ¡vl½ÍaÊıôÒ²W:ŒtJOŒH'uÿ°<ÓôŠ€<60©*0nbÉb=L°¥Í€E˜ƒIl˜-Œ òr[·jˆ ”tX-ÌC3Ô4ëj"m¯0)ƒsyö:‡¤¿†ü(Â!Ø·n.ˆú–q'¸bõ:=GÐOt(™ž‡¬Àì&ûiÖõiy^ô7Sm.°d®Ú„ÈPç£ge6 ‰);±o…´aå6!‚!ßRX{”ÅI3°ñ:+UÖn| 3¾™ÙÃü7{‰å¹wŒ~3áõ’ÐÞÁÐ^×Ç»„z‹áà:— Ï©äñ)¹\.þº@Tl<YiëÙ³>1 ZíöÝÁNáv«b˜“! ø¾9Õ Î)û¿ðé÷Â÷Cë8ò–»Âýbñ´˜Ä/c|¶ê@ài… Ý£:3šÛÇHº–€a!\G²7L¡§ãûº)æœyikù¿mu[h’¡‹Ý"† µ8€ÓD“³qh@J«•uµ^­`ȨüÖDpAá„cJ/Dh]k JOÓ-±nôƒ^à’í>Íü(SØk-¡–}­ WlÜ,ìfí¶g2òÓ[p,ä°÷µüó ;F=* è/1ÒÕù—ûåìøü ö}»endstream endobj 420 0 obj 1455 endobj 424 0 obj <> stream xœ­V[oâV~÷¯˜¾$Çß­¨•È’hÛeA%ÞFÕRYŽÁ­ÁYÛ$»]õ¿wÎÅÒ$ÊC²ÏÌœù¾o.|Ó `òú]﵋…ÛJ3a«}Ѩ8õ³ÞÃU¤Ù­ÑŠZ€ß(Õ¤'Ë· Ûßö ÚkŸÉ(Ô-×$ÁHÿ#úE™†åpÏ‘eÚ†i:0rÑp£‘‡BþÄûðŒRÃ÷L ÃáÁg’m€éÔEkê¯Éþ>gñ&«ÖeœgU½$“Gšxjû$)ÓxÂVºÅŸC‡·°Ym‡âj¼Ùo¤Ž ¬©ëHÇŒÁ&cÒšÛLµhð«q]—ÙJ§¡†%ÇšA‚¯t›¿°m"ÝŸq|Ÿä©0=÷/]EYu¹‹Ç:EPaà‘¨'»!‘Ž*¨vÅ1ßÀŠAÅjHËbÏ yz`U¥Ÿ ’ AÜ'%;Ô€OçºËI³,‚êŸÃ=+ñ~I—áˆb¥V`Ø–ÂJîÆẪPÉâÊcŽ QE!o¬uêxF´ÔOáÙm¥7XÃà+ .dB6æ-‰ k šúG/®úN aZk#~—£®ádžT“z3_|ŒßMÇ··ñ§Ù‡Ù\·¹í’»Ùå«5÷ £;6ae•Œk¾îQ¤8$¿)*WÙ߬ó"ŠðX"kâÕ¹†4«ÆSo7 žå‰˜[ ñ Çïª$â"EºØ’ 8> stream xœÕV[oÛ6~ׯ8O)•Ê ©»Ðå¡©´[ÖlŽ·aˆC–hKƒ,¥ºX0†þ÷R’å8KÖîe_tH~ßwnùŒr`òÕG[íbæÁ¦Òl´OW‹ÐE[¸škÌ#ÜÅMÀ¿ùZëNr0=“Z6x– ó­vO&n:Œýù÷èOM¸ãPÆl˜8¸)ÖH)ê¦Ìßèó?qÍ„ ·•ù³4Èß7Yå‚4p ì 4ð„eÉk|~ýz¡Ã_ú+íèpš×И¥¨Ôéi~~O¦­ÎeÜ HX®—ïÃl q½Ý. ño¶Ý¥›\Äg…Ú¡¨û °¼ª½dÒ¿âfzÔ¶Ì~¡gÄjYdÏzOÒMò"Œ_òªÛÚáŒQÔñë  -ž‡2ÞðŒé« ¤kX´jú]½èîèn<îÜ2ÏSnã´ŠÊ¥Èër¿l$1C¹= יЂq&©I¤Œz¾$áZÔòøAiãÀýû¾ÝÛÏ^C”åBWL•2“À¤¦ãcB‰ñ¸M™ï ~³J y¯/Í~ðM”ª—)ÅÿŽR|Bé)›±ÍâÕÓ^ñ 2|¼]^œÏt×–`Lòû3J|Ø>U•®2AOúý¿¨‚µÐ*.Ó—-«K0¦¬Õè´NºVh@˜ÇÐ&i”ˆ>q¹J\Žb¹¾ß'è8åö`/»N¸Ô·­k8-mkmèO\¶0 ¨5 ýG¡Êá´–¬à+j©£Úõ×MQC%jÚU”O¹<=€ü©,Vá*ÛC>"î¸GÍ‚Q«ƒºP÷a³}tß=IìtSæWà“0k0#¥ÜÉòH›ˆRP¾‰gQçÉ]º}ÈDaUËà z=ó¾å›(]ßóïI[«[4㈵ØÐÙÆSžq‚AÎvAFðu]fþŠvi$Ñã–‹KDY… ½ƒÊQ ïxœµi–AŽºnD 5².QèZr—SÞåŠ;Äø® µž‡˜«âûHîæúª×*°ƒN+ ¨Aš…%†‡7‘ŒnJv¢‘Û\À¶©pÎcû/ްx¨Ìt˜È¹…\»B˜ÞÓvñŸWî“rýgƒËÔ4ž ERÆÏ+‰ì¬£¸ö6ŠÔñáÇp&3ù˜HJîÿøµë¹ö3¾¾ßœ‡endstream endobj 430 0 obj 979 endobj 434 0 obj <> stream xœÅX]oÛ6}÷¯à[•¢fERŸm“¡Ý²s½C2ªDÛÚ9“ä¦Ù¯ß¹¤(˲Ý>lÀ6Bòò~œ{îaþb>̧Ÿî3¿Ÿ¼œÅlÕL|¶šü5f‘uù={=Ÿ(6ϱKH†ßùrbO &£”«€Å*bóû‰7ó?`›…äiѾy1ñ|ŸMiéå,aB‘…©Äç4LiYq²ùãÄ‹xÂEÊ ÚDÜW2é ú³a=¦6văDšÐ?­uÅÊ–5»<׺h^Œ&ü”Rv9>™¤>É}é#ŸG‰;SëvWWÍÈn y⣶vÏå§ÅåõÇÅÍO#KqÀeâw»ÈiaœÎª‚5ºÛœª$8D_­>¹#³QÀjÆñÆ<Œdâür0hÃÊäaÌ#g(;I®«bœÑˆ®8¸Ê8v]Óï8Pä·^»eíZ3S‚ò¾¬2@÷Ë… ¹/"åe›nØ h×YËq¿Ïœˆ‰tùÊ鮩àJIrwHÕ§ìãAQä»S›ò(¸¨ú8G87WøüˆD£qwæËà2Á}™tÆ”ÙC•6ñdµfë‘oG.¤šJ“ý©Èœºx³ÑÕª]/¶»1Au*ƒQ.~ËËz{ϲÑ] ž‡=b‡°)›öT(Ù£#Ï6›.íQ .‹\'zï–ã´*ð¥Âã‚cPs8—ãN ¡ê|E¥KžÔfÞ,6Ùg½aCl½ÞÕGˆE]ÙP¿±óàóaÀÇКqö”!‡my ó±kËŽ–û[©ú6}fÏùÜ .Uü½äE ÷ƒ =›<és;U< ²WgÕJŸÏžÏefÂQ ”¾A1&Rä#"º.{ÔûŽNT8°e|¶ˣ2˜Ü(T"[`ÙºKŒ™QP¤ü8ùõeB{™>í3÷vW˜Ùþ~æò?g òö¸Ö¦>Î/ÕÙÊ Œ’]'9ºbZ“{“5mY­€°~3ÕµûcÕ¶eÙ¦› BÚJÀNôâm_"Å“ØeâÖ{jØjKÆapE؃¯5€7fnhg*Ò„ÇߤWÐæÝÙ¡5V±êg}ulˆqÒ”…¶Þ˜ráPI«R8TûéK1'¶¥ ~.æ¯q‘µk& (½[kÚ}>ȉž pßrWåö§•ÕT)eôG¯Y­¸z³¸z?ŸýFÛôÉÑhöÝåü†ö„n„û¾Cs5 (¸ áf…ÙM„C´lÏxE§„龫Ùìf6J~Š©¸:|óRìg¥Ñ½#3ÔŠA0pÒv<À”U"[òзž1żV×!á eåÝhs/“â?x›v„÷wž&Í¿|š4ÿ×ÓäÃهɇÿàY AÌQØó5šŒ~ \‚vOh?Éãýóñ,۷߈{áèÙÎ÷Ç]xëåú¡µRú”î¡fÓNtC¤Úf—!eÐ ´I ª.íöd'ÝI3à(VÂÚÒêuˆÍ^‚„΂—åš³7˜A˜‹†;"t¦“yýEݨZëüÏc·©žF ¸Qf2$} ÃQxnÆ9¾áýó<0oiÁï°Ÿ²ëmnæ1*œøÔTnÐÚð¯!“Ù̓®Í¦æ›eŒúó…ô½Ý xÊII7N?öqÆ:”€‰-ÕÜZ˜"ûvé>žB2¡\¡ÓkêÊÄGhª5p1Ò¨R¥ GräÔСcÁQ9c³ÞhËÊe»Æx°j0 ÷‚ BÏ>Pj½Ôµ®r#,)»˜ObŸTšO—Cíâ‹4u÷:[ï®8{e|TP’ýäÜ_†§ýšÂo [0¡·Õæ‰uò©›_îþØÒ:IÓžºŠƒû¥{ó±-BÖf̼˜ÈØÅ$²T^¹Xçe°­¡| ¼E@ºÆøÌ OuSäçÞ…ji8|p3üåçì‰Iø²?¤¥±;þÝÿ1]Í'¿àç¼þÀendstream endobj 435 0 obj 1763 endobj 439 0 obj <> stream xœ…“ÉŽœ0†ï~ŠÒœ /l¾Fš(Š&‡´¸ÍD‘ M†¥L“~û”Yº[¹‹]õWÕWÅ0ʹs{æ-y<$P„AE>_6a{ä-|Έ„,G+.¯¬$«'+*CHd YK¼€ûÙo”Ac.¨R±³Ë â1Û —D±[dT¢ÖL^¼®‡ÙWhFÜÓ¨;°G3|±f(}Î(ã,õtnF°=TÆ‚Îí¤ÐE1˜q4#õf߈cªøpå"xÙ¢ÖÖÕÑ›¾\•Íh¡.áÒO³ã £¡ˆ¶œug—”CžP‰Ò½lä/XX ÿRWÓàª^¦W¤4ŒÄÆÄÜ jˆs˜î°ú/Ë}ž¶Üú*¥4å×¶ÎÏ7Íô~øWbëøã„% ñGjáïÌUKÊäžàYÞÄö ¨H?¾ã"˜à7ÇÇ+Ù=ÿû>eäžÀ€²endstream endobj 440 0 obj 565 endobj 444 0 obj <> stream xœ•VKo›@¾ó+¶‚LX°‘“Kå\ÚTUSÚê aX(†dÁ‰Óªÿ½³ÌøN„¥5;3ß|óØYi`d²G®áF¹¼sPR*&J”s!’K¸Ao=ÅF^ZØBðóbEXbdÍ\Þ Çž!o£hc<ò~ (cËpÝÓó"E3-4f"€p%ÄÏ]4žÎ¸<Í+DvÁæ>#> žü¬³´¬VÚò) ±¿$ëm‚¢u¢‹÷J ŠÎ [V#Œ'È»U´?£3Åšs4f,ô¿äešä$Ba±O×È\0#î–’Rlœh§µÀšst¡q¥¬¢šf¹Ò7•£ë’³“¬Ò­¸ñ›k´üæ/o¿ú߯Fè€-%Õ–æŒç7îÿrÊ1`k@Ì[ǰXªKfy‘^…ûLMc"÷yÐ tq‘r§ ٵٱ$ý$AD¨_ÄqIšdá àyOµöçMeHèøeú›4|ðœý®gMÈÂàRÑ™‡•°dW`Sä”%´0y´Í¢—Ь9÷¶Žï‘P†Ý‚ÅÓy¬ï wfšÚâ’/çÓóÑïðã¸ûÀ.¥§Éã`†‚(‚r–ý@°;Ù—ç¿à~™lI’ É!ó$#aUЃDMÝ—Õ`n650[ì÷Ý K Îè³ß;?êE,{Ç( ž®F;NiY±ÃĜп˜n :Ç4!U}J|^Agùë LCyfS½ÕNûëj«ÅuµÛ˜zkò¨²«tµ]q],sª©‡™Ý{륰£°Ž´›.n ¤îD9>— ®×¦S£—4m³mÆq¶ v ˜ð‚·÷uA’ë ó›\<Ù–ô:†$D# «f£ Íßž¯tShyg„‡MvtŸæÙ ²¢óú¾Sº…Ë;m5ï隆¯)j¸—³µ¿œg g[\ïŽþ €môë¹òh7·ýTî–ƒàå{Ë´pcè`ÃÝ_T'¿n<å<ÿÏìy…endstream endobj 445 0 obj 772 endobj 449 0 obj <> stream xœ•UKo›@¾ó+¦—Û°awy¥î¡rNIeÕ¢íÅ"°* ¤Q•ÿÞÝåec§Q…­µgæ›×7;<‚0âéÎp¯\mH*Å€DyT°TBw„{øì)¼[aüãÅJ‹Ä@lQjƒ·WTϼŸÜ 7ƹ®-ì¼HQ ºPqnçBw(Z‚nÙÒàUh± Þâ ®VÔ«9¬‹Ù¥bÈlÝR^{V?¤yó+Ò¥.ÀÜQXd‹Åµ«i ;ñV+àÇ>ø½›Áî‘,Eä+0$D?Ò¼þ[D–£H=q»~ÊØÿ–Wi’³¦,â¸b5Õþð‹ØÓ²ªý¬Ëëò¥M{‚dy4Eþ *8†^ò‚óJV±¶žËÓ$ê^#r¿SÔ¸(y‹àú ½cÀkX,8ä\Óš1;_Q/DrÚÅæ_¢±²,ÊÝL=&]ΑLãà Ö?üõÝws+ÛÂ}™–¬nÊ\’ðÖ@ÉÁb5ô¯åOì þ4RqŽƒ.V—ÐÍv»Ùþÿ¿#šÙÜžvçµ½×KÀT^kÂï¢åEÄ’7ÖF.ß5‘0¤.²(Ÿ¾v-HN³"ˆzR«º›MEÑÉÁ³ßpÒŽÖšÝ7 ˆq9wÉæ=Þ‹&¯µq$oÄTÀ¼.?Ø‚ý"hÓB„82µMTM²ªŠ›  ˠ.&ea¾!1îäÙR†V k×2‘É£ m°~`7yX§…˜=ÁX5‰æ:ȶIm sâß6QOl“ntJ¥dË$r¹SdPÒY>Ñqé[‡‹ñL¹äKðÄ xD;¹N÷qã)_ùóOáÌèendstream endobj 450 0 obj 691 endobj 454 0 obj <> stream xœXooÛ¼ïOA_->¹ï‘Eó¥¾ n C-nç¿õ¤=4f›—Â"fÌ1ž¬‰î‹p¾è¬SF…Ñ„§â’Q?þmÂ0uírßo ¡Žk;”A~è‘FÚ¦ßí-Õ9Ì[´Y0 ¤c `×›0jÛ¼a< §Íû1hL·43ötÆŒcréø+3&Œ¾pÚ©Ç‹Ík´ú³–Q 3 œ¹9 -7ÖÁ»bœ¿`úˆ ˜7â³ì°Ãìû£, kº<Š‚mw Wü,6 ÇRÄ]"£b4—9>äpÏ0›“nŸqUŠíÝ–¼™c¦©å<¢ì80üÅi;'Ã4À`…¿^öU±·hsèdŒ*`ñƒÆ†u>äLpz9/¹$÷{¨4¸QÿZ==©òqî&RÚÒÆ82ø£¡ŠR\„Áùp(Þ ¯€‚‡þÛèmQjgsJAçd"æÌ«EÜ—^ñâº÷L3"UÍIè‹Ú`i†Àét#$Ä–€·+×݇3ÉúÙDæµêM:¬Ï½VÛÞ,ÖIØ9miß;è2Éøl—™ØÅ4‰n½˜‰®ròEzOÇ> stream xœ­Wkã4ýÞ_áo›Ž&^Ûq[$Ð 0ì@)¬ƒª´q;aÓd6NçÁ¯çÚΫiæ!@3RÕúú>ŽÏ¹×þŒ¦ˆ˜¿æs³Ÿ½_Äh§gífŸgÔ.¢æc³Gß,gZnÀŠ2ÿËíÌí¤ˆEÅA„–û™çÓùò/pÆ”a)#c·Lg ‘o–Þ/¢ñà3øôCi–ÌB´|˜yw(5–ÄaÀ„Ûÿ‡÷TÛÕNÕ«¼Üä™®Wåv«ákV¤êqu?—&Zļ$?¨ïf>ÿsù½IX6 û­?ŸYÄÆËŠ¥¯¸v/¬Õ…Zv(]ïÎMŠL`ðG¹­ÐüZèlW¨mÊ¢Vkmì®Nì\,UÔÕSkûîÄè¬1sɬÊC=mµËËu’¯^0¾¬ª²BgÊ|Hï†gê»z>ŒbA„éº@ú°Ù(­Ý v˜RB0‹š#òÞ†#uNÚ¨L ÌIë¤Rõ¡*ÆàðŽâ¨ûãêâê·Õõ–)8”rÄψãÖå¹î9I!ߘ5 ª¶+1Ž»í]e@Ä€ÈÆð¬ì<0†©­ëΣÊ(„3™9¾¹$€Êu‰ê[…îçŒiCi9‹²ÂþºHŠBWZÎcËêØKÖ¹ XNScP4@&¬Ï)Ǧ´¡¤ª’'K;‚¹ä6÷‹î´Î“8vF›tXa|ø”0öÍÇû)rRЖ%´Ì¯5Pb¤ƒc†-²G-Æ’ 7"!—å‡q)ïÚk²©ó'”hw²Wê#µä^¦òÝ%ZC©Ë¼©XÒ^›§} Mtèl£§zïåŠ*ñÝ’ð—qÃq ž… úZWª×0qÐqÇ\ 8Ñ;¶²õ yÓ®J]›Œ¬ÀB„­ XãðÌ8¡Sñ7å¡kÁ€,œÐÐmUîG.yˆžm¼Ó€›–.ÆüB¾ïÐ ë@n#  ’"+vh C¤¾Mê“> "`¼Ëü„¡ƒÀ2ÂmÉøÀ@½æÞrb¬õåÆúW_”@ÿúb¬° Ø[‚B#‹¦YÉAûf½FKò¢œy4”ót>“šæÁÑ4¥¯jš™ÛÛÿ­éFÊÍý ³8°È|·U™†jó4ç{T·€ñÞƒô¨ÜÄ·› öô]D€%où㪄ùši£ÇDªÌ”“X'CÞljn®W—–‹ß'F»I¡+ÅòC–çhݶ $´Å 'ÑOçfŒeÛH’jNc˜õ0Mv‡=P­LoÙòñëáÜÃö÷Å·!J“:1~Ç<¹^ò™ËÅâz1Ö4»Tw;Úg»Ûz‡ƒÈ+Äà¢RœôK2T¿»«ŽrØPðf7wkŽRU'Y®ñèÍE¦h­!=ywð‰wÇé³#χ—Øóº°žy>¿/¦_ òŠÃ~­ª©w€ë ®L¯§ƒÅC÷|°ûrULý¼úœ|t4Ñîh*¥¯›°i“Ç» ,ôj 0}ÒÙßêe³¾P­»¯:Û_ö hð¬³4œ6fd`óæGÐà郲ºá±F Ò0ó“Âa¼ðAY\]žˆBçnûs¥@µ)\bµRÀó„¦@Šøöf>ºéæNIapˆâ›'·®ênµÐõH7Þîƒ^èaÛ‡YŒàËÉb„Ñ~cL±ìÞE¯>â/—³ŸáïSÊ_Õendstream endobj 460 0 obj 1443 endobj 464 0 obj <> stream xœXmoãÆþî_±ŸÊ0·Ü’KôÓµö¡iœqÕŠs PÔJfŽ"’ªÏ)òß;³/|“ƒKβ¸»3;óÌ3Ïð'QF"üq¿‹ãÕŸSrè®"r¸ú銙‡Äý*Žä¯ë+AÖ¬bœÀ¿õþÊîd„'’¤"!ëãU²ÕúG83N³,ÁuëÝU%$ÄGpDæŽ9$Œó¼hê^îëóq«[·ÐÛÊšØc>eGúgMì:ÒìÍ_ŹmuÝ“ª)ª²ë‰9lÅb1žŸ{ºúaý™isdÈ­o°µ}Ý4û}§û…i•Q¹0Ýé¢/›l¯¸¤™ŠU€ÉSàž„‡ªÙæÕ° ³ žVÞÝ|“¾‘VM»»tј]ܽé_’R5ñ¯©59å4Sás7RÖð vä9ÇÓC` e‚A\”;>¢IfüW4&pVŠ+yF¿Ý¥¢fHçˆ,#ƒm{ÆI·9X¼!Ç"»°«•Ãi3»½_Ç)Ze~]œÚu/ ™ØT©è×ìC)#l:²Ó]Ñ–Û²>;\E4õ( `ÃAwO+ºÈ†õsýùÔnšS·Ù`>uåÏzõÕŒG%£*’¾Œ"øxQF¸ë«hûÚkˆŽ«“Û—U†ô"y·{r–t×a!A]¢ç°}ÐàM±æ.² èŠT4DÏ‚\Õ%̤«¢ ¹]?I¤'ý—|Zz*²gkwæ3nÕtÎç¼'»†y}=ÅiÊå¥w9ùyL. 3Sºm< yXf,<¡|,‰IîÞ¤^ÆMÓ ÎØ„‘lâ À©â r›b×5¦ìÈLBß"DZ{ì-‡¦"([¨Ą˴4ÎÒY¦?#Xnƒ~8Ë_÷Þå}>Gë´û‹æäÔ”À­§NƒÒ9H³8^‚Ôñд ¾vý|lQ†]·ÇwîñdSu¤ì‘«ŠXO–÷àBQOxòöþß›ï6wß­ÿ³ÌeäñlP ™˜½;JeûupYëÐnFžÃDNx 15€?â¹¾ÂyµoÚ#ô¥¦}à ”€Ë¤‹ò†P@‹k@&=ÄÍ^ú| kgÌpÌ_}<çvãØv±Y8ï—vß{WbŠ …½å"@‘ÅNcc2¡ 4ï›ÂîPPÀC‡s0¾Ç^;¡­±\éê…üi”¨û¦IpØàƒ¸r&ÆsëÌúYM å§Sõê¡mÎY’ИÇC¹%"çÇÌšXv„”Kd¦LBõ+ÏŽÞì¨h<@õñ=¿Yl1•Qœ}q£ø£å °ãZ¤ÕðABVó­îöÃt73DyjºVðîñ}Lší2K}Šfë‹a]Y鎒»¼­J+öÇöÍÊ+4àõÑ {Î`8¨39êz¤Çp ·›öÉ;ò¢á[øíøqh"PA±œ ±—†åÂÉ̲}‰qûÄ»æÜûjö;Ó‰¢L8C¯Íô\a¿¯^; óªËW™1M36¯LhŠ(‹––0E^‡ÿ.Lál}ŒÂ@c±Ùà·X•#KÜÝ0«p˜IÆQA ßHpø ôÍA÷¾˜7ÅSð´Z6o¿'”“¶m‰ì.÷CÓ½5ß¾ë{vçô|2±ç û‘G¼YÔ´ù»Îw°ñÚËþÍ3|a6àÒ{øŸZhÛ-ÿª»òc ¹†þ‰xó—íkÎuoólŸø&™p×¶ÀþFÖO·küúiõ—å†,V8, iaË„'3àýý¹¶tôFÃF¥UvF[â³rvóÐ1ÿd2aB)Ú”yÈêÓÊ2áž`hí[œ1óªêðkÓF˜¡2MæÀÞé>/«A1T®Œ³ÕÒVu:Ž6Ýì’œä-„8ÆôàpÆ1n‘M$+æz@Áh6<ïž›sµ[JOÙPõq¤¼öœŒÀÃ+ô×Íĵö—{ÿðø­¹i>Þs2Œj¸i-gqÔ€ëyÀ.#mÕÚ jÒ‹Žq¿Mº•qƒ†G…:|/øfùn!žK|j‘@dt‹ÈJ9ñ®§å±|‹£¨lŒ84¨+k !h4\(˜9µ|n!€­ƒ¾lÑ&¢.z1D/?ž{è¨ÙN¶ƒ”jLL%å0ùvVtHúK9B:1+œŸ—£¤$F_ÐËØáЕ m ¾†šßŠ {Ûæ-˜U†ë*eq5¾àB‰WêοE™%â4QŽØ2y.ìH W¤”Þ¥¬?#Þ.ufè÷x2üµ›Â4³A °ØåË(ó­önj‘ a)ˆ ¼ë-> Ì{+÷ê¦'¯¸7Ü ¾„Ì‚¼›^ËÜÞU‰éµ¡wÄû›WSõ0N¥~.«Ï¼ÅcÁl~t]LFŒ h˾¹Í ncÅxñ¿_–š?“=98Á° ò<ÆÑ'³­Ró5ŒÊXòNžˆ ÕzYÍS| RGœS ±Ôïüâ«Ø»õÕ÷ðóßÓ endstream endobj 465 0 obj 2154 endobj 469 0 obj <> stream xœ…Q[KÃ0~ϯ8›c’¶Éò¨lŠN,A‘ÑK6*¶um'øïM»ÔνH !Éw=ÝC¬_~ÏJr+ص„ÁŽì ÁoY ׆`2‡âÜg¶äÈä ¤Æ H0%™Q>7ïNƹ@­e39™1´¢‚@#9\ÞT%­…z ¶iê¦8í=T„Z2á–Ï›åÝÓfDZŽaC*Zhlwh*›CRåçŠ!\zèÅ©ç(J“Tk;èj't̹m‹]•tE]aO¦BÅ"Â…’@Å‘xÕLCˆPN†`®íYª¡Œ"ý·çúa³Z›øå,ç~¢¯³2ù†ÔÂgݶEúa! †ŒépvèÀ…O -:¨óçoæ–P.ÕОÊP N±ýíÀdÁó+8ÉïïP(p‡{ç)˜àQqÔjdþûûW†<ºõÐS™]endstream endobj 470 0 obj 342 endobj 474 0 obj <> stream xœUmo›0þί¸O i å% Ú~h•N“–iZ˶/‘,bœ”pjHÚj~gc¤Y;|/ÏÝsw¶ŸÀ±]pä£ß43ÎîX†kãÉp•ô‹fp>„­\ð®ŒÊÓo2µýþÂÌ0‡î |D4v={:H»06Lç†R…S 1ô\†ã‰Òïx{‰²MÊHÊiš%Ýæì9+2cËíâåÚªÖ×e)’å¶dPðŒE¸Z $¼;‚pn˜}Ã;·1¦ |åõ#/’uÎbH)ßæ%\s!½´zÎ)ùÌ¢˜PÐ\VfýÚêV.€©ÿZ“ X*XQ ¼s•†ÅÊoÍÊš¡ ³ÎÛêµcáJ¥fõT€Å@¢iRÉ ò f¿Èlþ“|û²ÀGl“†h•W`cýŸ óìnØŠ †þÁ…ªUŽÒEù+VnEޝŒeK& ä@£4•@ñcšxAä¡8Jb†vY¶¹!89SÞl1$V%‰¹^êî\Àéi¢Ø©ÄßлÏ0FÓ¨ôw’Ç O]±Ž!ÎÕ.J·ì M•DôŒz÷}µw ¾á<…X'‰âXmí¢$–©Œóéz~Û²¾FÌxCP”ü!y#ßÏ«fÉ^6‚ð io¿5½1+h5¼ê‹å¥xý¤„bE‘ðœðÕª`‡píØ ­kõ΄ïc“¸;Öá &V«[½¦EÒÎìé†Xúë¤Ç‹]édi­ž,d½>R¶FµÏ³k­F©½)R×¹-kí×îx¿³mvSùÇý%¾i0Ùæ›ƒ¶T[ªòG˜Ëã$wØãœX÷øÖj›4[£uK ž¾§Pï˜ôW‰ëÛŽ¯Ïsçï–Ù^¸ø½‚çxîÞ1píiP{~xÛ܆Æw|þ=í}endstream endobj 475 0 obj 702 endobj 479 0 obj <> stream xœUßo›0~篸§ŽTàò£ ¦>lË^¶NÓ:º=4rÀ*‚©í¡©ÿûÎ&aÉšþšˆlåî;ûûîÎöxÄO›9]Z'WÒò °î,ß8a3¥Kx[!Ä)¢üðçVéC0žð¢p ñÒ²]ßâ2ö2™Œ5.Î,Û›€«]¸Äd³„;FÛÙØ¸§-yr]˲¨Y‚¶!\€÷V‡ø§_>€ð&ó{È›C¾à _ø¨/Ï%S9sAët±…ç†o“hËLPÁTRñ”ª’× o’5­V,Éf¶ çàjÞ( A“iÂj%:gGЭsÄGÓ8B½¾£ÇÀŒaoÕÐS ¡Yˆã>ÃÇ„àb6ÒTݽ­Ëf[Ú0ý™L/$_?ÏFð[óØÃžÔƒäK¦e]@[ª¨Ä1A’˜ŸŒ‡˜k¹¢UÕAÇWÐÒZâ°’ÌÔÆ œPØTm4Jª´JW•É›ÔôËzÍ«µÞrN1–fò•H™©TûtÖJ0šu0g¬†²N¹h8²b"âã\dØ”Œ\?ð<ûødô+þdE$ÐÝèžyät ~φ65‚ú­p{“³…öÕÎ åXD“j;›Îu-²GiÄy&é6`¦Ë_•R{_#Lõ÷!Í¥„V𺠀|Ñ'˜Z‰úa)ïõ6L[yûž—Ëò"³Û †Ú«E>Ÿ·ÿPûXZ#ä]ÕÒN÷T4A£í_Š$àqö³‘Y{·Cnllå\0Ýy•9K¶ä¢*%Ou#gý ÙUþOç8‹íŽß‹Úì€ü×e×4\‚OaçÊúkëŠ!Ò<~H¼p“h{þ½ùÏ66D€¾Ð/0OCùdm#Ÿ}3>ÆÖ7üþ}ç&endstream endobj 480 0 obj 688 endobj 484 0 obj <> stream xœXÛrÛF}çWÌ›A—8ÆÌàZû䔜Ýlo­—I¶JÚBàH‚M ŠV¾~Ï\ º¤d2fÐÓ—Ó§»çRFBõcŸÕ~ñáKJîúEHî,˜^$öQíÉë… ë »'ø³¾]˜/áINEDR‘õ~¬Ørýb°™qšç‰Ú·Þ.[©¥_2„’°âx®â\- Êc²>.‚„²r²U[£„†‚gVÀ±ìn‹;9»¶Úʾ*d3tOÅö&¸YÁ^·•ûrÅC#=L‰¿>•Ý®–y\²ˆæYÎÙõuÛô¤½%Ã}Ý“ã2ÇB*ò í¾‘c=Üyú(¦aÈ£ñG—Ëÿ­ÿ¹X1EÊjže4åÂ*ýûÇ“;2Çܾÿò£z¯µÔk‚¦,±kt}ú&¡"‰¬ …Ù­¬ðzæ"ÒzöFÑr·3Ú„TÅ£Z¬„H©ˆc²b‘~ùûX!–s«Q¨½ÿñËä¶k÷0 »¼MIHó”åoÚÄIÛP‹ÜÅ"Oµm6AÝ dûr,/õÒU[ÿ嶨ȇ÷س«û¡¸Ç‹÷.”|ÎhâLÒ¿+åͧ¿6}}×È-©›­ü®w«}Wný?{8‰¼ßídñXî²hÃÅòâF³‘˜ÛmGÞw囘ÛóÌŸ¬ýж¾•›Ã]Qb_qhÊDzޕ›œ‰ØµÕ³²ïëÓBøœqÊ)…üþÐíCQµ‡f˜È¹²Ž­ôVã^gé¹ÃœC¬—¿Áo/«Ž”½Â~ÑÞÞörz왂Zóm“³?u] s¥zÜ,ÿ† ã,6Q6¸á”3Ÿµÿí¡©hA:9:•ˆ° ´Lã‰Ã\>Ê^e‘#”NÙ]7·m·/µ¬r-II ºy¡B  ¡,êêõ;5ÂSÊÓÌa‘¥4 ™1P{o…z íƒìÊ¡í°ÐI¥}WË3Õy–Ò$>ׇFìÄ€íÆ/j\mséøTVÞî8£< íŠVRI <0´ÓŒYN³DxÎ8KWm†BÉžçè— ÐO™Ó"L¤» Œû6€ÇFîô±iJc‘ZfIýÖãÍ’’Ÿ]@{‘£À“°ªì¥bßþPUäÌ„XQV2¢½âòê·â_?OTEñ ³Ü:”Qžká˜Á4-üíÔg Ï&j¯-)w‡=òËPGéÚÃÝ=ž’<´à; xÙŠDá¨Q1ÐäÌUÊK Î{Œþ‘K¡ïmkñ}yVš“Ì%æèGIÈØ£ú¤"ô¨+^ ÏJ‘˜Ñ£‡azè«OE?”Ý€žl–´£Ä˜Í,®DôbŠE”s6ÍŒq®íÇo§žj¹©©€º0«6`Þ«2”È(Œ_ïU•HSÑ´^L$ÀñÜÕÊWš]q¡ZƒóO—ˆåo7Ê‘GüyÝ•Œ9~ÍŸáHxÒ{,ÇNxÎæäb=J¯lHÿÔÀ}ý§ªp=©oI=£D+§þDÿÎãäu“®aSŒdWã‘¢…SfÏŠ„@s`8™eÆ¡”ÍÀ2¦ÑX”Û_õPZ^AËÌ>>ž½îˆPtõ¶#ÁxhÐæát{´*«³5FDжcU™çõÍWY™¸F!ê“OC°¿irz©›\°‘Þ–°‘Ta7]«n¥TL«Ú”Ãù²«U….wzbµÃª1#ÑïÊÙЪšÈô '¨mË£¢}\‚–Ã0Nèá°—ïåÖœWÒÐæoð Ô#L¼Bä¯`ýŒ#M]? sçµ=w-œe°ÿž(ÌŒ–S‰(4±“"ö*2ºm¤¹ Àÿt.ñì< ÞYòì<Øãqú:к؎dn:>ô¶óÖÉ|û{Î+>8J$ñ™0ž«Ð@„Åé™R"do"=&öÔ ÒOgTUvÞG½Z.ÐÀ9-mÜÐ? ÕÜ8¢‘Hlqq—û‡„ŠÇC 6Á=õË£Ð!㯦ºkIÞ¢Luwe+® ™ëTú~À«`ЯU¢^€Hg¤®îÇ’«?70(ÃW6KøÕ&jÂWûflš !§,9µ ö†a"> iì7•>pNBžnîümÄô– RUí¬i*£… eÕv[Ò´ø†Tm×ÈÐ*Ýo‚¾Õ£’² nîv(7Kì«ÊF:•všh™º…‹òÀúŠX.°5呹1Ü×ÀFsGÉoËw‹àâÌ—»“ úÄ]ýM÷­¦¾gøþü…ÜrT¬õL9Ü—¹Õfæ,¨ñ¶‘r«ÅÁùЧx/;›¯ƒöAú¹t0™á?øHOŠxºÈ¥¹ÃŒE¨ÉýÒÚÈACÜ1”°>×;G¡ô£ÿÕ%ÎPËm±ÝÜ=3ó³èlÑ=»‚ØJ¤†V¤Ÿ‹˜¹È´ (FµqÜ®PDo~)Ÿº1vú™‘ûRõæuó§õâßøù?pÔûèendstream endobj 485 0 obj 2198 endobj 489 0 obj <> stream xœÍXßoÛ6~÷_Á·ÊAÍ’Ô/ {êÐÛ­X殚ÁP$ÚÖ*‹®$ÇÍþúÝ‘¢$+jÒÇÁœÇãÝw÷Ýó…0Ê ÃO÷onc²kŒì_Ül’î+;× Ÿ¬3â‚ÀÏz»°'9QBý€Ä~DÖ‡…·âËõ? „¹ I¡Ü:_xœ“nФS±Ü'«02ûWuz~HK¾Ñ§¶“sW%> Y,­¢€r&Éú¼øäÕª=ÕUCÚ½"KRÆ$÷Òò¤ˆÞšÕí’'`D,¼¢nZ¢ªN«œ•Ù-u–¶…®HYÀ¦ªÚúqù÷ú—…ï‡4HDg8EkVHÈŠ¸ÂiÈ#kÁ‡ª¨ZUÁ•Sò¡QÛSI¶º&µ:êº-ª?p¡ÝëF‘sÑìq±Õ$×hDQÝ›~®H––Ù©´fé­1g„p³ðJ}Ì–¯Æ IåØÞ ”qo%Øf1³ ¾€cFb'Ä,Ì*/PnT¦ÕïF7¢Q,ÿ‡èzûâ%\˜²Ã(æhª·Ó|ŸÆ~â’~w:€ã“€Ï9€i£¾ë>n2}ªÚ™Èð0¦ a6ùw·œ˜'„O/k]qðPÁÄ4É ƒ¢äYtfÎY Õ‡w£·ÛFÍç½þÄ8Ç´A(Š(“qw'e3µA´;ÎÓ\Ý£p,!ǜӡ¸óhÞhëþÊ9x’˜@d£A0`,x°¨¶Ož—¡ò€ WxƉŒ$Á8‘ÛF•[°í¨aá¾|ÄHºân¯á– —žˆú 8È/@…˜ËÞÿobÎy2ÊÈ\5Ù3ˆc­Ü!ÊZo{,¸2”¤¡æ¶³t2z®ÈVØH(øß Ú6JMÜOb*ü¾ˆ cXÒ7Ÿ‹*7Ù8™ $ÐÛU…»%Ö_æm[c¦±²Û²ó»‹ü|¿øÎò`Ãg @;t½Ÿ‘¾iXª®u=q1O=6ï>nÞÝü¹¹¾½}; ™Lœk^Ñ(€-µ@Œ5ÔçØ«ñNUõ¬U[èZP”Œ,øÖ»ÊàA{Œ¡í„TÆQïÖÛzoUz <Ö÷2A£0L.ýüíýæú·õí_Óìtê“×ñ.ŠtMö–€ñ)¹/`¸ÊsÚuTI`°ÃÔáQlpXE!ª‚²VE0ÄQŸÔùÐ5.ž†>¶ªg3…såNvp@gNiÁªÂ2¨IÀàf‚÷%2œ=­Ø£Kûj ìâr’å‚A“¡Âމ6”¾L!°û´u-ù‚XPraú퇺‡‚—æy½9UéCZ”) ÝÝoÙ=Ž@›ô°m‹þþ˜²¤ã"ì‘–bªÌ“CQ¬vt $ `wÖ%6:làžª±x6X ÚÔŽXç¢ÝOG¥Î@ºÍ6½ÂçäÌ~= 0"¦CQÀéòlr}÷G26­týBMΪ,ñ»ƒ<´û¸áþêÂ2J|Ùãùpyò"¦u>fò~*ò×@|rȹqV¶ùqBeÔGF nžê–Çõ‰4­>By3ó«™fU¸N0 ­»)îtá¢ä£i»v=[„݃3ª F‘ J95c3 Ü0¸A12¶<}L`ÇKq¨Ãlðª–|K¨ýÎlÝÀ$ü“JóMFÞ\¹&³‡…«7¯¡ ˜ܽæwTlO~¨°Zš1-W__›Î¾”ìþ˜ÝÈUYªnƒflTâ0?¨y Ô#ãw(ÊÌì‰Ù=|”Ínà«Âm°9«¯fß#=7`™íçÜ•A§ótÔ¢¿}íìX8ºöÂÀÉ,3s÷µé\¶ÙÝ-¸|H­løbߤͭê›÷±ˆ;Úù#jŠ˜ÀʯЉ`¬åÃéSîø‹ÿ|¸^/~‡Ïتendstream endobj 490 0 obj 1631 endobj 494 0 obj <> stream xœXmsã6þî_Áo•3+’z½û”6{wÛn7mν›MÇ#Kt¬[[r%9Žûë ðM²¼I¦7IÆŽ €ç¨ßI@ ðÇ|»Ù·÷ yìfyœý>cj‘˜bG¾[ÌY Å8ßÅz¦w2Â㌊$"&‹ÝÌóÙ|ñ?PÂŒÓ,‹QnQÎ<ØåãÒ·÷)a5ø>ý(ÃeAyDÇ™SД(Æ4<5 Žy»^>Ê~¹mŠmÕõËÌËå—ª.¼‡¹VÍ2ão÷ú\í”òªîIùšÔÂS ÛX¨ŒÞ*éZ²[þ D Ê_£$Ê|˜y‡º«kYTEPÓõü»÷]Û6-¹’øn~3Ž¡¯mi…ÊÍŦ9Fó.Òô"Â཈ÿ-„' ¢Äúï]OTÄkÆLâí~®{k‚LZ¼¤hÔ¤8TCzÞ[ÇP‰P?7!¦!fT8¡6pU€y+Çáv16Z`æèF9Ð} Šƒ îÈŽ ¦)áú»$·š)`\ÇNrëÛ§›áL)ÜìrÿR6Åa}±ƒ±hp=P‰Î‹sîa®òÄÃŒ²(²'Lcø¸:/Ë ÑÊÖd•wP´V^Ç •Ü–fï0ˆ©✿«5Ék3L$©¸àTi`à¨ÁðéšlŒWgf å,3éò9Õ~åOÛúôå":Ç×JÊÂCa¾ma¾8Íc,î8ò.@•›: /fÜ 1UK‡zhUÐ`‡ à ¼®Që[eËå/Œhoç/Ò3‚òaNMôˆð(¿q§€TL«ÅÄ›GI—i–èÀãD\ôhÎ'’“}3‚lqHo ¤UO!eÞçð„ìä®iAª.É‚¾š´B×  ‡¢îM®Én+ëÇ~ƒe„ÿ)u0•[7)ù¬Ë¶#» ð*Ä8•'¶âQ¡Ò÷Ü·à«R²:Á´¯\)e¾%G˜5®ÌÆqëÖe•×5v˪ë€a­/À}j$F7ôl¤a¤C¦¸ø¢j0+pѳÂy«†îÄ_ °[ef{„&P[h6¡¯±š³ëˆk}_a¯D럦?La¶"\ÛýËÜE=ÙËê>´l5d¸Ûà§q}³l”ÆDsÜÍ_¥*²’ðT*‰´"àEŒã†Ój°› ³èDî:OkG޲ÕFr€òà?ôxÃêe©ZªPÁuÐ å(ÃtiÝtnÈ [øSÕºk…U¼žtªB±Á«"–¸ å÷jâbHœ»[ìdŒ¬P özÔ[õ$GL>tÛ|äû!.ЈÝEM´¼BRƒÚrð·•kø« © Énó…‰çúð?aRLþ,u<é©&1qÞ¸=Î3¸Š%"óÆÓñßȧ uN&lÉSÙ‹ßîv¦bsÓ#¤s4ÿg}Ø”ãíÔ…c]Ùû¿ª¡„·×|ïY<ÜÊb3Á±ÐÞ!Ë•]KÔZßl÷ñNåÙ[µhÑúòK®GæÏ^»&PDÇM•ÚŸöÏt¨¿ÔzDL£Ô;Ö×(Ï÷ ̱+ ë¾iÈ6oçXB@.Þ£¾wCp;„bÏR 8éú¼øBkíIEZÄ›hLU>Ò›€«hP, =8¶ò¢EÇ &„ªîdÛÚÆ¾^0m¢Òea|aBû¢È¡1 ®î nz…Iª. óÂ7ŽX_{õ0>9L÷–x‘õô¡§Øj‡¼Võúäê‰OïA< i¾Bíqf£©þçÇ_—¿©ˆkÝ>‡ãSËÃXâÆ ïI çŒÆ ¥p xòS~"<àlØ0š¹AüÍ·Œï³_àçOï(‡Ðendstream endobj 495 0 obj 2052 endobj 499 0 obj <> stream xœ…X]sœÈ}Ÿ_Ñy2ãÒ°t74PyÚ¬íl6޽QÆq¥¬- 1=k´Àh¬üúœÛ ƒ-§¤*ÙÐ}¿ï¹çò‹BÎ"úq«Ãê‡ë”Ý «ˆÝ­þXqó’¹?Õýe»’l[á ¿ÛýÊÞäL¨<”1K¥bÛÃ*ØðõöwˆÁa.Âtì¤Üì 5Ž=”Ã`®zKÇŽ=uÇ+ó¬*›F÷߸ú Üï=û®/nËê~ýâ¢pò bï‡ÒúAFé‘ôŠnoLæ±H» ê–Ý>z¸Y#â&ÎL¯9¹%âàËC¯‡¡îZŸ›È±ë2B-¦.vÍO,ò —mb\Tf#u(?¯9‚!1”•‘=tЃˆ0øçAFׇ„I·6ø^;³˜þÚ0¹ £\˜8ÿ­…Á$ªl™î{Xü‚Ê>7 —ó§JøZϵ…±Èò©sŪ÷¨„‘"ÑëñØ·Ã"I¹ s‘ž›àÕÛ¯¯¯ß_/ >‡µç¨#…¥¬X† }G½´Ö_ЉÓPLb¦ÉIJA'72ÍÃL ŸŽàqÖÓðMd^R.Ağ؈ ŸÞ½/^¿Û^ÿgaçqÈ¥“'Í?}õQ¥—·Ík»‘•çDÛ8ºâ‘0•qÅn×…Á“$8¢*Ð{È"Ês4…Q®·œ:纵]ãQž'YðtZç(µ,ʧµ¢‡J¶>~¸Î°öÊ”zJ†Â‚£ ‘xÅvT#h#éÑîSpMW55 l߯y†ª…ÀîPhtGQÝ7k'|ŠÆÆ qÁCBb«hK=„ß¶£Jû¼¢t¦2òé8uç<‘ºÜs;t5¡Ew¼»§¾9™>âItýç•ð§i诃! £ÌHJ“Pr¯âQ»J‰3W<Î|ÕËÈÛ_±áÂL„8™º#èjÿR¹1¡²³­ûz-Ò,Ì„ F‹´Æ!$;bɦ¸(;ÈxÊ0À°gÝíïºYÕíô`A?"ãÅ%–â(€ä ÇÚ±n*èƒ#ª¥—Åì´Šì åñ•yõJßïØîöî Å à€Wš¤¡µÕžûu왞ð±¨Û+RJGß®¿8ú¡ê»VïæçÝÞ÷¤#Af‡.`ÖnG‹¡þ¯¦3ównøW 1»þ¯°Óyù ….:ÍŽ¼íªâg]îŠê%C Š{ü›Î¤‚&£_âyèažë»ûÂEÈDë,á5®SXf÷ Nݬÿ¼@ O2ÂuŒS ©Ô2í¨û½il%1Ì+m»hdÃqï ÓÏÔ¡ ³È B*CßK)Mî ”(« ªÍxÁä6òSiz‰p Ó¸UšµG£eݘ©dÆ8Æå®KFEDÓÉAñ“óØGg%®~êuSš!ò¡uUÊAŸdâ[+šw4µî‘8˜âåÙDÊìWƒ#Ã}?Õž©tƒW ðÎ"? —S`6ÍŸX”^d&ñ’ÎæqƒR‚kªçe&gWŸS{û•F¿›¬½¸˜§À˜©‡fZn&ºd¨È¥x§÷ÆÌËið&ÓÙÚTHÈ“ÁˆM‘é4=©-˜ºŒC©¦ñý|zñ•%=ÚXòʶUQ)ò¬âãó±$ÂCíõêcSXæ'§*ŽsšŸUÙR˜ÂÎel {ïØÛÄ„†@ ÒF„‰ícýÈôY§šq&‹'ýû\ƒÃ€e]ÚVVR|ßn˜Lv3J.CüK&sL…Šv¨ÀÃTYËÞôåáLAq`ƒhTc—q¨¦ þ±øéÍ:ƒ d¹¨,ˆH ¾QØ–ÍYì+çLyïK—V;@ÇÞ!|ò¸°†(…»ŸðÙ}à`YaM€ÕnïÁ#OW-ñ±U«,º¼o)bt‰ Í3ÚMe!ç>WŽý½ÿû¢é°¥rå‘ÝÓY»'ì¢iT¢’a·Ê'êПK‚Žî³eIa鈗ÁÝ‘Øÿ€MeʘŸ¸Š2cñhÊšÆðØÔ,˜_|&Ñ'·› žäb%kpm`Àe í½îõÍÚÔ!ðeD°ÁD3žÏþ%ÉϤ‰Î•ÆY*š0ƒ6j£ÜzÇÇa4<>ÀƒG;31¹š.¤¸êH´ˆ4Ššsm™K*œò1Yh9T¦háòÎ#> stream xœ…TËnÛ0¼ë+öHˇ^<¶H.E› †Ð¢H C–iG‰(%õßwIJ2ê LíÎÎÌŽôŒr`öšïU¼ßdp4ƒcðp÷æ[ÕÂÇ"PTXÅà¯8¾“ƒH•1d2…¢ HÄÃâÂ`1T©ÔÖû€ð"û(\B”¤öPÐ\!î[@ŠG ƒ§¡Ó{xµuYJ¹dKwÙLÚž"5 ÍóDÌWMmÆFwsÑÂ2•4Æ®&Y§ÕÆG‡'3'Rù‚•Î=é¦v§èÐôU9Ö}:ä eœ¥ä÷ó Á3¤ÖÀB¨;ù³ø„ *OD¨a™›¹âX¢Øw蘺om=žì¤²ªÞ4´å“#g]<§y{†÷DסH7Šù *e2k }ÿ„#ÎýRÒduI—f]m2ŸŸÔݱёîÆáQ}©_›Bõ¸6TçîБa@(SW¹¿Cs±*34dÖ@®¿o¯?ÛÞl6w›‹uåŠ.Ue·£ÇK¨Ø²Î—X\9  qJÅbר#¥C£«Ññôå *aŠPg!Ú+ëG$y†«ÂÃ9ÊÉf‡™oÀ•:­¸¹)fk¦µ·wÛ›Ûbóã‚+çÜÁÍt1˜ÏC¿+wÍ êö¹Ç”íýv¡`È9“d¡*›FÌc?5{(™Z õµñùãøJ&|ÍŸÏüFá¶·$Òt–ãïå¢ JÅ‚µ i»Ÿp$X•F{ë"Ĉå†^#Ç%er‰Ü«<»˜ÌgTd€¾”'Àw…Ÿ3NU¶tþ÷SrS_ñúý <endstream endobj 505 0 obj 634 endobj 509 0 obj <> stream xœ•VÛŽ›H}ç+êÉÛŒ ÓÝÜå%òHÑj6É:쮢8B ´m"l&€=™ò奄ÎL2qdˈîsª‹Su ê2 òc®Åκ\F°é, ë“ÅÔ&˜K±ƒ©åAZ ŠqÀoº¶4“×ó!òBHwq˜~Ä0fÜM’PâÒÒ",Gn9Ôå¾Üv8óÀ Bµ{l&s£rC«JCb±" »óÕ¾ø|Jd~¬yïI¾»­EV7…°YàRÆCòù¶-Vdqg'n'>'y»ÎâÆæÔ¥4ñÉaåÍfކ+,HâMß‚ BUìæ¾ÝÜþþiQ7XxCBïÉÈöûŸ}Wmö¢”!|Ä÷TˆZìuI»¶Ò‹GÄ—y½†¼,Û¬«þü3X³¶¹zHNÖèÏ`ÇlDÛUÍ~e+¸Ã&i¿He§ûGq®›"{)ò2+`‹xôÙÏÎDl)º¡²"û¾½Ÿà¤Ú÷ЊŽë¥?~ÄU¬›ÛâÉ“Fä¶:y¨«®Ç‚œ‹6OÍ3?‹Ô‰¢G•³¡P¾.ÔyäÚˆ§È¿æ½Ýåu 5vÿÑæXä8ŽI^Ä9¤¦Zd]sh‹§ cvÕ“°«¶mÐ>êwÄñxèySöR“h)ÒÆºmv™¶õå4°´¨nÖa*°3æÁh[íCtí÷>t |tâ> stream xœ­VmoÛ6þ®_qûÒH®ÍˆÔ+—õC‡趬ÅmÃÐ ‚*ѶV[L%:Y6ì¿ïHJ–œ4]7 ìH<ÞÝóÜsG~ŸPðõ§ÿ-wÎé2uçø°v>8Ô,BÿSîàëÌ +ÑŠ2À¿låØXÌIBÄíwA½ì7tƒÆ”Îcm—UŽKcXè¥M9,¢Ø¼|&ÚV¶×Þ™]a° ¡^xëÖ+¸v[Ñ1xñÎ=Æ OãØý9?¿ô¨ïŸ†îOùÅré…æ!qß,¯=øÓû5ûÖ™:ªî<½7 Ý¢]å[YæQTy™W¢Øâ㵫Ÿu f'îºt0°Ú·Í™wbaO2sÿ#ÀøiÂ-À·î¶ð±´ƒèaÚ¯ß䯳¥‡:3æþrÈ|Á´KÍÐË’ùQÒ:g„r縧3xyuu±Ô>‰5ŽˆûÌâ „»ìKØH9ñãÔøfy[wj+ “ÂìÔÔ/¡Äg)=D]ÉÙ¨áøgPÃW°Ç|E£Úû¼”ûF=^ä¸yZ²ó;ä ©Š¸Á|µC  oŒƒ2›=2ú±éêu#*´«èg[²Ï¶ >Órå1,*÷SwÕ … ¼k‹¦ÜŒ»Yª¦}X™@e]ùIb\­…ÒU.T-›\Þä·Ö¡´Ý‹ë=hå3wþHôõžÉ›ù3M†ùfæ;Ào›`Ê$8ŸÊlË“ã®DñœKèäN¨Mݬá®VP£b`¡ûû âê0ydM´…B MešªÓZH›å Ý,f?ì•7ßýmý©¶xôB§öïÜ?rqºLzL²@3™¶‰ Ö:  câ¬o*÷î©8מIÒ',|0ƒ‡³>n娰”$‡–6‹tW`añ äOâ:·ÈyÈŒÉ%š¼2&€Ëºëócä} >œ ³á²MÝÁjß”ZÉ Š÷VæQâŠÊ¢Ø, ;[맪¨·J dƒm©`SØ0xR¥WàS!}°8°ÃêV€ÒØCñ§$‰¢~4»2‰‰Ñ„ ȇž=!‰ÂÂ1R§)E€óÒçñPñžÝ›Z”˜tÝTµí°8uoëjûï s’¤È-ž„6ú\ÒÂ34ˆx8%¹_o ”âÚ ÿkTÝìÑ¿’HŽ¡ìQ@>„NÕȬ-e„lßwÄRÉ9ŠqR°(íþQ½V­@çCyvb'Û{(ºN–u¡pÐ oÕŽ„ZM²$!xN÷§ŠÑ†‰ v¤â4&=l—dc™äi( öª¥ÖаH™–CÏ?%A¶ÉáÖv(€õ Lô %ð:±j1¯K'Ä‚†‡›J·ÓÀ¡|PÆàEÊ nÚ™*…®Ò„ÿ}à'xPGÙÑ€$ì YùÇ4»d$I´êÝNTº@(b¥D;ŠÖIšiÖ-±¼s,ª•“¬½iîT±€²3Ú3 äxªÉã©–~bªôÍ0Ì&<3,œ\.0 Žª{õÎ(!‡¾ÃI¥-^*ÕÖïöJ'¬Ú¹ígsŠÙu`•èJ˜ÍfÛí»ýjŽI&ýÇZ\Ù£{Ö_i´?Y¾Ðg!Ìú#§#Ø&dsw—¢¿f™š!¬ž…Û`R²¡Æ,|ø¾¸æ3:nÄKO†ÿx›¾Èœðó7á¼' endstream endobj 515 0 obj 1267 endobj 519 0 obj <> stream xœ¥Y]sÛ6}÷¯À[¨Ž…%’ Ó8™énšÌ:Ú̓ÝÑÐ%s+“*IÅë¿çIQRâv'™Ú‘ÜÏsï¹·° ÒŸîçêéêo·šm›«m¯þ¸öKÖýX=±ŸWŠ-V8%$ÃßÅæÊÝL&†«ˆi•°ÅÓU0³Åð  ÉIèÜb}ÍæôÕ\ ÅæqBŠ” ²ÅóÕ]°x,V”m^of"äaé [ål••eղǬ\ïrv3ûmñ÷«¹àQD"¤„ Fv"¾¾d§<Ž»Ï­CR‚Û1«jöe¿+ZvóLÇ…Šxh´;*E4«7œý«Éé Ì6Ùs¥%O#Áæ"²B×Ï8¹ÜæírW­vEÓ.W÷Áý¬»Ö{+Ö<ô¾ÀøÕ )׬ÎwY›¯ÙæP®Ú¢*É M›gkvd «6ìSeSSkt(¹„ÛœÑßòÁhh¥ƒ +âé!¯™ E|?ãö¥C¥Ú½"iO.ó^‰‰Õ:åZ/Ò™ìÍ-Ï™«$"¤ºóMÞ6“e ±þûŸv»‡ÃfòD¬¸ô'´=L:¶ÛWȆ_²’eu½ÀEÓ Iù‰éƒtc5þX­Öy³šêRu  xl—VN^7lUÕuÞì«r]”[œg«GŠK ‡Á 9Œå3!ßCüwãMI–uÛIé4’Hp›øAÿ9óšQFœñ—@luï.œÜååÄŽDò$ìÓj’zåÁÆÊæ»ü)/[«}ã\ç°=ÔåTâ\èˆ+(Ùûðëòæã¿—Ÿÿ1•«y'4tŽ+œg²¶­‹‡™$,§*8´9³ý¾®öu”çÎ3öþ\ºx"ŽêAcŸ‚C79‚0€„mcØp“Æ*Fáe ÐÝ]Wå*J¶ÛU3S‰Á3Å4[­1„ÖjDö~D„„ò ep\QÛ`“ï9yhrÊ»7GA’ OP_©y¬¤,@cåAóæ°Ýæ U…Ì™ñ·°Ã[Ce+NQ†|´aÖµw$EÒ­}¬ÛÇIhU•ŠÍ9=Ïi)Ä(¼V»¶Øí ã~_ÕБ»+©ñn2Ä2v¼ ~9ÊAAÓ}B0ܼDdÔìðôÍLÒ…(¾.?|¾ýu¹ÎÚ,¢2"žhïõÑ™´ÓËè¡G1²ÅdŒ_+ q®‹J!؈ðš4rîN ªo_[¥»\‡#äøA¯m¬qFE¾[7]°ZŽÓþcß¿WšŒâÞ®û é̉ B©¡¶9ø" ô-¹žr7¶‹-~š:ßÂ1à88€ä×ÅÞþN^'­%zg’ovìÀéü€»¿K ò‘Ul{&ò‘P)I÷ª£]á]$JÖTO¹wÙq¦h:‘—<†Î8e'Fsö>þ–{d(SÿÅîû(±•`w"Ùð0 _«±D²ÌåX£}¬)¡œRxÑô@'ÒeŠ>eÛ›YŒ6’š”Mñ°Ëß0£%¢†—жÎêö­«V¨ŸÞëÊ¿ddÓÉW…Íà$⑑އŠ)ûBŸwW@+bž¦Q÷ýõ®÷˜á:J§ðHá`’±_Quš‡¶™ìÖËÇbü¹ã|P’¨ 7»Sq7‡-ͼ*9{[®O9Lj>^jzaAሎPÆvó¾¥Ir©%~\δø)î £ãäÇMv­b†»y}?c}Ê»¼ˆA–AX;ûH—?gñ ðž³ò Oe ¿ŽdyœD¯ÂÃX"ÙOð0ÎD1!mP«c®âž&oš^S*Êô ‘«6˜#˜ Åí&˜FTÜåJäoŸIÌÅ`à“îÊe˜‚†1õ^ j!Ý|„!$•é1V¾ƒ“Dý‘Ôa:€¿´¸`^÷„¡#‚ïoo?ßNd¡\v®¹ 0u]Õ³TKˆ€Oûàœaò/0&|ätú¤dâÃð\ aˆxùøÅðdââPÿŽÄžŽ5¤€êÇGØõv±ôh?3%x_O©r$͘&ãâ˧œÈ÷ÅÑÕä…Ñ’#­¾µr|I$þ¯¼wFõ¯Ü.‘/ÛöqúürÉXéRu¤¨Ò‘VHM#çmºÎÆñ2~PNr›è¤ s)ºÌÖëz¢ö\…$£³ó.óÍ(¢úÞ¸$T<Õâ2?2êšÁ4eQþÌ‘2¯‰³AíÐÂÂd}›Ijò:µõ‡=a{°ÔgµË'#¬àF‹ÁšwŸ?}YÌ@ Ã0‰‚·Ÿ3 h¡@7:A–ÿHÿÌ¸Ž¢ûó4§¦žêJÊ;ª5m$¬~ÌiBŒm=î9©d …½J©¸ÖÂxï›™LÀ|ƒêÅêkÉ)Êmu`ež¯]G„ÛD” 1Ý4a9¹ ª‰ƒ¢m_狞Š2·‘tJ¨PoŠT;†V7˜&Ÿ–öÞ9ï€:¥~1,”qŒºnÔtsÓJj: ­w¸¯ìºœr… ^cÔe¦ ¥’+Ž4%-ʸ³—kåaYÕ§@R25'Ï^ó)Û¯_¶Ô@;Ö¢t="³‘KœUU6mV¶Htjú’L‡LßzAŸ^tžòŒ|Áªö‘Fß×¥ºmŸÐ†ÿ`×wÜ~ˆØº¡­á:ï&²#Y—M±Å´TÒÀÞa .5ÉQËuHYb!›8ÈÒ.Íæ0׉ƒ/mUg[·\XÙ}Þà ¸cs°«…Íaç ›® $ÚŠ’âO 5?ÑÞ—Ú1Ú Á˜¿[SYç½.D¸¥é£0vî&þYV`·åÖmˆìr!·3w“O‰ŸHPZã#=;Qç´ ;ˆ%½8xŒ-\ÚDÐ[û¢>(d'ÅÓ]^”âtzÂ8OJ‚îÊѺí úÜaÕ6nmèR ‘9åÔB ¤¹ß±Ÿ5÷8éd “zDwrSô‰ˆ)ÕH_ð‚¡½[¶šî_‘(1S“Γh9ˆr¦ˆ:ûxwcuÌ#m†±:Š]RŽ’=€”mt»~ i_ö'nHCnd<4¹›o—?¿[þŒÿØÕŸvÏ7w÷È䣿szhÂk±+(œgf x˜´íFøî·éN…8îËw³ÏÜx5B”¨h Ìœ]’4 úYˆ8¯|ß# ™h³æÄ#7sdAŸúcÄùbðr”–b¡×Ò¥(m:zýŽ ÔrR ø¦²›KšA… ž]é­!õ/,œ€°ŸMÏ-Û•7ÏvÍפ‰´#Û±O~qnôî¨`ó>RDÉçB¸oíËv\¥Õ¥êGT5Ê"ÿ„Ô ÿøÝPÃEMTÉßüáÿz¿¸ú'þüáuêendstream endobj 520 0 obj 2530 endobj 524 0 obj <> stream xœWÛrÛ6}×Wà)¡&^›¦3Iì‡4n3µÕæÁÊh(’ØP¤LR‰=þ{w‚))Étä±-b±×³g—Ä¡Œ8øiþ.·£ËÛ€¬«‘CÖ£‡S‡¤ù³Ü’7Ó‘ Ó%H1Nàgº雌p?¢Â%ðÉt;²l6žþ j@˜qE>ÊM“‘ÅBb㨈6 #b{¾:ÿR¤ ‘ñv—Éhf]}ËÕüJ.ök’,Öýýu]—éb_KR[÷Ù•2—LoFÖ?ãç#R°„@©¾u—®s™lYìóš¼"ÎK¼ÓÞËDVKrq‘e‹ýJ?7§×eY”Dªßæ$%Y)+ó€‡Êxó(Q÷²b™¥U=Ïg–ñtBž) “gÚ‘É3¥v6FMéŠÌE¯ÈÕÇùÕÍ_óïgcòíÈÒ.¨8:³ôxþsõKòâEzBO@¡_GÖåù³’¨Á ¨¯Kæ¨åó}ú‰’7E½!ý¤ÅyBêºg÷Ü‹Ë2~"Ū“'iMvä®"uAâR]²¹JU9ÉÒ…ÊÝü„:Ÿ” ¤;/jRìâ‡=½.÷˺¢äâNúuÞgû™…˜!Æwû—,™WÑ×ó›oçoà×{̽òâø®¹zxéêúî­.Wßô¿ç”h:ïî¦gïŸxty&T§p—Ø®À#A¹§ ãSæÐˆ$(éúÔ€CÝj‡œYºCÛÎHÛü Îˆê¤³…Ct]*XŸï¥ DjÖÃëêÏdŽÎÁ±î¶‹¦/àð€olí‰vÙjÀz¤ÏÃ6:’µ¬ÛN\d¢å0/¤œúŽKìdpQ]Ê,®ÁÕÕ>_Öi‘WѪ–qÝWˆìß U6àÐÙŽ;m+ðEv,È(sÍóíB–ê–ëÀšÜd– êFÚ8w˜7S2ÕmDÔ÷xsÝ83ÝÃÛn?ôãò·AsâMÐV%ëj Nà¹5º”žOýV`ˆúÐyèlÕãªÅ‡°ƒxi(‚šÌ t*¸Ð à_Ðo)í²$Hs@¤Jóu& Dcbˆ3:NèY; Ñ Ÿñ,ã*ZïËœŽ?MñÒÊ;í®òþ]MN¤Ã Aó¿ z.ûN8ï1ŒŽmÏqD¡ýJÙ?P …ÉvËùCåm0tCCU޹ñF®…ý˜V$ÞíÊbW¦^ªÍa‹°ëvê1W;ñ ÒDV™Îóë1]@JëMœ}eNHïÎpÐ@šG#0ÖÚ Ó òzˆ:— Ÿÿ0ˆ¡­PŸ–Æò‚»I¦ZFPql=[@÷„"ê¦Ò¶kKH¨çEÆ7us?¦Ûýû»ÈpŸßájBp2ÅÀYÖ ¢¿Xt"Ïz· shã!¦UȼÖõ1ž*€jù Ú¹ jÀ›ìI•}¥++-A[_7(-Ÿ:g°±Êt‡ÿk0¸@4H;çHÔ6ý©ú½"7%¶ФŠâôAƒ:$¸¶ÉL'ôm‚zÂ4Âõíí‡Û#n1&±68.Ô¬bÔéN:œº" ¿0$s>Üs¹‹®7“µèäRÏmI·üŒ%:bŽfzt0??Î_Oç¦<'(Ïx7hb­!­"‰ëx¾•8NΪ qôžVg»<8õ¥Ž¡ëç2“Ûÿ£‘µ´ ÕÁ¦Ì<–\×›¡០ô„gûJö<:zá‘!^kÎ]ØqLÚòdèpß_ Éyœ$åy|;hÎe0B7Bέ ˆʞÁ;§ÜÑ#ñ®.Êx t© `¥XÀjKªýr <äà ¤X áŠcÕùq>ÊbkÜWÆ«M±ÏÀ¢$Í^Š(¤Ãp¥¾Ó.œx=RW¾ndÌ$’¯aЪ‰+]à]Fƒù¸ ô¼lWàc/¦î~kî`Õq"4SÙH,@×çãü¸!H·õmw‰E[ÀääNKh‚f:5ú]Bï+P˜Ö‹'ó2s ¬CB˜u ß#¦À¥¡D˜`P°vWK[(@Kœf“PȪŒ—›)I²]¼¾µÁFÂ;S:”} ë©·®±èÂjaCO¡Ü­lûà¯f[]×x‡ï~vcxò¼ÊAYw;`4 Ìõï¾ò_OGÀç?£Ädpendstream endobj 525 0 obj 1637 endobj 529 0 obj <> stream xœ•WÛnÛF}×WìS"↻¼-Q¤€;@im¥}ˆ "WJtx‰âý÷Îì…¤(Çmaò8»3gng†_ˆKqñÇ|¦ûɋۈlë‰K¶“/¦„Ä|¤{òj1ñÈ"…SŒø]l&ú&#<Œ©ç“È Éb?™:l¶øjà0ã4ŽC<·È&SEgq‚ºÔƒ/‹ãdšÉ¤(Ê4idFŽy³#ÍNó(/¤y¸—xÄ@PîFýÕï««›ËÕÍû׫WðçµúSØ n™;tÑc ièû±ìòšÔ»²-2²–dS<)b8äé3ÝWÐyý \óbPƒ{(ÊPóÐ5ô£Ü g#ObÊBc»(ÖíÆ° = ¬­óÃö¿Ä†»4 ÏBsu}÷z¤š¹.6Z&ŒÈá<¤Q ˆÃµüM¾m+<£‚ÊõJ9H»O=.lÚ4û8½þ–ìï ™ì8‹¡T¢ œ&ÕfŽyÝ,§ËÙìÅOC¿Ä4Š{H_Ë<#Ò(ZN¯Ž¨àJ®Û-ÉÖÛ¹þ~Ù4U¾nIêr/øšféf2ýkö6mFË]¾=@j‹´l yIÜðŽÞ”i&ë”\¨tiés+¼®ª²"Rýµ’t•¬í.”mó(;ž8naÎÉ3¥þL£˜?SJ—3Ô`Ðç²4j^•êßVïß-gäÌ­Ö(ï¤8&5as¸2²Kºgk)„†‹Êc¸÷¡–D{º“•¤(é\ÐØM•/§v}Öù±ÈVõœŒ[óþwoïaÝê[ΉGkB9{¤jØÓ5ìzDåjÈ2 >—dx4à4€rµ59ÌÃjS͘ ®zÓr¿’ßî«GkÒª05©»ó´uJ”ሆ£ŠëëvPi¿4ÐK#ëU~˜÷5öáPëúÔ²B…]uêòDI¬‡¸Njû™«î@¬ øÂýëhà¦ÿ 0FÔÃ0kyá;!X­U$GÌGÔ×÷<ú‘IFÉYzD=ϨÖx7í!U$%]®ë²¤¦*€þcn‘‚jOóõØÓ^abpO<ýQä®R¯ïÕ²©ÇAùÅcx4ìN4%¹/±‚àŸd¤Êñ Þ\>®“ò‘Ö8¦<6TÌa41¥[V0Ø*5Kp¨Ðàv ¨”²Ð£ˆú»º~ ²®ñÔq—§;Œ»V—!X=‡hyÈ©ˆúþ¼°µŸ‡ Ü”‡ ¿s’Œm¾‚M;uSµi3šX¼1îSÖ‘ n±†ï€N Àã˜:ÛÏ›¼ë6p6æl€@׈„Ì ß&énd^lXO OÍô^Ê:“Ú¥¶2Ù†EZ•88æ@z+;Öb X›³¯Þ€†û¯áÉÏÉá.gýíˆÑØŽÑÉ¿^L~…ŸT”bendstream endobj 530 0 obj 1684 endobj 534 0 obj <> stream xœ•WÛnÛF}×WÌSLÒ†»Ë+‚Hb§iã6i"7QAPäJbA‘ IYQƒü{go”DÛH ºpfwfΜ¹ø ¸„‚+_æ3ÛŒž~aÕŽ\X¾Œ¨‚ùÈ6ðr6â0ËP‹2À¿Ùr¤OR`AL¸!`¶9S:žý× 2e$Ž©7ËGsa*ESF9Lý@>¤Ä£øe?rÚu½+sXÈEZ–u–v"‡}Ñ­¡[ 0Šº‚î°òt%6®0ÎHyÆÐÕ§äêæEróîUòßÞJåP:€ú„™3dvô:$¡™ç뢅Þ5å=|qSêI WzÿÙYÖèà˜ùÄu™ïìÑõÅá‰t»^Ê@ÆÍ~=õœúŒa`¬•åb·4±Y/yl„»¶¨Vÿ Ê\÷°¸ºþøjp5u]b%ZÑ”#8A S¦Å¯‹Õ®‘*Š,"žo¡' ÷g‘MxL†ö|-ùì\M7ÛR, ß©‹ …¡“6Ëã*‹¶K–M½IĘJ<=ßùºmæÎ|<oJ9%Œ½—wu‘ƒ0wÏ«½¼óJ,v+È«‰þý¾k O»tú÷mÕ« 3VŠ m Ë2³7#çÛøBFÙT›û>í¬ÞU<÷™ß{îsE+æ!£¸qÂ|Õž‚4¥r©Š5ë#Ï-™9ÓYpÇ$+Y<È]{‰á®ê#Š äq/$nàÍéªÒ˜ÙÅÂî&Ì?¶‡Z-1òÀûã‘N,pþCWe²¢˜P»§p¼#Ô„°Î˜­-ý4~a€kRÏëSðÐn“š¼{ŸüüûmRàÈ.²¢K¶5ö@C*û„so°jÕ[ÑhÏñeWÈÙ¥¾ëד\‰'" –2êx‹ ½1»S-×ͬn‘uå¶Ma4"'zT¹jØÈ¸.ΗMâ…  ï FâRP»…iÂ#‚nh·#J"MR›Æ¹#«XøbÛ%ÎÍI„aUBäØ5ÑÙ£§ "„¾ƒe“n4î;)ÀØ ”c¼i y¡ÉŒB÷åiå%jô$«7Û¢ÔgvUѵXè¬ÓóîâÄòÏÓ7Ü =!U¢:ÄCËm‰Ì™Ë±,ÁÄ (V¶äŒNÔÅv„Ðé´ezº#A0 ÞßZ#*iVEý_®a-Ò‰çËá1³Ân<”t, ýø¿û@zº°{û€¯k÷ƒè×mÊ%j¶ òcè¦{ê)JXøä7ìá8œèñtˆs°ï¢?ü÷ìz6ú_ÿ6Ù1endstream endobj 535 0 obj 1537 endobj 539 0 obj <> stream xœ…XÛ’Û¸}×W ü²”k„%.¼=Nb»â”“Í:ÚÚOjŠ¢ ‰ŠÐ”åÉ×o7.©ÕÄe—g$}9}ú áßIJIñOøÙ?~.ÈÞ.R²_ü¾`n‘„Í‘üe½dÝÀ.Æ ü]ïþ$#<¯¨¤9YÉŠ-׿ØÌ8­ª÷­·‹„3²Â%0Q+ÎYe¹[oûl/µÙ=wºéZ;<ïŒ>>«o'ó\?%x4+hNVLºýïÜÞ †l^eŸÛþ÷à꧸úKoÛ}¯¶aK§`Ïqñou·#õvkžmû?5Yø¤›­² yû¶ë6ç®¾Ä ÿöFßb”Áf:Y~oŒ6ä­ÂOKXœ ¶ò9p‡‰ ©¨ÜÁõ¡µdwÕ=ßõÆêN ŠºœDEeY ±êG.i_Cpó”@(þXŒ…§)•ÒÌi*]$moUo)ÁðÀJä’æ¼ŒÀûL_3û´àŒ¦XW—š3óXİYšÓ"ÿ^äõ½ÈYIe–ù“ÎW惷¤Ýª~h›º#ƒ¾¥›àåœzÅ凬ÄPI¨Z‘¨ˆ«Ä Ú¨DÂC$Œ‹X§¯êÚ ° Ã÷_óB.K–&õ œgMS™%ßuÈp¨ñE Nrª­U¿Yþgýwl˜ 83fÒŒ.àq‹CÞµA¿yJs‘ñËþ|XnðVáq¿cl„›Ìó’ŠqS£û¡nû¶ß» ñŒ²–à1ò”ôÚ!ì" ð¿|Z’útê^`·C‰)YV3}Id>” vl xÀㄦá;ê2GÍÙÃA]¤dß ð*eÜä©(K‹2d”—žø"HLAsóâñdÚz¤‚D Æ^)ü~Ð¤ÑÆ¨f€DA³”@²3õÑ“¥Pl1ê§iزC|\šµ%Ûv‡ÛËŠ–䔆½¥ß¼SƒiôñÔvþ̹o ¼èÉ¡ž±ŽeWnrhhoá«"Û‘€EÄÊ{.H©xÅó´´–(ñà/-i6¶í»_¯,/)«x¤ÜãçÒ“)§y~Sv°o£W79õ×ïÉH™e&áþHóÄ3àÇÏ%AÀÛ%FPßó9eŒ|j{¤GŽy¦!O/Tÿ<7ÐH?”q8Ú‚¬â™ ÉŒf‚Gá²Wé‚h ´¥îePü/íp uÓ I¡:€ôÞàgZeÈø‹[µA¯¢*Ïy¿¾{šçÒƒ4¥ }©ý ˜gX­ñ\´'ÝoÑ‘ÕgÓ( ¸¯û-9½d€cYòäkë6Õ䨚CÝ·öè€õ7&§¢p X¿ý’€[p[}ÆÜ>÷²¥ËUyp™'ÝpÐçýáÁÔõÈÎy§YÅ"å°Ž(]ñPwÿ…‹dçñÛ®"Wúo\boÈUZÒ('7GU÷îó;ÔƒÂ6¶oüeÄSšÆîB;^,?öÐGP[j Úà'è- ‰Và“ (š AC/¡!ÌÏBã;@‚½KÛudê8©ÚÎ&¦= ,0ñꪻ™fÆÐoâF^C趘ˆô¡£â÷ Õ~×Ìf0Æ'ø.×ÝùØÇ ug5ÄŒÕ6 •BC±;¨™æò,^p/—iëóLŒ)݈Œ(ù` Ê=ªÔ05’â6T¼ §á†¡D@߃͆½ó µÔÇ>ÉIz“y…ÑÂs Ù¿veD¥ °ÜðãÝeYAGepK¹q›aVT/Xcî®ÿ<*tòÁ%Ò;t’WÑ4“™AÐJð83|«§(ÖÂÈJvKGÈ,¤‘¿Þ ¿×¦)„çè 3Ö¨Sn†ã]ÝïÏõ22uoázÑÆWÙÁ:7½ù&¯y1Æ„7w£ÏÝ@µçZ°Ÿ˜$ 'Ð {ÐKž%ä‡ÁÀË*³Ò¼~f«T‚©ÆXo4 i¸5Øã]P½àe5Ê8\VÜóçÑYû©4rl¡OQχK<[Å«Tq\ÐvVŒ*m”„õŒá"£ešUÿøK ¶»¿6œ>…1¹füÀ#wVÉØ BŒ“´îðftPfðîÇrIyáUÄè®Wï¼ëàÁ CòS°5S×{Ã/Œ²ˆÛQ«nßp±q›Û{Þ¢Hëæž]ÐùhÕ’ÏÇCÿ.„¶Æà^ +ý¶ó ·Æ~õÓ‚õ"Úkû9{RR™ºÂ&øöÀ?eÕUhu™V9{Q2¢ÀÞVÃsAËò>Žw_\¬4Ž'÷€\Ih±<7/”Ѧ{¢à¯8ˆ«oÃnû±GëÏ.ü†W\„r]ÃGñ£ólj/âPºõuÎd“™<óçp¹™¤n†X¹p…E‘ØhÀ%¨Ÿ8¡§ah‡§êøöeè„á-óÃLŸúÜàBÞùÁ»p¢„”c~}œšÊÆ;ôó‡ .m:ߨûvÖíLÌüúˆ¨|¦xŸÕS4¦{bh¾ùOÔÀÞÙŒ5T2÷„™?*¥7v£-};erYQŒv¡¹J|jÎì*…±sPÅkxxxEŸ»Úüéòƒ“L— (hl#ÛM/ÅÿØÃ@lTßâ\ƒÒEÁÐj´Ç„{܆LÅÕ`©/Qøðx9ó”³ëÁJ0’þ»ÿõ~½øþüqŠ9ýendstream endobj 540 0 obj 2041 endobj 544 0 obj <> stream xœ•XÛrÛF}çWÌ›A•0ÁÜ€AÞK›râµk:®”¼ÅÁ¡ˆh\Di¿~{n1¶SR‰¦§§/§O÷à Š0A‘þqŸùañÃ]‚ÚE„_Ä,"÷‘ÐÏ«C«¤Eð»Ú-ìN‚hœbÆQÂb´:,‚,W&§i¬åVÛE@) õÒw¦5„>C‘êe†©@«Ó"ˆ1!`Õ/ªÓÂöq¾ˆ)æ1—NÕO¿g¤XÆÜi ÷êP½Co‹JµèSPTyÙo‹êµŸ—©¶(¦*UWW¨Ôe›RµŸ–Ëÿ®~:JŠ•) ©ÕŽÓXØVû¢E­=g×WyWÔU‹NV½àAÝ|nèÏ*£”Ù`m,0O¸sãùF»̹Y”béÃõñ§ÑG‰… îùݿУ^¡"¥ö)ó¦ªiÁŒÎUó‹4N¿®zðΠ×ìš_ p`‹º½š©KuÐcùMK¹ÙÅ!¡Œr®ŸSœðÔ†q“µj‹Ô’pˆeÁÓQ5ÅAU]V¢îdBGÃdˆX–ÊèàJw ‹#â£YöX ˜)Ë).9%.Ð÷Áˆ”5 ee‰Úþx¬›Nmñ2LhŠ£T÷YgS,A¦œ+´­aûæÙ!0‰W·v—äAÖìÖm“kصŸ‚OK8Lo0UµEбì‰wê´ Op<€=Ð;OE·×¡Ò¥¢%DŒ%òq+×Xö à#8Û¢­jó¦Ø@öªQØ„–R”#ê9“+ÀAQuªÙi9€ *EƒÉiåF>Ô¨ÌÞ/ï>8# çrùOÒɬv_ ÓtBòƒ€$ÜØ¾«›CfJ¶íó½O9Ä>³É£Œ`)’YòºúXähã@³à¹v5ÑæõQiufƒm÷ºØÑˆ'9ßÎè¢íòÕ‚Ç8‚œx»OKH2œ“%ëÆÉ jò{}’\‚ ãg‰–¤N^K½]@h:´=MA¨Õƒ)€åýnŒÄMØ.Ե͚Ùn>TmñPd®-٬뾻%Tb +÷s]—èªh×-@ Tko-M„4I¯_×€ª§]åö‹Wèdn›¦nЕÒŠW‹Ðšk]^:BÖý¡UAA%C#ê²ÏÖ©I©´`Ýv²6,’”uð`²«‹¦¨Ž`kS¨«áŸ¼>‹2Ó tdÀÍ‘ðµKë}UtИ^°† †c!&÷R7on1ZÙT ‚Ó$xÚ‰Ü5¤º1VjÐ0ꬴDÖkrÛÕõM]Ãði›ê41[¶e~ƒ°vô }nlò…x$üÞÖ¥[ÓEK·Vµg”Ã|]}ÌÐÎpòlHÒ{×7oÿX¿ÿm–Áξ7FXH×AíÖ=pU÷ªÇ%/NG:ƒ@·oêþao|t¹3Áà¼Ñ• 4héØÌ6‘þpo¤Aò¼ÂbhÇž½ïÞ¯oß­îþœÃÑ0ÙMýõ¢3`„öç²+<ÑÆRc–ÆÎŽ7»‡¹!Šä<à·wwïïffÊóÉ\uf^gzãnj† i‰ÏÏõˆè'©ßåã’èÑ8EçJ‡üxÂK‡ †Áiè† fÖ²¡¸€,¡GO˜Ao$là{Ó ¾@ë2–.ȃ-0¼µ²:ð?Îíq„:¥@Ã;¯ÎòÁŒ–&C­ÁWŸg=;ºj{4EJêf7Tõ‡ Tõ®©F`R¡Kg[½|hšÎëÎ9ÔyïÒ*m‘̧+h›Q”$¶ %C6aɬ ­§PÃDÊ؇—%&¼:ÙÑÓ.Šb]uQüÞ̳fë\¶7£§Á¿À󰇄ILR:ÿ¼¿\$VÇžç|uhvI¨€±ÿ§š»y¼õpP¡º)&kž}W0Ì`æa§ÚEc™ØhvcôÆOJÑ@Þd”¹p”Où¤hqƒšà£”*[½C–ù/€ÃŒ„Ž¿`FmœÚ!»`,$£¨§i© vú^ÐHh§c‹ø§ 1C1tÇ1;:3xÎb„ÀXÇ&0˜L—  ˜+Ù˜Ï  “|̾ô꬧ÏN… K?¯]˜_.á.ö7—Få#{Šà>$ĬVOû†Ò¢B¦Yƒi¾}?èk¦Éö6ë2O 0¦Þ—“‚›ˆ*kŸ˜Ä$®^Ї}G8á!¡_ñQ„ý/æÆé­áj6jm u~yäJß=îÍWj`ý§ìpÔ“w»¯ =¤, NÛ!S§=ŸOÑ!NJôÀ+ÈË× ™È^¨!zkmíºUæ–¾®²ƒZïÜÄ$ePÖ0æN‡ìô«Cö8Cÿj¯Ñ nß5XzÛåû ÆÜ+ÀdnT}ÿ|õ}½H…¢%t„h×ç÷13L S¿1ÛðÏ »í¦$2‚&²ÒáÀwõæ/àÝ’è q@[ÎXפáÔ[ªÚ{Õ‚¡üx,‹ÜPž)§À›HŠe:p- î“6¶¨v}i¨S3}u“ˆ8ȪNc ïØè\ûa$ôªmp£N¹IÚ§Rô掙×}TÝ^;;‘ñÅ̘æ†\–Ïú.‘5wðÆèÞ¶°Tâ$ß|Ûâ^¶$f±'DÌ4œ}.Ù¨FL§< ›áÉ¿³gD#JÆÝ‰¾ƒøíß|Ëw»Zü~þ=u*endstream endobj 545 0 obj 2079 endobj 549 0 obj <> stream xœíXÛnÛF}×Wì[(!Üì—íc+hëĨª¦(’B ¨•Ì”".ÇùúÎÞ(J6b}*P؆-îìÌÙ™9g–þˆ¦ˆ˜/ÿ»ÜO^-2´Ó‚v“j‘ÿUîÑ÷Ë Gˬ(Cð½ÜNÜNŠX*1(ã)Zî'QL§ËàŒ)ÃR¦Æn¹™DŒ£Ø,ÅŒÂ_Ij Ìa}y7‰ªfÛvû¢¯Ú£×­î©L1I²Ü9 ƒmq8ÔUim5º«êºv]¬ë{Ô´=* xÒßVmMi=gL$8‡°ƒ3fýd64h­ì>µA… sA±¤Åðcàyl“@)¦Â£Šîûñy9O¤[ Æû»¨Ú+Tl{Õ"…æwSJ0¡$Šn»š«õ”Ág"EtÜ¡ª©úª¨«/öh°i…§-†¬q,r€Ã¬w†—ÿÖzGEúX–JmôK Ê%C¹8 ÇfZ•«¦Ø+oŠš̸ô%3ArW´êQߢÚª±ç1tßUÍŠÐßZíúƒ*]_2 „Vc.ãÚ"5áQÑlÎñwª?v¾DŸ L8÷èç¬æ×oW7¿«_öf*p¨žÛº#šá,ÏBO¶Í©x‰5!+·X¡¶Rb8ëm«UÈ‚;iNq&øé¤, Ys§QÛ1øÍM¬”à„„¾Ž~lB³Ë6‘)·Ö‚E2tüíêß6ñU½õ‰×¨êMßZ­«u}†;Ô-@r̾óûõ5jÝQòÔñG1 2×ÈŽgƇ­|ƒÔþÐß{çxgcC'ˆ<#ÜÊDqÖ,uªlwMõEY¢Ú7¯m–³w‘;BUWÄ4ÉFµë38"xëÚCW½ªï§Pm)S A®­ OÐo›Vi+jJÍŽ”GŸ+Ý?Ú~h>eËz?õ1O§>} ˆŸ8=Úx÷ƒ×KgQ’átÈÀÜÕΙ +¿Ãª®ëä‘)šÍ¬Õú¸}9}V~«v††3ðØô£µ+Û.Ýp “Ø¡`^¾Ÿ›Î«Ä‚Ó4èÊ®:$ ùI¤ïŒè“m˜–éÃq§‹±bæA˜3†´ÂôÑ:°ß@B=Lf¥-%ÌJyPß+n±€Úr>¤ØUÇŽ1mõìñ¦‡ sñØ@Ïl˜¦Ë…Ö ë¢ü{  víqç&˜ï`‡7¦ ƒy1ŒÝhyk / Ã9gχb¥Ôˆï ÆööÑÁœ…5ÜB´>Âx<—s‰ä˜B¼€é¦AcZ¨8$ˆÐ§U!—8äq4±†Éìô¨l7ÊÝN¹º”!`ä —_—‰˜KÓ£ãƒù6øî2”ÕøhæIügœ„@£‹KƒŠ®+îQ» ×0³h è©î—êaý ÌØzysJÆ4ékŽû5L]ˆ"€ÔÛ gšB ( ÎJ c¸T<ÐÉä[t²¿›š1–ð$jWµriÖ{b§XÐäŒõá"KD½jKèsÔ–f›+ÄFl/v­Š²?µþÚîGl¾Q²û;SOª~†vs¸¯$ùó¥ÛHãW• ²0 ¨5~L¹ý{„Ëm( t »ÛzQGNÃ"'­áÁæI —‹TÐ'”ÞIdJط鸻˜3hprº¾œi»×¯è/þ… »ÿ_ÕŸPun_ù£…:½Hs£a¡uùèf^ÞX†àÃkmF=mÌ k³°óÉ9\-'¿Â×?ެûendstream endobj 550 0 obj 1505 endobj 554 0 obj <> stream xœ•V[“›6~çWè-)*’@‚¾µÍv¦7™fèS¶ãÁ {i¹lÇëߣ#d¼8›ËØ3KúÎí;ßÑGQF"ó™Ÿeëýø^‘ÃèEäà}ô.’ùQ¶ä—Ü$/aã¾ùÞ³'á2£"&JH’·ž² ÿ``3ã4ˤٗWžÏcš¥3AÂDâŸï:2ËRãOf ೞéç¿nêNïŽûàÕµmQia?øõHF=‘©'EGŠa(Τߓ7§€E4Š„ò‹a¿Ý yìënÒÃHƒò?®m…ˆrë(š,ûc7Í.9«*¹µ9=hÒÛŒUgÔ® ;Lhĸô­Ý`fSÉOøûžôà!àvýD HWÕÝ@Š ‘tÀ%JÿéQu«»©hÈtBHÎSÊŸ݇ÆDCuS¬CJ…ŒÜò'\hÖeq:/5ÍR;HžäsíÀÏõM§b×èbÓ&d XèeG‹q´E–Š*°²Ø 0¥ Þþ½Ù}?¬ÊÄàÇ…+®êÛ¢œŽE3® ÁXFyê*ºjÍFcv x©ç5œøšÒr`vÈžäÙª†«ÚINe$ædrkÓëÒQ˜ÎU;[J¥’ €w©¥ xiÎnúC]BY1%#]y¥ Ò¿%ÃMs#žÝõR;KkL}õmì “TeÊÂá…CÈÏîóar!höEÆ_]$Ðÿ—"¨Œ­ìCØ–Î îVŸÓù’٣ٗ”€²ºPFºå n—Ô0‡TÀÊXÒHðÔÉèÉHó8Ð`0(2¿Äȶ•&÷åvwïß7Zí0œ†¢O}]‘jÆ»…A~+£ñ6ÿÍÉM…í¯=tïÓ„YÝ–öåsÀlݸ­wÃÐäµ6pêÙ4 -4wúÛlæϪ7RIʾ}lô¤ÉìT1Õ}g2høÕê¶ÎóÛº¬)Âx^pû¦°‚J'UNCP/l]ý­„4޳3ë&Z¦Qæ”ÍšnzïC†ðçxX+‹V“ýзŸ‰Œ¥œ&â‹©Y®^’èw‹6¡ÿ.îÎFÍå¢2¶Ò9èé8täÜÉøÐ› _tv&â.£t0¼˜3s¾šŠp£I#gÊØ,#ßvͨÉɃ[žXÏ3é²g\²ý±ŸOã0) [ÝÖ]-†I´Î1ÂÉ]¾Î.BÐëîüàGí˜Õ> stream xœVmsâ6þî_±ýL¿ðÚ›|  ½N›KZâöÚ °—àŽ±r’Boúß»’ŽëÝ HÚ]íóì³kß À×û®«Ùž¤ãÓóÁ Ì!دt ßÅNqJVAô/Ú3€p0ö¢ £ÄkÇííøo CÆAèÇmgŽö¡«(ÄØ†è£1tûsþÂó ð•­Ÿ Lçî͆‰er“#¤U’å8okç ñ­ã~l·œpä «72çѽº„é“w¿ÜN¿…›÷“Ù}j[ °4E)½v7}ß½¼jÿÿä =ºãØKnóá² ÿ‹jI‘Í)¥ßèGüµ¿GÞÀî¾Ñ›Ý`2ñqò§3ÐS^• ®Á7.ÿs}ÂRU±BÒ} ôËi„‘ïõ¾&Ýûty$ßóRá«2ÖIjưõÙxŠ+V쌎±=¬YQ€b‹BG#ã½#ÿkPùzç ªßJyÈã…ÌyyŠh*€BìäT)Pî7H7žçéâ:ímÖ}M¨¸¸’-ªe V(E¾Ü’¤¬„ŒCÉÕ*/Ÿ`ÍÖ\¦€Ž%> stream xœ•UKsÚ0¾ûWl/ÛñƒgÓÚ’\šN§)m¥ãX€[j$I;ùï]ÉÆ8ÉcÌ`YûíûÓê?„À<å{š;Ç—=˜+'€¹sã„VåkšÃ‡‘ÃhЍ0üfN¡BÔøqzqF¹ÓôÂÖè7šApùƒA×àF©ÓŒºàš”&¼0ý6x®Aô|Ü\;ÍãC ƒì(´Ê(‘S½`|îÃá±xáEýõs&•6€^T×Ϩ†¥ÆSz z!År¾’e¸¦0cU1¥ijm·c4è…m<ã”1NA“IFaAIJeIÔ÷ûZI4u éšÈY¢äÔ¨©ÄzH¬wªÆM³™L×ôV»ÆÆ QÔb݆QDä’k·AyZîR)Ç­“}çlã"‚7§0¼J†?’/ŸÆ-ø·çKõmSS˜4»ƒµ|þ¦ÌÊÀ.œ¦¤z)ùIë`ÇÓ½-ñ¶ìWB^+D=¬úLH ãýåyäÆncœz&»´èĸµ_nÂÓB§ƒø¿TЇ Ýø7Ö½*Ý 0x›’á×ÑÑ£uÚF}çŠÍ9zI™,8r -ð. ©f9-ä{âYFù\/vÄçBæÉhvá0O;).+ãVkŠ $†Ò0] ‡œl}®cKVO0ÌN&;c®U®3̘u›d]h”i!áŠÜeÄïvÉ`i·z)íª£ +*KÖmÎÒÓ|+Æ<œ"Û‘‰¼>„Dd§çwëüD+ ¦HX/¨Ä<ÛdEÔO;n®NŠŒ]ÓìnŸ|k¦ ÌqÄTƒ"¥š°L½}ÍŒ"O̲ìÛ³cˆ'Ë™Û(”ÌŒ¨wí©f½xFœI)pÒ}Ì(á°üc,#‰ç.'š ^õo'§”âŒÓ]Jq=ßìQYN»Ã·¬Þ++YPAqø«²œÀѳì%¸T…,äOöëÑvÝ¿:³ÚUéõCäœGÖÔ%5¶ìuÆ~—Ó²¹Š·7g§Üó£àÇgrQ…[Å^è6söù;÷lä|Åç?ú@<,endstream endobj 565 0 obj 809 endobj 569 0 obj <> stream xœÝV[S›@~çWœ'C4 Í¥6¶Æ‡ÖêŽqK¤Vw‰Ñvüï=»\B´íkfÎõ;ß9{à ÝC\å3H•}gs®0WS*¡|)|pÜ­L ðv#¥ð4ÁêtûvÜTQ5³ë~Ç0hlZúhÔvn¨¨Ö4¡Â£2„fÚ¦~Úa_X t.uŽ“D˜ô~ámHM~G %)eÏs`$!>'a„<‰3â4ËÉS.|5k¨A3dr? ¥ÅlÁOÂ( !£Kð9ø'³0æ|F€ç~B`w;Nc ƑРñY!®’ºN! è"«%²À`#â ©ù²Ìª\5á~ …ð©LO–>‹¼Ëxž!ü¸ÆÐäíòrâ¸ï0×°Ä6©óg‰€(áŒÁêÉÚ$ÁUøÉÓ=aqJ2¬ò%ÕòHIHw®ã1ÍÀxŠ £/B¨×BŠdæ’HšÊ&ùYœÍFøŠ­Êh¦!©Yè³PPÃI.u"*‡;Â06ÒÝ©¸±†qJYÛ@t8M fÀT;0UÛPóiw»µ 1ù*Bÿ ®¬ëœæâÍÏaùf… Ø+QÌZnQeYz ‘-Ò ¹'ƒV¼ÀÉõ±sºÎC‰–3 3†PöŸ³@$à&ôdB/b4õŠq“#8]HÙêµx;å÷vê•FµÂóƒ|á'¼aP‹De;„±i÷h ha ´c¬Ç;9»ò.>O»Å,¯™FÈÜT-¦‡ù=Ô™Ž`o/nõÁAd— oâÛ^ƒYÑ•NBçq€(;€ ³˜p½õ¿Èj_‡P»‚Òy IeÞ‚¨ÔTpÞ@³ÑÝøIBo¶ÞÌ‚õ×N½œÚºwÛrSó+«­ÿçÞäÜu¾Uml´Á£+¿£‹$„†Hï)ç1žœÌ¹8zõÕ»š94 I¼u?)…7Éà”²õ(ÒAë&oÅ8qœ GÞÁ¥Ýˆ”.%)xVqÐñnð(—¿!¾½eòV ÛÏß3Z|í­úkoÊŒ¶%Ã8²\ùWaÚºa—àÕG{õqXÊtüyÀ—/þ3X†e®¦>Tžüõ˜¸ÊW¼~¦–êendstream endobj 570 0 obj 854 endobj 574 0 obj <> stream xœíWMoã6½ûWÌ-RsERŸXôÐ6)Ð6MPCmP4…!ËR¬…-e%:nýï!)YVì.ÒÞŠq,çã½7Cê#xŒƒG?ö3ßÍÞ-"xèf<Ì>θ^û‘ïà›t&!ÍÑŠ Àß´œ™D˜0éC$CHw3gÎÝôºAc.X’„d—®gŽˆaNKè"±.æÜ,„yj‹mU˼©Uñ§‚¯À{OæÜ‡ôÚ¬­ö¥y|f¾ç;V'OÐb™åjŸm»—–Ó•¹ˆæD0ø_ìó½[Ä@ß±áÃÜ×K’fNȰ¶kŒI–¡`BzO¯kë»,TVa2÷Î¥ÃYkм„ÅAlA»ûz@S拸Gsñ]zÞ÷®U  &> 8Â*ŒéN%b“¥’…‰ÆÏïΡrCî!ƒ±Sߺ¤?˜h>g’óÈXùfïÍsÕ¬Š„ÇæÎãwŠØ¹Û5dz÷ˆ^."æ‡})—‡¬-—„ÌÒb0IœË%BCJ Ø&ë`U ÿ¶Pû¶.Ö°zžêHrÔ` 4­u¬®Í‰ün¹ºw^ÀDÑxd Dòð_] Úd hh%ºÜGǾƒ”­3•é"Cc`â²ð¬§[µ1áû‰]°\çY¥P!m¥I™cjÖ“˜yadIqžŒx0ˆ‘gÜïa\ŽŠà£gRk¬RPã_’ã8ìñLe³Ý6®˜ç‰P?@W(hJÌp»í˜%U. *"∣Âqn¬±…üyÈÿ %ƒº‹Åcã'Ž…_e«m±lʃh&&:™÷n¬bM£TØÛO½Œ'ÈpÒ¼fÃ/uW=ŒÎÁxº8ŽD4ÔÁéUÛ6-œc¡œº¯'“žÞ»ï_ô]€|ô55Ü }[C·Ïó¢ë.—ªƒr_çªjzEwÄæb q(' Umž¯>¹‚Rƒ&â„õ¢¢¨maÛÚí½KLÒ^3ðìÓ;{02õF6Edƒ¬TØß´[/mŠlß˦5¹çÍî±Úf:ý}]) ¦6m³47"Vú ê»W®A{‚RïGá0¤½hÝ€ ðÇHe°0ôûô‘%ß ‡Ô ‡>%6},2Ú@ƒ‰y?¶Í Õó MMJÐqŠNÁf×c‹ß©ÖºUQU5ïL¡ÙªÙ+È4"¦­l°Ó¶Òò´ˆ¹Í ²(®1­9 ´¾¯±Õ:Ê´œPbQÄ"ÑO’‹ ’¸æÇ±ìGéÝòòú×åÕbq»˜à™èY1À`YF†é™ÕkM¯ŽKÐB¯s(h´FñXûSáËûד=¯±8rê &eœ–ss»¼ºI¿M5?9?Õv u£ì Õ5±áT–¶%úÇ©'#3Ç“K€žÒŸ7ºž\<±6•wÔ[o_O½·O.ëê?]W¬ÃÑ䚈"DÑwmÏßí·dz'â=Äÿ$B=cLß< G­© êýŽ®£mfp‰—>ÈÍ ‚׌W”Ñ-Ô7ÉõâbÑIB?Î÷W[™.[ÿ÷ò¿ÞËÙËòKz™Ž®åºjßÔÃG'_Üĸ€ÇM¾É°/ÏÇ)ùã»iŸõ¦Ó†¡gÏNˆ2®m¶,¶¨;Ö×ý #Ë#¨F+f|Žáñ¢¥Cp8íGíYéž‘ú*è, ÌFÚ· Ä­o.y¼ÿc¢ñºøä§ìß„~C4»qD$õ÷“¯ŽWéìgüù‡Ûôïendstream endobj 575 0 obj 1330 endobj 579 0 obj <> stream xœíXÙnÛF}×W òÒ°¦œ…CúÔÖÐÂIP…­QÈ…@Q#‹…D:$ÛùúÞÙ(ŠŠ“Ð>2,i–»œ{îB½G&(Ò/÷^ì&ßÍtÛN"t;y?!f¹·b‡~Ì& eœ"Á_¶žØ›Q!1ã(ae»I0%aöˆÃ„b)…>—­&•hª·@„t"¦”04…Ù?+êÝ]¹Í»²®«²QEW7úF‚…LÇÚãs'g•)ŽXäT¸'Qv? 6y‡âQÛ5eu‹vù#Z*ôæ·«+T7¨Û(¤vwQ:%‰ÀÌ#\ËbF޽‡Q¶QúLœ Œô‰¹;‚îê²êTƒÊ}iŒ£ˆ“ ß–+´¯ºr«u…f¿ Ñ <ÁI”:§¶e¥E B:›÷=•½ë›¼T…V*ßnë"ïÔ ó©Œ1‰8š2n±HbãÂÏ*òV¡zTÓÔ÷¨ç£(%úªÝº¸^\\ý¾¸œÍÞÎFFI‚IìqO¸Å¼oT·o*µByµ²k­—Vu°ÐÔûÛãX+%@+!âÞÔÆ)%DØ…h8ÐÃØà-<†˜SÌX,½yóvqù&›ý1OÈ0°Á}¹Ý¢ªî4a¼OØ^IÐXDbò`žÎ`j1R£•>Î0”º(σû¼Y/Ú&$†J2(tÜÛÅÚq& Ê-|-«•zPíMpŽ]šzS:°p@+'Û‹<–tav¯4Ë~²,CCÊЧÝS#ÙÞ{WÞꘞ¡%pÉÈ4ôÑ«“3E œ?_žl¨jå«€ÐAÁ¥aəޠ´§»¡ÁMø½ax„ù¸*@Øé ®ËCaà˜¤N hâ6Ÿ» º°ÉKú˜F=õÑ ®–8¦n}ö*6TÖΣµ>“Rà|šä[_rTíwK]ÀQ[̸U•r7σ‡24ÂŒ&AÕ™µŒáXD^/¨Ô1B]¾ÁÅ&¯nÇuSïÐGÕÔ6ï¡0á£@ "²Ï{G\ g¯è9;ç7!êjTƒÖ±(É1=$ÓÒx/-¾ 1ºÞ”ÅÆÀ@p$89R9v*â–ÃP§¡ŠÊøŒ¶õ¾)4ú+ŘJáLÔ¡hàqððkˆa Õôñ¼z°åÜPD;µŒ{´Ëƒc1N½cÔ×T‘ïÚ©¶}DåÚ@µo•-võv¥šQe#@I¼±ŸÌR“1&ÛG%20û’š@¸õ¾*Lg» 4¦š™¶ä‚9h )¾¼K¥ÿ—•n8 bNI”ê¼S ½*o÷ò„¼ŸdgóàÅåC¾»ÛªJL(±L%§Á‘Kmû ”/ks³$ÄÐßV*¬GðƒK"OÂùqO…J°·-«Û@ãè-+”¯Ý€’Ù„ƒp´¶ôO ôÊ8í‹#Á1³™ŸùôõÄàv«˜À8³žµÍY·G|êËÃz=dí©17E[[§)°¡“I»º-ÛN{’Sy£rà 2=fÐ_<ÿOj>‰f Î³»¯Â#¾޽±v*0 ÃN17H¸fiqƒÃȳÊù·óÁÀøŠÂŒgâÈtNs¡e"dJè$ƒHšˆ¤ÐžÐQ(Ý&„>‘O†2¦¤¯L‰H-N§1Må7 ©L1‹¢>·ßG ÀÈy ‹Y8`⯧¦<š<=äAÿò­á s^ßéú©ò¹ƒ^’;üé ‘ŒØpÐñé ?cÐ;þçyNÎ7òÜg¼¯œÒžÎàá ª¼É¬·ð@¶7uüÜç¤Åñ(ûlÏ0íy(úëëòÑÎLV”O=Ÿ¢Ç<åЯü¼öOê<>êóÿ§æ¿”š19MMñŒÔ\å]nï}*7A'u­Ic¼¿»ÛÂ\ÛŽãÊ0Iýܨu~b $Š~ÿ4’·šK¯ó¦Ø Á óºþ1@_bÖ=Ò¦Xô?.Üç‡v9ßÏ[ÉBÛn#¡õ¹GÙ`f¸a‡ vxp >°AãÆ ŸaåuþFQr¸ # Lüõ/þZt™M~…×ßX"ñvendstream endobj 580 0 obj 1571 endobj 584 0 obj <> stream xœíXmsÛDþî_qß;ñ¡{ÓËð H;Sš!:LÂxÎÒ9µ¥ Éqïg÷^d[M“ø“ND§½Ý}ž}v7¿‘˜2ã—ÿ,¶“Ï/SrÓMbr3ùmÂìCâ?Š-ùj>d^À)Æ ü›¯&îMFx’S!I*2ßN¢›Î3p˜qšç ž›—“HÄd†fœ 2S þ’ÓD02ßO®¢¾!ýÚm©ÈÝ”+Ç)‹ôfgHU“óé/óo'3F¥´†YB3.¼á·_n̨RÜý^ÛÑå+EÉ|mð˜J¨Ê3ÿæjW}ÕÔø"Ë}d^å©?Sîu»Ztm±©jÓ-VÕþ/u¯¯£ë©1¤dÆEJ2c_íåES÷U½3—†t»ÛÛ¦íMIG·r8ÿzUuO>zçbyÛ‡¯áÉâk°mÞ÷- ÷ÃÙô³ Ïh¼°ß£#›Ú”ÓÒ¼?CðÔkçëüźÛõ¤Xë–¼x1qÇQ­·æÌ"àüXwÎÌ RV­)ú¦½_x“Ÿ=ph£»~±mÊE_¡¥‡Ž`Œ‹©oúõÑWM»]œCà,w‹;ä„ ’Aª½lÛ|†Œs*=z{=ýb SŒr2ãöTLSÇÁ‹à) ÓugÓMô²ÙõD“®ªo6†¬¦,§y&ó¼E^"cW63œ1 ´$Þ`’çÖ7Dà”î«ÍñoM¿k1æ~Ý6»›µµqÛì¦í¨/g+ H=0*O„B1Í%çðŸ”M±Ûšº×Hw²‚LÙb3º†ÈH³Â;Œ pÁ¨ ô¯Ì¦ìÆT‚æi–û#E³«{<‘£l¤§$¢?;—ÈP½zS•ãJ`(æ-¯Fø¬ÚtÄÔŠÓLÙó< ‰‹îôáNFcž±€OÌ-äÑ S·tÌã1ò%Ë©ä"‡*œ…‡C=k×âU!T³Ú@­`Â1ù{<” ÕÁ©ÄñPßÛ½^"Í:RǼœA6€:Ëû1OA„€üLœIJ^YM””å2ètc½ å ÄbH¨.}¾1b0.©’í²-h–2 ÓÁv¥¬N…¨ÕážLÒ,ð÷w;’¦Oª˜RjA˜1 ÛÆx‡âÄ¥;£RnNàç‰GQ8ä±%Tõ!¡É©·Wd½0m¯«zsOô”ACb2‰öïöSÄ”‰,Ò-h¸EC,¨IôÍjÄ!€N)Ò4ˆØˆÓiBE½€Z"‚t¤nêY½ù¨zdîCõhȭd©‹wðá%èÑý³\Ñœ áCmyÂ8¸g–yœ¹œøÞ,AÓÌ÷æÕ¨k³˜û'¹mASêž’ 8Óî+M~7mg­ffê^ ¥dH¹ÁÙÊo@#FúcÄ'p¨*toÐ… KØiÌJù:¨34‹X†*p­´ sŒBÀáF–Ì–÷`ÞÅœ‹ÜEæ2m!Ÿ*èa@eǃ4¦J\W©/hÌÑ¡I[6ÅBEЭI×`ï›qÌŠYi˜Àú;Pª’Ș[›çQŽñ­nÝì6%äºYBaÝ“¢¹µÎw;ôˆDÒ$ yÝWSž§`7ê{ÿ]5}Ç– Œ02äZ»¾ñÈÄ€ 0äd¼A0¨¶ÙX-öS ––ouõ¼ÕЙ]±ƒýPŠÑ~u(QE%Ëóà§íœ¶ ¯ÚfKB½|¬.M;UˆK–E¾!14˲P‰Œ¦ÒµáojRh 4:;XéMi:Lyg£’g2ËBÎß.Î_ÿ´xyyyq9ª•Z5œ$áBŠvèóº.­÷öbdLgúãæ?n~ " ù¼=^Dž«òUäkªW0¸tO´0C•Ÿ†óæbñòÍüòçqõ3v¬Ûvn©›þxvñó@F`’wÓtlh39[aÜ¥!>n›†Ÿ¡Yxý„;eHÀ$¨ëF™F§s¶gHA°6 ^ÛR³Ì³éXaùd™ŒtÄA*†âP´F÷v &0¼.A6y üóZ!R2Øu‚™Xט—‹èé,Æâ”ŠÀ„Gf1E¾;GµÄÆ >ú'–4õ•–Ÿh ‹ Ç?¼¶6.I ‹öày¹dâtk˜r”%¢“õázú;ß9þ#Çß¹N„éÿé}Ó‘ÄP/24¿Šœ,$còÓ· §Šþ‚£uâÑ}≽úÏ­ÏØ'BœìÏ]'†%è£ûD8ðIûÖ!Ö>‘<ŸºÜé>‘> stream xœíXÛnÛF}×Wì[–†¸ÙoèSÛ8@ 7A5EáM®$¶™Täü}g/¼˜ŽìÔ(d@–vvfgæÌ9K}@”0Dõ˽g‡ÅóU„ví‚¢Ýâ™EäÞ²úa½hãþÖÛ…ÝÉ"$ŠDˆÖ‡ö™·þ Ü€1ã$IBm·ÎX0äë¥ç«1¡=øÞý ÑË‚ð­O Ø£\›ÊPÁcëàŸÒf»iEÚo‚³²¨T»)ª¬<æj“Í&«U÷¿ó¼?×?ëÓ&î´~ïËçÆ5ÁŠªC¹s{ÞÛ cqË›ëªS·Ò¶°l>,õQy ‡ö™4©Ú oŠ]¥rtŒc¥×¯á&º5»lšºAÞ3¨ºK+ýÝ;ï;[¯¡ä>!S 2N´£küºBí1ËTÛ.Q·W¨:nTƒê-Úz,j ¥jQQ™u—d y´6KMF¨KoJ…ö*Ía÷©(Kt£P£ºc™˜’ânßÔÇÝŽ;©®¤DîoÒÀa‰^ð™1ˆøQhþu)á·é=aH{§e‘;—}L@‹"·\T¹ºÕ h0Cêüãè=$œ›Ìn‚–¤åª’6 €Ýg: K)œKÌs•àBž‹»lƸk *mûÔ¶TYWT;Óœ“Ç(¡4ŠpúÉ|a»R´(W[à ȰuóÉ4Ňò‡¦œ\P׈ÄßÇÈ1a çcpa2þ~õñ¥@i•#i»¬ëq@˜öóû²îó®=rp‡›4ï·š¾r m¶ž&]$Ž ˜nÛ6˜OwñN¨…ñÞúvÖ>Ñû·]£„ÓŸ™–ʉ†¶ò@G¡+>Þ¥Ó–ðÐMžì›‚K‚Öû¢ÕV"™ÖÁ~çK.ô\õ•¦¶“™jº´¨ÊO(õX]”>ým;Ê‚§MNLË4Þ¯  ‘ÅÝOÊÒVéQ4³ãE$K¸œÁ0Ò;©ëñæÅÕÛÍåjõz5»„6À-’‰%½viÓu 1TC¬U]|½0‹ÊLD˜LYjNQ"  .I_—kü¾–U˜r$˜Ì©YrÀJÜÍæÕëÍå«õê™{Æ\A,ŠªênJSd&2,à?Š÷…&yªÐäi—~5±Îþ­ÌpF‰Ž8¹1L8s€õ@³®€ë³} bsáù,¦WéA-M ŸÕ$4èг;=¶§àW4±ŠÎ¥7õ±iiÙ`º·æP!к@ÃÖÐÎMa¦ªMÈReÜ*—Qª¹$ݪaBçß•ÈRœC`KÐÕs‚åËP7x ±sdéf[3e^gǃªº´+ê m¡HúÈ•Vš½azác«zÕ ºªÌ[âÎ6¨^ à‹¥ü_ö¾±ì™&z‘éM„û¶8‹Ð=QÞ#e]h ^'eÇâËx,f¾ 1GñÃÄ ÌDÅ„˜áÑà ?à$xœ™ÛãÍ{ø2Ö‰H\ïx€ &ül¨ì E¯£³ûül¸Dgà`÷ ]Óû\=}4Ë$üüc Hø´·÷ t‡g-†žXõFçÖw’c«¶ÇX´Û#eï'\âÛ÷ª) ©•¨;¹Û \Óú;®ýá*e/†Ph1rÔG5sÀuÏ]îžqÈ»Uï|í  Ws,0À³§Bá¬RkùŸ AÀ…ö1$œj ¸&~Ð=I¹¹¼£ÜÎÉoUÛƒ*WY¹Ù‚j.¡jg–õùô2“p?ƒ;wBïïgô§áŽ%r¼‹ÜA((4^)HW¸Ç:<È~c€þ²M€üáÃ/ Qœró[‡Ý1’DýÎG¹\/~…×?ß‹š¤endstream endobj 590 0 obj 1403 endobj 594 0 obj <> stream xœ…WÛŽÛ6}÷Wð-r`3")RÒcÛÝmSÝÍæ0´2m³‘%G—8û÷áE²½—bìÆ$‡Ã3çœ#1e$Æÿ»<ÌÞÝ¥d×Íb²›}›1»Hü¯ò@~^ÍY•°‹qÿVÛ™;ÉW9 I…"«Ã,Z²ùê_›§y®pßj3‹'K\zw—–`„%g‚,•]T’Õi) Ÿýª{Üi?+gRÑTå¹óÓ§1>gT䜻…Ø×=i¶äƒ©uG¾D7¸uɨÊp{šÓœ+¿=úüÓ‡Ó„g!Ï»÷|! éúÇJ™»”ÇW/YSÉYr»Q|!^½Úk²ê²7MMZÝmÝSo›öPØÏЇf艶9ð6'KÊ’põw=aÇàóŒŒwØ+ÚGÒ5C[jRÁ „&9moÊ¡*ZR6‡£©ìmjXQžåd‰€#È"æ6ÒP›žH·%ŒàxÜs ÷Ó‘î¨K³ÅCŒ ól:$ðÐ}dô†<<’Ð(›¶Õݱ©7¦Þ‘Ñt¾”\R.£ßz²i FuÓ“n8›¶·ošÿ³ú0N9* iÇ.r_:ívݵs–¢ ò¨´oÿ;1e gèNzz:U˜àöAÂY¼†g4 G7vÃÑX©…-1,| ¨)òö-ž~¶‹ù›°ðÉìj¨¹])›¡îÏÖnÛŠñVã/HöÍ…’Üí<HzËFÇ¡ÓÛ¡²|’N[ ðâx"i–Q)yÀïî½$ÝW[k&²HWº‡àVCžTÈ Œ@D™Ê¬È]\ËsÕBt¡b~I 0Áü5zà휱Q0¸ÛÖ&$a‰²º¦eÁh±rÑœæ Õ xŽ–?É׎aö0ö)5BÊiêmæy_0±q÷¾p{w÷ñî*·6ŠÐÁ“mÿÇ=™»¤œ%г4„¢qQ†EcSC±K樳uV;”Ð*:\Ò‹‹–qÆ~÷høÎué–ݾª âµm5TqÀÞpmÓ0¨çã4xE¿†VÕ”ÏÉ$•£Kžöº¶ƒkSïœ9C‡Ð0!÷Óˆè]FB…o*Þ@£÷f7´ãü sSy¤ù„N8~aô:¼äöGq8¢±n¦ù÷I›öƒxN³QÂ}9:ƒNšÕbJ#˜ å)ÿüY<“ÏtÄ•§áäÿ~_¼]Íþ‚Ÿÿ¿ ä·endstream endobj 595 0 obj 1587 endobj 599 0 obj <> stream xœXÛ’ÛÆ}çWÌ“ÊËYÌ ®åøA©•bÙŠíH¬èaéÚ‰h\îVÊÿžîž€ ¤8•’¬µ€A_NŸ>ݣߙÏóñ—ý™·ïc¶ë>Û-~_zÉìüÀþº^(¶Îá” ~¯Ë…ùR0¥\,V[ÞJ,×ÿ3pXHž¦ž[ O)¶ÂW`"µ&V"IÙ*Œèýc[L?e‡c­‹wwκòáNoO;Vlw7öï•f}{ÐE¥7K´&¶~·ðþ½|± OØ €5süCµktÁòöÔ ì{懟ØwïªF³—5ü¹=•æå‹«ïª«Ç¯»®í˜¦?Ý› ,÷îÝ™P@öQAßõ]Ž~úgc¿aßXÇ7ßPpð€Ìn–hÃ&U•lc }Ïî>>ܽûçÃ/?m–ì³lKhã™p!꿘Œ¿cß~[ÑqÈzvþö%;õšÙî«ßØË[<´šúƒÐš§ðP謮Û|ãaQœ…ãÐDÿ#_xtÁ¤• Ø* –®Bxv^x¯–Õƒîšl¨Èp5AV… ÷Uš0{>æü£f§‘yRðÐÒ®¯šÝíd^ÂÔ0ùiZ]òhŒAñ òWT·ú™U=kZV·ÍNc²žµ%“¾ùB÷yWmua@—ÁˆƒÏ“$B[÷Þ^wš³·;/…ïµÝ§ž³®kü©—¿­œ2å"µAÞÀ¼\#8I@¼î†m§¶Œ¸ˆ¤mK "6AœV l·Z7¬Ýöm­è·ªÉ5dä‡|¹ cÅS‘xýPAp.÷}QÌèDâß•BcE«{¹#úÒ%E (¬¦€8Øðƒ$ËNk(zÍŠlÈÕ#tÁ©ÏÓ˜ûQ`“^ïõuMfýœ°ŸW6Žyè¾êÚÓçÕ$"µžA:ÁÈÜs†ïI …âI,‰úü˪çh;‰°¡e%!$ÂЫžØ°×ìØµÛZ4€³ƒÙ ûmà ÄÛ÷ Ã(°]"žD@#•  TG0¡ªû›0À;ŽÒt:ëõ€Ž>´§n)bˆ3H=¨í›ªÖìçì`ëuÙšÎÒJ¢À؃°òÔä"ëôpêšž2jк!à <”#1ÀËis^+‘ò¦r_†®±'p¡uEà&JÛ Ð\VÜ™Øç£ùôdA ]V*–DèÊ … ÷ª&´W§º ÓGÐ]Ý í3e²›ËHžÈdÖ…¡18ïB¯¹›Â÷y$—¡óþö5g¿4õ3™P\*§Mc€¶zK*MCa°D¸aT5”%*ã”'jê¶T8úXx€¤t».;àϺÝ4èÖy_å{4“ŸºÏPÔ+ÁƒÀ|·}|5±=á¡Gïý>š"ëŠu±Ó%L5Sƒ¬Ë # ååÀò“æñz™ O¤ò2è öƒÎ C‘e¶C=ûA™ÖÇi ¸M}kM“(ˆ`T¸Ý{V ó#`>°2àiÿ‹H’B\óß™XI'©0z,ÿ!ÃóJ‘¤4¢sÿCCõa¦Ñ›ˆE }+\0?´äÙ§q …­.‘뇬œícŸŸ` ³aÏg;ÌJA{§nÞjþ˜ãUž&J€òdGMvyˆ’Àuš²wð`EQ…W‚Ž——„Çæ¸7b‘Šéš¶öŽöu-ó‚êe5,+mé„Ժ QMBz÷qŠ5å‘r9< ‚R(5Ýçbaç9îÚ¡ÐÖ+(,Íq\…`é°ÊjŒJÜ:ݼò&[N˜2çö0ã–mÔíøâj˜Zq"6ìi²›_’Œ}ÝgÌ…Í«¼f“ý_o¼ÞîSØã%ƒ’‚Œc')È”žÿ¯ °/Ř~-Fò¦heóÞkè w›òÇ2=ª ½lÐoOþž=ÃuTŠé.{F»Ïÿô_ ^¯ÿ€_ÿ´ðøendstream endobj 600 0 obj 2110 endobj 604 0 obj <> stream xœXisÛÈýÎ_1å/]æ3¸·r”bÉ[Jd)‘¸q¥¬ †$vI€Æ¡#¿>¯gp’½rJ.S"=}¼~¯g¾2› fÓOû™ìgﯶ©f6Û̾΄~ÈÚdÏþºœ9l™`• ÿ–ë™yS0éGÜqYàøl¹ŸY 1_þ 3X,$"ŸÖ-Ó™…5 z´Âa Ï×_æñ^U,[³z«Ø.Ë«ã»b[§ªdôøÖªnç,.Ë‹š­›ÝŽâz[q2&aûb¶|ûÅÚÖõá§÷ï²ß2ž>Ì#…¾Xq¹®ê”å\„ܶ×Ú¼ÏòTÍ…‡?}Ïzä‡íá/uVc×?Îÿ³üÛl!¸ëRÒö¹OMŸO†ÈB|/Í÷_¬ëÞ꾯–ó€ö }‹‚X}Ìðße³¿See Kéqa‡l!õ«’;i}€óšíã'Ľ;°þ•Uç©NËz.ȪY°gòS1zˆ0ɪt\.°õ¯ª2Y“¯NÀm¿{€—«[ ©¬ ÖTŠž£šQ[Mßã‘oGíÚôfÒf U¡ñò¨ø¾Ë;»|9N‹ïy]Á·Ó=®´¹H¶îómÆÖ±¥hÓns¿"GVSg»¬~b‡²Ø”ñpÐ1šçÉ, GÁ><ôNaÏÐuEŸÀ§ÌòZ§6ÕËÉ]GþNþ¾ ¼ŸKñB+Þ5ßœÅišÕY‘Sra¸­vèó@†]¸´‹®¶•ûC¶‹õ MžÕìôüŒuå~Þ©ªãlW±[‹Öì›dËöE©à §Àê´PùKû\̬7ë3€Æu¢Ö{d)imÊÙâþþž-2¶Ø±?w¿®çÒ¦©åþü†¡a4¶l¥pÛܼ1ù:²<±·Æh™¸Dƒ:öa‹5ö > …T¨…ã Nõ8 Kpá¶;í-"âýa§8»ÉòDc-°¹”N»Lt˾X”Ö¢©MÍ’8gwHr BPÄHXõŽ=dõ–=MÉ Y”p.i*$W—£Â+sA5÷¥µÉò<Ë7úSçPp'Ê[¿÷lOû÷æÃÕ§œ_œ­~¹<_¾AýÒB“XýtPºÖ_›¢V•éɯM–ü¶{bU·(b~ai¦ŽÑfäAsžA òˆÇqMËã ¿¬+z© XÁ6¸Î#2dñ!.kBìn¢°¹£ûÈ1 :ý u]-"ÙõÇ Øî§Ic;ruäqúyõéäÃõÕ VÖ«5*>éoáø=}¼›Ø¶Ð­î`ëâòfU©—íØ¯¶r²\¥*Ùý˜V_ÕÖHï#.w©«’oX‹ÇJvä*ÌK„Ëç”Õ Jlé;êITÎq4óçFI4!^Âö ‹ …ÿ¯*‹¾Š‘®¢ŒBŠ®$Ë¢weá¢}ý•,­†Dv-Yºa—¶ÇjÀá~Ç„¶qž8’„)r„¦FNKaGiVª¤²u“嫚»ºŒ¢¿ ö$eÖV „#mP(|.|D£\¸ºGtŸ8îhÔëªÌö*¯ãÝ(áS$ È Ü#$Ÿ_~ü–=Áå+ñóAÙç‘*ý6”ZðJÊ Œ:]Õoµ0ü.Çèk•Íñ¸ˆúÎd~ÄÑ(¨ÝZo1 âó…‡È¤uŽï Ä€Ë´+5hX±†½Šsâ3…Ù/«4rÀÐ 9E^8v4è m(͆ä-(±_«A*LPžI£,`>ÁÀÞ‘̲`Ù}t9w T¤Úz¬ÇÉv/:jÄYumƒ!QwM\–˜ûº–Ðr¾.‹}?EŒÁºð╤&D7·ÜZªN 1†M„pGõœ{žÅ§û  "=]Ò¸¤g5=™9ˆöóîøÖ N¡WЬw£q$ÙBwÞ¾}Û½ûÂÒ®¾É6¹J=JŠ&¯GÎÊE|«èãvŽïGÁ-ÌÆ²åSÙÊíç­Ê¦©ªI¥Òjª %£nœ†ƒ-¦ À°Y^ªº)ó©Ėž Gºwzñ¯ÕÕß§ÓlDêÛmLDÑÕ¸n‹´ëA3/÷œˆ®ÜôP6½Xi§Šë†%fë'c|îŠ ÚÜž%xš²»'½v“uè73—ƒ¹ßïzȺW|GÍlåS–„Jt™A±'ñJŸ÷yrŠg¤1q††³úêÓB_Ÿ¾}ظ<ôxÚ¢ký%ë¨íCi–ª¶ë¸ô½ÔÑ9 Äx]Ù‘µ|)mD=¾ûƒiÔßL2ƒÄvyÁˆd›1·ÚÍ.eÛøh\ö0StC88È7kïA§ÃÑÇå²_3ØÛÕo&ι‚팰¼<ùye*jE‡”˜áô¸ãMlÑà™Å»ÞVdüI¾i´³ïÈ^ù\eéh–6¤)ûEωÌ}Ù/Ûê¼+s*;@®2ôÓ4:'¹N;™öKLOpTÙ&Ÿé%˜7ì»Ñxœ*¼U$/9 uôº–Ö£*9«WLž¦Ð“' ÆÐ;½8YÝ,¯Ï/žlÜí¯Ãl-°:´’- 7»"ßh1`ºÚªª‰—ûžtv Й®€_ýÈô`žR± £iÑmÙß@D®»ÆœIÚqD`›xmÎ@ådÒ¿2{B<è¯×ÚÔ]œß,Í­“¶vDAÔÚü\ Ý"ˆA„3xû°.Ç8 _ñ…kË£[©VÇÏ®¯¯®§%Äå mí;&^„§ç#`ú[hDòí]2þ:ÝC:OÉàwi,•Ñ÷üûDÞd渼Z].¯ÿý|Ô¶Z¼>𥓢ƺʠ`&¸„Gäc=—È[+㊿c{ú‘åë¢ÜëŠßιq'ìËí@AÓŽÉóÇlÓ”ÃÉ3ÄLÑUWÉ!#.X§MÉŸ¿º1÷ìQ_ékQ}áÃeÞèmÈÊÜó†H·$áÆ¥ëÑ\ï Ô?÷Îhìè*ŠúáO˜Þ¥-Åè@€#Dнù»×ágËÙ?ñó?d8>endstream endobj 605 0 obj 2407 endobj 609 0 obj <> stream xœ­WkoÛ6ýî_q?µrj1âC/týÐ"A‘-k1GØ0Ô…!Ë´£Í–RInÚ ûï»$EÉVœ8†@}Æ’aÔqâCr?rB}x/5ÑHı)9O r®ŠÕ˜ GAì”Õ6mò²€·‹r×@ 7y±ÞH¸Î É8fÄóXऋöÙøsòã~Ñ»v—y† }³Mr+aUbÔf³(rîV»"S;Ö¥,¤Ò È ¹íÐm?0ûÈÛ+aÍ´%FzW3k)ë¬Êïš²ª±›]¥Šwñ}Øiœ QÚÉÚ•çñ±ÛbÄ„Ñø0™O ÑIìc©³v¡¡ZÀ#Ôó-xçfÚÆnî€Òb µl†HX!Q'F«à¾6¸O6ßoS¶£ž¥Í‰s3úÉ)ÊÂýKVcU‘žÏrØô8…¡EC»] ›WF]ˆ›‡Ëñý°-4„~d<£’wèò¨mV¤ÖA±Û.$ž3ES}ÇÂNÈkئ՟㕎s°½ÓZSt±7HöM½ÐûRJ¨h÷b„E¦ì1“…ò£ú„މ™ÏI$tº×Ç"/¶jY¥(•b>ž•:¢óHÐO9¦•@1EO_húÏTª(s„à6=Ò*£T(Ð`ã.>o¡EEw£Mâ…?&—ë ôQÆœ«l¹L\õD‡õ~9~œ0£<´Uƒn¦»YM ±lÄ#ô?aoPäJ r;HÕ;akÜ8&FÝÞ¼¢·aºX|:LG~yf]ÿVýÕâÏn|´¯]áá ²ÞÐL¨>Î/?$Ó߇VáÙœìÙU#®2éåÀ¤š4N}Ä¥e±¬å—,2ù-úáYþü:3ÞšO;sĉ8æÌǃï´ÃÓ¶Œ'Ã3l9$ô¶,{Ò–½Þ–CÓ£ÎsހˑÎc­ºJ÷·yv‹wªZèàa†yÊŒ9¡‰g‹1¤Á)Sœí› ¦ÊIcÜ%Š™ó­.}cÀ¦oãî=7FŽìyž‹Ýìw‰<¡ ?e¾è¸œÆÜÍÔ!t킉m=fèÇ`eÂ[Ê×}T%ªU":nnÖ¡AùøÖjî¼ÝôÎ¥n<ö¸rž>Rõ ,έÑiÃq…:¤Ô¹ÊÍã©qÍÖt½N ¯|oÛ½ïÞÏŸüœ~æ1Ú¯)‰C»üäWåËdô þü 6š"»endstream endobj 610 0 obj 1442 endobj 614 0 obj <> stream xœÝX[oܶ~ß_Á·£ "V¼ˆóÖÂ.pÚœ5¶ ЏXÈZ®­¯”HÚØÎ¯ï /’¼^_(P8@li8œë7ßè3É(#þ„ÿ«Ýâ»3M.ûEF.Ÿ̽$á¿jG~X-YU Å8«íŸd„+C…$Z(²Ú-’”-W‚fœ£PnµY$ð>ÅW)g‚¤¹Â‡p?cdu³ø˜”=±Í¦n.II»dÎ ‘ܤ·Ÿ÷¶©,©{R6 5tw䦮ð¯r³élß“¶±äÂ+OîÚfC†+K®êË+ۣܾ·›å«ŸL’ÕÛ…¢Jh@rqçä«}×Á Ó¥í–\× |(/®­»¼¶=9O†«r‹^»SÓË;gåò?‹4£‘j‘œ|€?}@ U‚ûxdîÖõÛw§kð{=Þ畜'½µNõ‰‹£R: £y!CH?|?ź yTLÎ~$ý'[ÕÛ%\i i’º*‡ºmΗçKêü‡4ªUARîqª™q6­àÖí¾©PõCÎMȹÎhfdÌèæ¦ì¶kŒx8OΗáÔX)šQ:ü©Îû®é4 C3)‚ÈɇõÉÛßÖ§ggïÏt%c¢-”C×µ à@¡y úß)D9HŒÆ.®’T)IR,xÚX÷êÒ©bŒf¼ˆG¾¸—"¼`P8Á£nº#ƒ²å!ÉqO9“Îàê»÷ëÓw«³ß#—Å;¨Shx‘2-¨4ÐRBã{Ayî’§(¸)ÈÅ¥¢\4ŒÉjÚYŽ¢Uiåà˳†NØÜ;ˆÇ fEŒ˜„›è‰{‹­‚²¯CHÆ7¿6}}ÙØ yE|ØMPúÚƒ3ªf§˜Tò ^0Îi,w—êÕ•²œ Ñnªž/c•ÓâXߋ̔IåsÕ«¨9¬Þ÷?(Rê ŠÀN·€ª·Ã¡FÉi®bê^ù[ƒÇì‹7´¡¬ù¼¬!GF»ÛQúvßÐôC9Øb÷f¿»°©ZÀ¿þSë¡xhml_uõ§Á7ÚÜoH¿‰°“ 0p:˜®fæ-©¢Ã߯–f½$ Fc£{*3pTó±Ÿ@ŽÂÄBòe9ÇgˆÐTå¹¹g¥x8dž&@D|'D<”BÒü4±_È , )µâÿ ZúÒÆÆQ´GÐâãë¾[2 SDçIµ]r7aa \ÇvÁiòH:«mÐð·"ŠWú·" $)/øsR¤ŒÍ÷ôè`4Z š&«ò1lÑ£¢G %…€ñ=öÊ«ƒ¨qÒqŽJšk_2¾D< :£ KžaÁ™y¿¢‘á‚Cçpæ…?R¯” œäc)"›&6övhàߟýÈSI0†Îf–ŠØXNΗÛO¶«Ñóòú ùpe–€YxÖµûË«ÃL0¸]¼8мR…D@aªÜ3f š_m×’z ;[6½38ËóÄ…«Ü9Ú¼oþj±uM‘Ü4÷è¥#ƒ‘_r€®#Ü<Â/^òï„4VðØ»ÀóPÏŸ& âP¥2ò_9ŠŽÔ”º8:.>dÂD—£äË#Ì„˜º??Ÿ p.#&Ô}¡Q?zE{hÚ&qG®O¼kfºeÃV3ÕìÒï/†®¬Ø™¶]»Ëá¸ÏWÆøL;æÒ¸ÞÔÍÆº ¯2¤ÑØHooëù¶%‹1uMèÓ²ëÊ;ç°Éä,U,c~n¡;èÔ~ŠêÅÝa@EQÜ÷mý1dƒŠ,sž|ñ¼ `*Ç]WoýÎX±¿*œ»8‹¼qȳïg:%pWHFµLúø›LšÎEÈAà†5®es áÁ%…Ç0öXôŸ»žŠUåÂDf‘¸°pÎŽ±—¥PxTúüÞz«çÁžiÁ]+ÕYŽÁ·™œÍ³½ƒ¹&Œ[Go‹ao§,ϔڃQe­_wûú«[Yúôxv¹‚&3ìÅÙ…á:n?¶*a«~0lŒ„Ž˜|x^©×LZ¤\7-ìÛM;ó}»1`$ZÌ…õØp½ƒ½XkC&~€Û¢CÆÂeAP÷YäéàGƒØšS‹²…IPâËsD^–ИÎq ¡ôs3(£:“qåoÈÊñGÿ°Â}@øÛκFºˆQKBµŽ§ JÓšzûè©GÊ÷)8ÐÀÔËÑâ›E€…b 0@º§ÈûIÿBˆ.aô‹!>?à\ÈÊcZ d<õùƒ»)ðm–ÍÙ§‚ãªT³’ôëŒaMÖVãŸBÅ@f"*Q —ÕógüÉÏ øEðH¾¦õâìÈÎÌ]l›èÕ1û²4'ª€Êžüz‰gœM§‘íëxüÙ蠟«Å/ðóûèendstream endobj 615 0 obj 1838 endobj 619 0 obj <> stream xœÝX]oÛ6}÷¯ ö2¹ˆX‘”HêqE;ì#k±ÌÛ°%C H´£A–2IN–ýú]~Z’½´ØÞ†HP^^òÞ{Îá±ÿ@ &(Ñ?îw¹_½¾h7¬´[ý±"f¹_å½Ù¬Ú”E(‚›íÊî$ˆò³ ÆÑf¿Šb²Þüi ˜Pœç\ÇmªUÄŠõ¤È]Š˜†âŒ›õºQõTôÛÛ¦nUQUýM¤ã©ÄÅ$ÕA$Åðûi½5—ˆtô…Ô!—+é$â Hƒ^õj<ômÈ{±þ\_0½ëû¢”þu³†ÅI•±=žšˆÀBÚô›{…¶‡¶ë®]TE’Sêª^Vùmth#Ëp.}¸½é°È˜¥˜$YîbÞþ|ûöò§Ûß.2É g!QÑVhPã2SÌD†eîû-[³¼Mp’d6'ÁþÔÅ¡~½A *†¡+ëbTzªÇ{³V©¡ì뇱ë7 ”ãœyPèsu€€Üé`¦ó6 ­ƒR0ð+c?…4Ówél#ã4¡˜ êw½|wuõájQ{Nk&—ÅJ×"ƒÆõyL`ž…óìÙ)îGƒ8Á~…KÆ&f’«G¤Žû9&‚HL*L q€ÖÙ ä§’Ì¡òþÃí»÷›«_–ÓMBíŠDÀGƒJ±”)¸èu†©<\,ÃUf'p”Ë`Þm·”lKç”7;—Œÿ¦Ïdà‡z×ö^s S‹&ІÔfcl×]î4`Þ¨™$8Õ]zYx†Syªóæ„9br¾$ŒcÁùˆp‰)¡ùËO²Ì§z5oÓ²rFírÜ/»æ°oQ{Øß©#zº¯KKýa)Ø+˜m¯@ à/˜ÎÝóR€`ä^&G3âI~Ý©5ÌHÅ¢]ÝxýÛæs7œR?†¡=ú†_çªf‹Œž…Æ -írÿR}‡ê홲»í¢àz@m7Z¤â)JC€éB_ï:švå&Ú«¢­ÛIôÐwÕ¡„ÄM}×ý3*‹¦AOëJ‡|Q1 ]mk‡—[jI ä4õTV'ÍY “Ô3´ýë¨#ðätyù¤¼›µ‘…˜æ)NH¨NNS[ɯ¦3~kß«rDk˜J.sÍA!_ÞgÚŽHU;õ™>¬RÛ5Ñe1*¨[“å­­ø`„ž%9–‚»‹þüű‰³0Í«/ékö:EÃ*k3MB™_`]ž¢1ËÁ­€U™aú&”a1‚™aê ×°º„rsjqõFm»®¨Je¦OB,8ž´òd –þÁÀZ¥õžÂY¼A™ã}ßv†'K×Àr|Ôö4Ň^Gè¨ê×:A.Óè±#×td/N³c‹ ܘè—] }Ãs·C>«ÎÅí^h» 0¿›ã<¸6ž4°½WÅý„ŽA6€HWUõø¬Á‚Ù¨Âa˜iúèS¹Ô[¤Ck1¹LVÓó!n>÷E»óÏ@¥Ê¦èmQ™ˆºCSÁƒp´ÖîêÆÇ2ü6õ86®Éàí0Á_¿¢­—Ý$‹êñ ÝŒëzIò 5ÔŒpiõ UeŸÞèƒ;Õ^܆9C$¤:zØ¥Íæ «/ypmÿ/ Ÿ)|hŠ);õÑâc>úöîß;i½÷½´~åŽúÇv˜xjðžò¬Ö9OmÖÿ£§¦T~‚§&„ú‘œT{j«Aí8 ÒÁðA²èÏ¢›gëÞŠ=|” ®gï1L‹Ÿ;Ì4áür¤þœJZP(Öù§R=M7ÓÐŒ×ç-Ø“gùä†XÃøÙÉœý”!µ®;KïP ¬vc~4¦IâÄ;æîh^ Œ6Ö®ÄLêo"°vÌz#—Ç^BWÑ2Á"õôÕ¡&Ò”ÖÎEZ-e67±™Ù°ð°ý~úIîÑpxÍ|c yçWx4–‚åÚëÜý¾Ñ_Z u[ºÆ7ªÝ÷БދgšbžÎå>¢ìkûAíµi@ÅÎØÿ¶*újX°_v¾\p^ç?ŸSþúÈù$Xè»fQi&è&NO¸Ï™u¾±czÉ·M¼þôK L‚ÿù®xûJÉq7»\øíýïÝfõ=üü »ïK)endstream endobj 620 0 obj 1877 endobj 624 0 obj <> stream xœÅX[oÛ6~÷¯à[ä byÑõ±E³![—n®±ahƒ‘iG­,¹”Ü ýõ;‡eYvâll@VHžû÷Ã|%ŒrÂðÓ=³Íäõ,&ëzÂÈzòuÂí"éÙ†¼O$™g°‹ ßùjÒžäDD)•‰eD曉çóéü3ˆÍ\Ð4pß|9ñdB|\i'Â\?Œìz^6dù ÌjQ䥮Mvëáv‘P8È»ç]ë7½Â ¸ô~Sø0ñ²{eÈååôb§ð§VµÑÍΔN®=åÛåN.³G[áWÆT AããvÚ,zƒ­5Še4óñäü^“ծ̚¼*G.F! gÇȽ#ñœs+shu=(#ËØõÝ‹wï_|øy$)J¨à"ív©rIjÝŒE‚ò0t¢.£4ö\ŠÀ…KX—Ðñ¦"Šl+H6ľ”»¢ðám“—ªÑ ¶1y¹&ÕŠ`fTK5iîUCŒÞ]ë²ÁwMJµÑ¸ ~wô0™_~òêjg2í¯¦‚QÆYàå…&÷Úèé_óŸ†î$•Iì|F7F>Hɳ«mÚª,Û™š’ë7†ŒF¡8{)drû«ÙìÃl¤)IiÐî²~|òª’ØŠš†!xÁ=j÷EÐ0 •„Ö´k¢¶Û"ÏÔ¸¼Bà"O\òqwdwcHlüòÒCßIc}l ˆ2ùÕTk£6ø,ª5YVº&eÕ@†”iÈCÞÜ£†ˆi„àõ.‡=u±vHžv‘–í 0ãõÅ>ÉÖŽ.ùù\†”óhÇ7óEVm¶‹enÆ`€ìÔm½õòÕ0(XØ]ÝNIe\õø"Èàœ†¬ ìà0(ÓYS™Ç6v+SmöÑ{2ny·º\BuCÉ;Œ@ 6Þ*ò±aŠ)KO…àý‹DŽú‚:,‹„SÞD«UŸ1,`€!ÙªæžZã$KhÚ—§R¦=qÕµÖŒ­Ow€äz—eº®W»‚´htŽò(I“/f7a·»ëûjW,É^ëek& C}Ö¼] å3Ö™ÒPêR«¢¨ž"ÔP$/øÝÆboñ…çÒ6i·z\¦<¡À8C¸¿Y|œÏ®o~éIcÊ!1ÝN`§ EŠª\kÓyA6`…±Ô©ë†Ný1ïº!eKlPP<±U”Ð(qF|Ó}!€k> stream xœ…XÛnÛH}×Wô[¨Àêé ¯ó6Y;ïæ‚õj&Ø ƒ’Zw)R!)þû9ÕŠÖdØ€(vuuÕ©S—ÖW&¸d‚þüçú0ûé.c»~&Ønöu&í"óë{·œi¶\CJ*†ÿåvævJ¦Ò‚ë˜e:eËÃ,ZÈùòPa©xQ¤$·ÜÌ"]°-ýt—3©IÃBás‘´¬¹JØòy¥\&\J¶!ÙDñD«Üi¸žËnûxìæ2ãE^ÄQ[·»“y4꾄 ë‡èa>ÿïòŸddá\ eu:ã>ªšm¼¶K%×öý‡ª1ó…TBD5¯¬â$ã)[Ș4e\Y{ø»¶­Ù[2Y*ÅcïòTù-.ܪWñݽæX¹½+³«šoì“ãkújט {˪¾´Â$ôá뛪_wÕ¡jÊ¡í®æofË·÷^ê¦ëÚ–,T · };#ªFD-Θ‹ÔÁ°Ü¶=5ë¡jå1™âY–Þ¯¿ƒ'¹m#¿²‚ç#{:3œº¦¿P ®óDy™ë/×~üü¯ M™„"á “¥5¹l6¬7Cï‰'^Ͱ7í4Óz ¸àqV8ú8cçv. P1*Soz6´ìi®b°^äQYŸLÏÖ§®3ÍP¿ÐQ|¾H46}ÙWµaÕ€x±#ô (·†T”}:ài_Œl¹ ´Î ž4í gUÂE.lðñ2¸ó49øŠÖo`z‘êBž¦^åSyNpÉ…ÊýYx†ŒÅÇz>‚Tv° «…ˆÐ žʺfHB3—„–ÒÑÎtý¹ a@Ò´Øß]e щ…9O‹1 ´e?ÀÓ²Ûpv;ØxRX²â»äÑ)×Jç¯Éssw÷ùîRî³Òå ²ÉAb)á O2Æ„ßÒ‚þkš)¾XÓ:lZ LåV¹ybæ¼Õ0K¿»îŒ¼ ØÂ·݃þ18Á½OŸo>-ïþ¸Ì5`àžú8¸ 4ÏÏn/÷LÈq¤³¡€H§± u5W‰ˆšk2k1ÌIG‰È¬Íae:¦84v…Ø”ªœ ’Ķal )ûe½6µéÊÁX^K‘ð,VÓàDß³w/ìS‰,j$ ƒû —aoè \dI(eýt£Ä+ËBÆ7feÏR. ïm·ìN»ÇãiÕàð9ïÀ*{öl@y|óIKK\½+ï^á´À–Ã;€w4ëÊ—]DÕšmÛî€*A•ìxêŽmo~¶ˆë ã>²Ö*˜'òÂÛ6¼Mï:ÿK Z¶æÿ½ª\•ݤˆ+ i>V^+ü†*x’ûìÒ£6?›òÿv3gK_W±#?ŠFÊõ¶³"|J!"eŽ´uýà+««Þ–Üi Š »vÀóØ)V’k²êË/çtËyÚÌ}t÷ž©+}S9—š*·í±láØ´V©"á‰H^·ìïÛ%(?6À>MGS­´uö?¿ÞšØ@`H „w‡et¡So6ÜWhN½Óó?á©TŽq¤‘Šs·ÛîGåýˆXc¹~¶ï‹XEÔË­ÛUYÓ[R«ÖÒ`)­/牣öCÃÄ$Y–dvñË<·vF÷•W!¡" ‰„ÞƒHWÌ÷²Š&÷Ìp¯Q&±þ}.©/ úfÕ¡‹£¼DšÏŸž¢[d7Ò‰ öêlê,ÂWu<,–¢.£Bí±üz2ìØZ‘ü”ÃMëpÇ8ÉØi8ñç•ëá•ã¢'““je+³ª¡.7T¥+)ˆéºlØÊ0ÐÎiå­£˜ßÐÆ†m¦ [Æã8Ý¡ŠÒÀ”ùÔEksÉúêp¬+Îóëºì[½‰Bf4ŒÅ–â· ÛWÍCç~ !ç™NqÖE’Sç®s·§zÃö¥Opg¿NpL$³ØI>¶=>‰Å…¶ûȘƛܑkÏ]…ÂM^4»šRt`ívJnKbt *¥¯º‹›5hF_åïësî^öN£3Bbz›Á?{O·‰7”äÔUa~šž=Œ–§s€bž -§ ­éS˘;ÿ²å’'RLÚYÇJŒY|ªí\I£ªÉ$¢^µ§7"Ÿ~0.ôT¨qž3vfxK“ú8ôÌln¾%Aþ®|!ˆGê#.ü ÆêGê"Ù¡xv›>°Î·jU³Eoo Õ,±-’2‘Å€hlÇ> stream xœ…X[oãº~÷¯àÛ‘‹/º¡Oíz·8í¶ASo÷!.Y¢²äå¸9¿¾3¼HŠ“m‘N$rf8óÍ7ýƒD”‘ÜgyZýî!%G½ŠÈqõcÅÌKâ>Êùãn%È®„UŒøÝÕ+»“žäTH’Š„ìN« dëÝ¿Á ,fœæy‚ëvÕ* ñUÈ™ aœàCðÏS²»®ƒQµ­&ms¨®kÑ(ʳ ê ©ûÝú_»?¯„]^®òŒFI”;˯çÙel–Øç—CWœ”Þj,÷k¢U96}>ôH5^†NUdìIQ™ñYÙwEGT7¯äڌϤ0A3γŒ„LÛǶ?m¸ýõsØ×¸"Ii’Eî°1Írs® Öj$}M~SCOöAq¸ÁžÌ.ƒ°£q.üyô|žœÆ‰Ìf«™±êNò©?›¶0ëšqv×»dƒ1Å™íç›Ìà?û€4jcÎ~:¯6*¦åÖÑ~MÑ:s_¡ˆXúëjw÷üZ“²h[È«ÍyYóŠ)XP´å3a±LVm|Tª^ç4ÏrɃâÒŽ3wxõµç¹¤‚KŸ"t`Ì‚IÄ÷¶ºržônì×n­nžÐ<‰¸[‹áB,ÍhÒ%£ˆ&2öébTdܤ¬,.Zi¢/åó"Aqs€cšq„C×C2‡)†¡xÅÓžû¦Õ 'ÀmÈõ¹#öÔè]}µ•Áê±èªb¨Àîs±æÐ ,’ÁK¥{¶A0O©È±AˆnºRÍÏs&óÜþÇMMjc("h¨ëuÀx;j3kª((—\ÿ0}i:µþeB£fˆÇ Š™sŸ»bwXe«ÁP¼L(æ)YîÚõÐT:Îè°-Òt„Vê°f&h\ŽP¿[ÎmÞ˜LÄ1¾_ÏÞ5)ûN_N]sŽqAÓä ÔƒAý¸(=6Ýѯ„Wj„2…ÒgU6EK¶o’÷ô'ÓÞ¦Ÿ¥mž¦$_zȉp'ç| jÉ}LJÏ}ÿ)Nçº Á‘Ü€7d)•"¹XüZŠyÂæ|êkÌ’þÍ`pfèûiTl`œ‘’<Ã*?<¬¥ù' î~ïX0Ê(Ï—‘mÌÎ% „y6ð5¨ÉyèCqÒžœà)¼2ãÛå:¢yÊ'‚aS®ź6m‹ƒpAp¡ß8³šv4žˆ¨+¶…1„§FGzúéY•ï°ñ!ÀÃ>¥vØh“ÌéN9³v^—%§}ÙØ!ƒj½9ÃãBÐ,I§¹6fZÄ3OHзÚI¿×böôRPù®ÝJ³g[Ç@/Œ¾©3˜éi=Íi›`Xá—rRAÓÊðÂ|˜×“vÛ~“Dð7sr•èµ'òådóË2{Œy‘Ùå¨=Ã¥• 6sú¦$©¤,÷óÿKÿÖËÛAy𽤔Eéìıp?X²maT§xŒ2ê  ¨®¤ÝŒf–Âi&•8Çüïa-¨¯páÓ7ÀÇyPÆ¿2&ÑŒ¥aú9 ݺ.Ü‘ ˆlp6`?k˜ef¥Ñ\€çõ*Z³È\l&s11n\F b+kÅhZî fº`ä~#¸Kfmöz\böÂ*g4ä0€í,x!‹ Ai}³à’ßJ­­½¹±X.5”¡Oev†BZ»i¤ÎƒîÃÆ°ê”d9…¼C‹@4½Ð,¸jânLd"2_c»ï‡p¾hºElí\£RúËÖt/øþ‡ùðíž?|!hÝVf²'4ŠÅ¤p7ãZ¥°$ú³‰ÀV)£é4BÀïÙ…Zm‹mÏ'~CùlªR<ÝUâNnnv6ƒ¤*Æ‚Þ(#Ôèo´ÂGtk繫œ}y+ìeÏ­¼¯krgÃzø¹…Hvv½|À%ȇonŽx¿#n«n~S›ùnô~]«ºãøŒ.0¼÷ï_@ZüÒeô™“†¯3 ¬'\= .z~ù©æ™¾äî;ò^€Bưš{N^¨;™Ì$“Ä@é»4‚´(>Œe\㸼ÀP‚ãØYç0W< à ×V¯šñ3ïä0è³ã³±ïï²t¦ Ô3¸€~*ìÕ ZQÎR˜[Òã³´³n#æ1‰K<àa¸{Ú`Ù’6Ì·$FOØïfÉË3¼,‘P¤¶í4s4Míõ"_ -ôU@¡ð䯎0ÎæÝ)›uÎÿÿëónõwøù/Ê:endstream endobj 635 0 obj 2104 endobj 639 0 obj <> stream xœWÛnÛF}×W,òÊ7Ü+ÉÇvФ®Ý*BƒÂ)J\Êl%Rá%¶þ¾³7R¢S¸ðE²¸;;{æœ3ão(ÂEú˽n³wËíÚY„v³o3b"÷²= ŸV3†V[XE(‚ïU1³; ¢2ÅŒ£˜I´:Ì‚ÌWCXL(NS©×­òYÀ õ£†B!õ‡AÑWÛ®¬+”í÷õœrØAÒà©EÝc ¿j´Q¨oUŽŠºAY5ÿkõÉfBâ™ØàÁ 6‹((:³ÂOfŒºÓU«P¶Ýª½j²Nå¡~ß §£j±ÎëÝ2AÜ,¤Å…,Ö[¦­žf„ó0EïÇ z‰bœ²Ô™…ïmèßúM•T;'&¸ßÂl¡8>1ayŒiD|öOYS¬wª[ïöõ&Û·_ƒ¯sv(Gèw@öC*ÁJÃß8W›9Iqš¤A¿[]ni®·¼Éš]üB‚97F fäàËû±´ Âg·ü@°Q×ÖïcPÈ$"¯nd “Áåf…‹â×Oå®n$õ0Á1£Üc”U‡ò—àém4Á 7ë®Íškµéw(ß즰ðèÖ?úÙlEWW.ÆbþÖ?ú\î*àçjT×7Õz[÷Uwöü¦i€ºWJ¿@ÕÞ^Ífa³%“„.¬òʘÜ1e8"©ã[ðƒË½` Šáa³Y¶“¨"Â">êõ—õõíëû_&‘rH×­UÝ4¨&Å< ½:‡ešYDKZ!p{P}˜¨.Ð@ÖFÐqÒCeeµÊÚǶ®º¬¬Êjg©ä"»,(–Ü";Ä*±ÂV°>åXN%†ÅgBÁè£É>%˜ÆÒa0†äkQÝhIuHbðAâéì¤×¸“.lUÄXº¥‹ì8PÌLêU±U£í1Cû²Õ(½(/‰è„â–Ç“2À¤ˆý•(¼ÕWÊU»mÊ#Ü©] ºRÆU¶}Ô%ÑÐPÚRx0ḭL|ªgšÊ0©myèUZ]%1òë•2çñBü²G```Ýï;À»±¹é€e3°ÏCI ¯‚òÌ×w†•'"¹¤þÍry¿œÂa¨üP#̃v=ÄFâ&uS1`‡$…?êìe[ìšÑÞ¢³†õC™2 ö6@ër½»_ßÜ­–NÅå…å:AYŒU¢Ž W\t¯¤¼†?ªºCjN,£QÄbã°3¹dð0#¨“Smð¡ÜõÍ`HÆ*EGø¹Û0<å—ðÝ> stream xœVÙnÛF}çWܧ„rÄ1g†k]?ĵ$U#ÔfÀ JIl)R!)«B‘ïnVä-lXðÜýÜåè3Ø„‚-šÏåÖ¸¼÷a]6¬ÏUBh>–[¸‰ ѵ(üV†¶¤À¼p|îA´5L‹Ž¢?Ð *SFÂГzQb˜KŠÐEظ°h‚åzJþT¤ ˆ¿âí.«™y{ˆËÕüV,ökHëÙHÚR¢‰aþ=zm°€`É´ÕÊé: ,‹}^Ã5ØWÒ¤‘½ËŠEœÁÅ?+-|}b—¶Ï>Áì­ô®,‹„üÛʰ4îax]صÝUÌ(ñšWÜ¢n@œ6M[yM1¹RT]‚,P5é§D…\‹z¾V W3‹Ã+•÷ø•ª ÿUéÌF2Û“t3íän›ßN~Oœà+¬VXÍÌÔÅbÍßk¼®àÍ›T©«”ú—°¯¨ÓOpq©*{¦óE!Ý$¯Ÿ'"βbÙ ó×±tÞg<œy œÅI¦Ðe„z®DóÑŒ6VF1—Ø63i¾Æ8‰€´‚DìJ±Œklo\A±‚ûìÔ³mW¾¥5$–5¬J!³Æþdbô)ú`X6QsïPì,gMoŸâ~Æ)±YÐÎx^«2ƈçu…lŶ(RâÛw¥ £í¨¨wçÇöõ;ÕÊ²È –ïve/7#Ë Bâ̬ês=¨DÃøžô–޶¢ü³’Ujêj…J7?CNx¶£ü¤„Ž6WÅÑÖ§Y&}–¨á…¡8]°4!0ÍŸyàÁÀC\÷Ч»_.EU­ö²õ¾Ì±#Åöôhp†KH»­2Ï쌾aÎéÑìí¸^*×÷ÚönÄIHìŠëµfÃ{r2¡!¶·`r‹JDµ,Ó]]”T›bŸ%°ÀáÌ“T4ΉÝáŸ&{œ?5+—î¼®NoÆ<åQÎi‚[‰“~š©íj;;L·ˆ•4¤O­}Hë ÔµîLZäPw§`àâÌðþöÊcóvþn2½y;™ÿ0ýÝý®Ú%óþ.%-Ìã™9l@Ð!‡S{Z–;?‹øR$즰Gsœwšy¡¶EÅä _¦= ¶Y"JÈã­CµßíŠRÞŽ•ÎÈâ¶Kœ°ÛlF|'Ôº,¶;„l‘fi}Ä;Úœ$†æ},Ž Ü¦^²aëø›dxºh=ã¡ÎÎnHC‚ϼù¶³Î“ìù‹ö—÷PÚ&›IUTbzÈœDˆºæ^R›¶ ÙÑ·ÿ3çÂjÕ­+ƒ{u¸þBDìžy¿Øîp ó‘|á§øˆüËhoíSú­ù¿~…¼‹ŒŸñç×çÔ:endstream endobj 645 0 obj 1165 endobj 649 0 obj <> stream xœÕ˜[oÛ6€ßý+øV9°8ÞDJ+ÙºóŒ C;²-Ûl)Õ%AþýIQ’e+NчmH'&yx®ß9ÒWD0EDÿ4Ÿëã䇹B»rBÐnòuBÍ"j>ÖGô~1áh±†]”!ø]l'ö$ELF˜ ¤¸D‹ãÄóétñ7ˆÍ”á(’zßb3ñG¾^Q#Âg¾ ¤YO³ mžãb»ÜòU“/žÞ(,‘O…Ùtk6|€ ñíÌÇLoÒË'‹›ÏÞzèæfêsIˆW$U]dK-m6ýkñ““pW9lKôÇ—éô]ß0ßÞÈŒÚKPwñ<ñûmël]¥y6°C8Œ„3thÈ·Û[ÏчpØn·*–‘\â€(¦OìZ©2Tƒà˜5ñ½Þ$Ý&ªÿ"­?‹Î_«Hº…ËYÀ–AÜÍçó׌ãpŸ´®ÏÉp§´Ô× Š)k³?8eÍ"ƒEN\&gq«¬/(„”ÎÕ”`ÁCsKY¯×IYnë²Y…¶E~„p¥e[03Ø&Üå>¯R¨§"ØÖ%|;°¼©¢MùÚÑ;HªHaˆ¸œž=w®•XrÕ˜Aí)Ð4­öF#3Öz¡êåq˜U”˜±¾Ó\þ¶˜ßú0ôzˆÅ»K„¹äyŸd(ËÑ!Ïv÷ùVŸò9‡ZåÎ{:º0’²Âè¾2¤PZÄÝœ½|@thL¢˜°ÐEæÉ,òfºÐ{E/½зµãrz1Ì;™M~}zXÞ}ZÌÿB«õ3¶+!¢ÔBœ…˜ zaó$†0À h£`¡N‘ña¹I“e¾Ý²z¬lKÜsC1uµÀ †£ òôa”f ‰qZçY§™FÄíý]9C)N0›d5¥‘>F½z·L³m>Q¦hbûîÖFE`¡°d)]±¦ë.¦é¢l'XõÞfÂ5× çok0à[ŠEÔuS~ÃãäLnõ» ?Ÿ¯ª“ÒçüÛ+ÿRgëêU^¿¥-9 KA›iãÚe ÍÜçWò„z\~(ÉþE° È+cÝØÄ5°­ëïæZOÄkÀùëXƒ”&#X»äŽjü:ÕÞ@µ 'hœjTÞÿˆjàUe}¿ÎéÁŒ/~¥Ú'ñÆLæÞ³eºF‹Ó»>m³§/w2 AuKy~nryãpÍ!–.”Ýl-1ñóÊlÍÝ&˘K³µ!`xÑÛØ8±WIè24ToRöˆn`="¹Ds\@yÒ5чIÎxø8¤P~œ‰1ã8L*]úÝP³Ü¥n¶m<•‘8™m]™jÏ´›ì¯€•† V,#`½ ÌSr.z¹Eîm²ªwh³Úá6=§™Û^êzŸç˜E,ëOŽòz ·–ø­o3ÀŸ¡ºNpéz¾÷m>»€uß»šž ¯P]*¨÷Ž"ñW_vP¬hûFææÌyä´Úg`-×/ðÕ’š©H·¼ŽÔ¡´åkð«‡Ð.ßͳ„D´ãO“ïž<ÏeUW úù›»CV=ŸúÝS; õlkXÎjç° ©9ôøNºEÚûú ¬Ï{‹d_™ksžÁ ÝK ¯jùe^'qj¾÷æ?g;Ä>ñNLПG¾ù%~AŒ0ÚVú‰Ü¿úRòn1ù~þ‘郒endstream endobj 650 0 obj 1569 endobj 654 0 obj <> stream xœXYsã6~ׯÀ›e—‰¯ÇMìJ9;3Îj´›¤f¶T JÜP¤ÂÃ.ç×oã$EIÞÌ–gÊ.hôñõ×Ýøù˜ _þ˜ßÙañÝ*B»ná£ÝâQ‹ÈüÊèûõ‚¡u»Eðo],ôI‚h˜`ÆQÄB´>,–¹]ÿÄÀfBq’„rß:_,9Gž\ò(aÈ Bõ±ýÐÖü¢#š…˜Q›ƒ¿l>ükó¸Z=¯ÌF«Cœ`nv55mÛ´rG(ogƒ 1ËøI.°sµúZ)åc»Æ˜=äQÄhýºXŠ$Æó!&QHÍù¶íõA0µ —-ù4&§–}zÞ<~Z¯~›G|ë¬TdAˆ)|ó¨þúTÌ„&•·÷—ݦ¬‹f&4pę޺ÀŸÒ¾²CuS{жAý^ÌäÆ6r«tYo²a³i.ÚMSèçŠsŠáÿx U—†®G­(D‹ú¥çb+O¶û6ŽÃÎ©í±„ã0‹ —k³X‹êDÖ—ñF¹ Ø,\"·Ij†Ñ™—xˆý˜¿ï¤G±Ñ¼ôŠwäùßâŽIÌFéì’w´ý<ˆ3k¿/7~Y*¿Q¸Õé®þí(:4qÉ¿×?-€c›øã‡}Ú(TÉоÖ!}º¡êQY\˜—W|Ç\JUºC­²Îš¶ý Žý“Ø€ÆêjF:ËÖ{Ø,T¼Ç>‹lòÒ6“¦$–©F!ä£&/bÌAÐ3ß¿,«7¤²Ж5‡cY¥ÒGÞP—½§c$ýEð%Uþ]6ç»ÑÃÓ£u-ã1æ.ÿm„=N¬uÁœ1°¯ËíJó¼¬wÒ©¨+ÿ LýU™¥ÛJ þ‰´N_oñ­ ú ÕN)†ZGþN«®A]s}y€¸(†JÇ.þ ]Õ;_Ë~¯‚xsCŽ­Ûò×´-6¯"ý]bVƒõëòëí°AìBz?CÜ’–&5ý¿¥yœ&ÖFž÷¹<ðܬM§# ÌÇô¬ó9g&J”IF%UòaÝ#}ÿKÚ¾oN9áÈËÆ©»×Hg3¨‹§ùÛï›a·GE™¾o:á¢Û)DäiŸÊ875 ·¬5M‚šIYrD€§…ú i)b€ïV1"DÕ¦ €£@Ù jQ`àŠ¥†¥²r'zie^ céfçò躧~!ß|L÷.ÏÉoâ2eƒØ0±…ÌŸ¹ü’2/â’h)˜ÆØˆåƒð ¶ÃåÛŠ‚Î HNzËsQ  T}îñgÛîP3Ì’ÛÌŽGÙs ;Õz€¥7SlxZ7me8aÑÈsӔh;‘‹";óÖòÛœ²Ù*ßH"ŒY<Ëú.C C@¨©½Z%S{ç¸}Ý—Ù^©Û—U%•>6m:k@wšf°Û«j‰ÆrE¨°©V¶#Ÿø2Xßh³±xj'åÀf%Á‰¯c ê®z¹þšÉ~ »¶—IûÂæHÜ[ž?qÌò§¡÷ˆ‚}؆^ Öw_f¡~½…tñ O–i œUi úÀß7ÍQnH«™ñU¹Í_o!ãÂÃ%xïÁ£èiõô+êÞº^ ºi¬Œ4ym>>ýüyóù·ß?Øü¼zü Í%:ÂMPgz¥m¨gBV¸b6ÔHÖ°\ô¢=”µ° ÀÍXseÚßœWYƒŽ¶ÓÝÇD{Ÿs©=|©W–ûI¼„;u­míS®Ù§’ý&Κ3šgîô$µågÔ!Åì—¸­j¶iµ©Óƒ…Qw‰”ìÉk¤tIÊþùQíEúˆ gXÇ&Û§ÀwzìQÒ$—\ §»‹l£VΨhÊX™8Ì6ÔÐÑX‚f^‰ŽI’œTø÷ýI]" c7$]†8ÌK¾›ÐÌ0ôü÷™¤ˆª\oJëÉçÑc0 úcï0uðLÔë$‰c;œ`t‚êúŽ ÜŽ'õPUžÎ†T²\×·ºƒ”ÙͺQèÕøi3€äxž*ˮمáЧ£º†PHMwhÆ>ÏØÅà ­òqت½¹è²¶Üªâq¡i'!ŒW‰¥ø)Bçž‘SOâšC%õØë‰z:ïÀܹvç$ˆ,OëÂýtoèMÐ¥²ØÅ¾Ÿ Ñ1Ž(± qãq˜'­ö{/ ÐŽc*ríæ“ÇýÊ ¸vÂ÷úÁÀ.Êp3ðÙ£Ab'Ê oNÄÕw‚CæíÝ Ï^x7pV\~@xטI³ ¹F(™»KN&…e}rÈ„ñ4‘Ip`*PÕhVïLFå2£Î:¡N Ì‘ÒtU²²S"¸Ð݃_®¶öPØ#‡$×Ä_ŽƒÑý$M%GEn „üÔˆws#'zp4ó̉ªpy4p½?tcÃ[µ¸uoÇA“Ç÷H’›ü _5H ý lã«Æä2t&n>ºªPYaVž×ÍhÖÔ} SÄ\z<»}h÷ 9aº³†¦n¥¢ïÈ€²‚ ˆm ñ³Z}v€þQfvN(À+qhT*k8Y&º¦^JT´Íá¬"@â<ž“µx1ìS“Ѩ§«³šÝÓxØ2/"kïõRÔNÇæ<jbïö¶E+Zw Dg~‡aß厲-i™gíaZÞF¸c+£Ž#©Æ…y<@J¦îÑä,~¦ ÝþÉKíß6Ÿ×«§O?žËäV œ~ú]M^TÁÝÌuàl2»O_§¤fðåcúÍ6%ãéH÷¾úøÿ|~\/þ?ÿóÅ"îendstream endobj 655 0 obj 2124 endobj 659 0 obj <> stream xœµXÛrä¶}Ÿ¯@í‹gT"L$@>n"9¥d-ÅÚq\)+¥â˜9æeµò×§’CI¶óÒVIK}?§»ù )#!þ¸ßùqõí½"‡n’Ãê—3/‰û•ÉŸ¶+A¶9œbœÀ¿í~eo2ÂeJED”d{\­¶ÙþÄÀaÆišJ<·-Vë(&¾ 8$ˆ¥yøü¤kR7¤jêƒnI³'eÝëVw=ų®~Z•,%ÛçÕöâçõÍždäÔ´}ÙÔxžz·a)hŠÙz8<ž†]uGÖ¤iíkÒ0L#|Ý¿œàîó‡ iõ 4éºï@dÞOe•±C]öä¹ìŸ6ÿÚþuÅ"kD$¥7,¶Jú'0–”(à]CžtV€oö(JE‡óü¬ÁKÔ DL£DÙ@¡"…ŠÖ75\Êz’g]Y*mBè/h„ñê3Ey¨/&MÐ~^gíþñ/U³Ë*p9oÚ Î[õº°mäˆÇë¬4Fõ¢(õc³ßðüIÖûN÷äWÝ6$« s] NÉ–ñ!ðÚMŒr7ZÝm ªÌqˆYc$èã©!]ß‚[&Ù‘½u“p*|Ù|üuª§„r©¸{Ö€µÔH‚g"¨¹·g¾èsÁŒ²ÈÅgÝf_FÉ\ÐX ÷V•¹º¹&j'a&—¤k\*ë4¨å¶ÔSÊãØ‰~Î&›Móö¼tÆØˆ3*÷¡ mšŽ:«±¢À),(S† "¨gÈ2 gÙ|ØØòùö>!€)À¤PXªL1‘—”I*ÈÇ<וn1Ý›oÛŠ¦ÂYdT¯ñ@ב¿;´qôÀ߸‹Ïgœ|˜ÐŸ«y#ázPÖäÊ•" ÑoƒñÓÇyfãØ'öþ;aÊìÊÄÊß¡&Æâþ»µ$CÖeâmfTÆ‘ñuû'û¡6.t¤9™È¦6Ui<2XJàŠS‡·…MÒÌIÒ¹0^ðê %àØsVÖû¦=R¡%V®K=:YÉ[¯ÝÈâMUHYiÊD; í{s‡‰h]V:èrð‰ ¦¨Ñ((ôÞø—Ò0 =ÈJ„§Ñt‰’-ÇÄŠª©H×¹—R™Ê0㙸tt.®|RW>2¤q2êTYHš›g @áK£ëçMDFÒép¤muëO¡äl²‹Û¨–@å6Ïh[©wnz"s$—¨äÜ “-JšD騳V`«èMÛÜŒVù^ðŽ 3ì2ƒ]ØåTͱ ý1!·2>Ò PÀA÷cy<¬6KÐú+¡+~K.]îgíc‰¶øÿƒsV€IÕd&«'Åši ¡É¬åá¡+½¤Ø.M˜Ní^má"¹¸°é†ºÇŸË»yž7CÝÏÞ]·-Œ AD¿9 ¨ÕÎ}fÂÓÉH&ËÂÇí}˧WIc4ì”é›ÝBª€x å{õÓãÕ§<Þým!IB«„žäNa°¶¢ W²8ö¢¦ˆ,KIÈpD°Fbw]Ü\ÀÊ6|ƒ,#öÇèÆQ؈hxì´ <$S¯'~î›upŽ5èqº áÐkœáÐUMz/II5(Ú\º.Çó3¦äÆpÂܹInVÁpÐõ xB²~jQÅÙY¨M6PM´àÁdºƒ—ÙišQ€Š˜œ´Úvf'0œ©2R•¦b 1!´ù9E¢!®‚û)(†¿­ŠBwy[žÀ3ˆXSC½Ht–?ùÆ7&&0·ÉßJ=JµáZրͻí<Àåj²×ç{\¢R8õnK¦›@©˜2eð9 š¡Âi¿µN˜1´îËVOMË„9%Ťɚ|Ó“·1ˆ¦D(ú1Ä–·w¾ûñv»DyÓY MÂÔf²&†xð´²Oó¤.’ãÈJolït/þ5â·oç=“|›E"Ê^±ÈíÝãõíöþŸK{A\âí]—û³9)fT…¾\g™°‰T!•2Y´Oí¢„ÕMOô†aø~-;¿¹¥+Œ,ÝÜÕ¸ fPÝ•KÙ·ÍÑò´÷ŒAÆBþ.í +ú|¥P9àMl·‰H} ^7`ºProÞÖŠ>gÕ„('\¡£‰d¥­íu÷Ô UAvP®­†p\&ÈîÌaãéc¡³ªjò· ¤ÍßX¶d ‹¥ñÿ(KÑK,ý–#pÿŸF]•ؽø¢0øÛ5°b¿"J9M‹°k¦FôØë"Á 6­}“ÈwåA§g“<;kYŸ¹\ÅT©è¬¦×–|VLïB;û|!b;Ó¹%ü¬óí½5®e°hz·¿ædúl¯›„ô>ص6|µÒV/جdìù¶$ž±BÑ·pØq·œí=¦‹š¸¸œs"“hŠ·ð³¶TAùËE4&„à ì‡OMóŸáDv/äLûàU¸Îª+ÜiÇ™t6Oõ 6WPý]y Õ —h,ͧ¸,y2~{¢¯ Ö×_³ã©‚‚ôæ(cÎ뢳뛟€›e¿_ÝëÑØôCá-ù"&K<”(Wþó}öBxÈÙtQ1šŽŸ5~÷ûÙõvõüüðzDàendstream endobj 660 0 obj 1988 endobj 664 0 obj <> stream xœWmoÛ6þî_qŸZ9µ‘”D]?tH0dëÌ6 qa(åh°¥T’“Ãþûޤ^lEM†ÂAl‘wÇçŽÏÝcPðô«}ßìgçKÛzæÁvöeFÍ&´o›=üÏ8Ä´¢ ð/ÎfÖ“ %á>B¼Ÿ9.Ça4¦ŒHj»89~®Þ² áÒH‚„fÿýC™§ þNö÷;µ]9I•­/Ôía éív5×ÎÔ‡øÃÌùgþzÆ"«ÐÙ_VUY2ÿß÷V{´[Ÿòm¡RØ”‡¢±{¯»­øë½‚³ÿ×£Ö)ï—st®34v%5.[Õ¬ï·&ÚÊAÜ xe¯ÌÙøhð­æ:@›NžÁÊFy¬/>ü¾¾þe5‡'if˜ØÊ±xÖ6Ÿ·ðæMnÌ1ßûó38Ô €›ü3œk÷Äæ_S%‹Þ®S•ìv妅oÑÛ“,ê ÿ‰¥óe”škf>¸\ê-FDñãÌ ' Rmë Â<ä„eŠÒ±HöjåØË?fNçá2ãã™ úzÒ§ÞÚ7$ìðQŸøÆþèþµõÂ@Ñ ôææ.©àì¬RÍ¡*Ö:Òs÷Ž-ÝÎÚûÄÍ£îpíH#5¾SŠM“—Å('ɉG¥l‹0‘G_…¾NdÔ•Í"­GQ^ÐEíÙ5ŠÑ£@I‘B­šq$— I|ÙßòqiÆá$ mÅ!ÃlòM Ü—xMªóPv;Ÿöy‘4ØjuSåÅš»¤·ÆJs¸2Ü‘~ÔÂtS•™™ ‰yݘÉuÇêšZòH è ã< -’JÝc¿©BŸyûU2¾ I¢@tG D%*„Ù&z㤪ÞTù}SVsßÃÛô…³˜Ž>¹øÂmä)&Ž'¬é)kF® ‰;#ŠŸú;mªaâ"y¥ßmLòhBOép¹\^/G™IFxŸ™cÉêúXk) êë*4ÆHôÐ,lÞmRý©Ùؘáížð˜ËH™‹R NcàäaÏù£Ü)Þó©ã¾?j…×ëËñòÏ“,Ž{ÌëïàúHDxÔX$u„qâóŽÚ‡&•Ãf£ê:;ìÀ6dU¹Gêåu?v–†Ø2xÑm•B½¶°Ú©ïÊù‹Ó¤RHâC«£|iä“@†'¥Ÿív˜Dû‰°÷/‡êJ"BÑ–=°^zâ6w¦CMÐD§Ð÷ÞÉä šM|k]û÷ëOñòêãOcâ…¤…lgíã* (aW[ef~¨º!#™1ž.çSBÃ_£}ë4Wë2Ëpú}¿è<4 Iá­îؽë,ƒnÀÚ0ß­>¨Z|Ÿ‡ßâ&´ç™ÂôƒŠ#ayô¬áÑäëÊ7!NŒ.;§…‹¦‡jÜ™zÆ ks£ÅI3¹ÌæÌG1äÂÑÎH6³\+S5üT4I^輸ºÄïE9QHªnç '¾Ç¹sØ®ó"+:”žý.eéÃ>7]?cèÕÈjß x4ð‰èºî%Á³ª‰ÓĪÐí·¤FØ}IÚ\š„:ØOÕ-˜P·PklÔ õÊÇ/È‰Ö UÄÄ„¾á’ü¹ï#¢ÿ¥oxzØoi~ÔB½¨ÔLŸ‹OiGhÙ€6š”5ä¥èÈöTՆߔ5d•ðguÍõ=vÒÒ6­h©~v¥]YZ±í™w€øpÁñt&L®üš|æ1:xc'˹/ý(¼Œg¿áë?4Æ­endstream endobj 665 0 obj 1374 endobj 669 0 obj <> stream xœ¥XYoãÈ~ׯ跡bo_<úq; '›1¢2¼AK”ÌD&µ$5†ÿýVõÅC>fÌ’Éêê:¿úJ¿F9aøÏ}nŸ?­3r茿/¸yIÜÇö‰üe³d³).üßìö$'"ÕT*’É”lžQÌ—›ÿ‚æ‚j¢Üf·ˆTFb|õÓ:'œ£†XpIâ$Áׂfðù¼ˆRÊS*©";V î³*ž‹v:?ô/§ò~{¾oöû®ì‹~[ZÅ\;Ûb.æ$3ª«º'»·t †$£)‰¹2—]É ˆ”]¡¾úeº>+q»ß“ÏmÙŸÛÚ)[-?¹­ÄuÛ6-ù\â˜úiÅØÞiÍL©Î­êÍcIöçzÛWM=ó-Ëiʵv!yÓŸ“¯\õöœ5¸›éV’J–xÝWßî¯~ù×ýíßgš2E³ ¨¨w.œkŠežÒT‡hN#47)ª²Ôjd4…¯„»¨oHhöK¡ ”áaRÕæqWšðmS÷EUWõ\Ý\w+RÑ’º+–\ã1÷U½oV  .ÿ³ùÛ"ö·:%Õ*7Áß6O§êX òø\W=y,‹]ÙºÃäâuÿXôފΈœ»²Eeªhª” U¼+÷¦Š4e9ó}QÕåÎT¾‚°Iš åb4“Òµ+»m[=€ìËñao8–«4d.Ôîõìëíýõ×Íúß-21{¢S/À õ%&i]<•®/»ÿK§jæpÊ¡×F8…U™Ú¾{,&?@jIÓ P•;£ßHÇæí8_wc(^Æ\0íª2À1VôæókR0­ÐŸl€ËlNÕ[€ýFìCG±ìCÌ–šf?€ÙP¦c6´¸Àlû‹‚LPÖ(57aÄ.È©ê¼4Ôçã1†¿žªºè½º¾E¤6˜y¨¦=& ´<ô˜²ªg}Öõc’¡´òîCÐVóQ“”&*xupwLæ“1õ€ ¹=dš»2wàL>À_.̓íïá/ªv¥0 ïTY`“„”k¬úrÇoʃK_ŒƼ£Ñ±kˆ++7V]ÌM@‹™ÂLc8ŽÍÖ̽Îåx‡9~x™ÇBh@¤àehDËŒª‰™7f522JðêÝü Z¼k¡…½z>Ó3ØkZê@Ddö¹²§HÝH` aèFçç> K$XÇS5D'M,ä¶å©-»²îm…<€3ùÊûùXìOw#¹Ð9§&a  hK“L9.ÈÑØ .£çCƒÀ‚²­I»X¨ÞÛve­z|±y1m9M’$O'5«üKIª_§ zÀ¸·h‚fr6Lß  F$óqJ.hBfŸnZ… ÔÃ˼¡ÍˆD:TE4#Èt†ˆÛhA¼‘S¼Ã"ºøuÎüeàV¯°!à–ySŒøÄm0ÅI(’ÕEŒI ì={naä!tçí¶ìºýùè„ìÛæi>Z„F> ôÏŽA¸M8jð%lm›%г8”ïã‘ä4Ë^%³‹€CåtD¾ ð¢î±9øaÄ·%\rî Ÿæ—À¨f©œLù]Y2½G;¿!«çqyéÀÒ™=…è4Ml”{ÃÄp©q=|¹ÿu³¾ùúóûÞš;žËšÔ 96õÁ®ª”m,>ƒß¾ ±G„~AZÿu™á™çÀ»h5šäÊ[…Ü.÷ °8 L“‰iì¶jöQl´,ƒ­Ó'Óï¦GaA \Škª¢5 .»9„Š }É$œ? ´ãrÛ>™’ðf2@”,•²KÔfd‹XÍ䛦\Z0Yrí+0jïØ”Œªcw[ðãÞCF¾kDuÂÂj&\ÿmU<KØØÝ–Ø f0¹÷,5V¯H¼? wûÝþ6&Bqpã:bÏLù‹F7á:óF'ªưKÁ>ü¶ÃÕ%-i œÓáQG˜™ã²ê½öcÞŽTN‡K$ÄN ÀéºhNºÉ?d£ç8Þê¬Æ¶NiÎ䨪m-¿YÖŸàl!~úâi»AM=ûþ~­Œ±òÁ.áÁA+,#8Oe˜“y`i´.ázÿ#ÃÐÑßåˆKŽ(BL‡'ÿ(^ˆ`‚{|†Í(ÚG¿b^oÿ„…X”ºendstream endobj 670 0 obj 1925 endobj 674 0 obj <> stream xœWÙnÛF}×WÌSL9Òx6rH¤yhkÈÒu„¦E´8’ÙJ¤BRVŒ¢ÿÞ;7«I`´9wîܹË9‡ŸÁýãž«ÝäâF¢M=!h3ù<¡f¹Çj‡~ZL8Z¬ÀŠ2¿‹õÄE æI¡ÅnÌétñ¸cÊp’DÚn‘M£¹^º¸‰¥ÚÜQŽæa¨—–ðÀFt~nöϦgþõû|S¨ ™÷ËUy(šÞâUU•:WúÑžõ8·Ç»Hq·ÐÑ.îZŠU“—ÅèzQˆãDø„>¹R›Ž¶D,Âv[ûJ5‡ª¨G>y„ÁÉå‡ååÛß—×oFŽ¢ š8G*3‘¦E†jÕŒ= †Ã(v{iùŒŽ[ŸASêå¹` G‘ðE8$ÒœÕ@VŒT®‘ö‰Št§jT©}¥jU4P‚¼@Ú¬V&w`^4i^äŦ¿!Ç ë£œ©;(#˜ÄÒ…A%ŽB{¹ÃƤÕlÂ蕉žêèhôÕ|†'2bÄ^ÝÜ\ߌ‹C&¡3¤¢="7íb”Ø×«IÈ0'Òg¿2áH¿Êà/ᛪ@&p ÷þd¸sAàN’uc`#~w½¼z·¸ùs4¥˜$‘o’Ø¡Í׃Ìg%$º(¤L˜”C‹I»‡·{¾äuã MGŒŽÝ¦ÛºDuSVºn'†!ñ ÏÌåÜ ¬ûŠÌÒ}—‚Cê=”ªB¶cœ„ðæ<¡8ìå'ÝvøY§Ò9íŒZ7éxÌ̺1kñd<D{I:ÂxÌT½ªò=$¢ž¡²|PQéê^ƒN|¿¿Í˜a¢\ˆµÃdÀð£í{Ýõ$N]óƒC¶Åa´ ‡mS£´²‡ëCaèòJu»>-^O¸LHklÁìº@)ª«•ªëõaë¢uUîÀG^·H73QŸõSÆX¨ƒüVÎd¨OkA±KªïËÃ6Cwr¥”á“9'\"ÛrjÀ‡§J9@YÓ]ËL¥Ûm¹:…´ÅRºúJØn[áx¯,&ei“¢\Ú–Åú *gNÁŒg’&1æaãw†RßäŽöà8Ó¦‘ºwëI§,$A]šÇúµ)žij@o΄Ÿ–ÃöÑp†!!nÙÛE©S Îm”¿ä›CÕŒáÁ-P¬›îc_-ï³w áÕ—t·ßª{`î)ÕÝ*eð”ïtØƒÌ àTyV Ê> stream xœWmo£Fþî_1ŸzØg6ìò²Ðë}È)î)½4VÔ¨ŠO1‹MkCpܨêïì Ø&—¤r ;3ûÌÃ33ëoà Žü˜ër;8›qXÕVƒoªÁ\–[ø\ˆ—hEà_œ ´'DÄõ€»ÄÛeÓaü'†AcÊHÒ.N–-—lF]°ý@=LE½¬ò‡¦¬jH*E ›²X‰ Ê ò¢•¨"ÝÎf¡Ù8òH8 lÜUÆø9_í*i¢²x>3{ vã—…-˜ÀÄœ ½{ ëÓÍôjO~TÜ9)®e–(¢vµ€T$›M¹„ ™kÖy­Þ¹ÍYG𠦕ܗB梤yL¿t›[š'¤ë'Íóxÿ>WÑáÄ¡É]U¶wùWÓÒ¤,†’Öf¬s>_ÜNοhFN1üûzˆÎÿêò&~Ñÿ;T5Q%X†bu#¹Ä÷‡¡ññTÚzȽCÛ’RPäæE²²L!uК› ÐoEj,í¹>#ðH¹Òj¬ ( T„å:©`4 yDZ0•hvU±ñÆúåÊ5Oï|\D#£¼^í~ ^h¥ÅkÙ®X6yYôr |[?¯gñ±ƒðrÝ‹è$ò¼6bW½@ö6+ŠîiR¤X¡M?¦Çˆ&ä航^ÔH6¹6ªÕ”ràG²mÚc$ ͼ¤äáÐR9ñBn]ÔŒBSª¶ M »ÍÆÆ»m^$ 6º©òb…Ř4 ‘ÔøUWŒºÅ6ô€½@ÒöþI.öÕÕîù\3½¬x€YmS?Ì™¡'Óõ¹5î·nß#>sÃVç&$—ֽѧô¢ÍÈ¥*‘ÖˆÊoNÔrY¸¢8$ƒváûpÑÄ=•Àd6›Îž¿/zÕ;KÞ =$N@»8Œ8¥ÿ ¬R¹í5F)‚ñÛ¢·QI¡ÚD<‚8JáA'qþZ¾¶ç ´ŽÚ±Éùzº˜\dz?t"õNGþTc16"ŽÛ&[$u†ù„q·£ å,“Ù-—¢®³Ýtq@V•[5)ºÂ+ÙÖër·Aa*lê#+œwÝ%® ›U廫ѥ—±—‡§}£ëêºm¸:Ì ÷~}TkËoÞ¬P*‘À¡yzèÅã çѱÂÎ7ñìòús_bXeëMhZâ~- œ®*}eH½à´Ù¾xv;ˆ\ŸNçÁ"ÍÅ¢Ì2lb8¾{ : úÔÑž ´Å4Ë ír:ÖC½2Þ½8PGá›C te3Žž “džÏÎIôÆ0ð|Â?zc` ÚzaØnˆc<ê¸<å§ÍñˆÇƒnºpÕÏïp"(m•Ùyx ÷#K:ãÖµ!9x8*š$/d\\Nðd’A€¤â~ˆu‰nÔÚ­y‘•c©ÙÚeÿµÛ]mœ~âLtGyìAŽÛføèIÿøÀ‡• øä×ä ˜ÃèÁ›SñÖýÍŸ%“xð~þº†kéendstream endobj 680 0 obj 1349 endobj 684 0 obj <> stream xœ¥XÛnÛF}×Wì[¨@Ür/ä.SØ)Ò¦1ê §0‰’ÙʤKR1ò÷Ù)J²6  wgÏÌΜ3£HBIðϽ®îg?\+²íf ÙÎþ™1ó¸—Õ=ùq9d¹‚UŒø_nfv'#<Ë©D‰Œ,ïgQÌæË¿À ,fœæy†ë–ëY”&$ÆG1g‚Äi†_Âx}œEï.I[>´eWÖ}UoIW’Dzø›ÔÅ} ŸŠžTY—ݪ­¾”kòå.A{)wD"h 8ìE»¹ýFÜ2\)86ávÙMd>ôM;— M˜TÑbþçòç±åXhF%€™4ÆÙl®©vçÓw¸@G¢o‡%T‡$*û}[wSŸ8\û­Ÿn/Þÿ~{y}}u=ñJçTÚU‰ iS“²m›6 Šfiš?‹®6·ÀÜ3!ü¦˜ÓTãåWRû3ÊTæ½h¼Ësþýî}¸º½ü°¼þcâ!KBhíM3·# 9ÈH,„M+•˜,£ðˆ¬qƒT”'ÌÃ1Ù×x»Úß6›MWöŸ£Ïó ¾ØoŠù(¶UÝ“õI¸Ýä€O”! M>/p>z?Ã6÷ÍŠ«Í†¼nMŒœ±Åü•;ή¸ÄÛ$¯Í¥ÎWãÐÄöL‹žjk{ e´Ù׫¾jê‰g:¥šå>N{®@1šëpÕ'¯Tf4OBž¹+½úeZ„šŠ`¨¨×œZ‚ª4ÉC,ãs”’JåŠ?¡™2Ìrõ!“f3çÒ1Í#ÜLªÚ|Ý•&6dÕÔ}QÕH=ÀEÝ‚T´¤„®Ë/s–ã6í··U½i`ÊpRDìOu?„e´UsÿPí 4ïëª'we±.[·™=6çPtúÓzáñ¯Æ‘âpåRæ/`>­“ü{˜/Íàž´òEãlB¶AÑ>C}©_ÄàR'ØOPÎxþ$?¤P~ùóì—sʃgÜC††és\˜œàB³[Bd’D†4>]6Í…þŸLÈ$Зç˜P>Í„˜m®ººÿJ†‡6^ćË×7Ñê®r{=O’(X²ù8æÈuUŽrü$×èÁ‹I33¼ö gie'9óLàÂ}8?K›‚ŠЦ¤ê´™ÑlD›âÔ¤„ÏgfÞ¢ÿ@˜yhàZ®Ì‡z¿ÛÅð龪‹X¨ë[Û£em+W!¸{5ã\z€_͉v€ ‹ƒQ&}ævý¸Q”\ 8rƒ®Á°ŸcLO=±À#8óî1Ê•-ö#®<Ñ"2¨aÅå³D™¡UÏ#ž<´–ë„+ó•ô47J¿ˆÁ»Lù€õÅA÷,Rÿ`×5Äå—®]³2úÑÙ¨$ `Ɇ¨ ±bTìM®ñ&­zŒðCë®|࣡°,@càÀ‹sqS¦žÛëõ4ÜÀ;\û…=w@&C˜£ôH¨Ì|ÞÜDƒ˜ë\1ï|Žœ#¬Ns™ÒT^MÃðà­¢!XMçŒëõ¨aðÙiù õö>`c|*ÚïdàŽ¯#ÉWÅÎ\´Z9Ò4MSäÕ=åðN(os¤¬¦‚˜œkÓX–¿@ZLU\º«É6gO´uœâœ¤_†÷@\9*§ÞcuŒœ7Ài-äS>àÀ)V[P£c™•ÜŒ“awÜ+3÷ä~Q*AÛSÏuÑ8¹„£¼C¨îÒÒÔ~µ*»n³ß¹‚&›¶¹Ÿ…R¦™è÷h œë1óÖ°:6»À`Ŷ$OQ%͇ÖàŒrqHÏMx†Íˆî®Ùï€xKËH$aéÐëL˜e›¶„Ã÷ÔΔOa(š/ëóº,v@uÞSaÍœ¹ÅãPVPðÜSÕß™25¦L“þÛñ8$T©ƒ’xsûqyýîÃOÓvS%qæ‡ Ù<Þ•5©ë~•/‡ÉÀ,Ø5õÖF^Ë®8aº@…£!ܨmKÉH™]Ù¢ø¥°D4äãaÿÉ)òÚ¼­n7ö[\³sMNÕ…áÞ~üéAΪ€Y“¨Z6„ïë¦'EÛ#䮇/‹vM.ÜìC¥4uCá ùŸÞ W€ì~g¹~;W8Ji ]«%eh‹R-ÃÜ ^§vhƒ¬º0Ò<çIc•ÏŒe0ò@á Ë6Þíà‘Ó\‡' m“ ꤩÄíù§ºöÞdµWç–±ÐB\/8ý`Œ³løz¬w ÍÚXt*¥Y–…ÙE(×WC•X­·¨Ü2‡J@ª:TÍ—¿àäÅxÎ…æ@§c9â,AòÌÏDÖäaçå}¢cµ¡ ÈÐÅtߘ¹YËü¨¬¿aômQ›z`3I h¬GSt–Øæ%kgpåÚæK×[µ8è à6qO xw0qÐ8®ä0Fñè]M§ÚÚ64£tíLáàõ~]ã¤.Ü´;êŒÅˆ¨¼´]Á‡_‹o„Cƒ;ü¾†?º„ÞëÙX/—³ßàï_HôMendstream endobj 685 0 obj 1903 endobj 689 0 obj <> stream xœ•XÛnÛF}×WìSB9âz/¼"ÍC;€ÓÔFõ†8hr%3•H…¤ìEÿ½³WR”’º°ÂäììÌì™3gýL‘?æ™o&§×1Zµ‚V“/ª>"óÈ7èÇù„£yV”!ø/'z%E,J1PÌ#4ßL<ŸNçŸÁ S†Ó4’vóbâ…ùòÓéu‚(•|F9òÃP~f8†çÃÄ‹0pqÒ8ˆ1#°Ÿvñ5ËÅJt‹å®ÊÛïfªÒÔÄä[{Ÿ©D¹,«ãµreãù4PÎϔř¸Ý­Pq»šIùé½ýô¢“µ~6}n_(W•(z¿Èë]Õ >ž7MÝ !íóa}½½‰G…Œv~'ôÕ•u5J/ q’¶ )¹r¸#b&°ZÛ7¢Û5U;òÉ#œܘœý¾8{ÿÛâê§‘£(ÁM#•©H³ª@­èƆÃ(1eùLNœO¯«åg?` GQ`…BU"µWUQ^P½Dm—ueªl#ZÔˆm#ZQupe…äŠVhƒ¼®º¬¬Êj5^«@Éé]”£*±Àâ,ᘶæ1XÆÊr·RUW 0ºPÉ¥ ¦¡6 œa¶nkØ´n¤ã¬Õ*¡àk¥ªiöÙë·1†³l뚌¥Ð0Ìb¢¬‹u5ÊкleµÆ-Âym™Žp/Á=: ÐDîГ@'Tˆ6oÊ-d Õ€.²üNžŒ*ú~…[{ª °K ÇãÀD<,¤‚&‰/ÀÜÀÍ&FÐ!Ò2Š1OˆÉœZ³ç(ùnݵ(kt2€GÙ8`à©QŽCJ½‹Ùù47¬‹(NÂd¿Eί¯¯®GK ŽGQDWjE*turõ0´ €/ä~È›]Ó*Áœ[ïf†9Kè~¬—W‹óËùõŸcv ÆŽèº•Ëþ˜Áxtït\75üQÕS XJ"æ}¬aU8Ÿ&0z bu~W€²Ýå¹hÛånmÊ–M½eACØæÉwy.ÔŽ÷gÔÔkÖ Iì{ žán1&pn¶fßl‡Xmhbê›@ƒ6–CÐñP$1 ½«wëݘܵ@BãH‚yÊöÒU©. ‘­×u~ŒÚCêèü¥°;MÃÿé/À ±ËÖ`—K$:üV¢Ç(…&µ@û“yÊBâµµz,ß)(¨Ú‘ ÍÛ­ gˆb' ì„#„9q½ãÛrµkܦ ÆPèðÏúó †¨ñAn6Ìó¯Ùf»ŸAL¡™¥‰w®Qÿû4d˜r7ª½ûº,0®nÆÂA—ÖûfÄ›ŒxV Eè"/•ížÐSN}{¾/=T„£/fQé^K±Psv,QƼ:è%©tÐ3­iÐ3-_Ð3£Wäz#€nŒ“WÈÉ„›):ÈS2í§‚¸~Ð ½D/^”Ê\M€ýé 4…–<íÇò:9UØÛ³ùG•é(’U&~µ“ûÈú#¯†jŒA÷†¦,E½«a#%`l9õ%m´`}ª"¯ ÊRƒä™” Y+â»!Øå»²ëùSR‚<€ תµ| x h}p;î³éöó´¦2¢ÉMLo#6uó¨uA+¦˜QK¨xÞû¥Aì ¢ÚZ΂;È%Ûn›æúÔÒC½¶+!؇i ¬ÀƒÔ«›¿Z™Óƒ€×:7¡‡\,7Ó”ƒ&²-{/´Ü"Rë«d¨cÔ¦¶3‰íp2ÖRÆ]U{x¯¸¼¬=î€:O=>gp… ŽÉ¿=}R µ§N»3;6~à •>aüÀŽÌ¢Oí¾¯ÆP?kʪ(ÕýôM¢~U‹îËb°{Ô3©W]qOõÇæ§Ã ¨ýÎ@]Ý:l·twJf¨u™ÒÝãö (psIc7“%ß¼^¼ýõòÍâÍÕåüü¹Uáø à>cCœé[ž=„ØÝœ´Û»7ÂÑÉudÝ﨔=LÔ±Ö€‰Ïì\™eÓ„ÀЩWÕý샮 n‰´Ù]ë4ºÔT3ÐCÛmÝH¾¼™×›-Ôä¶\—Ý#°¥æz`pû( gDMTuHN87xÖru(»V¬—è‰õgi„ƒ}ùzñþâÃ||‰†ÑkïçwBI}¨D ë^ÀUÊòªFëºZA9 VuwRHª›¿š;×È\+.·²LÂû“µ]L‹~Îlí¥JLXúÏÿOœÏ'¿ÀÏ¿m†endstream endobj 690 0 obj 1736 endobj 694 0 obj <> stream xœW[s£6~÷¯ÐÓ{‚.èvvg'mOÚN'Þñ`[8´6d'Ýéô¿÷HŒñ%mÇ™£s¾sáÓùÄä`‚õ©¾›ÞåÄC«¢ç UïKèET}-6ècØc(\€¡þ¸g< ¢"ÀŒ# nz–MúáïÆ„â Ê.\ö,—"[-]Nü Á&ÄÃÜãÈv…6¹NVÛ\ÙèXÔÇœŒ·¤;XŽõkXÐ]^®Yy°FF›§µü-_úÄÁŽãyV”dz•,gñ6]SkÚGÙ¼ÈÖ²”ýÏá÷ 'h²£P˜#MM¤ç,Y"YaN­«…u%çÛZÎWӾʃpÞö¬¿ú*}ÙêøãQžg9’úÿ{ä¼SÕÒ5äƒ:+³tQ¯Ü'«T.Ñ"Û¦åñ¥¤¹€IœË‚ú:êÖò¥S=¤=Doôá~êô¦}å^U“ÄhZa¼GW¿Î®n™€Ö”y9@ã÷ãÛQ8úRV!u„ÙRFëu¶ÐMæÙ³DƒKÝÚ1µLPÌ·¦ÖwèíÛäDm!‘}H>×(&TD×VÛ MÚf×?ß}gj³÷0ÿ>ÑøßÞ܇'ýÜÒd'šNxεD±ç¢ð¥g Lv1EKeË=LR¾i\m¤êYE󆞵yEOG#*,;®ÊÑõ°èQ3NY •A8x°QŽƒ>¤ê8V.ËmžÎÆPï=*š@'Z{Ï6qªŒ° :©ðÑ<­2ÉÒNÂÅþnDt3oŠnö6×2 D&pÀyذµ$`¶ ²‚DÁ]e¥K mÙÅä»BTƒVc:¨ ™Õ*3ÝyìÀ¬‚±esJ±¼y ÑÓn¤ ÌÀøQp0}ËàiÊ•ŠPº]¯møµIÒ¨„=_”y’®Pù•HeRÀ¥„»Q™,šf£\>Á¶•©ò˜U&]U‘©Ñ)ÍPš¨'ëR‹#¹#Á Ã[S¥_çêµ¹üòèîYššïƳÑ]8ùÍ"ÔÚ×q§iþØäRÙ%¬.6Š& 3ËcMË€Óª˜íb!‹"Þ®‘Ù! DÙ8— !‡K5w‹Çl»^êØÄ…®x^½ƒ}Á4,°w[€K§b×ÇÌó÷‡GKdôAÂÀœ(xø²ë¯ l­û›”:Q éT~}êîg Ï Ú û0»'7wŸºƒcŽ Í´ñ«¹øò(S”ê)Êg1ÞÌh3Í×Yº‚ÅHOY”x_TSÝÕzrqJNfËDβ8†1÷?UeAù9éì‹‹9G²F3ã8Fõ(5`CHÚiYœÓ$ —þ«JãS5ñƒ¥9Ò.pŸ5 Uµ [û‚ï8xtcr‚)qè+ŠV4ÒvB‡læsìí¦õ~ÿºZép8\‹FâàZô²¤¹Å}Êá|î–r†™½)r,²´Œ’TíÓ«›€,1ÂK9ïÃ\7bmW³$³¡â§R5ÿí:j•" ßpPvrd¤ëP¯´œÁ¼0ú2?¥Z ‚øN3ÛÏhDN‰?"ZÐa‚¹¿kq­[â5Íb‡o> stream xœXÛnÛF}×W,ò*7{'ù˜ÂNê6QEhP8…AK”ÌB&U’Š‘¿ïì•ÉŽ[8ˆlíîÌì\ΙÙÁýã>׳·ËíÚA»Ù?3j‘ûX? ŸV3ŽVkØE‚«íÌž¤ˆ© s®ÐêaÅt¾úÄÀfÊp–)½oµ™E’£X/½]¦ˆR-!f¾“R/3œÀçã,R˜*,±@½Y$˜ÐgE<æÍöv{¬Ö·ëãm½Ý¶E÷5ú:·Riæ ‹ý¡˜™cÄÈ-«mÎ ÐÇYŠSSaÔ\˜mïaÒ{zƒ^ú8ÁF˜Ýq½Ý¢7MÑ›Ê [Ì_;uvÇeÓÔ zSè°óõбÕim¤ËÔÊ^ÝFmWÖÕäf©Ä)Í2çó· îqJ(ÎRïBkn;,Έô‚/¾Ü^|üãöú׉¤$Å<Ê« …SI1O9&YðåØ?SÓˆÀ"QV"Á ~ÜD]:ðB½3)$³HFee¾n ã´®«./«²Ú¡‹«ËvJ\`„7ÅÝœfúŽ»Û²ÚÖ ¥ÎÿZý2‹½Vg"ÔOç×õáÜçZx|¬ÊÝù¦hÜat²ÜÝç·¢µ¦u°¼áC›¢]7å]ar™b&mŽß}7Ö¼:ŽKL0„LRp¥¥¸šº‰¬‚CW7sA0¡"‰æ–ÉRàD1Ü­“ ©,Õ¤¤MFÚmøÊ”ŸßDõo>ô]Ó—8…¼M¼ì³¹Å9lãÔº\.¯—“›eÒç µŠÁWàES>#›yŠ3ÊèKl55là‹‚-sk1ÃŒŽâ*ú+¿|½˜ã½ž1–`½…ß [jÂ.BùSá¹í†Ì/õwÿkc=ŽZ4J¸N³C‘i“O9л†2‰‰ú!h¶ÂÜcæX˜¤À\P*kÔó@Éý&@K]>„ÉDùû¶F.e<¥íëµá•Öz*cmÀÇ€ÞÚ+6†ûïã¡ K÷W fÃeŒnà³$Z䣨ÉÄ}_m¦®G°Ô;1çS ”.Z ƒ`¡|ÆÜD=ɧYjH¾õY”^:4E[TMNÇßL &Á='.i&ì»@ºžž’uJçƒ~bœ¦ ¦¥åĵ݇…Rc$U 9©’½ œN“ÌPRŠ¥”©exÉ­2-; 5 ÞK&ŸåÝ vP:ÆŸ³Ä ´’ùÌÒ­1Òd5PR*ÒôÔHÑéW'Œ VpBŸbÜ^È„v7MAº|¶ÅˆaÐ=²žEN¹W0˜Rèt†éYøÚ”qæ7AÓDˆï³¢*oƒ=™U©[Ñ”¯À•ŽëuѶÛãÞ7Ú6õÃÔPhQ°Jy0ô¿PèõQó«Áv“©u“ï ô<@ê–i€mç@DHÖë°ÚÞ×Ç=paÑ !Tö˜*WMÊ-ÐXap.swÞù`Ïß”[1ODgñا?ó Uv÷¦V(Sʨû~8! Ȳ$1ñ»ÛÏ«åÕ§ÓRHž|_©ofðx_T¨ªíõ¡Ê©è§³a_W;;(’-Ú®ïê¸)ÆDÓ¾—Sè¤Ì¾h4ŽP’à̳±“Ð;“Th5ç&#¸œ[ë{üÐúøÃ®û†vCÍg7-½Òs‘¦39 f½-³š`Tê¼ôW¨lÑçWHc\¹µã§€«†TX¬êò¦ÓW ¬6y³An¾ÂÂT4çsô/ï†-}’ÝDË÷óD‹W tÂæ¼€³4àûMô5ú¹¶$¡Òèѱ€]Î0‘ø,ê¢8éO{¨å‰˜ÁÒ–”{xÀ¯ªì-…¬ ÀFíîGÝ@‹¬ó}˜DÁ!ÞF¿wåš•Ùó>Ђ¹ Âò=ú6‡ëà §¢¢iµpnš§ ze&[}w Ží{Üáx§c×¾ZØU04ôµÅ´"N*¶ wEÃá‹.¿«G"PQOoOѶc l£úñ§Î§Ð¤·}›]ÀÁÔªmƒ„]öÒD£` ÔÔãì aq„> EHÂaßNó»~h `¸¤ó‚CÏ%‰½òêu¤ÙyU£W»Ú·Vo&¢r_Äí.øX4F%‡½ŸSãM±5Ì0II€yéZ›²Ò¸®C³ð]pÌ%°ïI¯62˜ c´†½Õ´s´oO¯.mi˜ƒã¦¤mõ•|z€–ó¾½04§io–Ëxè·\Àµi5䀻¥ïÝt(ÇæÛ.(èI؇oNžpÚÑ#M0È¿=¡;xõ3¹žÄ?N&qøiÔ>3ˆëJzªŒú\?vÁ‰¥ ‡LZ|@yNˆ0°|ó[þ1ÂhZ¿ó…¶þ‡Ï°—«Ùïðó/…뺚endstream endobj 700 0 obj 2003 endobj 704 0 obj <> stream xœXYoÛF~ׯا„r¬Í<‘æ!] ib·©zv ÐâJf+‘ IÙŠþ÷ÎìE‰–“ÀlìÎÎ=ó}ÌgÂ(' ìïùzôüCB–툑åèóˆëKbÍ×äÇéH’餸 ðoº™—œˆ8£2$‰ŒÉt= &|<ýÔ€04Ëb”›£ ɯ@EfUL—dÅú¾¬:RÜçÍb¶TݬÛmT{àƒ(¡1™ðPKi‰3u³]’âfyŠxõÎ]Má!99ÑïOÇOÝñoå²RÑçóz[u{wçMS7äDá¯ë1œïE91Ö…ŽÓïGÁôV‘Ŷšwe] bŠA¾úA@ ßÈû4Š˜fŠ7ªÛ6U;P)š†¡Syöçììݳ˟а <³Rà)Çf|/.__þ~1.®Ù”0šrSÇŠèÕ„²±>œdJC?¾ô ^I{ÅṆêš~sÊavíÅñM#)—.“½«³ó‹é‡C_A_êŠZš‚»Š„M˜tzöë` c—ú¥ÎL¹Üh5”«ª;¢ÆP©,…ñýíkò¦¸ë¡B³2.+èîv;Ÿ«¶]lW¶ dÑÔk³È]h<‚.‘ñ×÷rdô⬻ÐM]·n,uç·jHžP–Ä.×ÎU’hƒÖ§~œL–V¿g™ìö¶Þ® rÚ(èÝm kpèK©ô¸bÂÕ¡Î •¯VõüEÜï:Зuî–àwë ¡Ʋµè!‘øy¨tN¤mP&\K]÷ùXD,hkýkñV×_ç>¸.¬bf¶ñjGxtJcAÌÃÔÀ8¯Vd­Öu³#ÚË¡äf7NˆŒŠì½ñHKØD¥žÒ¤1 +,)iâû©\n¢H{ˆ ”è» àØ‡dôA&]RοäëÍJ­€*9t4çiðÐ]ÌÔþâ‘ÐûÂò˜à®. ¢¬ªë!©2ñZVõ/Œx= Ùô^"/ {/©–aúîé!9Ó~nì£Ò#lz1¡ç>0'*„L<1œï‰¡wä‰åsøÚÆ[êÚ¨xI<º“1"\ÆðéÌ òìY©Å5ÛØ“~‚X§a«½*?‘“çº×dþÓ)::9Ú}ã½±d¼>òþÈÑ>Y Ä©&Ç=W­Á^Ì1噣’(càëyÔ¼.)[R ë2“’·åo‡ 0¹ë—4Ι³F­ LWÐHz ¸Ë÷q¨óÀpNK*{˜4C‹W¸IC­†”{Ì›öúzÀãFñäbÉ7›¦F2žDÀ#&ƒ¶+ÁÙû1CfAÝüÓbL÷ ŽMlÊ0Eø8ÒXÀ3@E?´w:HàyˆüTÝoŠýf ·AZid7%—Õ€r7ÞAÞWÀ½‚ãH7ä"Tyäxí²pH1G;‘øšƒ;ø ̾î2Ï@„±~È#ImeU”zIèÓ4îVtW[h»Á@O+XO+‚c¸(=Ã1‰ù ‚aÜ2ôß)2´ãÒÝj¾c1YKׇë³Ä4®9ôÂy5›~üåüâÕûóÙëË‹éù_ òK—;þc%¸ Ü78{1&㜆¥PNó1À ªº‡X@D‡¾ý´ ªUŸÈäNum6uƒk×å¼^o 7åªìv°$ÍÊQp¯W“x=V<‚½€‹JêE|Ø#ð-$ý É¾û¢}¨‡N„mDÞç;XH‚÷¯ø˜IÜóoþ?Äùtô+üüR«qkendstream endobj 705 0 obj 1719 endobj 709 0 obj <> stream xœW[oÛ6~÷¯àS#§KR)­ëC‹xE¶4ÞaCQ†bSŽ[J%9Y0ì¿ïð&ËjÒE®¿óñ;}ASDÔ—ý»Ú^ÍÚ4#‚6£/#ª‘ý³Ú¡wé(@é ¬(Cðæ#³“"Æ„H¥»‘çÓqú7¸cÊp’pe—®G^!_-ùŒȸzâ8¿÷#o-³í¶ZemQ•¨ÊQ{#ѶhZT´Üæè¾hoôÞYûp+•G•XP,á8ŒÝ‘g-Ï.Þ./ίRkçÀÇ“€ÅÖîþF–ʹ†ÄŽhˆ|øEbá5«º¸m«ºAY-QY¡mUnd­°e+kÙ´ØÛ3i,äÚ‘÷K±Ù×ÊD3ÉbFÌÁ´0Áà42+Ÿ¼é?Ùîv+·h}?¦Jc/«óåF¶KÅL³ðcT]7ÕV¶rü9ýµO”O‚#Ÿ™“îªb¤ñ¹[xg÷Ê×™¼ÞoÐúz³+Š‘‹‘÷ïøDÁEÖxZ×U¤þý‘×j‡]º*6¥\£Uµ/[³vâ–R€ŠN5àÁŠÝTtgTÌàúÀLßЫS4{w5»˜¦ÓŸ`‘‚íõšl¤¦”_}ÖÒ N“”]Ww╾³Ó…fÎ3{Ì%ôB˜¼ÐaÁGúbüºGU‘£…ññi5þ¹œý'~Ea¤-<+„ü³áê5zù²ÐæàòÈÂÝ7R§@ó©ølÁ{h›†él&ÈæCúñ÷éåÛSõò±ï÷¿o»é|¨œzrÿ#tZP­<¹$j‰aéËá˜rÌá&×Ê6„;%ÔåFwge¶“êº)ï;s«dsÝJ+ëÁVµ1˜;dj¡6î)QYO4ˆÀ ku“Õèô´–í¾.—ÊÓ¢&½Fø§öúa±—¯¾9ÐBÃÜøL¡åûr¥ÊØ áøP4‡!tÑwõ€ÕŽ*ƒ±x 8NÂð¨&*q¨G4±V¶+¤Y¹Fl‡>C†#έË>7¯‰*LΫ×VºüUéü1ÌyWi½ìöP#̸Ë_mX*]hQ[¡ •ûíÖ‡O»¢ÌZ¨M[åŠxÖ"…£ÑÍRDW\Å8ŠC Ã_Ë\çh‚ILèáj¥þåPln!we©¸~p¢¯=–@ Ø ¦‡Æäˆˆà®vÚÉ8T E› +t∮E¹^'”õ ël3fø\k×QõIœúÀ/…žÍÝÂã² À$8VÍt>ŸÍ¿¾â†5'«Ë*M+8Ę J¿ ¬N Ÿ`Ý-)€‰\IðA|±>DÞ!yì*‰à]>ôf˜ñ­xý€Eï.MÌ—³åô24pU¹Žç Ò‘?3X¬ È+ ¶Ìš u‹ £ŒyïW+Ù4ù~‹L>¡¼®v º¢éjÅD«Új½¹©ö[¦[h¬Ñ-8æf²Êk òÝ7°e1$E âãRÓk‹&Wµ›'žÜ÷6bŽßï›Õ(L-B$}…½]^¥óóË÷C‰ rÖ%jl«¨ÛÊÊLm Còã©í[#5W]z؆hC'Ou¡åºË*Ï¡(þ`3:ò0ìIö"3L¸IÇXÌò¹Âkœýp[ÆÏö%˜Š¡?$_õ¥Çùè´"NžéOa„‰’gú“PÓ´sôDW‚Ù=Ä,é¸<æg@û¼kxð/Pð š”Ön•Yï/Qâ©Í  “{R“ãYÙfE©òðì| sQ%Fx-¯Ç÷°zûͲ(ójb_gt}÷Ý©~ _€¼¹ìÞ ÆÁ;‰ð®÷FõçX¨ž|È#Œv Šá¶?û6MGÀ×ÿÉ­`endstream endobj 710 0 obj 1424 endobj 714 0 obj <> stream xœÅX[oã6~÷¯à[åÅò&R|œE²E¶Ó 65¶X¤E Ør¢…#¥’œAþý^u±gúR8@l‘<<×ï|G"‚)"æãÿož?Þ(ôÐ-zXü¹ vù›'ôõ‚£õvQ†ào½[¸“1©1Hq‰ÖO‹$¥Ëõÿ@ l¦ k-;õv‘d¥f)e”£~ÁC‚9Whým‘\\]¢¶|nË®¬ûª~@ýc‰]Ùš#”q¬xæ¥ÛrgŸjLrÄWu¹Eýës '‹Uږݦ­îáñý«g΀þ:è/9Ü®ýñ‹oE»»[Ãy¿-˜©2££ßv›8¡Ï}Ó.Á„ •¬–¬ÿ5–œòœb¡J©°Â{/VÎ\Èrœûûñ•ÙÀÝÖ·ƒ?»˜^ö‡¶îf6q†9ËÃÑ‹ßî.¾üçîòææúffU®±p»ˆuS£²m›6jÉ–Y¦ÏjWÛ‚b~óp(e8Ë­ðò•Ãy‰©’ÁŠvbÖìûÍûz}wùu}óß™…”D׺•Qj£#ˆ€„¥(åܬ3¬2«&(&±¿lÍ¡0#4¨c³Ã„ñns¸kv»®ìO~_ÎôKá”|[Õ=Úž`Žgàè˜(CÚT^Ù4‡¥/ ìêÄî¸ÞíЧÖúÈ [-ð×¹—&šè“ *èùÃØ5©»ÓénÏr'{ %·;Ô›¾jê™ey†sªC:œ¶&º#†@Q¬óê“!kó̇ôúçyæ˜GAE½Epá\TÇDG_Nýs” %} ` _Á·IßXàivK& 3˜Ã¨ªíã®´¾A›¦î‹ª60¸Õ­P…KŒð¶¼_(Á1šîªz׬@”Åi¸Õ«È±®B6ÍÓsµ/ŒðôPW=z,‹mÙúÃèhÙBœ×¢›@%—K!>•¶vÛA)HË­RgðŽåB~?í÷àg&0Dˆ àé; a5FåúˆRL¤Èß…È#IôyÕÐ?yÀQ¸Ya)7‰«'H” ÐZ똨®j¯zT—KinesIBÒ¿Œ”b ø;”šÐ3ý€fïh]<•¾(»¿Š¡Ss¥Pe#(œÂ)—®â €ÇOŒšc9¨rkåÛÝ©]Gêv ÁË”2B’mUF6¹¼þtjW„J·é{ZZ,=ƒÓ”ò$N¿áõl g¡øÒ Z`õ¨†D9‚jïø£<Ì0ó·ZE­¨ ôÜ@^LÚõa¿Oá×SU=€V×·ŽGT>TÓÒbàW*'¥%œèYyuý˜Í -‚ù£k€w ¤侈VÝ&“ ṃbw€„<°8àM2÷ èë9ÚÊ ´bùØ5¢}  ;–Æ ,o@Z«Õ9¤õ›¨ù&"!,Æ#‘®î»ù´òÝÔû èÈñ>&ÒÆûfcÛ]çc¼51¾û‚i¢he¬B³MYQTPf5R2ƒLêíü R‚i±~ƒx:“­7HZò„)÷\¸SE<ËÈ 2fYFÚ=p Ç8hG¥¼”ܺçíI‰@§ÁÎ3í…L}ú§¯9ë°£ p„Zœ)á)LäDc…4˜ÍFtô-v  ÿÀŒjk•àÊ|“³åžÂ´yÆÉtÚ"AQEcqEþ ‡¬Hf¼ÁœÁãÎ[àoC%Þ!€ˆ™ŽU|ÿ¶ ”êy` n™ňF\GUì&©10±ºè¢2¤} M†R‡ù‡Í¦ìºÝaï‘íÚæiÞZ˜64d˜½¿§‚_™§s™ýj;!þÅCù> •:I%foÊñˆp3÷ ¤{l{@}hîm —:(¦ù%D7å“þ¾-‹=àe°ˆƒWçÈ7aõmœ[:2sâN™NÔ?Ú ¶BmõÇYa¢˜@Ä8>ßýº¾¹úúÓûÖÚ;¾=–5ª´oê7æØF^výÀ5¹kPfø“F S¡Ïû²5m“ñ‰/røúëOWÈ€S¨M’jcÁž×Mž‹¶7Vt=<,Ú-ºðÂUõÂß>100ÅÂptóÏ¥2ócžç¶ Þ`<qXÇ‚æv „Öñlý7©ÚYÔT›R0q†àÃPúb †£H¨¨v.+Zë˜h²oFFå0ŠÃùƒïf°mŸlj5 ÀŠÊG)í¶é"[S•c &®[¥vžRñ¤Ú—i·Ëß{ˆÈ‹Õ†)ÈÇ2æë¸h«â~_´î'|À ö€•»@USaÓ& ö0PÜÏv»”ŒˆŠN6ÝÛ $îÌ”DÑ8jt‚ UPˆðÕØ‹}vñ½tXp£I9à†°€>Ì6Õ`uèõuH>a>à;1 §¯¦9è&/ >¤c :A—8FË/‹ä¦„2cûP'/|DÓB°„¿¯ˆF‡¡Ø¼kŠïìKèËõâßðù?|Jötendstream endobj 715 0 obj 1976 endobj 719 0 obj <> stream xœXÛnÛF}×WìSB9Özo¼!ÍCZ»€Ó4F!mM®d¶©”£è¿wf/¤D+M`’¹»³s9sæÐŸ £œ0üqŸùfrv“U;ad5ù<áf‘¸|C~œO$™ç°‹ ¿óåÄžäDD)•ŠÄ2"óÍ$˜ñéü/0›¹ iá¾y1 ˜Ìpéì:!œ£…™à’Ì—áóaD”G4¿ ܬb*ÜgL| ²f¹Xénq?Miš(¡‚¬io‚›éôÓü z—:ïfþäL˜³Ì/«Žƒs¯ c‘WÆÑs³á\ßîV¤¸]â\zë—>d 99ÁÓ§ÓçþáûrUé‚àãE^ïªnoí¢ij8¢ñ\}¾ŸÆ™½ÛyIy’Oçwš,wUÞ•ue³Ö‡…”I—’` ˜·»û2ñ„J0j·7ºÛ5U;²(#rá uþûâüí‡ÅÕ/#KQ )S·+« ÒênlJq3é7 ÙÙŠCˆ´·ÕÕ¤»Ó¸e¦˜¢ –̓Ñ$MBŒR/ÉÒà"¡‚3—Üd²ö1(×zÖæõV“¶Ëº2'÷S¡…a @)³Ûµ&U¶Ñ-iô¶Ñ­®:¨YYáõÉ6ÉëªËʪ¬VpÂJ*FUì|ío0îBfi” Þ²DZG†ë¡Z\ŠÃëOII5%´Ð·æ®UÂi·|ƒu!©»UzÃ`Æ äÒ¤4L©Jú40øj6­ÛP7xSÖñ¹“ñ~‰L¥=~ÐãÐÓv×i¶íÛZ@6RáXCOé†@ 3².[,Ñè¾™ 2ÄaA1væP(0­&“…nó¦ÜB4L]A[@/é,¿C0`Ý–Sðˆq®¾V}@Ǩú¶â&õ3­sïc`ª‚&Y’ÚZà>Å苹J÷ëáÁC1¦TPÆÉ°ÕE‚=m@µÙ­»–d#8–lÍb ÀÎeG|ãŽiŽË¦j¼ló^\__]ò nÅ\õnIn oˆÉxnŸæ@|sÏô#¿Èñë›·_ÒHE~á8Õ„°E2Í»«ÅÅ»ùõŸO˜K™]ßÙb›â ðÃý`0e¡/‡­¬¤KÞ熹Îtm^ÔP¶ªîˆžrIȃ/€_êZùFˆéºù‰-Þ²^¯kÛÑ¡ !J°aęٿãpYÓðr´µùªÒ(X¾1gLÖ"ö|(ÁnýHxxJc¡E§L8sà°¸»ª ßÚ]žë¶]îÖdÙÔ›qûဎ®"ÇG ëh4ãyH}£ŸvCšD½Ç–¹÷nÞJÂÐÃà«íŽÐNœ‘Ô^íµ;iïêݺ ·ùFCÏìZHù“ðRB%£ð0´E¡3(X~l**å±ÝkoŽ&"sÒšû¹\íŒë¦¶"¡*ôÑrÈˆÚ &àt|«ŸƒàÅ—l³]kÀàÔ#ÑÄq0(ãã¢`GÓPy¹Ü×eA´³v3V.®°Vºü²¼OF4l¥‰!òа—xâPÑØÁkÖž( Lñè¹;RöQpÓõÛïc¢Ê"ÏŒ zfµÓ3§•¬‘%¹±'_‘^œÜLÉ“Go{;8ñƒõý%yñ¢4Ûq¦îï?;Hi‚,?‘“33Ó¶ükr SÆiã³½Æ:{äô‘GûúO@9•›y<ŠõgȵHâTõs‘G–· ýäu¡‘ƒ ”3y†j&kq0¾Ùç|Vvãa7J³¶:†Qo ÚRõêí>ð$ÔãÛʹ™0¥£~r½©›G\Š)‹•1˜‚Nó"‚Î{1UÌS·»±3î –l»mj˜ïÓY˜/0 bªgPó§R¥AÝüÝbLÛØÜ0Gmì§f°oÔ{$Ðlº`ú94Å~³~è¹ÝøÒPPrUX íSÖ7À{ßÅÒR¹sõ –¢Òï$iÔƒ} ž4ÚùGà •y`p÷SM¶GÒeU”f:²ˆ÷e±ˆ=P÷˜ÏKhÊù(èÿ¡mC6ò3¿ÚVèîŒ:0ç23Þ»ÇíÓá…´—´†I^/>¼¾^ütõn~ñÇÜAcõ0Ã"¥½¶oŒ6ÅèB/„›qI±?S‡ÚÌÜhK²±ÞŽû7ÝÓl*`ò'" ªzÐ ){½o @üë8 ŸSÛmÝ  æõf é¸-×e÷Øs 4%Ìh5â6‘pîöѤÒ!ó/ 3PRÐ\½š‚Ф•"N†ñ_v­^/ÉwD0x÷U‡õx{ù~>ªz¢ Í©'Ÿ‡;]9¢Š®j˶˜¶8=P}Áº®V#pÕ¼®hÔyæß f6^k`néìðn}¿7ß}·S­’_³G`VÁ{aÀcŠÙŸüæ?A.æ“ßàç?˼“¨endstream endobj 720 0 obj 1833 endobj 724 0 obj <> stream xœWmoÛ6þî_ÁO­ìZŒø"J\×â Ùºs´C\²M9l)•dgŰÿ¾#©[vÒbpKâñî¹ãs÷XŸ‘‡ òô§þ^íW³mʇ6ƒÏbQýµÚ¡¢CÑ ¬Eð%»“ *$fL h7p\2Œþ7`L(–Rh»h=pü¹zéjÖ\B8f”#ׯäÇt³/´‰ECÌ}ZïV¬s«7…[Š­Ó—oWîÉßñîq«r´~{^8q‘,6ªZ†Ô‡›rî̇(_–ùVUjø)úY»’-@Fƒ@.µÁyºFªv;w®Ÿ´»kµÜoÐz¹™5ÂQôaàü3|­3€¤õØk'E‘H™ÿï÷V益îÒM¦Öh•ï³Ê®½n–>Ænïy½%m§°µP™½^?µi›”ë½Ò×ãW&Üø•A4Z' šÛïÐõ‹ëÓ_ Lg)]ÐõÝN#ôûÝä;T*U‡Ò®ko·ùÊT8^æ…FW&ÝrŸ;4`ÿÞ¦ü½y“>e_*¤}Þ§Ÿ'6PäT›Œ-ê÷‹ïg6%÷Äá¿/:hw¸¹‹žÝ~á‘!61¼ÑœfR/Qø(z8LÑZÛr¸òm˜j‹fIj’ä2ÒÉâÒ<£f㡦¦g‚èãoOÀnÕÑü‹5£Àf¬—£Ñ½³zÐ ºçÁáWû˜µÐ>Æ&ö G5] 6GçÚ8ÁœS*zP(Ùg«*ͳºW›,D€}&ú•{Èm;w6 íÔZ[ŒeÏ# p DmÒ’·ç&å´v¤4ÎÖÀáªï’sL‰×„Ô¦çØeŒÀ×¥æ8L î*G1zÌá|TÌM¶ßn]¸Û¥Y\A—U‘fT=ÄÒžK¸„º ©æ¡NºUn¹ÊXÆUºBs,LêéÛT0.Òx¹5¨Üf¥¸ê4 õÍ­2uùE‡é%,9’˦ˆ _΋èqÒ0x­ÊU‘>Vy1䀘ðÀ÷9ëCAxØ`=XÅu"-”àæñi—ÆÚ‚² ™ýUщÁ~À±¸È †}!É)5&³ÙtÖKLzX´¤Ôe3UË3;µ“ñø©Ë‰bÚfZ=˜Æ3ÎbU_ûâ2O7÷ÑPµ’qÍnnêóI4l¶CúéAe(ËÑ6Ï60 ò™± Ê ÷dÄì„™rIHØ· ÉbªEž$0×þ§Œœx諉éT½å\U UùÑÒ4IP7;­¿1è‡wdóíââa?üªº„>‰”}ué—¤'2æõË"Öž/¿¢2AˆYëèmqYȰ×6ƒÓ¯Ð™‚r1¿é?YJ€ hÎæ‰aéP›p«@ÚÍ–Ê” ~weUœfºë®o&ðË'Å #¼VK+;sö›Eš%ùX;×Üq‰ ZºYçIQkx7¨Õ«gZĶ ¹¼$bT l¤Ë +(ËN£zÌeBÿ˜zY¢\kTC=)ÿ‚H åkIS‹týir¦R„5V0å©„ç2eõ%q”s Üþ&‚1-¼)täL© p£œÐè’ô0é7x³Z²X=})ê0®g¢¨R§>  =×/(íôäbÒ.÷(=¨§vYº T}ß¼DÎTû Ø<Ö:½AúÇóÓÁ“_ã/ˆz”t»õ$h+öÕ÷ÚI4ø >ÿ'éöóendstream endobj 725 0 obj 1493 endobj 729 0 obj <> stream xœXÛrÛ6}×Wà-”GDˆ Aò1;mz±§ŠšLÇéhh’Ù‘I…¤ìúﻸ’¢d'í8Ù°Xìžsv×_Q„ ŠÔ—ý,fo— Úv³mg_gD/"ûQ< V3†Vì"Á¿ÕffNDE†G hõ0 B2_ý f`3¡8˄ڷ*gAœ¡P-½]¦ˆe!¤„¡0ŽÕ2Å |>͉À æ¨T›y‚i÷i·ÁSÞnÖsá(J“ o×ÅaÝl6ì¿_æó¿V?+3ëb莇Tˆô UÝ£ÒX:6 .Œ,PH¸vùRïú”·v.Ô²Zøþÿ”)³áf³A­ìm-Kkm1c¯3{®Ú¶iÑ…Tàè›q$Cs©ñ‘œ¤TŸ\ÝK´9ÔE_5µ‰œYšbJ²Ì†öìkàsÆ'LÄ8Km,ão7±ËSL¢ØÙ½ü¼¾üõÓúæ—‰¥$ñ7”×%‚ §–B–œf>–ÓM#¦,66 Ž˜ACß ¢Ðl4 4B [tne UµÞØI-T4uŸWuUoÑ凫n*,1Â¥¼›Sž„‡íºª7ÍBW¸ ‰£qS jnP–‹æa_íre=<ÔUîe^ÊN£³Ëý}Þ;7:½ec®f,¨v2ìŠfþöp¤0÷GXS,xÌ v ……ˆ¦–@Î"ƒº¶Êïv•²+ÚêN–èîY]0I!1d)u©tPžÄ]¤8‰Xæflîû¦sp–ð$XLYú I¬áGcR€wS… ÛløƒÚÄÜ&ÂÞ·¾$ƒ(8h…(c°%š@ôj¹¼YNž–A@#æäÇP(äÀ2IMFí¼ºšR,b}ëð©ŒõÆŽM¬1æ…™TgH>"9œIK„çÝè±ÒŒ¾þX°ïà{}³¾º^-ÿœR(rÅ':cžr2vNkãïÔÚ:–½Ýÿ•ÛcêZšâôÅÕËÊNq¿½dDYšª¬Vâ²’#¯xu-¼*ÌÆ7óPÆïÐe`ì9]> Ý$u)û¶4s‡45þei<œ“fåæ ªbL3âT—÷V˜s´o ¹ ú‡ú°Û…ðÓCUç=ˆR×·J~µn+K’ªAÁ#Nõ•ܘÖ@¸Cr×» žñlpDû©PN[¶·P®„,º ÷ÌMåm%8Ê ~:a¥¶’Ld=Î)Š’ Ðÿ‚æN(@²È%¾-º ¹î#Í=ÎS b8ß ­yÝë:kö%•2}>–ÙÌ«~°ëd1uTÇ‹i,†ZÈ…Í;|׺Ðu¥ÀÝó´þpTæÊÄ@JÝe{G¯Hj#?4C|A]N¯€>QøRàÙýÒ ‚cóE?ŽE’ _M·¡òž&©î-:Wã¡“0•šA­Ðzj¢c¨•ûVv²î ê¥/Õ.À"­a«‹Û“m§Ã¨wÚÂøIÛ ðƒ:SϤ±Û«Èu†o앆oÑ ×vÏ_‘>”wâôX.)tOoËjŠ…ðyIÂàºlRÌÎVnŽ©px€¤‰DGú:_²¡,é_3€YLÙ‘›‰[#ê;ê]=.ݪX¹öà´t6^,ß1PÄÙ>_½x/¥zëWˆé`5Ôñç‰ëPby6 4 9ˆc%.ü óÈTøîP²ë6‡e8Ú´ÍÔF°˜ü÷¢cb\Õ}ƒ†å[ùª,„4ËpB§P9_|2oÏ68èî›Ã¸ÑJ¸æÐW¦oŠ@ã;zS)óh—{ ÀhÿRìOC¢A   ó^Szªþ^TÕüEýó~Ú†ƒX@ßâ(¼[\-?\ÿxú^K8£)O÷²FuŠ[oͬ¡ ®ìú¡Åãú} »I¿oït Qíîc]ü@™Ãóû|Œç׿þ®Gï4€Ð—àRR£Õ!ÞÕÍbÁçwÞˆRF_³nƒåûøËÜÌ]0àA)jO¶túf‹¤Ê¢Ÿƒ1ORßnÙ¹n[Ø¡Žêoüd5wÝXu¨v½G¢_3Ðu³í©rk™Õ>ب]8¸©´©šÚÓÓx%£Ô7-‰„uºi’GwÀý„%n0"@¢Al\ EÛ$˜©þ› O)õØ yÜ£ $ܶ冠¹ÉoÑ°ÑØRÓp³á³Éö¤ìwy!§²§ô$óܳiÙîÎe†¨ $q{ó“ÒÆ±€ îQƒ9E¶SsT“ÍÆ[ 'x«6”öšÙ­ÿz.¿z´iµÑ+ r"•^V5Ú·9l,$6¹¶¶ªþG© k¦•z9’i¢÷ù@'ûŠm}˜ÍÌ»­…2Ãi:;± ŒCØ<ÕªiËkó§Šó#›5ñÂȦÝ<62Ùô¯†ìR@åÝvô÷²ñˆvi¬ýÖÐ*ëusÐã˜nb‡mÔ]µU½€5Â'aU—òŸu ëÍY>éÆÎwÇX±Ó×ñ –£©˜¸n‰ÒA üð[þŒhDÉp0ýð}ì7ÿzµšý_ÿ7”¨endstream endobj 730 0 obj 1976 endobj 734 0 obj <> stream xœV[o«F~çWÌÛÁQ¼awa§TŽtÚæ¢º¨U•Tˆë˜Ê†„…㤿¾³0¡U+UNâxÙ¹}óÍ7~…€Pô˽—Gïjóòxö^=j‚{+ð]æqÈJ¼EàO¶ó¬%&RÂCˆ¹€ìèùkºÊþ@7x™2’¦BßË*Ϭõ£5£֑ЇœÐ4…ìäùÙ^Ânhʾn} ¥.PLIñÔ¹©NE·Ë+ùuxnŠ£Tù^•ìžü§•³›L„qoíŠÃ¡-‹^*(h_Š×ABUô¨¾Ê~è¤M.Š ‹0Aj³@'÷èJVP7€N ÇL[üÓ&±¢)I“ÄwÉ@‰7Yýžýà1´½õü»¢Y}ÂBEld”$TØœý÷vÅA‚8õw½±2À1×\`M£D6`²‡¶‘`  Q@ÂDœMCcúÖwEÙ›ÜeÓ×hU¶MÿB»3§J¿—pÚ×åjeРi‚å`PÂÒȸCÆëP÷ÊâŸËNb'´í'&´~K Jbd‡í˜jÏL ‰llå©Á^ô²kŠƒÉ’Ç‚àù{‹=Ñ7’ ã¤ÌÒ®…¶ÇA‹Ä!gûÞI,å¥(%Œô© Ù˜²÷…BcM€”úu£AÀ§u¿×¨%»Ô¥é™iò:ÆHqÚ9"lJ, AÀ5—ò¥ö¤6T \]ÀµRÃQãÚƒjrßG–Rœ“XŒØ\œA‹´p¿«ÏŽß”„,±ò 1ÈèO·^vñˆóµ2”};g¦ð'¿úú|Y5—›ÓOÃÈÿ5ßÜ^ç›û5‘}wósþåæzó´úl«Ä1tú–U§çg§A^Ì,ˆÎÐîÚn1û4ÅVEìÌ~àlˆ£ˆõãòÁ „!ÀCj(K©”áí4_Ħ5j™N!¦#ÖÁ/ùËà"!,ˆ&áiª¹7nC—žÀ$Îí)^ædQPíyk˜®‡F§g±¬4Eý˜úÙï»vxÞ/òÂù„b“·C¿È9ä„}@,á$â`Œ¤«ìû¦Ú±$“VÙVI´"j6 F¢ÄùÓ¦ÂɨSIÔî]ë©6®õÛéBÝTÒp(²ÆHò¯L%¼õg´¢Ù¹-^»]€Ài'Ð è o¹É}âokŽcÎý·â—%Ú? Ò¢FGÁP1ùLв¦Sˆ:MDqtºÈoî³íoKFÓ1Xm%¼Vд —‚Îx2¶ÒÌJn@]øKR2r̉µ›ŠLà¶Â"ÿµ½phò±†›íöa»ˆ“Ì’À«ýZžWSœ…d×áòÀÙÜCá6GÙvÝðbÆÓrÇAN‘$éÔÙy5WÛpŸè,©8$¹]`øÍ÷£ç7>£ílÑø„Å€'wÅ;°€Ñ³µ–­x4ÿϯV7™÷¾þ1’Ÿ‚endstream endobj 735 0 obj 1160 endobj 739 0 obj <> stream xœíW[s£6~çWè­Ø$ÛfÛNgûД}H: Ù¡Åà8núë{tÁ8Øël§/}è838œ‹ÎíûŽü…˜ PܳÜz·÷ Úô^ˆ6Þg!rr‹¾Í<†²´Eð—­=kIå)fJGÙÖó²È~7 L(NS®õ²ÊóáK Eà"u.ÆX  æF£nT µÎ+¹ÚoÚb+û¼¯ÿ’ý£gÞßÙw?Ê¢BU{£ÝQ‚9 H¤=Ãóà9ím_oZY¡º­äŸy»ß®¤²FetçºKÔËr¨»6ïÖë^ýÍâO»ÿpAõYªTµÊ¹ÐÚ›´‚=Ó¿]¢ìI¢²Û·C %‘lõâ^Ü ¶ÐêeÈ$ŽÑòöÊùe·Ýåû¶rc~9ަ+‹&^vòMÕu§$|ÿ:åÕ¾üC^ÕÐÝšä¯ °îš¦;ÔíÆÔÀ(™N™äûëi›~Ū‘y-(š&od»ž.‡Q¬VJ>çÖ`lǹšéC¾ëºæŠR±ßlA±0Ò ˜u8[>8³÷Ju -ÂЗú¿åíãbñ[öÓ)*4¨…ɵÐ) †N€ž¥–pÌBê$$NÖ»#ìhŠSF­€YmsÕí¤j`Δ,t¥ŸC38bÁ¥_µN<ÆICœ„NúàOuÞA4©H…€q.KÙ÷hèÐzARýÚ¯eS`Lúx'˜îíYØ>7è6é³(ž`íß}zwÿ}< 'âØcq¬’ )Yvjž˜S12Ñ)Ìœ  âbr}H¹.*´¦Ç>%8¤‰9÷“D‡cíÅO\\1&¡Ñyðë¦1È®d_ªz%Ñ !`kE‚á¯äPÔ 4GIlJFÃ)'‡Âú«4.fiFÓ0gâbÕbqT釢­ U!x̹™ñ§pÜØÃÌÕ~»›yä §}1Ùm»ae³:b˜\=x.¦5A –Çæh`u"3_ë}k¸Û3"ÌÄF”"¥(`‰r¨>›c’Ài&˜Q1Îë¸WLÍþ¸`Ê}nÿèOМŠÐdS×m†÷Ôäf¾•¾¼»,¿éÅùÖÎ:§"·]&s䥅fˆtœjgæHY·GË^Gzbj‚|m{fÚŸq^DGÎû·Œ× ‘\e<}™‰[í¯d<à4B’/2ÉHÈÊ‹q 2§<&aæÖ3c›rDx¹·‹æ n0Ò">vâG¥#G9À©n‹Š™?aÇ©Õ "l—À)Ï¢‹ü ‘ÅO¼?øßÁ£nÌÂCáJàÂçÀúiH}KS'<§p2ÿŸ'ÿó<ý3žt×È ly„õè*àÂÄxo o²"L‹Æ¤Ø”T|Z ³o~.^ )™¬‚Óq\Þþ‰ñ>ó~Ïß2™‚˜endstream endobj 740 0 obj 1086 endobj 744 0 obj <> stream xœÕ–Ko›@€ïüйª°ÝÏc«DªªôДžœ aXZ³$°$Í¿ïÛUí4êCXv^;3 ·€¬{.[çõe ‹ÁÁ°pnb„`Oe o3‡AV*-BAý²Ú™, Ð(E,€˜EµŽë/ûªÜ(eBQšFZ/«7¢àk‘r‘Z>Å!JÀ#£Ñ Õ}Ñ×yÅçãB-òeWË\Ž9²¸rµ JP> ŒÕ™±8›´ßñ¢‚Jœj--¿pô¶îWZŸÅÐ,¯ ÿž‹±óþÔ;Ù‘wu=p¹¡`BîqôJÉHØ­YÙBš=øZöt§¦f“Omw¬°Ž:³¶ç}ßõÊÐ(Æ.×wWž÷%{¿ÙŸ&º¨tr›]sTm ¶ªQÄHd£ïÔ½|¬¸Š ÷„ ¶Hc´Úþ|ÔZBPaj²_cv}æòš÷\”X€|¸á0ŠFBí‘TQ·áËj@6¹³¹”`•‹µ†hhÚ!£*+ˆf4YÅYe6yfÔ]¥X{4D“Ôíz$ê2¡.WÍÙÀm]ÞGh™*¯vo+l´ŸÝºë·ÜNïó¸U§£¡Õ6m#švleV›î‡=ÄŠŒuèOÍ"Ùc, 9öü¥™Ÿ¹o–Ënj®é~€žË¾áÓJ@Ü;Üz0ªB º¶SD߀¨Öð5v[ØE »“ƒ©³+±;–ß<}EŠ:ù›¨Í•7íäϼ§hG“fÍžõzœ¶ÔÕ¹Îdzœþn®‹áæÅ˜–}¦ª¥Áþÿ¯HÙìÖ¡˜Øôò‡ß3‰sÙMeËÙ?o˜ç˜r¿éºå_¦µ˜w£4í fRLU²”2¦›ì^rÕŠiŠ3¤Í玭‡xh×AÝ|(€bJÖã?&(W–¿ü<ÏœêøÊ«òÞendstream endobj 745 0 obj 720 endobj 749 0 obj <> stream xœÝVßo›0~篸·ÂT\ü›Ziš¶‡Uô)“e*К4ÿý|¶ÓuZÓnª´‰HȾ»ï¾;>r¡áãÞ‹Ö;»La9x,½;#¸×¢…¹Ç!_h/Ê@ÿòƳ‘X’. å ä­ç‡4ÈhíLɲýòÚó!šÎ.g@9"„L¿Ã8C3',†|£ÝMÉ jt ‰8›Y€¹¿)USÔ² h¦9óï—]ÙÊ¡(«w¢,ó+|Ë?y¡®,‹ .ˆàÜ‘ë)»(MÝ~Qm‹UWˇkÿ:°,iæ é,ÖjªÌ8G†çª¡Þ1Ú©”\OÀŠQ’@H…ItnBέûGYÖPw§è…öÏ6q³óºê†Õ²“5°¢»o+©Nƒ“'v—Vv£Ú¢ÝdüÎ;m£B¸š]Ô¢¯¥a¢éç$ÒPÜ…Žåò¥!–}Ñ7®I?ŽªhzÕš‚WrxeNhî/”ê•F ‹"_âJ1Šd"æÍ´èÜÏý÷77}ÀbE1õ7(‰‰ìŽ þzÕ-aü.mãí6Çír\õÝê[(á¶W¸†¾1΃\˜eµ5P c ŽÍî^ðÔHáàFdúFœ¼ñ…@eü­û`±Þô:Xa{^!iËãÕŠÞ‡ÿû‚žÄ!\ˆ½?FÖú ƒºŽ‰ÑucSÐÌÇnÌlWÿ£H…Ö(B>/ÒæëíG¶Íü/ÃðÑé8=#]«,ø2qbÊÿzDkrGj¡U(øqƒšÒ)Úà¶ïo¦"~,y‡Ò(1-¾”ØHnç8~ \ë×|?Æc˜(ž°ôΗr ,btR’¥»ðgÿ´]äÞWýüÒöÜLendstream endobj 750 0 obj 649 endobj 754 0 obj <> stream xœ½WÛnã6}÷Wð­ò"fEêþ˜" Š¢-ÐÔÅ>$…@K´­®Dy)*Zÿ}‡¤(9vŠÔ)PذaqîsÎ ýù˜ _¿Æï¢Y|ÿ˜ ]·ðÑnñuAÌ!¿Šý°^h]€¡ÞëíÂjDã !J‚­›…·"Ëõ_`„ ÅYk¹u¹ðâ­ô˜ÈF+êG8E«(6•P¨˜Üæ%ßô;ÁÞå\(y<´mýìimJpŒV$4 wFøÎ þÈY‰Jq£¥ôùÏ Ñà¤þ]µ¼D•(ù·\ô͆˛åwçívÛq•Wbv­ÅŒã7Ì}‚3†c’l³‘ü%/Ú’›@Vúèu¸'š&R§ªØîZ•V÷œõB]«j«Ðnsñµêc‘@¿•ªX›X.ÌøºdO£±{)[ –V!õ}ë_ÏËåŸëŸNaµ¢©†5~ž¼Ûºn—4¾oèäJVÜ> ‰÷R‰R{ŽJ¦ÚʶA Z©ªV@'ÍÑÔF´9šî—Î q:%õÍÐ q@ÓºOžÐ°XÒðL2O§ŽÇ¸SDv@3LŠVA¢uL#—žbH­Ô¶#Š#°ëÌ:¬/I–ê]€>YR¥§ëÛ={sÅ&…´Õ±h¦æïɶ«»†ScÓÎþá´‚ð êIÉŽy9äU9tª­‰m+›iBÔ6™îB?òqx’ÃïÕ.ýGÚS½ä—fþ>•\±ª†$?Hª 5LøO¤ -©4a€R©¥ÔĨýªñiªãã ÒÖ“‡óúpâ5ÂÔ2äŸÔ¯Sè¶(x×!ìè—¦è—ïDŸúÿE)3ÇA”¹jÂì°­¡ /t}º³—È;2ÞÆ‹¯Xùi«†!Ž#‡Qž™ƒ>‘Ä•ðÌœ:Þ1'9­0[jšàȧ°p”Y€v Ü2YN!ÞTJ Ó»¢@pŒŠšP†JíÑÅ(Bµ) £8uù~¾Ûâ(ÛLÎ"ŒÖv¼à8¤£ÀÍñP¬®tFÌž‹(ÆÉ$ï‡SG4J\U å€Pgæ3Ü9Ò)q¯ûbh.ÃÔy'43ÞyÍ`ž@Üi|'8ö8|óÙ3Á$œ†{Ñ+¶©¹)—fLw¨+=’a C'¶®¼çÓœÄ Î¢3ÀTbÛârhÏ»«=ÒlŽ:5Q:é={4…¤“I4L­è GjŽ#”œ›ƒØY¡zV;ºÅZƒÌLòói H6÷2ËRK»ÛÇSŠ3Úë)´å©ö•º™Lh0å¡>€‡Æ³=Û¶¯K´l @ ËR¯«V\CF–lw’5®Ô„M)‡Ìa'“"ÀiB²‚Ô†-ÔxËhL3·v]'Ô3C Å|*.«‘ÞL¹®ع@ £Å6ô²5§EÍ™èkÝ…ã"µÛ\“Ý.Õ’CÞma®g¸H}‡KNøí.8I›Ö=+ö®Ò¨êPYÙ5@a ”&1Õ¢aÉ €.´w_:´çÒÂZóÒçÚ9ÓùÀcØfÞ®?=Ù妗‡^ïðrÁÒÒ“sÛ‹±ÛËiÚ#$!°/ÜvNxC'ê Ë23α-Ät)#€Ñ€Äo]Ê¢öNÆØŸîdöJ¶ƒëÈ\ç= ê"¯œâŠŒ z´j„’?-£—àdì!ÓÁ“_ 2Ô§dֆ̳iƒ¾ûê~½ø ^£ÈÌâendstream endobj 755 0 obj 1316 endobj 759 0 obj <> stream xœWmoÛ6þî_Áo•ƒšE½bߺdk·®Á oÆ,Q¶6YtE)iúëwGRŠ¥Øé08€!‹w÷ÜswÏ1Ÿ‰Kqñc¿³Ãìz‘š¹d7û‰xHV‡™³`óÕßà3&IˆçVùÌ ²ÀWà"±.ãd„ú}Y·$L›b³ífWw›²ÎÅ—Í^¤ùÚAK/¦1Y0_¿ÑGoĶۑ|»{‹ðÕÇYDÁùã̹¾"«½˜¿™ W¿(dUÉDzޑ´Ù‘"­” ­$JT"k F>vÛöé(¹ºF¿ íÁFŽCêk7Á;)+RÈf³Ë·hW§¡ ÚØf®±-ðÙºpOì„pt¢ï!QrE0_más›ˆ9ø[­Ê]-à¤Ä ÏÉ14m+™ý³ÉdW·&ž9r&âmÓÈ ü^Ï¿³Eñ†¢hš=íœÓ„3m»Ú—ŠdH[ %­‰<ŠZc ’ׇeMT·Uâs'°–i›’4Ë„RCpߣÌbF·Úëî÷‚ÄA6O¸=8Bž*%³bçä±l÷`h¶O$K« 9é+æC½zzlO ý” °‘ÙÚÑ5Ÿd﹘½±¤N8ÜÀ¡qYB)t¡CÊ]Þ·y)ª|ÇchÄ.•k‚€?bØÓ ú²…|Ùíöšª£„Q1¬ãcݶð$ ¢}*(ƒ©äS?Š)‹B tz)kaȨ˼Þ÷ÀÎ?§,vÙ˜ÏÑŒêÈkç›,‰hÙJÜ;i“#”;åaî×sÒªÌ v›Ëü¯ÕO؆ŒFáxfîµóU4ràÃÏ™:ãsgÄê‚­çHµÎËÆôš¼1×rĸ‰&æCAN¸!¹„N¯eKPC #[01Cñ¥T-a‚*‰Ã±}"eKÑvM­¦- $‚ZoþØÜ|ü}óénsûiµüsÊcÀEÎz${ÛêЋ b>ˆ¡ Óµtáçð$™F 6=Š™lšî¨3ÄJ0Ó¦”2JpŠýͨü±O½`Œüv¹¼[N`'@K$'¸¡s¢0˜±y8©§ Ý·´ží“:‘t+»VWEœXj7tL¯—1 ±a¹@)9âÄäC@â™C"~H]îõ#}I †ÎVSog…ÐÈЃ„V½((vÔDáO¶ÚëÚk$·…Á­*+¨/„p<ÌÏ”ðè%%ü"%¯Žóë¤\ZÜÖËceØzf‡kƒ3»Oû4*ñ§ÒíâñŠäá äF*Qïڽݎú­…4Ù´ïÓªæÙ‡mÑ(ìË3N.c;rdQÀ`I­„ÞûË;þŒÇozRåW±‘ʼn—M úÿ¸Òš‰¾Lí`7¥Pg<ñðåUbêìÒÍÂ^IlóÐÄ3„Ýá½A_Ì^¿  ,Â}1Ö¡»Ÿ'1˜FO7N1÷\° §¬*½{ph`ÿ –‰“<9+\[¹ÊÈÎdŽF)ë·ÇóvÖ—¼Çj ÂXœ^ÝØï±bXT뺃aGWEW›M5“@Hikqº×Q©U–Û{{;a ¤GæRbsàfÙïïc£™0'ÔBtö©–s¸xµ‚˜ÃxïÐ?é»vŒ‚ƒìÛZÏ©í¡€Æx«óM?.Å@ã(*6Äf§ß9Ô‹<ü’>ÏõسaÄhõ–ßüÇãv5û>ÿâÖž‰endstream endobj 760 0 obj 1327 endobj 764 0 obj <> stream xœXYoÛF~ׯطP†¹ÙƒÇ}jc£uëÆ¨ª´(âB È¥ÄV"vœ_ßÙ‹¤h;Iq¤ó›ofóLQ?öwv\¼^Åh×.Ú->,¨>DöWvD?¬­3¢ ÁŸu±07)bQ‚y€b¡õqáùt¹þÔ€0e8I"%·Î^!_ùŒr䇑úò½·ÞKT,i’"öJyÈ—¯Vvk'ˆp@#«ä^6mYWJÏÄ•ãÀ¼÷öi‹:Pz¿¤(eÜ3WPÕ·²ÑÚ#í%Xaã7£Û1&„'ö oYu‡GTvèØ·ÚJİ „Å8bù>ˆ‚ŸÜyXØ @„S,¨3¡ƒ3Ž»Ø@ºcÎë¢heWV]½Éå¶ßmʪ¨g‘ÒˆàÈÝP©2øÞ+MÐu±d*já)UèÖ++ÔÖG‰0h\2‚ CϪFµÉ$Á‚1äÓÀäp&"qÒ¸6¦²E˜ÒÄf‰`èÈjÔ‰d 3Êlý‰qTfãv ®¢½©wå!U_¡wdø'™æP¤P—.ö°±)朹<ÿoдå'¹©‹IV7i#Ó'©ØÝ°éT•£êß,$ !“9Ê&^÷àµE !½‘ó’à NÑÀB,Dò98P¸Ä@V÷U§ü.«\~Ü ›R¶O¼ˆÅ+C‡Ú¦ À`^…`o£´ëÒlAtµ–Øêì_I0ëÞïRÎý#˜3á:H›b³“ÝfWõÖI­N»úxëÝ.gÎ2)¶6Ã'c ~nprUŒî¹0 ¨ºïÚ2—¶ÃÖ½ôPæ¨I«È’ ­©ûÝ~ –$ã¡—u²ç¹…‚ÅÜ ûÔ„ãT¨Æpi"&ߤ뛪¥,§xñçæâúÍÛ›ÍåÛõ꯹=êäÒ*Gy åªên_V;“,FJÙ˜¬XDÚºIV#U†ò´K¡MÓßi€Öa€V6eÝ·H6 |õ¢¿L˜…§î^®V7«™¯ ð€“‰¿@8tÚU8€‰0M4¿¶}WÇA9ÊnT76GÓKéÊ«K« ȲÀë•@09À6ÑúzÁ•Ÿ*z "üŸ/_©¶'€PëÕWãÓï»ûÐ “ÚVú"Öu m–>ñÎÎP•å¹®…×;#ZâÕ"ÆÌL|æ&±wVŒƒ€mHwÛÇNžÃA0äëT#œ>§²}NeèÀïõ6=|£âî9Åw².t²ŸhåÑ$ã—Ögº®“|kß.¿›uŽO£L8ˆa’ M,KÕÆs¡8$gM 1Ó+€ÚF¦©çj(KÌí}N^,¦œkHæ‰!ß„'†|íGª>öÀ[~™Q°Þ6hÂÆFù:N4½ø1‚Í'Å 7=u«OŸe²m_f;µ§dwóËÌXoc?aº§Ä%a°šÞtãg C*€.ÇѪgœgy°Åè{½Ðê;b˜bด†Ó4Ø›è.mذäÁÒûöÝõ5JÕØUu#s“š8Öú¾uuz‰3¦ âùî­ÖPµ 1föPÀËÅÕ¥ösÜDáxØD[³Úu&\»0ι$œmRl–$ùì&'PÄ5óš3&Ö6¼§BH‡e—$ußí÷&´€yiS¦ÛƒT¶è+H¤f‚©xõÊØÚ–àaz]­‹£{­Œ‡bÞ+×À¢ J(,§ÎqK1„”‘Dq5 –¶% YoãJ‰‰@ =hPš‹À‹t 6ë~‚L-bWmYôûöçU`·'>˜WÑâצ1`‹`$›JšG[À½É[@þè$uC«À‰d ¼qÜÀ»3Kvži»º=º}ÝJÔ;O5Á qÌ>ˆqP0pJLg;x¸Ñq~®DL]ríÉŒš7 !DÇÌ€Rø³ #›uå‡~ïy;À&Ae1@­Ô â›wX¶H &Ìm®÷õ˜P1<½Ã½:6Cáè$—mÖ”[õX@£Ã>Xª¬žî ·ž©™ j&›*=ýû²-¡5à™§Z/ý6ˆ+ƒ+œ¾1 u±èN3}£š/E&s°ÖÛJÅP©ƒôa ¦P±›šñPõ’·’Ð?\­r.ü ‘zð@ðá×ô1Âè«fHìn~ñ¿3.׋ßàç?Ø—¡dendstream endobj 765 0 obj 1744 endobj 769 0 obj <> stream xœ­XÛnÛH}×W4ü2T`õ°›d“Ä>ÍÆ™A ‚ñ( 0ñB ¥–Ì]‰Tx±ãýú=ÕŠ¢ãxXØ@uwÝëÔ)}e!,¤÷ïú0ûù:e»v²ÝìëL˜CæþYØß—³ˆ-׸%$Ãïr;³/“*çQÌÒH±åa,Ä|ù/ˆÁe!yž+º·ÜÌ•²-¤ˆØ"Qô!ôG[>Ì‚åf[:– O’(wJ½ßЧЛ;½RàQê/tG]ouÕ5îž·/“<Šr§å¤èKpW´¬`í¡ØïYYuz. ©‚nØF·ë¦¼-«ë`IçóE"O²$øS75;è¢j‡SV¶ó.ÿ1[™ó0l!bRñ\ãÙEUWú‚³•& •â9Âå¬ò—žeôÇ7Ã=e…< ¥}¼\ÚÐ=°zˆ¹Œy&•<ÉNü==aÈ¥ÌìíÈß.š²¸Ý“ÍË»F«Sä8qR­4cX ä^z§Cž…‘q¦jÛW뮬«Á‘oDŒ y¡¿Ö㺉séúæiÈÙEÿ5V ˆS.çDðKEŸEÖÈŠyœ¹p# ÝðµI˜‰ˆÌ¸P2÷ñËÂØ†dßk†Ê¹dÅñX4¨·½©·\ñXyÕ—6&xíãaÞV5+Ú¶ÜUzchÖꦬû–é¦ÁGeÇÝõ ²ñÓY‹d1"⬺ú¼ºz÷iõæúúÃõ¤ErJEâ[©¨6ß™@O¢ÁC[½ùXÕÇšz§aew‡6ÚÖÍ¡0–·uß™\™‹ó$„*à¦M~¾ÎIÛΨïß!O‰ñ]qÿ¾X7pÄ|¶ž)äð„õÛqêòØ8£ªí\’¢( ùpÔù«e7Á•kR®lé% …/‹Ï¿œÚ¥'3¯ôú×ø’]™Xø—±äRøüÑËäf>‰ö"ÂHü¤¹$tÊRÞjÓ$ÈèV7HB=hŽcÛxfO5‹ ‚äÉdF‰Ü”"ZŸ¥gÛÔ“¾Ñ·¦àáQ><ïw+óÆæedôù¹¶¼©7OÌDÍ$B½h%‹mA›zÓ¯Éá®(ahošÈ®¤“EÚ-¶xÙ­†z´ JÖ8¸·ã%˸Êã& •[«;¦h6ål(ÊjbzÉ_0Ä¥¶äàrl¦lKUðù®Ü£CVŸê€ÁÚþx¬rohr ¢GݱªvÅI˜”œì–©Åw÷’|dåá¸×À‘¼Øh33EžrH-Ž—„8¦•i6e'œ÷¾uºjÉBšNks3‹Ð‰ÙDÒ—€r…1FÈH©ÈÑl‰°*Ú~}¯€k-’a‘h_EçHøPbæŠôºÉ‹n¿Ï9U«©!0£¨o3¸˜y(’<(ÖÚ„Ç óX\;áNdº­/…Ä ŽRý¦»ž˜X ¯Ñ ×kݶӞöw\Oƒ(Ä*M},¾öTM¿î̼z0Iˈ0xç‹f»"ü«W¯k"%¤>áâ„(ß:S2û}½6MrûÈtI¥4¡G ‰j¨ÿ`ó@²wº³]³Z“üoÝMð b LzT¬ŸHöç/H^Ý>®êí£ä;:d’r»“æO3_Y5JÐ@ÓÚG ‡ž ÒåÜ•-…cu_W;€E„´†‰œL^­7š£:@dZÖ™¡}@Œ¶«›b§lj›" :> ÖÇ61‚2̸nÏPw¢?òCî]aÜIÇu‡Ê3D—¸ a®«ü³ÏEÊó Hsn‚­ïQšœW’¡Ã‚Ž=[ WæàªÔlSêKGƒ²ÊÚ!e/}¬“ye'ã>R÷q4Ü ãß!{x–+cTçHå+vfÍ¥¥t†<£ø§3½öu_•«ºg,xÑ+¨>¶0¥¯þbˆÄ­öºÚuwÏ£fùøÆP«' ‘º™ÿmŠ="C¦}šƒßÊ »æé:IxJhnN„ïÀ *^¨‹í"K£¡7S3è‚úp,÷vb~D1ô_¼™›JAgøpqh¢<ÃðPgMôW h!èj;ŽkzŒSš¤=±Àº#ŽGc3ô(yo )&¢b¹gO6“Ø0³t¼üäÌ,;¡Š4C©»+:öú£ÝU¡¤/­ 1q'N˜fÿƒ;Àª<¶•ܦ èØ·Ä4j°*ø`ùøFwE¹oY½ué1/Qʳ˜f¿S¬üÄí©ç†£Hdæ?¶œ NÈbì0™’ÞâqçìÓ\ sÃ0ò§ñh/ö«”H}¿ ”ì·i%åVÓ°÷ey<ÙûN£é{lt JtLËóP¼‹Â<5*}ø û‹ý–@J”vtšb<–%íVõ­¤~Pƒg?šÓn®ªåSr^Žèi¾(’=§íaX£dxZJÜnäXpˆ]UNé БèLeÓvà!)Õ¥˜AàAòBp³,_} ÞŸP¦´¤\Ò·CqdI¹³o’?O^ØÎH‹êÂï3—ì·õ)1«üíh±Äï|ÊÖ¾J±­ ~B%&©±ëÁµ¦-ß~¡ ìSVüÑv`’0|ò¾xd¨!1l"ŬHýó¿x|³œýŽŸÿ—endstream endobj 770 0 obj 2147 endobj 774 0 obj <> stream xœåXÛrÛ6}×Wà-TÆB‰ oÓ§ÖN;i“xêÊÍt쌆¦ ™­D*$×ùúîàU²“æµãLlÀb÷ìÙ³ $>eÄÇ/÷=ÛϾ»ŠÈ¶žùd;û8cf‘¸oÙžü¸œ ²Ì`ãþ-73{’&TH‰,÷3oÁæË¿À lfœ&Iˆû–ë™ÆdK ÎY!þÒ§õ“Ö^^“Zi¢K¢á¾¢ÙߩДbìUè*W5É ³l~ið©e›Ýv]ÔùAµ§Ív+ƒØnŽ·½„„³ ¦­î}RU \Ai9³É0‹Cš9o¿çÖ_ò’Œü7g¿îÆ-éÄÍÇV0°“f¬Z ¡dœ°@ÇxöÊ0óÈ ¡Ôíüû «,†\v¢ñsnìÃ\Û&B£I\‰©ºöB™l+©HÏ»î"*ƒÈ­v;Ör¹?ä»Ôî5Ê×­w~};Gt5UB[ ¼ç´ ùþPVàée¢ðƒd"¸Ï2ðXqèÖ‰« ßüˆx–U@mO+5¡‰u"rLž)Â< (S#¶zÍÛ)v6×êr¯ÜXQ•û©òÛQ#Õ¨ÀgÝd™ªk# V±ÛqSFË—7¨…n‹=š¢ÕÏrÝdn"©S¸¸zh4tt‰ó%3<¬§¨Û| kƒð‹q÷‡âµÀÏO÷)Ë„m£bƒNy3íQm‹!}'aü dÁ8CZ{ÊØÝÿeSO7ÛP@(˜ŸxÏ =ÿ±§<7BM›ÈII?ô#Z=?¡¬/¾AXß™´E4’F= ;Šnù<”PrÀÍâÂc¤TÂCCŠV€U¦pâš0œ«ÜŒÏû?¤QÏIŸûgÓq<nø–!5€ºh!¸SYÚÔ–˜"‘´Ÿ»!¨ØÎ}> stream xœTÛŽÓ0}ÏWÌR¼¾$q,Þ` ÔQxØEU6uKQ“ts)Û¿gì\z”HQ<3çÌåŒQÌ>Ã7/¼«¹‚uã1X{wF>y¯SOBš£€oºòúH"ÖT† d iá‘€ûé„Ag.¨Ö±õK—‰5Ö.!ˆb{Èh„ÇéO[AûÝ@‘åuµÈ«²5>©N” O-dµÏʘɺ+LÙ¦Ÿg3¨jØ”þ·ô½0êrBP%GÚ}v̇S&’ѰÝ,aÓBmÚ®.ë„Å顸XR©¢Áóúëâzöeq3Ÿœ[¿¸Ïú¬ILÃÁž0†4ÑèÛÊ%4¦½¤ ¤NhˆùgXRä™÷WMÈɉ–x«wëBæfJ‘Kʦ®ïORï *àÏmvÁ?*Nµ#ÿyYÞ¤Þ'|~ôwendstream endobj 780 0 obj 673 endobj 784 0 obj <> stream xœ­U[o›0~çWœ§”LisY´‡vÍžÚ‡uT{AB›Ä àÔ6É¢©ÿ}ÇšÐô"MQ>ßw.ßñ±Ás}ðôÓ¼ÓÂ:¿ÃRZ,­GË7Fh^iס5„0E”þÂ̪™>£©;¼€ñpaaÙŽß¡û;Ž4.$–=öÀÑ&t1m\8þd ÎåHÛÇ..í,ûü„+&5rtáNj²gL‹ŠåDBRBΤ.@ò‚W+*€$*©D•ªJPMw0#Ç¿0Á#»ä ÍXIIÔÅaɶTûbņ e\íÐÕ6í_»Ðì[ËÆ-Œg™¤ yp3IG -+†Ï,›eÚV'¹J$T%ý:rC—.ÂLÁ©e_¥øaô |wÔˆ…þVDAã¬ö]¦bi’CV•©b¼”&1y:†Ú‹˜œ ;^åv‚)úY£lL&FkJ⺢˜•±Î4²£¾N~IUŒùªÖœ ^tE"Ö±ÂÅu11:më‹Ðš ŽA˜jÌQ¦Y !-^ñÆß1À &Øì¶‚Oç&ß-g´ïMN7—‘}³KDßÐEµ²X Y`Ò*&ŒÖþÁ¿Ž;V*È•ð¼™ñ\JÉ–º-[” ­íg­ùÎÔò•— õ€º²´ùê"Ÿ”ÿ°¬ŠŠùF¾Bª¥’<^ìsú2ÃkÎsÀNlöìÑÞ?Ì  j¬_pæBàäP!Úõ`b6yÆEdÏf8§úeÙ‡0‚*v0¾ÄÄЛ¨£Wd× œðzöƒ^‡08¿Þ‰ª]N¯£a½tªX½Žå¾¶Ï:Ò}»ºý17Û£Í.ö‰>lGƒšKZ‹¡9½>¶WU|mÿ¼;‘ÿ%_> stream xœ¥V[oÓ0~ϯ8ìa¤¥Éìô¾±`“—M”À„(²²ÄéB›¸s\6„øï;NokJ¥´ö9ßw|.Ÿ{ ħ@ôcßqîú0)çÖ¡fì+Îáeè´!ŒÑŠ€Ÿ0u*O Aoè·;Ðo÷ Ì×£ð; 1 üá°§íÂÄqû<½…C áQø=ðº=c‘GrÊÔMV2‘¦%W,*¿ò¬àÉwc)آȔÝ7N4ž üx´c0~ë¥`á;ÇÍR»3ÉK8=…³+vöî3;.Gãüj¯Uç÷Ž9#Öøý‹W£K†€,ÍfüøA¡ñ´gÊåMó¸èo¢&> stream xœÕUÁn›@½óÓRˆ f—bW9´M.m"+µ‡R! ‹KcÀYÖ­«*ÿžÙ]¬;nÒC[U v™™÷vfhnÁu¸òêÖ¬2†a³ÖpafÜD9¡[² ÞD†Q†Q„ÞQah$êïχ¨2L›XÑW¤Á`BÑÈ—qQn˜[ºbÔQØÄ¥Žö‰¯"²´epþ1¹zý6œ$Ë:gEÒ ¾K9†èr;#ÊšÉ ÕØz¹—á1çº\ìG¢~¢—ž:§`Ë 0Ë9g-œAþ=åE2c"©ÒŒ7’O¡bS¿gM-ØJ dî=ü2™‡sy|½¬¦Œd‡%ÂWzÛEË„Þ ¯Z¤[ÖAócYe=ÓÆyl½Â­Ý;©, Öé¾8“µ_~H&ïc kÚNjd"Až†Çf>í¦}p†“ ÞT€ùEý±u K”Göä¦á9Kçó&Kz-Ûê DK6ÎÄ’×»LwÊ;<‚¼¶©˜ø‚}£¡ìÌ|L9Kovq}Å[‘r‘åœiÏ͈չÂ=Cø¾æê+ؽ§ëßÐôÓ¦¨–M¨ëšO”[±‰ê+‰?Gïþ/ËjÑpñújÀs„í~صjñoe[gþgõÚ˜6ñ‘È£Š(dÒ«ñ­z|ófÃIgshør•þêRò ˆ3 ÖÈ'§ÊEd\ãu²é÷»endstream endobj 795 0 obj 536 endobj 799 0 obj <> stream xœ•V[s›F~çWœæ!X³Ë½™<$±“´ÇS i¬ƒ`‘i«rz™ü÷ž]V]\§#…öܾsÎwÎòBÁ‘ý¯‹y«Îp`e|1¨‚þÊ×ð:1\HrÔ¢ ð/)Á’ bâzº$kô©•ünP™2ÇÔK à ]°¥]ÄÚ…íù`û·¼ß¶Í ©a³ˆD`SO ¾É#ùüÁ0³¢HEYv¼O{‘ÖU×/Ìá÷ÂzaIeü·lyöYþÜw”g‡ËOéõ«7ó›´ZoDÛ§Ývó#ü#CìéÖ-ïà%_³¶LWnå­ÐF sø•‹¦çö³#ëϳçªÙsÞ¶ÚQVU ‹!Ê/%¨Ë¿¥7¿,¬X6mÕô):íÂ,–«£x·æ³«ùüfe+Ö–M™ã˜!_X s^XÏfÖïÉÏC¦3ò°bƒ“‚gu-òt/éƒèÇ.zRM4/ΡЉ5ïïªfçOõìÛ#|øŸÐ0ÀÞ¶Öùþ`ó¨«Ë<$l(E.a>$_ 3 4& Þñ¾Çœ¤~äêú±æý5–§ƒAn¸q"¦…âãôÄ+G¹nªÞó¬à-\f}6b¡ u]âúç M §€p² ià…„9TÇ»5UÙd-,‡:±9%½ÃP’!Š{cª}ØlI©çc¯´ÚË¥’\+É]ôÿžõ,¦ï³º„s5ûŒO×ëž·]%elmîLl?6]µjxç2¦ÞÊæ´BÍÑãÙ#Â;ՀއmT‘¶£žN!–u¶êN<Èïµõq~wY‡k­áSÌß•ç¡ÑéhgGÁô6íª¿yx'â= Wlx›5E—öÙ²æ{8ÝP±ÉEÁ‘ÛæT¶Œ’`’Æ•\‚ÇN†Ý8¬ É eSŸ’‘µæ»JùÇ;/RóFI8²JJ|â°@K¨iY“: ÄåFÎnÄOý õ(‰˜ŽÇ0P(³º57ÇÇ÷aå¶É{d7 [´ÃSˬ«r(-œé8ö©Yñºè@”©1µiïÐ=z¨Iƒ­Ü}ñ²Qð০í:Sa†Õ‚w>wÛ<ç]GwyÙ"Ê@¡4„qÜa1ñv9˜Y½å×9à ŽkOOêA|ŸxA¸Û~˜3’z¡2½ÚO> stream xœ¥X[oã6~÷¯à[å`ÌáU"ѧÝÎ,¶‹¶ƒM½S,’ÂPlÚÑ®-¥–œÉô×ïáU²|I‹ˆ’çòs¾sÈ?Áûþ.w“÷·Ú´‚6“?&Ô-¢ðg¹CO8š/ae~çë‰?IË5æZ¥•Ë’žFÊ pLúmQqR¯GÆj–NóÕÁÙÜï„çPãÉücŸù`M]o=†I0aN\øZT(Ä8u”»Ã <¦2OÈ@9èX —å*Ý\¨^®<åÀ€¨+u•O¦©á¹ì½¥–â ŽFnsY!òËÙq)~¶w0)^  ’<ðùº6NÖä|•èK~ °[äo«)@ÇjKœØs& A(’7ÄѽAnçH¯èV}|¿žç¥8ß\OÊÄMü‚¢J“JNõɨ¢ u½så}•XI´ÕŸf‘‹vâ8ÙÓô:!Ù&L€ü‘¡ôs<#™J#AÎ,Và‚ô"¦R¥ ¥(‰Fä[)ŠÊBý_ÝfÒ÷βlO9?œ)¦]'nÓf'ÊÇUuI°9xI1 |ã•™ðPi]³Vó4Ff?Ž Z9•ò›"\D¦» Å’XÎycû£¢Co´¤—½aÐÑØñLß;59ËÅñ˜)„ûZg^äbèÛÌ3õª]tåÃÖŒ}`«ˆw'«~co…fõ”سyZ6«‘γi 1*b1÷ñ-íØ>'üM¹+¨•úÚäªÙåöê¯`0>PžÆ‡»l8å"PM³ïFYÆUAß È2Èšx‹åú¨Ÿ¦(¸”KdF9qè_&3TJu³X6‡zÜ4Á…ŽCV~€fX¦teŽî¬mǺ~yD[S$“òزS„”×vÜ9$”O쎿öÝ Ž˜“LF>ìó_Êýz±²w¦‚îûì~zR±”ðXž] m&ûðÛâÃOŸ¿|Z|üe~ûïÓf{tÝð²7Ýa_›U¸^Àž8Pã00|‚Ëü~ߌ‘ƒ’…ˆAª?ÞÞ~ºÇ”bÍÉ ¦Q¥£d$'­LWVÛÖ±OÚÒ=î›Ã汿9 ›j ½§¦ª»“ ò|ø„34>u”üO…Àq g^fœ‡ºôƒŸï0¤ Z…‹K‹»Ì…Іo ]ÒζY3Ê!ÓÑÍi¥Ä)Á‡&ŒUx*çƒ[ûÙ­ýЀó/Or¨'÷í/ [§J¡Ø_üÑ¿—Û5TÇʼ¸ƒ,ö¼¿oÀ¸Ã*Qèæ½€ÛDƒcÉ7N(yó¸¦|…¾ ×Ò›÷Êaç½·âÌao2xÞvÈËùu·ftsƒâÑr¿/¿zW…}2 ú>ºœ»ñ¹w?ýXsæQ Åt-'Ê`–*X‘žLXk ®ï+ §EÜ= øÅ¥WûÊ^ºáË€ÈYš RþGZ䬰 Wúw1hG('M%Rð /*¡}ŽE™)….BEž½Tmw…‹ï‘m|çð#‘³(œH=FIg¸×ñå±ë Ë?qqš}±[Ëm†8©í«§€Þà Õå7![hÕãq{o–ͦ†ÑC*ÚÇcHÕ[c?ÇK3ÉòÌ{¨å°v1¤üççò+b„ÑôE àà"õ±ûã|òOøùþ¢2endstream endobj 805 0 obj 2018 endobj 809 0 obj <> stream xœ•XksÛÆýÎ_±ß zŒÍ¾ìN?¥±ÛºG•I§cu8±$ÑB€‚‡ùõ¹û@’â‘lIÀîÝû8÷ܳü L1_þçînõÝu†ÝŠ Ãê·µ/‘ÿ±»Cݬ8Úì`e¾7û•ÛIKæe ›ƒ¼àؼÕèwÝÚ,Æ<…Ô#v]l›áp4eYä+ÉækîwM¡/CÝû…![<ð«bŠn¢V÷C[C.nŸ&3U–†y»ßžàp{ÔyqݬGP™á°ífm8‚¤8ÉŠy ð§#”|õpw«[_øeã)‰S®BÈù|„Iÿ‚a•MäÑÎ2‰î›âiQéð>aÞÖ¾/›Úz@9Çêë+’bêú(2®ŽNNeæQÇÇ5£)dVàðV£¦†{{f×Îò¶°+:Ô€Cö Â cèÆLPiÂŒÃQû®EB h€Y‚3È«…~¯ë|è¼Ùǵ2(NhÜÉkä LS¨¾šYp9|ò\Ð>çH¤À\I(ÿÇo¿|ÿÃõÕ¶j¶!€9R èJÆê›…©X€­tJùdîX^4GåûbÿþÁ t2j>‡˜Är¢»å—Ð!ͽv¥YóãÙš÷f°lÛo;½3ÙÙ6û}§Áú»£Øu³Ûô¼Ú£÷ðœÒdä”à°ÉmãNŠÝûS¯üfãÈl·iýÎñÊ…­o×#gæ_wyU¡÷ï×1•„Øýv*ÚÿàhZ`1óú“m…¥ÛÂ7ë¿,P ‹‘éÎX2I¸KU;ü"›øå»îºK#µsczÒ—žE€’€Ž_ákhP@ì7(cJ€EhØò’FL0§Z#¾¥Œ9Ár¤­oQƼ¯(㘃¼JÕ4öGè¿}F°àä­{LZNߌž“B–éB!s!aÌeAÏ• ûIÆ¿¤æàå9õD2¦_j‘Ä€X.Ú×7á¶–ž÷ËÙIÂåà eŸý¥ÉÏ\7/¹)æ³Kɲy6Uz øÓË3`U£¨< ÃÔ£c­N¨¯:˜³ò ¨*H6‡|1NÃ’¥†¥PcTõx›p9¢‚ùMºÅúªkœÛV–gs›¬]Þr}rg(àÝB¯NWŒè…™¶Ìb —6^<¡£\ó4‚¢Þ•ÍS¡o-Ü—¢ápÑ‚fzêcÙÁÀ¹š‚q¥‹qf4b s Ù³·o’Óìsä²)…‘Á n2‘‘ñ>܉nõšZ¤%8Q?NÇFÍ;G/öò W\IBÓwÅÄ$|F ŠÂÍè1{uÞ$æÒNÿX›CÿrpCœ§yvå+´û¸Eq Ú^Ÿ IhÃ#Ê»3Š1—Q’Êó›˜KÆ­„}v6Cüx3ÿP"QR†³» Ã|Y°7[xŤš–9½dÙð¹Ðc }56ƒ`wløíÑôäΨxæ_YMz.1’Q˜G—Qå±@Ìu¶¢Š¸u¦¢0Âè¨Æÿ6É × cV¹:€E(&¢§üî¾ÒÌ9ËüJi¦th±1¹Cm*v^rî°pBîÕ\(w¯6 8+ O¸MáKLÙÓ.É,E‚¶ómvuÚ4KÕ8bfÑãÍz–ìévt CÏ>q¡Œ3½Ö8ô±1sùµ­÷ÝCx˜|JuU˜eþø É£ÓÆ Fiv¾ù¹è§Íêgøú‘.Жendstream endobj 810 0 obj 2023 endobj 814 0 obj <> stream xœÅXmÛÆþ®_±ðSÆq³/$w· ´¶ºˆmä &(|…@I”Ž)EÊ$å»ë¯Ïì+)êtj€Å½èŽ;;;;óÌ33üЦˆè/÷¹ÞϾ»h×ÍÚ;ΨYDîc½G[Ì8Z¬AŠ2ß‹íÌe ó ž¡Å~Åt¾ø Ô€0eX©LË-6³Hd(ÖK1£Åif.î ý Ô*§–%8ÂíÙ6í¾[®›cÝ;1ºL1¡‚Y9†%hñ0ûµElëbƒÊ»b{¬(A›b5§ Ìá4:îve½C«ù¿ÿ˜Q‘áÔŸ§õdZOtìQÓßíCÙZUÝôðÓîóªz²—&‚¢˜&zg‚e¢ìNs(FŒÅ)Ã<Òª§X¦F‚rT÷«¢EÍ­žú¢Óè »ç*k-væPCäÈAëfS,ó¶ÍŸ&>¢$ÅYê$Ay_vÆx®”¹©3ž£öùºmPs(Ú¼oÚ×ZЄĉ¿BÔåÂ{8Tå:_U…¹C‡'fÇPB¸B17gFï~]¾ûé—å§ÏË÷Ÿ·ÿššN½^ç|W£7ÖË1s1K¹±ÿsжmÚÉÁ‰Âp¬7ßúþööóíäHE±âdtl€R^oL¼Œz€RŸ—U‡ò¶Dúû¶9îî}¼À±+ᚲi<;pl< nѹS"¸¸ö¦p¾9·NY”sÌÐFoHf„º$ù=äív¹+ú¥õœ ¬¤È¢f¹ÄÖðë.º››¤ÇÍëpî¶X͉۠º±–wfå£yú¶‹?öÈʬí7Ú8&±ô¢ôF±ÝúϺ+wÚ­Íai“Áìв?9 &‚oPUÖE~ýŒ@ Æ=>¿Ôl·]Ñë5cÔ ÿïyµEoà9e ,<#¥l³8N¦/Ü´ëÑú>oç1K‰Þ¼q>èúèçÆ8šQœŽ{o6=Ïãnþý1M)q‰Þ5M©‚c™)¯Kñšfä{æYƒ€ ,M¢ymHÁ>[ÏdI½ú§Æ/f†Rø+ 4Õ¬A¢rPoïÙeùÇ”%˜ræs±.¾ ¦&@ü2VcYʉy'S9 ǯ÷åúmm ÈhTÕÆ¦0~œ½È¥j–Š„šÚ>ÏÛ¾\«¼ 'ÎS]„8$§‰%Ñè4íõI Ë…gá“40öÌ’ie%@EÔoÙ–ÁwÅ@±YH1§©½\ìë:]öjTnŠº/·sF >‚Ã]m¹±>ÖeRÆäp8ãŠÀ}ßšq´DF| ªozAaš¦Ò1“+lê7£órs)p¦T ÂÒ—n/N8QWnÏpÆéÕÛs{ûýQÓ„Þ ªiþƒò£_æ”_Ë,Ê«rc˜Âø‡'rÔŒ<:‹MUŒêgô-;Œ0é< ÿ(fó§:oÿ-À¸‰¯tBg™ÏJoìׯh^®ž––‚Ÿ9ƒ¥}ws›áú‰g½gúGíñCU¸„7É0»6[r´¡-ЄñPö–-ºæØ® S|Fí\È6ß­¸^4š'Ð&*5•ê’¹#*¹–Лe* f7uõd ßy Õ:TxPŽ, ¤†l8£â˜B(C¡‰úø×··Ÿu Ñþ…Šö8…&´ ”«KÈ  ‘‡À}†äƒºÌh˜Pãù°ÇIêÜvã””„S_rŒ¸ö Ð`¯š×6ã­2ãïL`1ô¼ƒ“Á¯‰ÈXÐe©¯2±Å1Nƒú–MÊéÎ52ÈK]4‹4Þ}°PLÆRŠöÁRË&P®¨r²]±î˦¶åæ¼Ðpœ`ê"Š$¦âZ…Ѥ"þ4I¬ã DžZnžaÊ+èZKñ‹˜=˜vf²³Év8wT ¹–ô):4´‰”ü¢I‡³«A§|˜ í óakpÙ˜–GÂe¥ïã´0³-™Lå¶ï+K¦m¨m6ÏPFyâPv T§túÂ<XôKäH²o&S®Ù Ïòå0.>y‰SìÌS z&\[S¢›Ê—_(ÆNʦ½÷ÔF³â»œ[¹ŽÏ½10-—(÷Ýà©¥V9žÇ©®ö‚é°éÕ|ÝóÊY Kœ…p'ÙIHÖy­çÚ•ž—&P²sݨµÈ¨È¸ ¶ÈѦtÄ1-´;¨Yý›n`k1-ïvhŠ Ë¾,6ËÍjgª,ÌÄtâÓÞ“‚½›Úv¾ó"p»R¾owÖ…cL·zõÃ_>yW9ˆºÖ‰%ÐܳÐl^袲Òo~|…lõˆ¹àÀ½jðW? ÔÉåEêÔ®Î}ÏË-“ë EþÏVÜE:Є™|=6}ÑùŽÄT%• ¯$„´) `E0eÙxZM‰‘ØY60Ç‹oE¸QíL;g^}Œ{aÒèÑh^H0)™ŽEz¦òU'LYƒ®n<Ùœ¿h9!Šÿï{]ÓAÛm^[«H˜ ¿ñ!¼~´5wÁL xò0Ë£Ãn¡kŸß~õæûÅìgøú\µcendstream endobj 815 0 obj 1970 endobj 819 0 obj <> stream xœÅXmoÛ6þî_AôKå bù&QĆ]“ú‚^‹! Å–cm²”Jr“ì×ïø"ZRì8ÙP D$wÏ=÷Âû‚¦ˆè÷w±™¼>—躙t=ù2¡f¹?‹ úq6áh¶€]”!ø­&ö$E,V˜ $yŒf›IÒéìO›)ÃJÅzßl9 ¤D¡^ å(Œbóñ¦ÊË6«õw­œh÷fu]u;˜ßá±]H¥ú{(Ý!ƒu†e„f·“ ÆÔÄ-õ!1# ÉȸnÓz5¿ÎÚù&]ÔS*±JdTó¦Më6+—óÕ”E˜Æ‚¼È.ƒËéôÙ/}ÃNbÈŒLb.ÛÐr ¼/Óˆ:5ËïÍÒÛ °¸k‘ݸ°ÿ½Òú²'`’Т©ÀÂH·G+›üºÌ–¨º™—ÛÍUV›zï;§Æhã *ò2ó›_îÙP¦›lž—ËìnÞVs³½M¯ôÞÙÉEš5-Z¬Óz2AHpr‚šza,šë£¯ <Œâ¸wÿ™v#:”10¡çÜËéw#ÿ†4¢Ø£¼M‹bÄ‘8Á4‘ʉyå‘l½§€ˆ@ŒÅsêU7Y¶UÝŒn 9€JÖ9!8ý<ÿæíùG{Ó¾k(Wà4«^5fø04¼°÷Ã6†$¨£bÐlnÐèÇÄQ<PÊH ˜‰QD«waµÊ}KL£hC¨‹ +–è&m K^¢|™•m1B F(ÄHÖ vY£m™·°ËPÂßJÇ‘ênûZírÅÒ«}_§"²8È–ØÊàœ`IÔc¶\^åÀÆ!»JQÌè1ÓA1fˆ²ßz8¤ÌcÕÛÏ-\Ûu¾X;H ËÊ%j+TTÕ_(m1ú4¥”)T¹¼Ìl1…£¨CêÎÙ`’q(X¬³’'å×´#a‰³ þQÌæÁb º¤u†þÎ@‘v]WÛëõ˜œ‘æN2 NuÓ}¶e;¯¶í¦ÇÓÍMÂZRt8V( luÖnkc®î¤P¦šÓΚqL;öšô;T@€Ã ‡‚-ìÖHž_ÝϫժÉöÝÁ¢.–ì8&Æ z¥ãâOU¿ú źCc@XzŠO@EÙyÇÒ"\Ve†ª• ¶UUÕ”  PÜæå5ZM¡äA¢Szëu° U%j¶‹EÖ4«má&`¤Àcˆ*v8Èö¡}å/§C†IŽG3,fFÇÕŒF>v²cŽ÷Çû>Žàéâ´“Ñ~?Ê Ÿ¢À?ºŽREXÄ»¹7U©˜u þQž†FRî“']´?‡ºsŸ;ð4Œ áf‘~^í€Ó‰„[q@0¢0ë2Rp×ììH%íÝnÛû,Û@VWP¡Ñw¥-ä‚aº û`ê*oË´ßuAÑÔóòPËÆF€VÞ¤Cßú€Èß—Uh­]æ„úÖ‡zk˜vͲ5Š2í«/t÷ýðÂ=¦À²G XÆ…{ '¶}ét½-MšuZŸ;°å¬ (̧ï>Í?|œŸ}˜ÿ>îMo-ÚiÑ«î5¥¯›ËJ·]¿b9ÇøCðMõ Ð¨®¡ïÀŽÈ°)øX";xÙ×\( Á 5?;?ÿx>æ(°™^³óéÌÁ#-³6Í Û=ù-®oö†Pu^úØùvS Î÷M5ij¦ù榪Ûÿ6Åèdü/ã ˆÖĶêz(ñm' zßö#1Ž ('²«­P>¸¢GG ¼~XÌv̵Íð~ù8Ü×îãž‘´y³½9ü†s#ûå‘Îè,ùð•xdÀ@ ír¨c¸mËúèœAò§Ì'8ñQ~hÎ Ç úùmm”¸L:-ôà=4?ä‰Äq/èŽ$Á‚uÄz†cNZÏùs† I<*p()BÊCC…§ Ä3 Ñ€*Ï(Dƒ‚~Õªˆî(¸)ïÊ^pÞ{Âr¨ ¾Žò^«Õ{½ÐT øò>½GŒ0º;-AÙ?:æ>›M~…Ÿlçendstream endobj 820 0 obj 1874 endobj 824 0 obj <> stream xœXmoÛÈþ®_±¸/¡ŒhÃÝåËòîP ­“ ­£>µFaER2©#)ûôï;³o|±cß â˜Ü™—gž™áoħŒøøÇü̳·1Ùµ3Ÿìf¿Í˜zIÌì@þºœ ²Ìàãþ.·3-É*‹ˆ,3oÁæË_A fœ&I„ç–ùÌ‹%Yà+P‘ ÎY„‘zŸ?¥Ív½+ºõ!ÍšzÕUWüÞ­¼Õ܈ٛΩïFoÝLµÚ÷ ¼¦y½9¯ëí¶-^ºƒ‡Üèׯø`ÁÕ#ŸL’åÓÌ»©H{ʲ¢mI÷PLìˆCFIbÔtiƒè •FŸò`Ó$¦>¨ÖÛÒE'œYUÅ>'eK@éj¼˜Ô[<*#ËМB#e$^HÊJlŠmÑUVä žue]Qc z) ê±¹ès=Ìep“ÆaÎ3 ¸„€‡.à—w½\B#aÄî½õõÇyàÃYz»ÿwù÷ü*¤o@¨Å:²ëòp¬›î;V£ÿø¦M…{–êg*ɤ>MŠ•©\Ê8³F4 uªà?ãh$ {ëh$ZôYD.ËœÑ$Œ¥õù ”ÖéÑØ—FIFN¯ÛÓñÇ!—©²“INãÐÝWJ@ö¸/Eˆ;“zó+*·¼W3€‹ñà.Øž*­¶)ºSSµówC3J›GÆÅË»õåÕ¿×ßnÖŸ¾-oÿ3)ƄҬϖۗRÆWuGê !kKfÁ¹ Ì—c7Lúl«} ¡°•W4 ÔþÈ`D¯HäØàO··7·kÈ‘°¨óÀ,í?Ä9­reºÒNò¢KË}KÒ¦ètM}Ú=8û`8‰úu ü2e% ÉPÛ>¶IØ@SýBT|]Á{AC‚ˆBF¯!Âx\=Ìf‘ ²¿¥þÚ×aH“À¾P¾÷ªíœ Z‡t‚n\¸ÉÊ»TX]0iÀ‡!pŠ¥Ý»=ࡸ´—Þ~æïÉ¥Œ‘ 8åÌçoKŠÿ[2xÆà |¨Â¦YË54ÀWìi%Ö"‘Ú›ƒ@—7\½à-“4tÍË @–ã³WäÄ{DÚX6 ¨ôŲèG ü¯M…•ÕÖ¥pÛÔ‡¾´¢˜FŒJëÞ£y±™säa™x§¶EÔàZjh ’תZSà“³Áƒ¶–‹t¿¡Ð™§]ÚC[è\æ0,¸ÐÐæ=¶a6ùRT€Ç½jnÐûØÃž+Ü pÆ‘O}3l?2 lD¸LYÁ°8#$ DG8Zvä(Äð+s½L PA!ÎWV¹/æ,†’ ¯^?ζ€{éþT¬[ d=j`G‹Ñlç uyö6äBÏ.[«”ué3:¾ð¬)«ÝjþÓ¤¼/%°dßâ¡÷˜x<*„Tø‰yÃKžUzpQLséà§Nƒ*©úR;^€YUž69A8yª±»Tœ4ÓôŽDj¤ÆEI 0ù&ªÙ »Õ`¬Æ»B wêëëÛcš!Šòd,UN~ ÀñJzå¥Ê @¡¡Ð®]Íè#^s„3µkåJÕjθN-ƒ˜F`‡´­.¹XxeÓvdsî\Ôu•€íþÀøëE—ºæÎLŸîÞOÉW5VŽæ)Ô¡“•×…î½é^™¤’¥R§­ÌÑÊÍy% NVM{á #\Bxl=»á|…fÓæ´ÿHJ=슊)f"z+ø·Z÷ôP¥yÞàý4‡9J&XQ-9¦m«@DMAYVA.¹šp '—Àyïf`œG|ÐwpñW¼~ ‰&Sna€<)Ã?I.}b œFqÛƒˆtN®Ÿq7À'Uëøeyœ(¶ÆÙ‡'¡$N‹4毇äMË´¯*ìbA?ß­?ÎR"#oi…5…4J&)J;HÄfÎ0ð@s'íÊÓYyÔä1@e|…«ˆ}jHhßp’`ÐpVs:=™./î½o5ùlFÒ–œA9D ¡8ãäZ«Rmó-ÆwYzº²~ša]ø¦Ú8g)5Å#)FˆiÌ,‡yûë!˜°+—7N ¥â†—á0†}>~q“ì¥a¬wÚ4¬4ð—û•x­_Ù%Xu)GХ̈ûÇd”LWj§äR½€Z;íȇ‹|³»øð^¸Í"+4Ršôá›íÖÐŽ^ŽÍyÌkNþ«jË6ŽCú{y8`“?Upþ=ð‹~}OXR;PC—hÎö°ê5êåhßÐ TI‚ùz꿸° €C€êcŸÔrp1‡½Ò÷q˜Ç®«I\ù©ÃõìÃÃ0Ô“íIb͸eÒ,c“ Bâ2fÏ˜åææMïz5êT¢Â ²›ª  ÷[vFi¢SÂæŒëÔ¬>²D‘Ë)Ь73äžêtاêÏÃO"Ö.WG&“ËBlÂ: cnöô¬nòö»KØpk }ØDƒ·/qÓä`c“úF˜y„ÆU6]KžÃ’Ùw:œkuK°®û=–ÆqdŒ=1F[É×í (‹]îÛ‡ú´ÏÉfЦµÐ·S’¥û=ÑÉP¸!]2/àh½Cc[6Oe×/¹"}ˆ÷ß h¡.MXÝùøì#@§£íÇõ/Ëۯ߾¨yJ«®pé€3×úOcÓ[à]ŸÎï–pgn4ÂïAŠÏzT½ù3žßů ̶N;Än¿×u† ˜Ó`Ò“«n,Æ%ßUߣìêÃñ€JàÉuz&P„¬—ŽaÓŒ­ø›Ÿ]?-gÿ„?ÿÚ¸™endstream endobj 825 0 obj 2157 endobj 829 0 obj <> stream xœ•VÛŽÛ6}×WÌ[e by%¾Ù)Ò5ŒE¶0´åUkIŽDÇ»ß!%ʶvÓ¤°Ë"g8sæÌ~JP÷™~wMôã:ƒýQØGŸ#æaúÙ5ðÓ&°Ùá.Æ¿›*-p¥‰ ›&жÚünp3ãDkåömÊ(Î4$n)áL@’*÷’™3Øœ£øÁ@aá`ŠÁ{CÝîð ìºæX [w-œÚÚ¹¶Ð»¾ƒº­º¾×œgA5¡\Œç9×Ü»>Yh»Ñf@ûà fŸ»8µ&*§,Øår´û‚\rÑD§Y>åb½½ä9Q˜_¤·ôVc ]k¦(ËÂððl tâí D=ÈÑè}—碯¶{c·Þh[[Ô‡á>¾_­~¸=—$ϤƹcŒ09EÆüª‹c_·ƒƒÔ>šÅ™iF´”ÁÇx`WUƒ±ÓÆp˜f‹«§]å–*­¨¾œæsÆðÜ`8‡gŽH%Ñ\tQ©ß[´%˜¶ Á¹gÍ+µîzܳL Â8Ÿƒª›S³Ýu§v=£”ðtÚ8 ½Ùu}9Œñ¡'‘ñ_|Ÿë݈ÖL ‘‘†Ó¾ø5E¤öŒ¸‚=îw¦¤$g^á7cÖ]cðŠ” ‘¦uÖë~°÷+ïªEÂRA…þ΄CeðÜ|r<}ˆ&>ØÞÖ”P PWîÝÙô&0$á2#7&† ÆRìvšê}j W1L´DÜ:¸±¥Î¦½“iER™Þ*F¯Ë`í% JÊ¦Öø; Odk‘å‰È˜ŒkJi<PMtxü4 hŠõÈŒóÿÓv+\¥4cñ¹õÆÂKfiN°9¾«ôЍKá¶Tâ„卿>ùúÊ.ú ¥–"cO};,»¥’…0ßþ±}ûþ÷íÝzýq½Œå]ñH½[¯H­¾ïúIîýë]$Q CÕÈ;·–‡%–;˜ÇU£N\E{5ÖDRNÔ•2Nñ~ø¸½û°Yÿ¹Lš2ºG¯;•ë.”,§¿]o^™Û~¼yœ¶9Ͼ2¡P¶5[\FrÒ$GÅeZ.•ÕÏoJgÁûÆ(”©`A—h*‚¸‹aðbèT•¶X¶3E%Éämé¿ ¥ð®¯™)p’_a9N/ê*|{õxïÄñ<$È)ÊgŠÿ\ïOžþj‡`ÈyÔqQÁüŠ%YÆœ ¸{*šãÁ9”çB½›Å_o"×É K¼@"Çû`¼6s< 1Þ«xfÊ#CðϯÅ3pÊÙÅ0C¥É‚å7ï£w›è7üü šžÕfendstream endobj 830 0 obj 1154 endobj 834 0 obj <> stream xœÕUmSÓ@þž_±Ÿ …&$ié‹gТ£‚Œõa:×ä’ž&w˜\Zñ¿»÷R¡ˆ£ãøEÚiËíϳ›ûB ^ö;­œ½³!@á|qBmû•Vð4vz§èF€ï8wLdÑ`ì÷ú0ì ®× ;ñ'„Aç0òÇãò‹3Çà)BŒ-„ŽÆàí´})XôŠT—%½Œwº"u>›Òy[@6/º`NóÒ¶ž‰Ý]öÿùÃÐñÂ(ÜŠrY_#Öz0vÙ¤s¿ÒŠÙF†¡m¨ÕycbJÆ)*\ãxO²*›™C=GyËS¥dÛ0^˜aJ\cW4ܧü›žiÃxFIYŠÔò¼¦Ðps8{Ÿ½|óâ—wÆîXˆKtôÑçÎÜÉE-Úb˜Ljþ4vë QCdFó+­…¯•ÃçÃ:[¼` à› EKjÂ%E^¤€•¨?ܦDQ7ýxxö2Aµ§îò‡7Ð%E æ×’b6]LC5k ¸¢¸j¼ÈÛò‘"­5‹[3§PzN Š?åŠRz[5ºÇ;çz\ž½o|+øÓV­ —È ¬¶ßˆŠJVamªf_Ë¿É)*¯J¶Ãþã)±Z°’&nò«²ýg›’tZ‡ß®Àö¾·DÛ¢Îuƒ^xá+xûÄÛ…P§øûòÀÑûÑ‹úàFÚvF•Qß aÏzöaî.{·—å¾=ó£!à?'ä¢ o‡¡?^_¿¿fbç-¾¾œNµendstream endobj 835 0 obj 838 endobj 839 0 obj <> stream xœ­Y]sÛº}ׯÀ[¨ÔB€Ÿ}Óãwœ{[Çm:cw<4 Iì•H‡¤¬¸¿¾g”}í$ÍtœX6 ì.öãìYø ¹`!}¹Ïr7{w™²u? Ùzöe&ÌKæ>Êûåj¦ØU‰UB2ü»ZÍìNÁd’s±T%ìj7 b~õoˆÁb!yž'´îªš™` zõî2c"" )[$æµâ1»:Ì‚„KÁ.ZZh•³(åIž9!‡ z³iÞIhˆF Å¥4BôÓGDÎÃL: ۳ɾøhwhvvÅN³ßîuW uÛôÖ^ä…cž¤’-¤Ù#yLvf×ÁÕF÷š­öMi6²û®‹ˆçY.ƒ‡ºÒ¬nVm·3bYq×îÖEù;[‘Êž -»ÓlßëŠ~„´Ú.™ÿëê/3òØÅ,æ"3v]Qêž3¨¿™%Ї¡Ê™3JdƨàXeݳ‚÷´ÓWÜŸgá^¸“ò<µn¹:vö©‘5¢D†¶EâÛ(A’”uÁ„‹1Eg°‰"Øt6‡ÊI|*S¨«ƒíC9rQ¥#ŠÝêv­‡ÛU¥o©ÝÜ·„éÔú¬o`«s,êO*5:öšDB{–E/‹)pFN’iÔ£'e±¯%sã«Æd_e²<¡lÓöeñI%ÌAn¥iâ¯{v37ÒFa"K‘R§wEDT¾hÈ„+ŽŠb?h›Uìãù_?½;¿<ÿç³ ‰­V$ßš Y²üåüÝù§%Åè(Ñúýj$DVfšðÐË\Õ^fŠ¢ŸRÖ6éûzWo j=¶c|ÉSÇvL‚Ž`ÈFo– žÈÄYˆãd–vM…Fù_°uÛV¬Ü´5R‹¾ I°¼ÜÔƒ.ÑT5-îPSéY$=²Q!:V2–üc1•Hä@&úåajM0*+Ý×ëÆûžÙâ5‘ÄBÃm„BÅd#$ñóÉ÷ RÄðì‹á2·+ùÙhPw¼+¥vŽÖdƒíë=V¹apzÝQZŒ|D?/bp·p ÞauLTSŽÁó^&¼Çºrt+å1ºÛ˜ŽÀÂ(Ò [—¹TÁ×ùŠuWÜo¸«,Æï”ÓæØNÝ?Ë[ yš}’ücðÆcLÑ÷{"½”× ¼ý³Þ)5çìG¼¥9IÊ…Ì|l–·ï»0jLÅ 6ªQØݰm}gáBä(EåÙT˜;Ç8hSÙ6+Cj„ˆ‚z¬­,g^,tCؾp— Âÿ´u´ÛÊô!PJfPž†{Ò`Ù€JÒÁMºcÐqÜ$ä1­ :<÷>"è=ðŠó©›Ûýõ„†Š êA\<ªË©‰þª«'°Ž¹KÉÿ¬§9ŒÙr¶Š¨§J…ü¦•Õ½¥ýSÁãÄÃFàÄe|ó #»ŽCAO (|·Ý~«oM'¿íëÿhëì’"FÇvMÛÜq…Êp܇¹$ÃRü¼Ýë#ËThðŠ'q=}{°N“hrN«Ê@Çíhè%;ëÀ RO²ž[·o*mS;ŒpBW£p%149ÉÙ¸ D¯ý™×ê¦êb;ŠÒÄc²)L…ޱJ¨âv-úÁjëhˆŒ@CˆB™–LüÄ¥m†Bå$Éf ‘;ÿ]ÑXÐ7/Jêãæ?î|éHÁÓh$䨭]{'¸÷̓¿r>î^œÆË1ÏǾ+ýRœmßNÀïÉ Ùè³0ò´ÂAÜùdÎ÷xÁÓ½1z€?â+[§“\žEö ÁDàÊ#:#YD0šÚÕ|‘ Oc€ µ“7–^#Á)‘YOt<å©oÚ˜,½ Ï<‹"énú²“¶©Þ0JGJ$´Ó Øo3»Ÿº+tY?~~‚þiÆ£ØS4ûʸ§ìábhOŸ’úë ,ºu1-i`ÝQÚ¹TvVqþJ=‹£zΧz¶ÍtÌ]E}¬¿’ï(Ôn¾<%Èã•£keiþ?ôÒñî`qcí‘øÆ"ª²#„.?7ž§ÔÿH+W¯©§aŸõ>äloïÑmOÝø•¦Æ¥§Ú^ˆ0 öks‡T4J5Ãv˜:ŠßݵäÙXZvÖœÚ+BAtfìÛæQϪEܹ#ƹ#”a6ŽU(î\Ø}֖懎Ü(ßF Yr  sßéA7Õ æÊvgonpü}³¥›¨–8æ¡F ú{]ÖŽ/ÄqPëêÄÐg,Çiúy’c®çäÄsÔ‰bÎJž•ÉO\³Óü“×,‘ìÐI·,…%ù¬lð1ÔåxÏæ.T¸åbÝîúÝ~ø…kír´‡â…k+x'“Q ÃS?(bRÌ,Ÿ]`鑌w¬Wè 2]<ëL~ª‹M<>nâ®^ëŒG­7ñ­—ç}Ç ×ƒaÎKlÀìÓ.FŸhPõ˜rî ,/òÝá•+”ë`û8ObªË$°h¶ˆBe¾P®Û(0Í”t[êF ÛÔÀ“‡…L·!#­Úí¶õ0yüÙ±€Qœág~À;’$:¾”¿FB—Éñ’øOÔŒÐ, VpÈMP`hî|,œ˜':äK:^”$¬…ÑŸ Œ°8³½×Îmã¼èKáAlÇ ÄeÊðä#ÒV†RL»ιŸ6¿û§“W³¿á뿽—Îendstream endobj 840 0 obj 2703 endobj 844 0 obj <> stream xœ­X[oÛ8~÷¯à[d 我Լe{ºh;³­gú E¦mm)cÙ úï÷R’ÓtÒÙ]$H`‹—sý¾ïèO–sÁrü‰ÿëýì§–mûYζ³?g"ÇG×Ù¾:|ž‹œçBºÌØMör®ð£Î>­^¸z÷jõÛû—¯^¿yÿêåê÷¹PîTÙÕÛ›9ÛûªmÚíüå?g‹œk­£ ytAÉvÑÀƒ,/yn…‹®³mÓáî/ÕîäÙ©]ûÍ\‚ ¹RYÓúu¸`™…Ê5/œf ˆËà¥þß¼üˆ’ƒæG”–J>ãà¹}µ÷¬êYÓ²ºÚíü7M½“Nsi ‡2ì¯o²Šu»5{IYædâänöéj¬Ç‹B¦x-áF°bâ;›Uµ?Ýùv¾0!Þ";ÞyVw»Ó¾eM7¡ç¢Ü–&Ýãõâ5Þd×EQÆgW«¿¼ý™á! «¹q¶< C°^çWPÑ 2(¹Í¥ª=ío!Vp{‡T;vWÖó²"5}g» h/¨‚LJtX å7y~ÙŽ‘Ñ°ÂÆäàÕ6Ä·;†+7þàÛÚ³cG‘.KnM.ÔýKÖvÇàcαek(Wè`YÊälöòÓhJÉÍP?Oô¬ªà¹Šá<‡ƒÐÚ+¸©j×xÙi%—ªtìŒeçØœšQOÎály²¥wã äa\–*nÇT^F ·©Î²ÓÎ'߃ëZØiž³/ո̑.õ)—B{B‹Üu'(ô[J©?Võgvß…òe÷»SϺMðÈ)^@ò†$•Ц÷Gøò*ÂÃ:8šo. ì™….ÜWŸCMÙÂd¾g½o{ÏCY):s ’¿_F»¡å­IãaTрƹÉSÁKc¨¬6” ›Ç]ôô\CZØ!–pYŠFï÷Íb×mŽKv ™Ž¬oB¹B¤ e覻¡¤„ pÕÌ5¤Ñ)‘õmXBÀŒfŨvÁ%åJ®Å¼k8èÒ9™Ú®Sà7==dô¬á,ÉËTÂa95Þµû s8øúÈ©ââqÎñ2/ÄpÜØb’–b¬ /ņßi(X¥Œ­¡ª"ž Coö÷»¯þJC(J;f×Ê1ìÁîð„¼Í(PÔ‘¯r›õ§³¨+[¤f œ‡EE K— ²E`w€{5°ÛÔŒ‹Øï{Ä-(•Šz¿ó}Ñtí%RÎÆb‰h#¿1ÖeÀS£µºà®T±Õ2 E¼'vºÔ„r¥áÚ­¾i†„Y‘òmX£Û5+<ÑE™ó¸q™.)5Tlý%ë;ð¡ëý°)”£IåØO#P~ègh0@"§¨fƒhú3fVÑ£zf×JOIAX hú~l# º07*Åý¾:@6ÿªº†Vmnw~àtxF—–ÔQŠ<—.ò Vر‚}|¾( Ð‹ -»˜ˆc¥Ì@ÈŒ$ÕÛt‡)M¹P“:>7Ë¥…“J„€)MXšC@Â^´‚ôZw:öÍÚkË>vOÞ*,£Ná¿ÑŠ\LEØã÷ØÎÆ~A!Ë¡_¤&Õt1@Y’ü¹µYdªá¨¨kψªÀ±T­•aH·—一j6 | t@2zUQ"ÚÑEüã´Ûó"IP3œã}Ô zÍ<æ±'4ç`Â5©O¬`¶kn×‘Ê ‰ÕaÃï°¬ˆÉ$¨ùÒºGL Û9ËW[\mÖ~Õ´›nU³ªãÔ€|…°‹}œ›l«n2èx¬Ù¨Ñ(Ã=q€Qg…%HÀ^PaˆØhð6n&@VKí§v>ŒÐ½€A×?¬ÇÕe8ç"Ž#“Ç‘s µ8Ÿ".ØC³Û·ö§þˆöHÐ|ʱ%Ÿ# ²ÍX.u$"¦´Ýdð÷f~Išiñ@\¹Ä‘¸À‘¸o×ÕòúÐÔ(ʱ34²œç¸k=¹S­‰š@EM,$IfÉžô5>¥ 9—å4ÆÁ°>[€—seò)…‹ù¬ŸÎgÈ%^¡Ï,OäÏ£1’ÔvÌ,S>Òê_evœ/o2Œ‘ 1`iG…д[œ‘Ï&Q¬cBƒø°I|°èyQp“ÊR1 K”hˆøÛCuÇÖ§š®î!ã˜itæj$±68!¡lÌ ©hÔ\Uj°6I ðU&ý5pgo j¿”rP¿´¤9²Ì>©h‹éü;*Å3Ô!íF¹5°É“¯WðýQÔÕ@=eaU*ZÐÄãðS‘¤Ã¯M¡¤*)ÈŸÎð|`ƒá¹´y„ØZàF)\»v94«ˆY\ÿ8…°À¬o~®Ïàé[ËöÕWòšª.”–CpIsÏ!Í@ˆÚ=7¤™8 êŽ¿ |öí‹ÄãÄÏ^£!(¢§·X( ¦çï¢C &è"ìÃL`i) –pBôØÅ’DJœ—‹0}þÝ*|ÕNpûÃH=ŽãåTþ%UÏÙ{:n5C&cpÈp^TÙg£"ŒÁ·pG@¡m$„×Íöaq˜}UƒPölíï=Œˆ0 'üýÁ÷ð©gïÞüú‘½øõ·G¥T©€*”ÛvËèNœýÕ0ÃÅw>“I(>þïI-‡|MH¥÷¸‰8¢4I•œK^¤†ÅmÔ^$UÀo€ÊcwÀ×Ñáð–àÖïºvÛ' Ì–ë\ M\Æ7Œg“„Õ{®Tø]ÄmÔQoa£Gœ‘òÁë/ꛦȸ´ >¼ƒN•¹c;Y”Xiç³/ì_-gÿ‚Ÿÿ°ËÆendstream endobj 845 0 obj 2417 endobj 849 0 obj <> stream xœÍYÛrÛ6}çWà-t[!Ä•`ßÜØÎ¸“[m%}ðt<´Il%2%%{ܯïâÆ›ä4•Ó™N.Žh÷ìâìîó'J0A‰ùå¿Î6ÑË«-›(AËèψØMä¿Ì6è§iÄÐt§Eð{ºˆÜ' ¢2ÃŒ£”I4ÝDñ„œL3p˜PœeÒœ›Î£X141[çÓè—ˆc…ÀÄÏðÇœ~)•`*T™ýº‰¸¢ie]?lûÜ¡S#pÙâH¦Ê‚{wÚKq¢ÒÌ#<`ã!Šßž£{sФ)æBúÂîåëF>^}x}ÞÆ§lŒÜ¯|¹IÛÁ¼è’Zèg¿vÐ3,õi½½¸:}{~ûêÂl˪|ÆÓ+®,îÓÛWïߠĆÅÍw"1›7ñ¬Zï6%Ú5zŽUÀVjœKŸžü6ý¹ƒ9¡Œa¥Ð„pëü PY¿ÜÕùk‚,/(áh5p_”[}BN)⥮Qí¿¥<^ÍVÈ·‚A} ê` ½S¢°Ê¨u4™LPug=pÓýû¢Ú5¨Ì7ºAy9’QIf©eUƒVŽÂ´Fþ!JÅ÷¢d bÉ3â„“ïCHbϹxvÜÍ+†%U},²òäí/ÖU¾-Ê%ú\,‹„›îÅ’#Sr$… „üI½ò@œÀCy|ÆdáP’ÇçüHB5ÿî—„ëÄ’†Zq­gU=7ˆêÜœü·Žƒ»ïÎÎ/.ߟÝ~²½ŸAu±0Ò$–‰o`,Á ‡Àá”R˜ ‘ 2äóàè’± è‚vå\/NÀm– Ŭç{ÌajùkÁ^›¿,Î,Ã)É<ApFy§°¡@î^£¿7¥hÀÛÑQÞ ¢D³|½ÖµEØŸÚ<£©VÌÔ¯V%{¦FZæéù¿/XØ€ØçNN]Ë]m¶ò‹*$!mšué„ÎÛÎýX`³Ñ—Âï\Ô&!—%Lù 0¾*ÑÕn­ÑiÓËr£ËmƒÞ^~¸¶”#La!€jÔå ™¹ã¬­àÆÍ7÷'/¢Ì°ÑÓÄZñ©I|j*o5êMì8M‹ñŽÓ½\ p˜‘`±ªGö`~…d[òÝ÷|’`)“pµ6©Ø¾ÎÁ4\(uÚV@|¯»›&˜„–¯Í:xL„Ù3÷%”/ïø‡º/ÄEDuÇš…$Õ&ŸPU¹Í‹Ò\ch8œ{MÝÆ6aÀ3ÅI[Ðu‡+ÃIJTæÊo6#8,dî  ü9iósØIhJßW@+é""^4ÚqC‚5ÖvJY€ˆ/mU…sCŸÛ¼Ÿ;¦‚^v§!uM³3#ôÌãÐHUìþ:ä©)ØÐK½ /`ôúb©¡ú~@«b¶‚e›š ÌÒvັPVf*åóbýˆòÙ¬Ú|^Í ä:¨u= Ä€eJÄa{Ä)›.>˜Qmè²) .ó h*Ó;ëÙªØ=w@SÜ=y2aë=y O½•ãkP‹ðâaþÅóß<Ö¼€Iß ±›ø0 æ‚…Á0ýî`è œg†üœ¹‹6܈Þ_º®L£0¸â]³«?Ãuß=Úiþ^¸RW©iª¡—Î:˜Ò$/à´ÉØ«im£Ê+N ×Wþž©Q¿øW‚ˆqÌ¥êh9$Ÿ’C7ôе—%ŸNI 5¼ôÈK›t×JÓ¾ßÇü ¿½Öi[4ƒË”Fó0L2²'¨¼Þ *ËReÕ¦ª5ZêR×€r$¢ B*9˜Ç‚FS£«Â‹Â@–w³ë¾ ë6”j<”a†w.4N¡ÚÒPՎ昋šß“TbÞÍäI¹ÛÜÙŸ,t ® úâôw;¯f‹|Òê;ÿ(tHüèe+=·~P3e[4ûºNAL¬•û:qrßvŒžU%¡~Gšç)«¶§M Æ x“Ñžðz¦f„+¿,‰Ù מ*F{Gµ¥iõÍH€ºIÖiÝ/ FóN3­ÌßÊ'³ŸQø €ñ´/T×ÛVm[LuÑouµqtMT?I+'6ù&"'ëÀ9ÿ Uwãz9CwU»mS̵ ¤(ªᇠJ†ã~ðâ=Ù7˵‡( æS8œe|KýËЄCà Ô@/‚FÔ—rô—Ñœ›a쇭–W:ŒP„I;Ìî{]5> stream xœ½X]sÛ6}ç¯À›)…%ÓZî¤uìÖQ’Ùqv4”DÉìP¤KRÖº¿~ïÅI)ŽëNgvâXc¸8÷ëÜCýA"“ÿ¹ÏÕ.ø×]J¶m‘mðG›Eâ>V;òÃ<àd¾‚]1#ð3ßödL˜Ô” ’rIæ» œÆ“ùï`6ÇŒj-qß|„J).ÍæÁo ŠÀÄÏðwÿHÍ)KˆT:ÂÏ]pÍÆOÊàãwMa]Xtê\šPÎMdª º›wº”F*Õ],4Ø#‡ ü0#O¸+NS*é6$f-+÷9ùõÓݯ·g½3zÊO¡»'¯BǸ½Ø»dûå—»¦’3ØÅÕÝ»³Å§›ËÙÕû›Ùåâ³AÏq^R)ãÁ»k@ùÚåYÕš&•:c÷á¾Zç› ‹hÅ,,ª|=ùÏügožrNe¢™ÆÂÜþ” ¨b1åòám÷!Ä‹’›º#YÕå~W‘º!M>‰Ô†á¶h»¼€3|háþFš)$†êh¸ò/ñ™hMÓX»'1ÕLŒbXïM˜:ÂlBCÎ& BbiØf»Ü!T‰2ÏHÖ”é:WYY‚Ùúo'gÁüü>t>+ÅN|æ/û qVovùÇ+\–)ûø' UÂ¥|ñãí5'±àÒ¸,pßÈcïðjƒË&ÍBR%#KÖà€‹•ëkθ‹Y˜oÇ ÿÜ8yf¦à@vÎÜÔÀ&oš|Mºú‚T&bMž•¦4 p#™¸0™¸Lqͤ¼ù‹jÄ3îYÝõLcÉÌnÁl5ìÇN´¯x“¨ ²œ@dµNY¸ïH÷G·Š!èþH˜} Ç$7 †;çQ0 £_ËÖÃ!‡|¦Â:o¡rŽB ¼aÚõ§|äVª¨Òrpëilth¿{STè•ieÎÑ«¢2Ž]ÚZ‹©0¬©À{”_F ©h’ôÄpwÅIY,ׇ‰Æ>à ”ÅLBŽ6ã•+dì+ˆe³èÈýÄTŸø*·f¾ MÐi(‰³ ƒr†^>êÓ¾`޹¤Úï–Py_'Ô@StÂãŠöO¢OŸ½<ƒ¾1u2¹¾Oöf<ñ1ÅãèIJš#Å;輤 Z‰˜‚VŒ¸g¨ðA_lón±i€•m¾êŠºZTðÇ×ðëÀ(Ñn”Lýá)µ;䌬_5tiV/óå~KÖËíšePx}:WuÕvdõ5äüœÀasðÂÒ 2bJ™¹ËZš5 ÐþyŽò øÍX³¨ÂLÛ5Eµýž[~B2èG§"µw•y×D¶ßåMK²Õ*o[Sñõòw°H¬uS|Þ„s JÛªrw¼›N¦0 +,œ?kÁϾÍ7û’lÀŸìñ±,VînÉÁƒÝ‰—òΤVjœõ.Ð"<ì/ì‹òÚç1kŒQÛôè¶ïy&"*z~¥ç¡ÁÁÕq¢!cì‡ðC Ù»ïÀ&ŠêD AÕ‘óÿP”%¸^/³% C81@Þì«•3Ÿ€æÑ¾ÇõŠ,s³ ¦D×U–Ž­QpA Gž#Ÿ»1½ƒbðäZ@\² ò‚‰Â·)N LikÝ0%ðV¸ßZw¸X_ô¾yŠ®ÈÊâOã8†|]WP(XùHJˆ›Ýs¸½l듾àæ0^_ëÅEþ°ØVû—š@Jê½7×OTR$…o+[àˆbžû(Ÿ é‡Ìë„ðB ª¡Ãú1o²è½¶Ëq(—q—Ùb kìHi¶½ÐW²%môà:`TØ® ßÛ"öNvÍ¯Û à’‘71ÎM/ÙÃsÏK'ØAŽ0˜xvÞae¤²Í;ìQèœÚ 6û‡¥ r(º‡›X‰À–N†Š™ ùQ_fÕú~“wûÆÊï1z¨h˜Ôýå—ÅåõçÅí/FÚáÓ0‰/Q.ÿ¦»¹ß¯6)LKŸœ‘RJÌ–ÈcµE ݸir“µÞׇXÈEÁz (|ð”I5ëM¾¦Çc=¢I”z„WµEȤM¢ùaSõn/ÍpœÚô×ÕtVn\à†;ì»Çºm‹ey„ÛçÍC"†x€Gn>]_£G„JÚKœ+*ÓTm2_‘|÷Ø=;ãÀOi ô'‘žp<â&£ø€¤ðö#âR“¯êmUü™ž½.˜>À—ëBQp É©³ÂðkSø€Æ*Ÿ'EŽàá¸?Єë _o½Èr²Hòð¿ ‹^,?˜ g’!ÖÚ$ŽEøyqs»˜ÝÌï¼NL„¥84z%òoÚgmêWóĨjF}Û˜Ñá4É©ÀG£ÀÝ`çoj2UFò¸9fww·w'Ý *,åŽÕˆ}åÃ趨5EO9~ƒáµ•)'VAHõSÑ·E‚/*B»” ênj6ƒYW]#MÇþ¦¦û–þÿ™´ëí(¼ÿ›Àû[ˆÞ}*-Þ$ó,]¹³½nÒ‘×w–)NdžL`vjõ™ãàJÒW%Öƒ5z){)dež×nCQ9 Hþ™Êã¼¶ ñºÊÃ{m…žª=TJ)…™ê' ʾ:gr€îss«7‰>¬<‘R¡äh;—¾£±ìp$’0•ô‹"¤›~IZe"Q+ »ãnxdž£QÿË Ïñw&”¥ž|Èž ‹X<œNcóâk¿íÛÐß‚ÿç§±bendstream endobj 855 0 obj 2085 endobj 859 0 obj <> stream xœXÛnÛF}×Wì[(ÃÚpoä}klIÓuÔS4¹’P¤BRuœ¯ïÌ^¨‹åİ [äÌì™™3—õ7SFbüò¿‹õäõMJVý$&«É· ³/‰ÿU¬Éïó‰ ó¤'ð=_Nœ&#<ɨ$ ™¯'ÑŒMç_Á 3N³,A¹y9‰´"3|5ãL™Jðámtñ0e1™’QÞ-ænúïüÝD%”§YêT%§œ12˜DÛ©šj¨òºú‘UÛª'eÛЦyS-µ×R Å­ÖGcH^÷-Ê€™÷`&dJ×dƤ…X> †•Ë._›Eo aß=¿7d¹m¬¡£ó“”roàg'/Ìýbu¿= i’íÆtù`zQàTø±°„H©)ïelaQ0j"þ(@xù~©ÚJ½]ZK?é·EaLÙŸO_í;¤Pg`Ñ?B `¹H3'…gdö H`o2´$'›¶jÓ¹ýÐUÍŠ }"i¥($‚KiªÓ@w—mWÊŠÄ«#F;eglšFWïÛÞ„ 8G5£©Ô;O¹£æÜ1¥#ÖxXS+åèªu­š­H™ñ¨n"ЍöÙe½ôïI5`•mÚ¾¯îêÀ!_ $«®É!þ~ÿž´Î µ¬ >ÀI‰c—¶&lÂbÖ›áÑÛ¶^1ˆv`¡bêhim7¨†hм®N¾ÙÔUáú¼êLÑ®šêB®lÚgÁà~-ÜF媮àtdMiòÚñ\£]»é*(­úqŠú™Pñئæg·¡FõÊ*°äš)CÙDDß«~8ÉDr1åÍ´N"¤tBl…2ú´øp½¸ü0¿±‡ÌUÒæVȘJè÷™Žé›…7cûBíUpg0`a›®¼3]×vàè°Í‹ê„kN“89¬“Ë››ë›£:‡&œŠ±`<¡¾ûÐŽúo*`tŒÙˆÎ,ª#s2 ]åJC)Ç2óYx}£ Ì´h…Á®ç‹‹<ƒ€ ƒ@,Æîºni5¤i¯ÉŽ(ƒŠ­ëŸHÚò„:*«”&£O~®Áè*ïVç–ÖÛ¬õ¦2ä쬨̢̇;«ñ±ZaIÙW¦6kÓ ‹¢Ý6ÞÌU‰Êxü3Êøê9åKËô/ÓßàÅÌAçO†ÒÓðŒk€Ì¨TÉØÕ•‹y?´ÂQKG¤]w` =U†æ3FåÄøØµ¨ÒôEWmàèOǃu& L•â;b…ðºnEù|W?Ï÷ž±Ð¸³DZ×üX±Ñgì‡f»¾'áÓOqΩ`ã |’ÙãØBw8\1$<‰cãÀLÖ _ä{È~L^Ü“7o/…JKرpÖ ÄnÇÂ/X'Ö‚ + úX­«:ï "×­b1‘‚êq׻Ϋ©de‰Š†Þ© (—Tz+žnCÉ4„EíÍsG¢pGC<4? ÔÄQaÑÊÔKˆ“hHø8Ǻòc^½Œ4ŒÊTž>OçyÌ ©ò]>.Ƹü‚IZÓDcþi™£¸vÖŠg)5ßÖTë@†(p öê}6Á~I®.‘Ü~»%”ïXh#¹`ö`#ÉøóìÚó*ƒ('c'xYÿQμ_iNŽ.‘ÐŒ½`r™²]úaŽóH1¤>.Åà6lûjÜLNCX YvˆÁOùÏÇ.aßQi¨¥j‰kH‘7¸U,§ A*¨$.˜ô®2½† ®NIìÙŽÀ’;¹ýî!‚†Šw•ƒ„'w‚¾_nko~ïkµvËêuóTð÷¼mšÞ‰ ýîñ°…õ÷í¶.q§Äm¹$Û6½£ë‡§Ž.Hì«H—.ru[XÚ¼šÀlú¨8à‰z€Ž1¦‹9=päo›Î¦Û ±·Â³ÆVƒ¹ÔmÓ0«¸ |ȧ–`É“î öO-ßíÚ"\Cù¸11g«¥~$Lû™ÒxǸn@ÊWÞ£ ¶á$®ªÕÖq×v^ £90Ûˆ£’Ân*.¥Oª‹ì–žÛèò{¾ÞÔæ¬>öÚ§it²FÝÞšdÔ^]„5~cF4pÝ€•ÊúߚХáú ®“?óGÂcÎvŠ)ƒ¡4ù¿†Ëùä/øúò‹Zendstream endobj 860 0 obj 1708 endobj 864 0 obj <> stream xœ…T]o›0}çWܧ¦àÙ hêË–ö¡ë4­CÛC3E õFâH³ªêŸm¾ÒtÓD¢{î¹÷ßëÜF°~úw¶±ÞÞ„P6†Òº·ˆ¡exŸX$™Ê"Ô')¬ŽI€²y>„ƒdcÙ.q’ŸªŒJ&Å1ÓyInÙWCªDÜ—pIƒ0ƒ?H‘ÿnv¿_Ú‹CZ«_ïKÈ×åÒÑ\âCrmÙOΙE#«ŠÛ%Þd‚¯ò´Máð;ÍéÁ¯¢Üò4œÉý¶íð³¾Ì·È¹g'TþzQײn¾D¨¬¢æÍ ‘Þ‡rÃ+y»Ò5+Ñ´K[yœÏñÝ/Ól~êu6¨œÏFEó™i¿tŒc÷E¾(`Ù7>‡Å÷ÕâúÛêóÇ¥O:÷Ej§ËT®UÎÓª’Y§F}p¤ï´Ê¨o”7è BÄÆ´ç×RŸûýVÌ¥¾ZƒQDXÉÁºµ“;…Tª Œ©}Û2©&(Èù®æYÚª¥ È®öÕ#`ã@ÇD ¹TDZ•fF”C¨yÅÉ•åbd6Ý'1öËûN[M¦Ñ°ÕÛÖØð)Elò¶áY?j„iŠ#JXÏ@ÉTŠ!oh;swÊBºÛÕ2Íî7ÀØnZ¡ô‚&$²eý«Ñ6\…;;£r™²‘‚¡Ý×í¼^9ñ£>^çÿ¸§"GÝ¢ñ–† …¸´K¸å¾‹ªúÁpLÜ›ŠúÈ›Ž)B'£%A‡ÜÚý•_«kaLâ0´_ßµ°rÝÈŠ·½[âÈÃ\u‡~säÔCxšÝ‘¨` ÕNÀ§ôQ­%1$(æÿË.ë‹zþ&eýendstream endobj 865 0 obj 658 endobj 869 0 obj <> stream xœ•VmsÚ8þî_±Ÿ‚I@±ä÷éõCh§wis—ø^fB‡1¶ß€MŒÓ¦Óé¿•dÙà8in`ÀHÚÕóì>»ËX„‚%^õw²5ί}Xí VÆAå&Ô_ÉÞF† Q‚§(|GKCYR`^Hl|Ûƒhk˜c:ŒþE7x˜2†ž8¥†ø0[è"¬]ŒiÂØõäþù)\½½¹ºœFS˜þóæãï—S8=ÔèÒ0¿Y ü!Þî6ün13'_ãr9ŸðÅý ÒÅj6 ó;~°€0VèVºÈ8œ&Ÿ§qÃk°^ ÇõæM¶Êy b;)îóJíôö»m—é¡í c*vûL§eY”Àåg¯aÖ,gh¼,ù^/°@’®—Ri´âÕ\\µÉöÕÌDΣÍI=I £nN4øÑItt"Q͆2ã£óÙfõůaò÷|rù×üê·Ù¾‹³GG—Hlf*Hæ—6ˆ¯àì,ëµÁDßï¹8y›}>N±¢™òx³)Å4C<LòAø™ÔG˜Ò-¦A/$<ØBê£#yæÝä0Ï1j<\~¸‰”‹g/í9ßseÏÒùuÔ–Ç;¶Ø² s!új˜a”8Š“ŽG,¥§Jö‘èæ|=3±Ð:e¬­ÆLÚYÒ­ôcÙJÂÞõ‰×)Ò¦”GÅ)+·)ÝÑ£ ’[|÷<¯Zý–nS»=Æbë)cU¼§M`´hÅÒ|‚\ž¦QúŒP –¥¢î⣌ϲïÍ’xUщ©Ælˆ¾òW÷Œ±…ÝÎìZx‹¶åmC¦„:z=á»Jzp°O[VØ$£ZÇU sˆÓÊâÿ·l[wpJâ%Ó=Tkï?ý «$=Oª¬È!·˜Â×óe‰ =âxT¤¶nÍ™yqv|H]„NóA°.Öqžn²|YŽ}`‹ÅÙ ?G¿ úM“ÁK*ô‹°Pξ*D“ŒaW Øy‰YÄ ËN) ‰Ïô,l¤Ý‰Þc…N¨ãÌ÷I™íð”JÞ-:ÛóˆÏ:mMˆƒ6 ½îÀö¢38Ї4 ©¦z*Gy*¤fZ±”?òûíIâ¯g1ƈV‹ê¨Âº"ÁÀÔ‘5‰Ò#®X–­‰ Q *Zó’C&"Þ"Ñîyœ¬‡¢‘PIÊrîØ¿Ž§p$ýܯ”¾´î䵡èa¡ÐM¶Í6q¹ù&[•4L Ç*¨cuk޲¡CCB=׬öR`2 ¢Vj/µ>$+ôaqªDôí€I:>AY¾@8¨1²&?º9*ÕP/  ?Ðj~Z,йE‰g±6Ÿ®øÇ‡Ô¦¤ žë†‡H))PÞ’'%µ ±ˆ-Sk©Èù¡šv˜ èµÔ<µ}l›87m97Ík¹,Am1øj_ìöª:jæ®|Œ¿³m­}ŠêÔæ?ýã<Œ?ðõZ.Mendstream endobj 870 0 obj 1140 endobj 874 0 obj <> stream xœ…TÛn›@}ç+æ­k)l÷ÆÂ¾Vq¥¦i¬Z¨U•TˆÀbSapX¨“¿ï.—Ø%•*,vÏœ9sfÆO@0âžé¼÷ÛvÆ#°óž<:\ÂôÊð!ö8Ä™EQöÞII…¹€Kˆòé*þei,˜2¬”t¸8÷Pï®|F9øq®Ý!#˜D¡¡ʦ8y¨ß%E›4ueSc‡µÔ¤AqL¥˜3ä§´-’î’"×IUšî=¬¦WÙÁH?†´ºëÛÚ,h¹ÄŠÊ rý=¹¾ý–¬·ÛÍvÁ)[ ›¹štÛ6­ñ3Mƒj_0>î„b)ÔPà§þ-AXꀫ¿5Üm’õ]¼ý±,ÉíÉÌ9î{TPv¥uÝtP¬¨SKQYç WT¸Þpôœé£söiWe½]wm© ^ù’‡¶³ôRäÏøæR¥O¥MMø\Ø,tóy!Q†xrƒ uÛ„)˜>Ë´1E_Mü£QÖç¡°c1:µ©ßâ¯ÀtmŸÙOmàØ”u§sèx|±ì¹6Y[»¦³oú*‡G E«-¤7¶Ð…ᮀÛy†Üüdå8CI®Óªj²a–Þy!–> stream xœ¥U[oÚH~÷¯8OÄDxb0 *Ý@WÛÍ&-µºªB…†ñØÌÊ·ú¢þ÷ž3¶ …d÷aedà\¿sÿ6sÀ¦§ý‰qµœ@T6DÆ7ÃÑLh¿D¿ùÆ|RŽ øñC£ÑtÀõfl8‚ÉÐ?1LËéûÿ v\6›y$ç†9E,41kMXÇžæï2€üΓ<–ÅÊœïy®çrSGl¢Aóÿm<æbÇãUŸÌ9#ðo ó©a¸S6‹1aèao˜W—ð»ÚÉ”D5M·Aô`ò¼ïÙ¶)vý¯þûóhÈZ¶ÉãZ’š5õب³kk«aV‡°NE¥²B•Pm%¼›/€ãï›?ð E²‚L˜ÄìÄB5M Pn³} ^*\Y–PedçŠläq]’t–JØóGbµB¬¸ŠKˆ(8ÄòávXt®"Y­Ã@®Ó•¹êcòÔ¨«4"BçGëÜ2r%²:`S+|×9F<Ïc%8Á·Ê\ *ZþåƒYñ Æ‘… RŒ6Ñ2 B̯@•d…„º”a³¾å¸˜ðË+pë¸`mÁ?©(•!H+¸ûN_ûQ.…’kU3/Nõ{¤{`¿ P•’ñº*q_R]V[êwÇQ(²ìîT7aKú5ý±*«µÜ®Lêâ^¿ù¥ý NZ×ìu@½¨AO#XõuB~Í&{Õú¾†ùßëùíçõýŸXó'’}!É”äm2ÜNÑÑa·¬sq’ ÍÙªh{Ìz1j^¡¢ê"igö> stream xœXÛrã¸}×Wàm(—…@ð–<%kOʉw&ñ*»•¥T IÌJ¤–OÍßç HŠc{&)»,Yl4ºOwŸîÖï„QN˜þé_³ó⇧ˆš#‡Åï n’þ%;“?¯>Ygâ‚àw½_Ø“œˆ0¡¾$‘’õyá­ørý¨04IB-·Î^ÂÈJ?‚ФW±Ü'« 4Ï‹²%ùç´ÞoªÝf…ÚVûí>WïÎ|ú>WÿÞjADC²âÒ´,¹Ñ§jÕvu©r#¨EÈ}]W5¹Qúe³üãòÝbe káË·o–½ÕƒãaH¥Œ­[ex»þ¼ðš¶ªUCÒ™2¡’'IÂ`ëLg$h,ã‰ÎÄè&ij¦3TòÿA¥×Óv޾:Ä)r3E1<°Z˜1êRÁ,8ÚR-¸2W"ÖœŠ$0B{R•ŠÓ†déé4(u—Çå sàøöT4íK°ËØh·GÎ]ÓZ¬WŒ ©ÓÍ4~ÿü¹ÓÓ(dý]ÚB©-üä9òmÉeÜ=mA®`j•­Šò Q'ïïî›å¿×E¢F M|‡VHYd¼LËÜ…GÂ!¿¿ÄïŸò~|¸oÈY׫Æ*$E™K!i'±÷\ä.ýB6^£)l^eÝY•mÚUIŽªV›%µf ^cãªÐpÈ€÷éÔ×x̶âd<1P¬üDÒ ˦Ú5ª~6¦SÁ¸Q«O W°ªVrº”çV\»w,‚¤oë"3Æ~.N'Ä»ƒ«–UÈ€n{ðþm–¤¬PäåwÆ¥án!}E}x?yy»ôŽ|j$!"¡‘» «¬:³²OÃPRR?Š\\!ÃDì|;ùHZê€Xp"ŸH®NÃÄV`V!EÙ >Ç"ÏU‰ë%¸’—˜bP5ù|,²£õ§ôïµU"iÀ¿eÕ\ ët>´éIÝÚlɾV¶’V"‰h ƒ…5ø¬ÎUýö{“ÃÚHDi]“"€ \˜ýádNÉÚæ²SŸ;æ¸v$¦q ³èmGFs´+SœÌß2=Kl:H˜RçÅNYÏXlêxE’X‚ÍU«²Vå$mf膰ÊÕÞ›1'»/äTìPö ‘íq_Cr¸<@ÉÃÞÀQŸECÖ'}Jh^;¥Ú™KÚ4šòM!øíYaÂ6ú ç© ÂÀxCÀ4%™"rЭº²q««Q‡ö6ýMG¿¿Äø~éZ+£šîÔY·_‚¤_&^ZœºzP¥ Ø–åÒŸ·ñ,ÙkÍwh„HÜW}¿nïÁŒš¥÷ËöþéÉœG§¥+.­,°||Òõ #¨IœX´:ç.UÓ;€‘’ ½1ïÎ*´œË@~U ¢0ÖÓËE•–ä8ŠœÅckÚxª¶%?<#<«i¸¹#)¯l ¯jêœPáß¾g}ÛGyê-|ÍL·ÒP«î;³†ñ—íÇ¿Í4!];‘Áýü€zµ°5]–©¦Ùw'@1†·+OøØÖF Œ‡d²a€Ýú¼ù‡>>ºšÓ¬Ƽ‡–8³5лy¤û‰¸¶Qÿøôê,àõüÒ_:+ȱbü{*rãi[û0­|)t7Ç«¸O³ã b$G£ÁT7·‰û@` u§š¬..˜Ôˆ}‹Œ…éhÐgÛmÓ]Õ×Ö¾NÑ[tëNQçu[dÝ)­m)£0B^¡ï5Ý®/Yãû®4qž|:åç³®zpÑ6Ç ÷î*å\–cXiÈÏyøá§‡¿ÿLš‹ÊŠý’ëjç^‘Ñ>œ1Á8­3\ŸCK³ô.ì@R®FL÷`|;Ý׆˜Ñ$á¡g-2•0K—•SÐOÎÌ «/;µñ^™ÙïÔ®;|wøzV¿Ã8£·d}ói²Ü,AHf›É[³hó^œñ¯á¼šö%•=2¿uWomÝ©¼¹ÅŒ3 ¢ËÙW<üš.0Q0¼I’Må5¶À/Àwd°Z£g£Ú¹Ê•r ïfj^ËØ3×Þ0à–‡Ð†æ;Œ©?–ó5ɨ«ÕKÙiÆÖ×´öì˜l¹žÇ‚²$¼8ó€n%¿Õfn`OÅl<,vc‚kb¶ÙšB±BôÁ ½ Çîµ§áV]ˆÂÑ>Ó·ØA¡ú­™z51½DÄlÒ(þ´ÞêÚ~!LœIʇž’¶¶wZD |‰pÞt­Ó0× +ôAôÿ@ÅåWPiϾ‰•2`ÉdöØy"t­ˆ{í~2У!„ÃÊÕ|ÜÞö ÂÌ&#nÐoàÂNÏ]ÚÙgKW Ü©&ž%av;iÀI­|~ ¼=*ÇÁEsµs\Ú¶6/Õ/4zýrƒªå™&é)x¨óÐ7?`QpÃ#j›Or‰´F!<(«ùRïëžù)©=tP1¶õ½„¿|ø¸½ÿ°~ú— ¨1ëúkÏâÙË žÌ•··Ÿì†HøDºνÔÎ>H&F¾j•†œÉ«fƒðüq }k ‡a¤ï³c °D@êÅ.½Ð¯›`–‡—H}l|\Oï8öd&и…ø#@ÁôÛ*"‚O~J¿ÁOGØ0†¹æ›ß¢Ý¯ÿÀÏ@(%qendstream endobj 885 0 obj 1995 endobj 889 0 obj <> stream xœ­W[o«F~÷¯Ø·à(lÙ ,«>µMŽzI•6uÛ‡“ʰ8T䎓ßÙ`âä(ReK¶ÙÙ™ù¾™ývüE˜ H¿Ügþ°øæV m·ˆÐvñeAÌ"rùú~µ`h•ƒ¡Þ«rawD‰G‚%hõ°B²\ý nÀ˜P,e¢íVÅ"…z \Hç"¤„¡0NÌzU÷¨8dm¹Þª~]jÝfõVÝzS,p‚BÂ奱úT(VzY/\û…Eç»æ°~Ì/–gþñŸuWmkU ór_ç몷ýýdý·vé°›—^u§7ºÕ×›oÊç•Z7eÙ©~²ò‡Û««ºPÏó]Úé«]WmÛ@:JÜ-¿…… ó¡eƒZ^ojÔíó\uÝÅŒÞXâ$¦Žþ“ÔÞ-Ý–¡¨1Ç~G«ú}[w3§,ÁŒ²ÔÙ\þ½¾¼þk}óËÌO±7Áz)d„c)tÖ©yººWh×äY_55zl ø@Rß ÍË,¡€"q¾lQg±x2¤\uxÔ~zã_[š¾M k>Ùçàð¸¤qäOËV?Ûfe'’zGÙnÝ%èïÁ§n¨…BÃ’r…àˆA‡`b@5鯰”aÊÞ€fìQSš_>?TÕÈt¯K”¤8‚pç&ÒI~†,Á¼¡aTÝWÙn÷rÂe¯–ºb2¢Ás‘­ˈš¢ùÓ<\/"¥òk<œÓúÅžôæ­$pšJ§":Hjq’Á¡Dèp¯Zež|º¼B@ãˆð$ØVu§ù%“tH¤||Æ.ÔfI! € öÛuÙfÊãwp1½ûPN`Ï çéšÂŒûwŠî‹ìJeK ç6I0 sîhzlZ“lDꘌ؆.ÂÀHbN]Ú•8îK§·föû& ™R{l¬n@ƒvw$øÎµ—òª4'çXJìwú"Ì%ûè飘P/)£hÏ‹\ó¡ïàû©¾kJ žÓ@ûpöÕ®lÿÑTüøpîðýðÓÚw†ÁIiôµŠcòÁÖ°”Ê Xs ÍÏXŠñV:ˆ¥ôªÞhÕ®ç !q:ÕçfI%Å"–AÙÂJAzcáKøºE ‚xN(œÂd@ëÃÇöi¾à“x^-9ð€Ý4¸€à”Á_yÑÍDÒ ãF¤ÇôˆÃf\©wU׿ßopù:©@‘õÙ¼'QìË”YÞ ?ö|3ð!åpl¼þÎ"QÇää¯Óô>ÀI!Ølžã^uð&f„M•A»F›ƒ·0KüÑ)ŽÖê )·S« € 0™8蔢µa{*“‡Î7uU$®Ä~˜!á¦$©tÌSfí¦o²˜™H§5än]TÃì¹êmÇLè‰Ö_K‡Ìö¼ˆ "6iù Û³.ÇÜ·QdŒ!ÉÎvD³é3×,ÛÊ5°%7Ãõö¤FoîÛmP‚{BÄxøÉ …‘ÆY]ŒŒ}‡ 2¦J,¡ZÛë™3–ÂâïÞàùat"'N‚ìÕ‰òÚ%=¾UƒByÓ¶ ~æœÃÄD>:)pHi:)œ–ìD{öY½j0@läÅHça»ÉH·ß®ÏZ÷ÃjÐbïØ”À$2§µ7Cco 0oŽâgÿÃ$~u{{s;Ÿ#áÎõ<›?ËXßZ$ðÙ¥Hkº¾¡AÕÍtË„½þ©íe²>*´o˜¸¡mÑàØëÅ݈qÐTýðçÅo ¨·ÎüV c:¯Éy`c»¹ÒÛvÂT xò+´(wCuå ´_ý#zµZü¯ÿ©»÷Èendstream endobj 890 0 obj 1385 endobj 894 0 obj <> stream xœWms£6þî_¡oÅ™ ¢$˜~ë]nšö:isnû!×aÈ6-†”—Üåßw%!À˜¤xÆ1Ú]í˳Ï.ÿ è¿á;;m¾½—èÐntØü³!æ _Ù }¿Û0´Ë@ŠPŸÝ~c5 ¢"ÆŒ#ÉÚ6žO¶»¿À ŠãXh¹]¾ñbŠ|}&âÁ„O C~(ÌyQu(ÿ’6ûä º$+TRTûú³§uh„#ä®9àüeã½7Âï …@øZ‹iúîñô·ª-•ÊÑÕãK§Z0™áo6”`1ütJË]=«¦-êJ wjì˜6èê*í'UuªÑ‡ëwdu®’´„_Z2Ù§YWqwÉ —§]º*gâœ,ÿ–{tÕ¨®oª$ÍóFµmÒ¨CÑ‚IÓ—&6ã—|-ª¢+Ò¢m»¦Ï:ˆ¨}Ýë5é¤TÕ¡;®$ê¦ij¸Bé¯ÏÛï@À·Õ¡¶Ìk%ü¼ ?b'$8à±E7ÿêŠ=5Å)mŠòíáš[ï*-ýRi >à52ÈbóHÈz6‡ÒšC‚ †³òv‚#Ç, †K=myo°EqÈB÷8ÍN€þHÀú<‚«wÕ­Qñ9§ƒ’¶9jû,ƒ"íûò²¥k°'Å\òÁäû?’÷Oî~ZäHDìäW•£VuKSœb×_g_ØŠŽ'[]º£BUzT ª÷Èh¢¢2±± Æ’ ¸J¤‰Më<ÕÆ‡VÒ?÷MzÍVÔ˜’éÇïno ô'€«n˜ì›Ç‡â¬ˆŒs,øY ƒ‹úUËÜíu¹s°ˆ×gBb„.ˆ/WmÖOÐg[à€„Ò»Þþ¹ûqn; 1‘¡»yÈ¢ÄBD ê3-a¥ðnò{ЄCa2öàAÐ5DÞ ý–ÄP‚Ø+T™·(mÊ‹Ò@ïÒ¿·$ð䯩O&Sp7Ò·øQù5z.R}b\öcŽ¥vÔÁÏ”ç©.4¦[4”7BSöNhïb$!€M[°K–îš)€5s™^2£˜Ñˆœùæþþî~Q(ÆC¡<À‰!-¤; ÄÃC"ÃÀ µ=ŸI­tš†¼Ç(×¶¹À\=ܼ œ\}qÎ8lœÎÀT6kkSÇèkíræ’¼2n¬>*Ïÿ’-ç(µöw0̸tW¡F®!ˆ‡rÌ÷ªÛ+T ]–­Î:!1e$É! p‹/ào&〣;ƒ#'D€³&@Tjν2¦˜+¡šìtGàý}_±Ä5ø~ÝkFYô?Ð'ú<Ãè>Η”Cê#ë‰ñg}SÖYjØÌ6T®ûéñeICý˜„UØü_R8‰k¡BeçÚSËÛܙ˳MiÃyð¾Ö[pL™ðöi“H*°`.šj ƒõïoL|ôbÇF:&;³ƒ=ŽIˆ¨± ÷Gc—~-¶ ªÉxèµóëÁ²Œ¥«cd7±³p¬5‚ŸtŒ±¶Œ%–$žŒgMGUT&O%,;o—ºˆòY%ôvµ,L J.S[ˆa*Í‘7§ îIùšÚm[žvk­Ûøi|D…EÚ|}ªQ])tê!´cz¾ÙèvuF@…3«ò¬P?v‡ˆI츼Uùr+¦ÑM¼å·äÆ;«R7Ü üd$ê¸fZ`•–o¡‚ …R3âLm¬ Ê">'•VEu€ jÈ ±0äðÐ<# -_gYªWv˜v/¨o•Y½ݸí;-S]W*}š/§ž13^{r`êP/†—3FlVåĬMk“Æi¾1i.¬,_s†ò!„æó×›ù¢_÷1ÒÎFδØÃ)¬ñoN£×v÷׃+G°aѷ犄q èÚ\9gIŒ£! ,à__xãq)™â_˜”¡±ãÖ]KLL†ºy –…˜°œ>©€ç‹Ñ_ìf¥Ù'5Ì1®Ì_ŽEv4ÛœfxëÓÒ.Åhþ65,ƹ¹2°f<Œ¢é";o¡3ʶ÷á…‡1A>·±Ü«ioczqë3›bçý†©DðäçôAµÈ¤-a—þ?_Úov›_áï_;aW´endstream endobj 895 0 obj 1596 endobj 899 0 obj <> stream xœ¥XkoÛÊý®_±ß.eX,w—OôSŠ8mÚ››ÖzQÄ…@K+‰½©”ô×÷̾HÑŠÝ¢°aYÜåì¼Î™™ýÆ¢³ˆ~ìçú8ûÝ}ÆvÝ,b»Ù·׋Ì~¬ìË™dË5vqÁð»ÜÎÌ›œ‰´eÌ2™²åq,ø|ù/ˆÁf.¢Hißr3 É´…±“T¯ß4çþ j»Å’Ä!O +# ³´`ËçÙ× oX¿W /ìúý-«jöø½WÝ-k¶zaÛ–G…Ç]ßž×}ÕÔ]8ÇIq2øØ³Võç¶îæÿ\þy¬‘(xK§òû_WïþûêîþþóýD¯…Œ“0e ÓNp šš©¶mZÚ^˜§ëYÌÃ$/r+5üH‹©[äô_äŽìµQ(íÜ[˜µ…€}ˆzbj*ƒg©°2ÚvAÂ/X›/ƒ é 11ù—Ï«»_–÷ÿ¸0cüÈ[³ô‡‰’Ró|ðÈžÂЫºgUǶòphœòÆÈ>­¸çÃ…ý96 wTó<¶K¦±SzqPö-žÛÄ“iä¬~RÃk<ä±gNŠE¦iâ"…I¦Õ^#eÎGÕvìPýF;¥^YÏÒ Úú¬VåÆ-´d˜ 9ÿ\GË0ÏxáB´]lÎÇ“jÉ#§ÒY«s˜’¹k½[z™ç@@.œW“ŒkõÊn¤Ùro2A†\Æ%nÓQ›ö;;5£§LÜ[«·A…ÇY(eâÔ45”º à çÍã¹ëYÝôìQ±õ¾¬wjÃÊzCfµŠBµ}UïÈàm«ThDå @x*X€23–ŠD+‡ìDÐ8ÓêCùÄçÃW¸·Ý®vª_m7jUÕÛ¹HÂ(Ê’ YþoWíœga‘ã‹Ú=s‡zf'w!´d|K Í,÷U§Ó·ÝÎy" ʵ¶§;W}ùx@˜š–½×":‘)Ø ’J¸œþõÝy˜$ÂéÿA°Ç9À œ{ë%HÞqÀ“ßdÜ+ØV^Z6.§ tR˜Ô­mF-йÓ*IÃ,âu­/æþƒ Ù¥&™‘ Pþо10‚wb—VÁf„â vr’A¼ˆCç§pZÌ¢ ŠÉUBÊ¥?$ˆÎ½*ïõæÄi£n5¢°ð³[øSy@Á 8®ÖÍá|¬oç?¹µw›MËNkþvV4ZûRíjdøM³ÝvP¤UõTÖý•P«ÂËíª>(`zêMÛ<¯NëÑã;ª*ìF—‡ùï±°0vï¼ârñ—^G Y2ºZ’ (ˆŠËºðù/IyF2³|¤ iè“ »¦BnâO·ÁÔÓô@MñŠŠ05Òuù¯›zñoÕ6¬2¿1ç±H"‰„:$Ùz r䎲žÊqaˆDîhÛ¢‡¤¶ºV%æd&El&Å(£¾3›ZdY%J¹a•'|½ªv¦è0>nõ;1õ¹g"*ë/ØH P;¼ÁF¦ÊFñPÚ`dìï©K!=n'ÆÇi˜Q}‹kшD‘xébY==¥àâ4øRÕè€ÐY*Ø_Ö¬©ª¤‹t–0O]'šGÒPyì¹:ؾ¼ÀªŒL²ücÚhÌñúÀ†ˆ‰*}QŠ@¹FüsáýžU€¼Z—†Ï¶¢yBtî‰Çò;Ó„ˆë…dË¢ÚØßêÆtûú9f7)¤gü~RB[¸sŽQe{À™½ñ¥@‘õ[Ãó¾Zï].ÃOÙhì¶pº”êt‚aXÒ6¦Šv,+êεm²uÓ$bô›±w‹´…á^­€²§¡‚=Um†LëªWz3B,œ«×¹©aê†ihtÔx„§Vuprg|ò.:ʨm’C¸iOðâJ”6e_¶ …0:?`¤ZïÑã—ðÍB!Ôµ4‡ `N÷Q–¢lmFÄ›‡2v¼k "P.EäîÅá¼-´¯mȈ”©j¸²)ý. âÉÈs?e½Rùsʼ˜*¯ ÁØÒœJ³µñÀÑ(à%Ók=[’kK¶k›ó‰®K†pŒq84¾sH³ØbÌ€Éq2{u9Š[ä:Ó˾dÝ<ó¸º ][ÅÀ§Ã¤,þÑ~І^—°…cš9Mm·æ‚Çô .ì¦Ì‚*¸µ­p®Çl›èPÜMŽ?ßv¢ ®ž8"‰C1˜yóJa]µ£ªÔ’äËVã;•DÁ¶²JJ—…ûéÀFw%C5A#ÿáþݧ»ÕÍä|äÈ0g}5] ç'b2µsý®y\è~®ª§ýOÁ!‡êQÏ(áþ¦È\\ ^;‰~UEB¦®ŠÀI:v•7´¾2r¸&þüî…•=°|M HGü(4ãtaoâÚ°ŠÙЧÖÕ˜’ÔT êåËê€R£9èÓÇ¿~¹e§ƒ*;]ñ_Þ51ÿÅÅU%¸»êrÀq¹ñUºl×ûªWk$‹ê¦—[æm0Ï•«-ñ]máhºÞÊñ Úu¯ßo¥æ®ý^ äB#—¯`rÔÞŒ­‰1<ù„*ö‰oÓÐã!þæÝÿÝrö7üü|{bGendstream endobj 900 0 obj 2362 endobj 904 0 obj <> stream xœ½WMoÛF½ëWì-”`­÷“è©­Âm·ŽÐœB É¥ÄV&’²üúÎìr)ŠŽãœ ±¡Ý™}3óæÍèa”†?ýïìqvy‘M;cd3û4ãöô¿²GòÓj&É*ƒ[\ø·*fÎ’&T*ɬgÁ’ÏWÿ€¸ÌM’ï­òY(²Ä#p‘ô.–‚K²Ô¡=/«ŽäÇ´)ÖÓ­‹Ü¬Ëª¨×EݬÓÝnݘMû1@"¦1Yre­®¬ÅÛܰ¸Àc >B ˨ÏRcºCSµ“D©˜ê%ý«¿ÖWïþ\ßþ6ñ3ÊdÔç’/Àëê8 Ò*'­é¦N—2æTI=äò”‡‰ãH;ŸÌºƒxH·5¤©ñš¥…RTjÑÃ;¶'„TÊþóû`o²²˜óX¡yPšœ<|žÿ½úu J‡Tqá93®Ü4Ø„*ïØ#z{uMZ÷Š€\p®^x^ ŠõöTjZNÃþâÑR Eµ/²¤±P˜Šû`¯q p·lIWW?—ŸÃδ±å&«ó²Ú ;2s® ƒM Á5íÙ”åz2ÆÜI•@9}RŸ,Äн ‰å”«ØÇ_¥û¹cjdOÖM?Ð&±Ofº;:å€bð ;õÓK+F&- è´"iÓ¤ŸI]¸/H]·I³-ÆŠ]IšDáɾO  \5Æ…­ZYM«–0%¼ÚuÝZ:gò¤™çG@W'B*è í©/’­°LbÊYäÖqq VÅÚÃÎêªKË *¿m 0¡3-¨Ü”mœëpÀJPŸgXÄÊ'HÅÒ½~Ü–ðtnªº3í˜<,`<ͲI[cL½£’Ð1UʇGÂV­Û¦übB‡PÐÉä„´. PŽ©„TD<ñì{ް†J*èr™hnñ ÐÈð:P'ŸæjÉ%ˆâ 9€€¬íÌSZMÑp)©–±ÎÒôÄ÷¡/¿˜¦&eá¡Å:vÐàà&èÛ·ŸU4ž Bøš=¥'qÊN=}%Œy¦³RÓ$T£¾:#€_Ly-:Éo én³¦Üwe]aLç/&`¢”ÇèfØÄ­’TŒî ¯@õ½3m X$@"õÍy&’ØÏ³ë»»Û»‰³fã@Hi5ÛÊNqt`Œ7ìÃ&ýš“é&g ‰fnϺ2‡ ¹\ä›Ååh¯ƒ¬…£k¸ø].Ê ŸÀ{oÜÛ«Å}á¶(Èbó›±àr@ÞĤ¼t-+Ï®½¸úØp¶r*ûìÞV¤=d™i§ aifb<ʾêAí@—´Ð^{ûö²ªKy’H‡–=»Æpï5Cá!,/jX|zm_*`T›ã9kÛe¸X“}Ú¶v&£fÇÚúLèu/ô`Qv-ùùæÚ±Î5YpÓ¯oÎÖÚV¼.ãeï¼÷ɨÍa©tÏ )ƒ‰ël`²XÿO8Ü@G(`fwÆÜIă\SIºßïÊ,ÅŠµdWþ‹ ˜ œ<¶#T8‡Õ-ĸ-Š~Óæ| Ôq4¯ àðæÎ·)òÃãž·ÆRtKŽsŽÛWÃ÷;2÷ v0Dê— x‹ÇÏ8â ”e@‹€ò·–'°Ÿü¨—ä;ñÕž8ɇÿÐöÎ _M þÑ-Oy9ûN OÞÃ+˜à'ëˆÃÚêÍ_ýn{½šý?ÿMžendstream endobj 905 0 obj 1533 endobj 909 0 obj <> stream xœ•X]oÛ8}÷¯à[å`̈"EIا4Iw½HÛÝŒ§ YŠM;ÚÚRF²cd~ýžËYq“™Y$°‰¼¼çž{èßXÌ‹éÏ/¶£óÛŒ­»QÌÖ£ßF¾dþk±eïg#Éf ¬ Ãÿl5r;KtÁ¥b™Ôl¶E1žýf°X$¼(4­›-GQ‘² ½‚‰Â›˜$B²Iªé}Æñè0ŠªzÇ–‡²]Í•™wf±«šzÞ¬VÙÝEd ÉyÎ&BÑ.¡¸²Û®ì–+s¿_³ó³åýúìü'ZLËnÜ–ã²ËÊ`QUÓ´îù{ÍξùŸW+v6žˆ<Ž£ó3rÐÊÿÌþŒ\·mÓ²32m{v~7þì¼|gè˽$nâHlZ—Ij]û\³n¿X˜®;ÉRŠüƉÏâÛ©¹û}} ÁS·¿E­ÙíÛºc»Ãøò0.Pœ,ÕÙÛTµaÞ kV6L¡%Ï•òçÒd¢r‰P›¸¨YY³p‹=–]g–¬ª¹­ULé¦;æw©¡)ÍušþŒ«¯ó«›/óëÛÛÏ·'±äW!ÊÖVu¬¬™Mò8My,RqëûDHÍc«Ïr–Kë)<Á6€ÌÔK¸¹kؽa{òøþ™•›jQR:¶©¾“ [Bs’ [rç«YÚlà‘})4¢/Ò¡<ö’˜ ¡p¶TÕr¿}d‡cËþÀcó8.ò¨DÀ¯Ç–Z‘ºˆ’g‰üEÞ¿!ñãD¡‰²êPÕ1/”tÎͨB›M3NP8Ñ¡c äv¿5mG1â ²Í<ˆîˆL[—Z±©îU FÆ4À™NqïÆŒüdÖO—Ò}WÕk[¡°ÍçMÓ™ÝHg½³Myg>þÖУ‚  Ä­å; ™ve‹$ Wa¤3/ÞIÿ®@»]ÛÔëÍ3jiVÀ)PÖ¸j¢–¹U¡¹Š}PÑ“=â$Z¿sG+Ðr®û޼ó.G¬J.]ÇP4wcΦÖ…î—Eª }©»‡f¿YR/•;¶1e·c%Z¨lÇ"#žÁñ†žPÒëýöî¢Ü­A‘[ðDÁ-90,ìéëªÛXªÚî½x?E«Åƒ«-ºKö¥EÆÊÑ|ÕùÎÆ ÄEl:¦ýÀ jEèVBüš¿4óª^5s,ž;¤:Ë|Ï[û;kIÀÀ;Ö,ç…>mMG±y®^?}1÷ÕÉ•ˆÖ3¹Ú× Ç?ÀsB–EMû jM»ykâºX{®C롵QT‹0ÅfÕ6ð°1l“m÷( ³ÁœAFJ—ÖmÙ~wg¥Y„Ú> stream xœµXMsÛ6½ëWàfª¢ÄA²=9¶3mÇIÛDMrGCIÄ–"’²ÇýõÝ’’Ù“IFËØÝ·»ïþLÊH€¯ö}±ýø>"ëzõè󈙇¤}[lÉëÉHɬ'ð3YìJF¸J¨$ŠL¶#ÏgãÉ?° 3N“D¡Ýd9òE||äs&ˆ*ü’I*£ˆLF^ºÛUå®ÊÒFç$-–dUVd›¸†EÖöT1å,i÷|L;g<¦q¶Î̾ ÷zÕb“5zÑì+]“;o>f „ż}CÀã<ƒ»¢lÈÛ_ÿøp7ÿ=ùmä³YŒ|–D4à’øL‡×Ÿúìªo™½yùöfö×»ë›7¿¾»¹ž}4a‹°“± À\šT/oIVCŠd3©uÓdÅššuRQærÁu¡Y÷®lôO¸N§UžéŠÔ;ç°ˆ”+ƒ¬8m´Soù0†dãXziµš‹ÙªJ·zVís=ËŠ¬IóÙ½I™IĵM‡QÖºLó½¾óîÆpÝdyNêýnWV^’Ôä®V¶H‚ H±ÛBÚ¤ ýŠÀžë´Öd±I‹µ¶€ Îh(•‹<0Λ’ìÁ®ÙhRhô`ZPP·À?,ú‚(pÀ]Eʪ‚¢Cm Hn‰t¡‡“¶‡ýÊËÀ-·‹®§_ÒÜ&±ÜŽÄ/€—!z!»ðZÏ÷k²œ¯_/FJÒ¸ï›ncbWŒ6³F½Ät¨MÁ!WœÆ1ïzþDì`—Ú wö2¤Ý$âNG@pAUÔz?°p~DböîÜÛÖI¤I fÇŒŽˆMTWRØ´¯ƒºpl­Á¡øf“ÕG±…rH#€î1’*× ]¸`²ÿp2Cˆ¦\צú~ÑsÉ]ͧÞXí‹E“•©4Ea³ÚUzÌa‚îÝgå¾,Íǘaêœ/|‚Q²Ä>¹óšô_½$ •1­ªr‹{šnä&d@þ’Ôê¦Ú»·] Rlb¡BBB"BKA¹]MYD–hr ÞxêuÚb•° ›w§ Äwë[ÔŠ,Ž^&ä²Û@´ô±)÷ù²-ø¤:(DX}’eö˜\@DC%¿8êyÆ•°Zt| •$GúpFA‡ÞÃâj¿8Ëìf¾7«œ~¯¡1 “0a΀mÉEÏápŒ(|ó6}$pLgÝ €áϱÌóÿ º™Œþ„×ÿ6hþºendstream endobj 915 0 obj 1686 endobj 919 0 obj <> stream xœ­X[oã6~÷¯àÛÊ‹˜I‰±Oi“`gÑÐÔ»ó0Y²DÛjeÉ£KÜô×÷^$ÙÉLóPd€Ø#êÜÏ÷}ÌRFBüq¿óãâ»Ç„ì»EHö‹/ f÷+?’ï× AÖ9œbœÀ¿õnaßd„KEED!Éú¸Vl¹þÌÀaÆ©RÏ­‹E ²ÂGß=¦„ ´°âð{+|,(Éú¼$åŒ2E <s žZ ŸƒsÖî6î7»6;êÍPz·äzáAYëbó¼Tð-T*ȪA?OËåÿ×ÿ™‡½ò6WÜX Ñëç`}(;’UU³ä1 ØçŽäMÝ GÝv¤oø%ýA“z8nuKšùvêôP4«V/Ä‘Bû²ëukÜBv,2N(K˜Iï|Ð5¹ÃÜDB#™pŸÛ§ÍËD@ôipëRcÊЧ†&YSî+‚fmø˜- 0¤æ¤Û¬/›š.W1DÅ|ÿBÐ ØKUăl¨zRöæì7S3©B۵͑Tå¶8w\BDiäZå§Œ}…ŠÊÔ§ÇÁ‡í^V`Ô¶šhK.b8ë î>moºßü÷ãÝýÇ÷w›ÿÝþˆo¤ÖÊåÅ)õÞéÓd)8›*÷Àu ÚUhÒš¡*\·°§§SÛœÚ2ëuõ‚8‹i"ü»76®ÆV™* Ù_c^ÉÆ`Bõ<'L´/ë=½ò³aJcî§<¸3»óï¬ÚáALõÇEP\-T;Tn«ìÄÙ²¯Þéí°'Åv³üÇBFtlþÌ4±o,ÿeŠj {è}®`]/sç)̸tÙ ÃGlر³þlP꣸0´tU .iǾåϳÞOÄѶoKfŒ»Ai’HŸ,£\r»r—8€»Ý‡ÿÈz¿—»äá„n_Ì™;‹¡Wé% D—````/¶8g^_ù÷/ÙT{ ¸!vŸS <³þ'Ÿ&»¡Îñ ä“[»ð!pDDÆyð\6C%7ßCnAçØP!¡k[ìùÌŸl¬S$]_ÆxFr=˜5R;D©+QÃxÕÆUÄÀ±—9èúv0{ø´¤—ä#,Â%í@a ˜î¯±ts“E»d ‚&t×mºò÷q Âïk¾y“j2Øò“¦\zÈW΂Áp " Â}Êa’à²LSkrÈ `4Û_ŽO«MYÍÀxþXèÁ&ôÒ8±;7÷g2&E£;R7=@dŸÌØq›G59m CÕ $¶µ¨€ýÚûMYï³t!tQu%TD¥œ"Ìž'Ä…½L“1ÊT¤®,e•m+eÜ›2šVÝIç%ˆ…ÈXÈ}+ òÆrŸðyèôn¨¨­€PŠN…`4ôœ<˜h…õmäÎ †Z}¡ƒ<ÿa¤¦ÁïÙñTçrG,ì„L¨¼EC:¬¹¯v€|®‹¦§„b &`élÝχ¦C(ʪËFA:làd[ö®‚Á›8¢¬\è±ùhž3TB2tûBÚ¬õ0ã^W¬ì‡ [æ¨k`ÆÑÃ/GvØ-Ë<›Š77kZ¨÷±ü.æyÛËkÎe,8Α!^qŽda¼É9’¥ß¦Éýø£i×läžv}ŸÍv2ß81»èº¡Rš¨xRb‚9;óDcÕÌ·[1aG3¢|èç™ AŸYŠ‘é²ô-ÖÀ:ËiŠé­Ülç²(œ =`Rõ-Š@dÆü[µbÆÕ¨ö„#Úšü¡[ Bñ þû< bϹì ‘ë2^‚Ui-»{]øM±“Œ«û^œ¸o éç\锸‘ܯB°«‰83jÔ‘/H:h¸ûïoÐ$„Ê”ú;hRÆoÐ$û*MîQà¡Ü^¤’8h6³ÏíÆRg _ô^¼5¹”3h*kh½m"PÙÜ´­ÊÞ?Îú#8*;† e±×Пn§ù„‚Žƒ÷øÀ Þ_*-<"­ãŠ@ý!úÁb¾{ÂðÓx!èÛ9=Åj¼¦qÛfƒr©£:wFNYÛ—ùPe­Áq›ÈMf4h¹î@QÄ"ï#J.5ÖG˜c»÷š€’4QGx Åà¢Ù­îöy^&b>™´—Ö²ˆ¯ˆu è¨FÑæo»së€|l4~ÓÍ!… åk¥aÎF¦T&l„¹«)‚á™Ég;»qDÄ„é—ÁŽÙêÊ`A¬Ì÷ìì¦Æ^jó · ~°‹ ÷ªªÌ3/ö \¬PHÀ~·¥v¸i•K"$G/]C£>‚gÀ˜ù%uÒQèËŽ€mýL½Û[fcD^îÈÎ'¨À…Oð|µã0yb¬²™üMÞTñžÃû|«DB<áñ«`Ria.0c™Ù{ô5bÃnŒƒœrhÊ8Ýëâ jà"Ž H7žøÚöBrË ·ò¨A£¸?OP–X“‹ÊÕ´V°ŽzêÅEêM°+ÇÐgc+à‹I0/uÝcƒ1$7މœ_ñßœF8¼±1`¼ºìì>Át§²¾Ä,a‰@F 'sC4¡sØ–$Œ./mXÌÁ¿ŽáéÖM1ˆ”U X8 ‚{öSWcY° ðå§ì…ð³ñ¯,aTäÿ—¸»_/~†Ÿ?ýÛm¤endstream endobj 920 0 obj 2079 endobj 924 0 obj <> stream xœYÙrÛÈ}×Wô›A—ÙÓ –Fò¤Œ¤Ä<‘8ãT‰)‚2$ ¤XÎ×çô ÒÈSR‰–z»Ë¹çžn%ŒrÂô—û,wg?Üdä¡?cäáìë7ƒÄ}”;ò·Å™$‹³¸ ø^lÎìJNDšS“L¦d±;‹æ|¶ø/¶Ád.hž§zÞb}åŠÌõ¶ÈÝsÁ%™'©¯›=Y‹n³z¨ö«ÍºZÕͦ]mÚnÕUréÅBQlÃc³âÂ̾ZW³?èa=ðÉü£ØnȾ¸ßV«²Ýv͇Ù;?v¾^wä©ÄÎ_U¿¯Öz,£°êè§ÜîŠí–¼.¶‡jµÿöTé)l<¡~hª5yßn6=,îªmõ\4ûÑ)~ì¯qH·j»W†Ýpô~Û–¿¯¶•1UpšŽŽûeß‘÷vÂÓ¾ÓxLãÑãÓû®=®žÊ—î\v]‹áJ,gÅø(—sWa2e}¼­*Rlû–ì+ÒTE·ýFêuÕìë²Ø’Í¡)÷uÛLÊ£)€`3þF6W÷Ëh9s«½BH˜l×Ò)Tb&©ÂÖÎÈ·6mkžÒXxújèš~rDÌhž¸_VŸ~[}þçdŸLèmœ‘1M…ÉÐ]Ô6¤?”eÕ÷t6W*¡±J£{‚¼ö³ÿ,~:qEŠœ*&ŽG›‡Ò4Ïíq’Æ™I;%mS‘v£gÏÕ•Wž%9ea.Ê0GN|\W—ÿþåfõùêêörA–[Î> S:"¦"qÓî¢/vâo3.cš«<:ÿäV-#ŽEÆ©p6ð£Œx(Í×çŒ&,7NØýõËÛÛŸ¯—‘XÎ j­ÉÜ$vFc0’rÊâØ‘ —a?Ø7ÞL.g”|6øäI ‚òz·^€‹£Ö²!#cÖ˜¤$TäÂí&¨Ê¹EÀîÐïÉ}¥3Nö¶jºjÆÊxœF¶þ êÿí†EaФˆ€Û»k'ës»y&RʘôÉ¥×Ct3š$‰çØvo. 2b¸Ä¯)Xl¾b8̃Ãï:7Ì•ϨÌ÷K«‡á8Ny¬ÈÀw‘1öÍ€«4E®nξ\ÝêCyŠýz9š'aâ¯×—W¯//ÂlifS‹3®hëŠAM¯ØL‰H £ž ,z¬ç™ÐJU¤W9Ûr‘yÔkE/hþbmBxéøqá–­}ÕŸ(ÔÔÃ6šöŒ‰™5#yê-œš¶™ÿ¯êZRoŒÑ¨}¡¡%D¤7"uOô^¡*M®®ÓèŽ|.ÆIdBy[ÐvAœ°­©0F™ ¸9`È,A€Ó€—þ©*mÐ9bo*wý¨FW»ÿ6HqˆÀ¸÷N+ŒQåAÛ¬‰­B2œˆñd`¸˜çPá}«¬Ír¥|ÈÛn&5 T9ª“¼S‰3^›ðÑ»º¸ôV „å±·iÒ8ú\¬|µ£}™¨Û ËÓ®E}Ë¢õ$é'qý/1¤p¬¹2ÏâÑ#`Q}åØ V™Ï*ìD g1Åüø‰d™†*ð2w†ŽƒíJÇrÉ …Œ”†Ó\À8~‘¾}Ž襙 o‰àÇ+=”T‰‡à]t¾úñó'‰DsMx˜&ÑB;‡ï¢ñÅÀ7ŰŒ®Q©Ýa ÓûŒ–±dq죤À©âB2ô4 ð¤0𵞦(MÀê¥ó›+ùƒ ë¶<ì ’z#`æ~¢c AS[Ô@­ÕÍÈòÌP»y†Öî±½&§üçæ —ëÖ¢Q€,§Šcc»;×Ls @Ýä±GÃùˆB@E™jDCˆyjbÁàúÝC}ÒV °Ä Qž-.Í’ÓÎõ'€N2 йZ¶‹"…¢ä±Ý†€>Á4ƒˆ”GÏu{èuˆ]z_}çUqМCß=QkIvB}oˆBõëÜüa.cîXH›û›€Ù„oн_8Š-Èøû$®?U8ð’ñùïµÐW*|ebG§itz¡Ë¥¦"– bö-æPhkÊC%Ó Ðá1‡—NƒP²BÊJ%®Ë„ ®QÊOb6wçx“þ(jZŒÚð?½@©ËüOô…nÁ¼»‹œ±Jyc©=°Ômi;] æ¥8. »8ŠkIæµä2ºyåxŠc2¿ymÛë\ê[úP¼–³Àz–¦(hQËL}}ËýÚ/çcÂKB[y•éÐ.y·K$ÕzM²€õ¸Ûc¦ñ¥%ööe½Òæûþ9! žKs¿“…†Ÿ²Å]Ô<Í„Òc2*ŸMŒÑúš%YH¶YêÙN+ K` .iú‚RÔDzŸ$+“ x.rí±êp–ŸZµŽÄ ¹‘„Ö½UIðû9ÿ‡A…©ÄŠk0Nᵇà[}-zAîc°pP¦ ÷ïÌÚ÷-G¸¶ ¨ K7âŒæid\–æþ>1vÆ ÝØ ]GäLü‘/<¡+òmÝ”ÎCã٠߸kU»¶«°‡Ö¸T?•¶Qâš'™¯"=Y Ø1|õXœ wÌÐXÁ+–Ú€Zâ/VÒ•‘d>½íÑBÚì]ê×9èãþ8ÆY¬ò¦ÔûÇу >»ºê?˜hz$}W|#G{—†Öa¾19ºw„ñÐìàäÙïMkM3]a4ãÞ´ã¨9E †ÐïD0câ˜É±(e<ªÁçñ±.C{“Rýòf.²†jõÝfWÔ£2Ž(f"è2(,i#rhJ¤ñ¡ZSrSé{¾ñžúîü$LE¾÷Nô‘çºÛBÃîÄŒè?oºb§™ ö솲vÛ…¨)[šñ¡:z͇z5 ¥ã¦f^j ƒ2snY¦õ‹èØK'i\û:·*’þP>Z23î³ýïóG$4§A+‹™äZgIÌ^d~VÂ?oÙ‹t¼LúÜdÂæfë›!ƒÐÛqêA+Ã,AýÆò÷‰ÄKÆÏÚfÑDã5CW>yAÏø¶ïÜqRSã-šº N˜fc«]€&Ãó˜9·8€“µyº{„–|èÚÓÖC>옧ú¡Ç•æîÂãªíÏ"”]Ù>ÒN Í?÷‰t4è¨K*O{÷—õÛ6Éc(> stream xœÅXÛrÛÈ}çWÌ[@—9;\óæDR•SÎz#³Ö©²R,ˆRH@‚@i•¯Ïé¹$$Gû””UEzúrÎén~g‚K&èŸÿ½ÞÏ~ºÍØ®› ¶›}ŸIû!ó¿Ö{ö§åL³å§¤bøYngîIÉTZp³L§l¹ŸE 9_þfpX*^)[nfQQ°}´PR³E’Ú7?né-X-‚Ug”òϼ{,ë“YõÏGãÏ…ÛsÅý¡oÑCÙ±þÁ°Ç¹Šy‘'yDO±«¹*ÈX}]]ÿý—ÛÕ¯s©é@}ø´ú|sóåzÉî"y7§§œÿcù—Ù"N¸$2&ë’ ŸfÑò¡êØSU×ìÞ°—Á¡,ç:ƒïÎÛ²^56¸¡S1ø·íLýŒ{ÚSg;ÖͺÚÎ%ù'£ÊlXu°!\9'$c›ÁTqÄ:û_?Œ©Íy’„,ÝÞèŸÛ4ëÓÞzXo&I]¨\s=Ľk¶äÓª5µy,ý$·R‰3.y‘Pøß¢ú¡9°›¶áóE ÷â"Ej [—õúT—}…‘¨jW*¼Éú†"sq N(Y#@wEpèêëYÁSí#S\‹Ø&ßp¨™@.Ï/|ªú‡)Šœ+R÷;"Np•;Œá{ WÁ•­ÅBkT;³x¢Ïcž K )y6=êû1"T3ÒiO#"‹W ÞÒÂCˆŒ9´Y·¦;Õ}uØY¬Å<Ø$‡ƒ•Ã~¹îOe=ÉAšðL‹@À¾¼¯ÍjÝÔ§ýÁG6åt!¹Bx,ÏC*†Èµ»¨-qo‹ËK ]Gí<ãéHáSn6ˆäÁy˜š±\˜ûò™€µmN‡ÍÝœ{æl¡Äÿ^$è¿ë/_>~þù…6œ3*V21¬iW÷u³þת6‡)ÈÁó Ú¾ôăž& íú’ƒûçÞt¬ÙBk¬Eæ´e!÷lÈ1×yn í;iŸ-ðÌ•;ì…$‡ªü|ƒ’03—ÈOÚüv¤ªY>;q²nði*¤.x¬wÞ¹è};‰>Kàh¤r úØTŽŽ _ââLy“ÂVöãõ”¨åΠô2°/Çø2^ ô’î¸cߺ9tÌ/6†uͩޜӂzÅ æœ )IR d({sæ`V3Në’Ÿ*ýªØåEÎÔ‡Û›……°†¬æqðYŽFC=8#ÁuâÀÿ_p §Á²è±jNPOUS¹@†GÃy1j òX¬µä2›¸uÀÈsíª®GÞÎi‹fáz$~Ê— R”æoã:™¿)=ƒà]tíÛ§—…QGûHÄÅñ_ôâ•Y"W.›¯tLO¼XG¿AÌëgBÒ¶i}&e†••ÓÎÎDë~ŽŽ&¤Œ£“#C‹/гå½B¥ã™ƒÀD9bÍßž?l•¦@ŒQ>Ì9­’Ó¢z«ÇS™ ‘æS4§ÐÅl§šÇ\…t½h|gå_¨ëêÑ€þ‚T>1¶_K !‹=‡ôÀô-Fè§#Ihj»"?•d…‹õ #oPÂC² H®^‘è)?.†¿4å9æm‘½jóT¶ÛÕÍj»1«ê°mVÀF£Ý´aaKÕšþÔº Ï4t7fü«¯««O¿®®oo?ßNŒ"(!VÊ宲©…dQ†•¶äËÃÆw„Š=vºDe?~¨9€3^Â.ÚSÌÓ$ :NG'ž¡‘aîHîlc‚̹VõžæÞ7ÖØÑ§9õGЫlç(™RG;?—­ T‹¹„”íï›ÓúÁ@.‰.(Ç'VÈO!ÕupSÑó?\Іã$Ðñ²Ž€ÀÝüÅX›ðÐÁ†°cÛÙ¥±²_ׯLdˈ»Ïr†uŽ`¦‹œƒØéÌ 8Ê.QŠ1åf¶¤‰â‰Vy÷‰n,Ì’_›sêã9þ0;½º·žy˜L¦}KÀØž&Al©+Q1·sRr°+*×=Ý©²êp¦´cÏŠ3.ã7 ~*Â+ƒ›bÄ›ÚÆŸ’ú âmcŸIz¥†É¼m ;ö !x0:îÍÎ2vóë%;–-Ö-´“REÀ5É$æÙH êḧ@T± Æ áÔßwu,ªP?2J—ýùÆ…TˆÌitγaýð8¸'™”£MOÔ–¶æî%&ÀP{Ý…u•Z®¸ÏßwcN°ù„*2†mžü$Eôª¤­±b£ Š$‹Ê 0”8‘F‚>jž[©íú¬h~‹}DÓü"úDBï¦ ¬ù°ð%à Û8ŽÇËoè[;HÉŽ†]hh[…vH]—Tì©"VâÔYyÄ7fÐfçñ¦a…Ä[úÌdœê¨Ž–[ÓJ¶µ—“&ÊÚV{Ó¡›VV“÷l—B³½ø>À~…¡‚ŸÛj9ÃÄ>tºh]¡#PíÉ%ÝLÉC¶^….¯Z_,À3 œÛuš šb)ëŽU?™Üí——ó ¦˜ŠÂÑÈNGÂBÏ(«Uk†á†Ü3-­ß„(Ä…ÞÝ4 ¿ q¡‡©Mõ (âh¡øã¯X 2iêð-y‘…'ßüvðz9ûþý°/W‹endstream endobj 930 0 obj 2056 endobj 934 0 obj <> stream xœ­WÛnÛF}×WÌ[)!Úr/¼¡ONl£-·•æA.Š\Êl(R!)+þûÎ^HQŒàha'6´³³3gÎÌ—PpÕ—ý™îf?~`ÛÎ\ØÎ¾Ì¨>û#ÝÁÛÕŒÃ*E+Ê¿WùÌܤÀüˆp÷aµ›9K6_ýnИ2E¾²[e3Çua©ŽÐEd],å°ô|}^TdǤÉã­ìâ<“qQåuœ×MÜÈ-7ŽºÎBÂ’ }çZÛßfÐþ:VwýÁÏI™C—lJ§uyØUoæ?ôgWYÖÀ>Eß_²íd¦Î‚q{“‡]R–°xNʃŒ»—½T&îØ ØV2ƒEç-ÆÜÈR>'U7z¥·À |¤‰«Ãî±u€©nÊ:ý—R‡Ê(ñGÏýÞ5°0û®QT12Ð9-šúïÓÑ+oëÓxJÚxW72Æóv Ä¢=lZ…DÕÙ»çPÜ4MVRýxœÿ„ç#&,MM˜®³ ‘obZ=-¨ï ½iRBWO@)%¡o òJñǹººD†2ê“ÀçÖ‰üz¢%T„0DÅuT©Üw€~¡{’PIerâù½¥sÔ Æ GJ[¦­¤™Ó¸Ôóœía‡µó¿V¿Ž“ñÐpûlÎà¶i÷!Gá§“*›À‚uw£>£³Ê¼æÈE ]ŽOEúH^77Ÿ§3-"Ñ÷ã±;!åi¸¬U)¡>Wç.ŸpzrQ\v‘[/WôªÇ© oí ô„ÿ)„ ©ç ¡sDºTº4y“ì¤i^@„àø”t}Íð1—2ßùÚaó.w1HÏ ˆ4ªu/yDèû[6FJx`hß)ò"‘ÀDYz B÷ÊŒ[Ž£GÍa>KgS¡,²PÔ•å­>Cª*+ë$²Näk…dVvŠ|ší€² ÂuÃIkÇvÉ l$ì“¶Å©‚i'-ܼ»ƒ"W bÅg£îZ;ÖëƒúïÏ9åjÆùÎÕÝÇ›7€õ¿ž³5PxÃûï¯on¹¿¹Öæ¨*׿sbçµyÄö‰¦¢Wû}‰íÑuÕBY|ÖúeNQÁ#"h4;뛀Y} ýA»ŽÉ)N€|ʳÃnÎ4•mk;Á”‡~O•?æYƒ,m5ãåYÿ…ñiÔ¿ð,/6ÝÚi^Œä«…!¢Ñ ð‰„‹Ð@œô\Þ¬üP¥ -’ùœ*°y„"‘™å VÛÒ°†Õ† ´e±}ÂeC6ø.©R|s·Ç½Å¤À1ñÐ{=G)µÕc»~H(  _Z?-…¾ÝA-™qø${ŒgßI'Ë—oFEHüa‘‡ñ ñO•rº™sl¥a€èAªj>éz? CeTI“ Ìv¦Zùk²Û—ºS1À馰d¸BèÍKui6Ýhbþ_Kƒúãñ‚Ì kCê4?h¸%¼Û7°óÌG°%“°ð“÷H)æ2zº¨í®¿þÝ?‰oV³?ðë¶®)Iendstream endobj 935 0 obj 1610 endobj 939 0 obj <> stream xœXÛrÛF}çWÌ›A•9Á\p{tÊI•wµ›Äa’+…‚ȉ„hãýú=s P²””äMôôLwŸ>§ŸIH õû»9.¾ù˜]·ÉnñyÁÌCâþlŽäÛõBõVŒü®Ë…]É3*$IDLÖÇE°âËõpcÆi–ÅÚn½]!#+ý.2çbÅ™ «(6Ï«º'ÛKÑ–ùNõy¹UyU—M^6m¾)‹¼U;‘ßßïÉ÷[E`òV;ä)MÉŠIí%–ø¼¾,œÙ»í¶%§ >«®W[³@›Þê#^ë›OÎôçcq8›åJò0 ŠÃYåý—¶ø}ý¯…”Oüþ\íjµ½!MYv8l«ꡨû·Ë7s »ÂÆm^ŸOÀ ”ó\2š ÿ[±›3¯ eÀ³YéÄ*‹™µ.MFË0´Ùü4'Mø¨{e'ÿæ_¤`h)œ‘YúûTõy¥µÔ›aôò©¡–"CVc”õð±9šÝL¯Ë˜ÊtÔ4;›è&£s&2ÓÂøæpêçªmžk HÑ,š´ÈxTÃ=²Ï¼š¼½ŸÞ¯’8äÓ«ðdqPEg´Ycð˲×Ã0¸|lNs¬jõåÕÁ@‰!nê„4%LØË)¦eY$–c¸mé˜Ú$¦#®öýñ)˜KõŸD´hüÜæ éÜøaʵë¬Ϥ|å½»é/tÍýì;ãÖz›¿Tyâ‹þž}Ë2¼èø¨væ %È ¼çæóä±}U`ßEL¾v¯üÝÿÍãëþsr= áZ­£”bDö׃ÉnÀ¸ò@yÿ[þþö×ü‡Ï<%Æ‘Ÿä0ÆËkZ¾@^åÌ5ÇmÓ ø¨TcÀ …çç1¹ÁNMq“Ä7ÿÁ½‡œ«1ùd‰_þâ˶ïÖ‹Ÿðódûb1endstream endobj 940 0 obj 1958 endobj 944 0 obj <> stream xœ¥XkoÛÈý®_1ßV ¬é<È!ù1­ ívƒê. §h’²Ø•I…¤ì¤¿¾gž¤hÙ^ p;Ù¹¯sï=w¾F9aúÇý.ºMÈC¿`äañmÁÍGâ~äÏ›…$›»¸ ø·Ù-ìIN„ʨŒH"Ù<.–k±Úü×`34˔޷)K&ÈZ™»b-¸$ëX™ïºêa;ä÷‡Êíò‚’˜Ê$¶·0óçæy±ÜµöéZ½]ÚõbÅ”C’ùܺ(š°Ä­«¢ÞéOBÒ$JÝj]•äþÇLE)iÄ#oñØvÕ·SÕU9Ó2Íhâµ¼ Ú}º¾!½'eœG^Ì¿7ÊáPE$™“³+çNœ*÷‘êOëHddÍ#½"i*"í”»å2ëf¨šÔ=ZÒUék¬§N‡ª'Z³²*Ú²nH~8ØOÕŠÇP©åC ãºþŠ<ÔFÇ50’jÊ(£Lz×>•• ÷rʽ#ï–M~\Å*¥*ËâÉ\c‚¥ØŸzgæ‡SE爈¤°Ô›¶| ¸±$õ¨8b«ó†ä]—ÿ íÎÚ|el´k}ýßêrD̦©:£±²— pïû㈨¦d—‡40r‰ —Œ¹ výå“^æÀ_꣞P 4}ÇGJ6ö\”PÅb·! ¦×“Â@Ù.IB³Èë›wÓ ˆT»ì®›Y”˜H|#)3:¦EY4„ÒÈgS°iõ¬¥A=ÜÏ”‡òǧ ³˜–C5FH>ÌQ"3(xó¼Ì•ÊYz¤Ò1Q‚«¼Ø›ˆP°˜p9@жòºé x ¿2ï¾ÞFÕçFFU¦Xv–lžZzf¥wù<­D¬¡Î‘ÚWù@ªFûÚ Æ$Ÿd¸@x;×Ìúªõ§Gèˆ/+(ûw;#Gв(òèd™´’Ÿêµ²Q(­ƒ‘(¡ xã¿ÂF{c•w‡+e[@$\2Ômƒ3VC/È©x·¼~^qXqôí¶·“Òb€$¿®èËê‡K_[Êg}𡶨ƒÛºÙµ[D ~_—_WóÊ š†£,Ø/ó¦³å" :2ëŠwYœß·ç‘# ¢4øX7Àg}²ãŸ"þ>Oœ\.GÐú¢«Î•ÆÏ ð—f©ÄˆÌ 7±r3´;Ûå3 ÒÎS„Ñ .]‹ô-§¢ÞiÇörîU£x¶‹ôóÞ˜Òx,ç׿m¯þu{s{ûåvžƒh^Lf> tæjOÕÆî®"¦h»@ÅT3‰€¦ªëÚnëÀ›8Ú¢Ÿ­7—ŸM£;u"Œ\ÿ´E>èjŸ&ÏW?a.COÓw ]èéPuSu~ÐM¤kí±ê?VJN‰¥vJ@l ÁI˜²V±íÔ²”/N…"¦ZéÖ …×ä,NÍð!´~ÿZ˜¨ZΟèúåü¸¡9è»gàöõ¶OeE>è}e>äW¶lh׺ÏÿlúúA7 ‹˜²ú~:˜Onè\3Ñ"±a*áF‡|0Q„!?Á#Fq)Ó› ÙÍ%§I&ÞÄ! @ÂÕ9 ¿ümGô”L¸‹•¶ š öÕ0¿2Æî±¿8ƒ6ðšùnk1ø²Y {úf<7×0È1p-ÐW øñyßöšß•Ž|™-ºÉÞþïõ´ã³Ø7¬™VhL2õn ñ}K#ÀËd˜I]þÏ/Lá±”…bðŠHð„NúY¥3#{rl5ƒ-u¿ ã}+ ÃC×zÃÜu6¢ÄÉHš7£[ Á¨é~t¨ôW ö%*Lß'SDD•GÚÝrÈ»¡'Ïõ°Ç µZÇhŒ C-¬“Î-15\ÄœŽÄÅ!¶8ô¦èj¦©LÝÙsŽƒ€‘C•÷iÑçÑ’ºVcsì i’Åèç•@ìZÉné7øn*C»±0’ƒ¶û¼'Mk.¯Ñ~ ѶëúŒC :Aä¦J,!ÙWÅï=yÅÀ§f,—%y¬[«u‚S–Y³ÌOeôvÚ6“„{>u¹ùD°OÍšÏ/_¶7¿lnÿ5/"HÄSn¥‡þÂÓX(#ß݃fþ%ƒ+ÛJ{ ŒÍ°–ÆÈ<„gž$s¢#§¿–%ÈÌI™¯Nè4I(¹½èP:ÀK½ß’1®FAD°+´dÛŒ3ä(ùh}d!c‡¬€ e?˜ùŽa›¦ n"}‡ÛãüîÔ†üy£Ýx_‘S”œ lvp¸Gÿþýe¡šãñô¸0QNÊ `î¨(Sç}ñ¾ª RWåƒ sC(æå3£"»LXÀÁ¥N›zG’ ¤¹l-“ $!y—$äÃöXüDÁ]aé¢ù‡È‚ûð±,;‚ ¬Ýmu¹ë0…ižðC˜|3'?Úcñbq_Ÿ-¾äVÍ‹•Ð/õ³´â¾hTbg¦…Ïûƒ†xí YÌFÔé³ “ò•‡¬µ“=Í'Àp¼³Àì1‘¡7ùôøl[›Û¥ßHdp_“O`˜òC#³Ûu•,kmÒ•&è:Æ3 `õmv!X„ðlNãræW©*¼Ò!Üó øäqCCøÍ󶪠ɠ§ªÀÕ4U[b79i×Ð13ªD¨°Ïg·“™²ÓUÔÀd_?ìIî‹öìé‚+í:_š^º–§tþ­ 5üÓõͺ½†ÅPŸ_*ùøúðڥ˃ñjï.:KâôaC­ã a sZ2)³–Â|¼µDÎáfò\)'°™LãK]_±òwðÁO#ųð"ñî£öÍfñüü9]Žendstream endobj 945 0 obj 2184 endobj 949 0 obj <> stream xœX]sÛ¸}ׯÀÛRK|gŸ²‰=M7·®ÚÎκ£¡IHbW"’ŠãþúIÉ^'cÏX6€û}ϹןID‰Ì×ð³8,~¼Kɶ[Dd»ø¼`ö ?ŠùyµdUàã߫ͽd„'’¤"!«Ã"ùrõ_ˆÁeÆi–%æÞª\‘ ¡9 9ç81ŒhÌY=.‚cSÕ½.I߇'²)õºÌûœTiõçSÕº£¢©û¼ªIÞ“½Î»ž4µ&ºîÛ'#Y8iÅBDŒfÐgÿÐKž *ƒM¿üÏê¯Î8ΨHý`§IŸ?ì5Ùå©+³ÒµWpAy ›™t6‹DY›aE¾ß“uÛ6-)vºø£#‡ü VotkL>ÕU]õU¾¯þúÐ8cˆÉ¬!)LƒDglµž ‡Ì|’þ°o§ØF4w ûS[[k‘ lHà4É Æ]yÿïõûÿZ_ßÝÝÞ }&UFÓ$óyjjëµä‘÷8°Þ9£S®¬ÑÇÙ…ÑÃ!3ŸÄKF3%ÑëF M‚£?Ý®¯?­î~»°›AžQéîV› Qçڎź٬M‘µºë/%Eµ3HŠœHpej¡'¦àê3ã˜FQª|=5K„$qz^b—R³»y=”BžDʘQ•&Vc«0OÛV@˜ÒzØ7ŤyæD¤Æxÿ˜·›õM©/Co&i2Ü2jR«¦Ô]ÑVǾi;rÖy—JxFãA…ïIs%u’Îð Niâëa5¥\Qùtî*ç¾d)!:Ч.à›S]ôUS“"¯Mä49u°íTïu×½°QÉ·¢¡(²æ }ÓöZCq«s|›pãBÈUD31f+È‹É=1ëƒÈ¡‚„æÒ¼” 1–uiíÛê~m‚º¯ºþ>¸_^Ö¤”>œîD'B¦$ÂÇI(RstŠ­æ„ÔP ¥¹s‹±9¬Býõ˜×åzÓæNèúöd£ÝÍ´{ƒCÿ>ä3ßP)¤ü–,«Ýƒ—KÇ»J“¢ÒWæØ|ôë[2“pµüÁŸü³îªmlTë½®·ýnvvc5ßÉ›7­E]®›£ ¦¹Å$•ÖdwûNÎsìò‘¿,šSÝ[ëBwÅWçL̵…ù7ï—?ÙËÎU>Ïì÷Ú§™KàM*=ô°TzèÉÉ_ªí.ÜÛ*qä '¡‘È|^¿h‡Kö™X6²Å¾Ë4£J&c ´ýÃMŽÇªÌ MÆ|ÜUÅîLq(`©rb…¯s`õ‡n6A0nØ8ÌSŒîê5Á¯:?àï@žÛ¶àÍçÒç=äþ—À%wÕi;NéàG–8?‡c;sÊ"×?«†TsàR™Ӣܕº¬ŠÜØ~* Ò©zÒ¾Hd è?ràÀc·¿8µÒÎÀ3‘T½ž YÊ'#,Iün¨$/ËÖ@âã|æ€qÓ½d#” ¶ˆ;Æ(ËJ!‡QÈ·Ï`wÔ…£M®¨d|JŒ CŽ@8sLr0´çYR/اg®¥õ·¯ò¹kg™gк´>¸.G<óý0XË#p¯Þ8ã×·XÈÑE.ðò{Y+¡Ê·Kä^=Zùä¶‚_gMIS&^ÀƒNφ…†ñEkÜÔ½‘j˜¹›LÝÜâL³É»çSAL¥øSt»T VR¾FxBÍFqâ3‹•Tø÷õ"ØH¤“lB +ão’lÁÁ9)tL< E™«ö9€’áÕ¬4è2L`::ø05ãEYpCÔ,9oÇ—fá kÁ8“qðM©Çơ˱Wº#ô›š–¾0G g|ÄÙ ë­¿=—`˜¢ÛÎÆfŒ6ule„‰P1rîóÉ5«Ë%.açíúâ±7#¼r¹Û (PômNû!ØW6#¾É„»¤Û5§}i¦¸M«u9p+ ˆO†žºªÞ^.Àj–OK¥Æ`Õ/ JfÏô¹EÕ°¡Ô* ‰µl?vmÿtÔÏš•qVo×7wo½^ÿüñöÝ/—º„4<\¿G=ëa]Bü#6.‰¤™E”oʧJŠ ‹Í‡G`9¶Ï}SokÓï+÷KGbÀiŰäú© üm»$øÔ¸eô݇k3Íž1wcWŒÙ˜ÏÌ=ùÞ˜ç<â#ÝÅ záîmÂKìéC{€ª™Æf‹(›UØèpÑn¾cwÿ`#Í.ç–a0c1OÎ'-#sÌ;3ùWõ4ý::3Êp˜p¾©¶§v µá±‘œ´|9ÔAD/Ó{"ºþšŽX60æ.™ašLv¤[2³óq¼:ÛY–eÆÕÄ …n@îfµ€­Mx¿ˆÉ@¿fa"øåW4CNS”¶Ÿ¾ý_–ëÕâïøú?Õ³endstream endobj 950 0 obj 1830 endobj 954 0 obj <> stream xœWÛrÛ6}×W`òP¶ãÂkÓ<¤¶<ãÆ‰[Uée¬Œ†"A‰‰THÊŽÛé¿w± (Ê—¤“Ll ؃ݳg/„QN˜þÓþL6ƒÓI@–õ€‘åàË€ã"i$òÓt É4]\ø;Í&’áGTº$>™nÎH §Ÿ6sA£È×û¦éÀa.é%€ˆZˆ#2ò|\¿-󔨯ñf»VõÌ9¿‹«l~®»%IËóù,W$ÉÕ‰! Ɉ»m–i*’uSí’&/‹6ècQçËB¥d­ŠÙP‡Žbÿyí7•”»¢!o{­÷éWvÇEoÔüzKŽ2ý[¹­Í¾WvøªÊŠ(ü×®ä€V©n§Ð|“b”úº‹tŽ˜ó^=@‹.¾_!”t‚ ½ì_ÚdN^bî'ä%f0¾~\|ž‘™9ü 9ÿc~~õûüúÝlH¾CJÞâdPÛÌ1_À÷?Â^“ããqdwzDvµ"6Ç›ü9:}œ×¿=² +©Š×ë2™9Z]ü‰ÉúíübòöýxþÓÕõÙ;]è«§ðžøêt.Q*¤^’Txdz7p|*8IõVOPOB»PÏ7&µTÍoŸã¯XbMâ‚\N.ÿ$õV%y¦ÃB ØímfkB²]'w«Èœá¢|þœ>¼Î;´9®>|¼º‚¶F¤)¾¥ŽQ/x@]õd¥!ƒ>X-Ú Æ“ÉõDoôæaCA¼®­ób_§OY×Of´8aÆŠ²ᔋÏ*ij³V¤Ð’õ¥‘ŸÉ¤z—¯×$^£^uŸ‘eæâIËÓ]Üïetú¼¯[q*eTB¹X(ò·ªJz !×§Ò³´^”zÍ5x›»‘°‹U±?WoÖ¡À³ããÇõý¯Ò˜¥ùß/ô³÷Á¡YÐ r`}S8x£â"/–:Ô…'©îoÇ…ÐUëÎØ,µmGmàÆì“²h˜s™áG3á4W”àØÊ¸‰p~ç&‚8Ç»hi™ì6E‡#œÀ峌·ÛužhXÆŲòÅrÎ.Ç$Þ-uxŒ†'€.mæÔ åA¹R>ðùÈfÃôé·Ú 8ª6| î« ì k¿5:e‰×;µoæ*®-×´½íàRuÛ'žK}pƒ¸ Þ¬ÝÅ*ÈU™`1è" ;y1ÃÞøë¶ò|ÍõU׺îñíœ" <_'aÂÛ ÖNåÈbdkÌhâmA^€a«j[é_´W‹õÑ–!}ž•ùmOƒœ2v 鳞˜¬Û"ôÅú‰„t í6[èz¥¾ìòÊÈ 6¹JLôºf‘mÓ}ÚwJæGQ×ÅnÆéì–KU!ˆß‚È€ÝÌöoð¦®è`{­@Ò=׃j&HM¦é =é9q¢Pßx´FˈÄt“o”i¸Ä‡hÚE¯›Ý8×…"ÛªYo`Ú›U‡Å¹ XZ¼p[·gr,/À35ð Ž(·ªBfe8t'+H`¶ªHa~@Ã×§»ÂzÆ}kz=óB£8Gôs¤ÜÉÀô†ÛÄ}—2{è`ß0´Ìk Ån³PUݙÆ£Lk¯£Fe†0pHjx¨–3Øû{ £Š¡Ôªfs›We¡Çñ¦ÂPj -ºÑ”†~Í÷eCîºÞ•»uªM2Uu^áë§)ÛG×}ö^«Û>Føàž(xÊÖy™ì¦Aöj'ÞÇ÷D0Á÷Np¸ÐmäwÿW8ž~…?ÿŠó/endstream endobj 955 0 obj 1614 endobj 959 0 obj <> stream xœ•XÛŽÛ6}÷Wð­r3âE>¦Øh»MZÃmPd C–h[©,¹’¼Îæë;Ë$+›^° Ø0Å™á™3g†ú‹„”‘ÿÜg~Z¼Z'äÐ-BrXüµ`f‘¸üD¾Ý,Ùäðãþ7û…ÝÉ’$"&›Ó"Xñåæ#˜‡§JŸܦXaDV¸ôj&ЊÃç*R¸,(ÈæºbÊ9DußäY_65îPŒŠX:;!>õ!¸/»ž|_÷º]²ˆ†!‹‚:«V•^þ±ùa±‚ƒ™xSA9„ð¨ÑœueÂc’s·V}?ÆÍ¨âÌoBû,×CìÌÄΔ¢,ø…‰ŸÓd?œ À 2¡‹–«³¨ ÊÂ8t¢s{þº—À‹³Úbɹ1°u6›  M†J ÁMjv>×£®my®»n©–&‹ÇMä³™T ^&ÕfEʽQ\ €úee" ©Q9Ò0j ¦ §¹’óÀ]Èu˜úíóP e*/…Íÿ %›8a4•zÀÅ‚‡åh˜ÀEÂi§#„QdÁrŒ„j˳ý52T6öµø؉f¡ò”¦>Ô~ˆTóÙ˜z³ ÜC²@  ÍÞ¤î¿ÆÃCNÓ(qŽ©›.–c,ÉÕ€Õd:nöKŽMñá㩵íw2 >õÏGgœɸ©†„¦C#Åv ×—ÀV§`Êìrõ ’‘ óVf¯(²Í¾ò_—ÈÆ0I‚¦ý“äMÛ꼯žÈCpÒY•jä÷Ô@ 7»°ØÁS§sYêí›Ö÷o'rèïAõ½ø2ÅÇŒI«¯×ß MâVÂ#IÎÔ?Køn%º[Â1qR .½= ¦;HôåA0EyV“¼Íº#/Ùù\•.yVUpJ{ ˜\d<Š(´A—=¸-÷D—Ø6HלôLÝŒIÝaÍd»z©ËÞBˆŽ¡ƒÒl»ò³&EiT]†¦AVöЕêÞrÍ-ø&DcüÑìÛæd9çDÅ–{$h(Tz3;ùùˆÉÔcØÂoqTµÙ%ÀcÀ‘EQ)&;@EǤ•öIZh—HÁÛ é´a–…ʆ¥‰#—¶ª‰µ#ôà2G9C4øûî©wº¿j ¦›—:ÃlŽÍ”%^1¥°ÃÃ[—{è˜ù1k³Ä v–¹“·wˆÆi×(+Ôý¬-&­>"€=v®Á4Žç[»#}û èòçŸDq`d²©°âûcÖãdP\r]Ü"ЍHú†Zi'&áLLF|èr…¡é«wT_*)Hy²/ìµu‘µŒ7Kh(JE*¸Ä Ðq+Њ… Ab7?|u ýb†à"¢*ò Ýuè™ CÏÇÃܽßÞÝÿ¶}÷ã\å|§ &wÛ{€cë¦_Œ?‘¢‘âã|m¿}·}óv³þ}>ðÀøåùÅñ›qйÁòi&'ô8‹ý};‚çceh¤ÿœu K¤34€à©qmB×…c«Í*°{¨”ÀTòè‡äì+!­ýÛjmsíEÅÁ§3üˆn÷䩹ØA ¦,Œ=q ˜¥£EÛ@MÀŸu ²‘{smÈkÇ(” ?p¨p¼¯`ÚAñ–sä%mˆÝÃþf½~·žaL–7—Ä)ÞØñ±ŒÐ\Ô•T¤éÀÊÍq>øÑãXyNÍæ´ÁúÏs‡›²t''®/ç´˜ ¸V>?§ò ‘øPfsÚ‰®ƒŸ0tlÊZ;W`å¦&UÐýøï,ƒˆ¾êq«àemz·£š™ ¢&01SœüÒbñ™/.­~išéA×—²Ö0“Gï?«.ÚÉb¿Ø¼ø`ÊrAçý”Εi(x}A‰ß¡”ºÒ@M§iw ¹¹àø©Ä+\Ù%‚"Rt#¢¿§ òzÓŽáÃ$¹k]Âà…Ã÷¾êÇQ¯ îvnú3¨½QYBVIl7LhñbBÌK ÷îbÚ~U:¥½{u1o¿7¯-€ebÐk{Ëó# Üé\:›vmI`[:ÀíÆL5poZ åAû†ÁóÇv‘Ì_ڈᕜTða<ä=ÛÙh$Cý[eÆu¸«!S˜9…IÒýþLKîI¸‡¯ðöϬ'0áøâm>ŠÑf4Íå _~ÊžŒðlÜ@HÃ4ü¯/µÞl¿Àßß &6àendstream endobj 960 0 obj 2059 endobj 964 0 obj <> stream xœÝXÛnã6}÷Wð­v±¼H$…>e‘Ýv»‹îŦ0dKvÔ:rV’äïwx•L;—¢èK‘,âÉáÌ™™3GþЦˆè÷wu7ùþZ¢M7!h3ù:¡f¹?«;ôn>áh¾‚]”!ø¯'ö$EL䘧Hræw“iÂfó¿À l¦ ç¹ÐûæådJJô˜È‰„QŽ’L˜õºéQùX´ëŦêÅrÙV7S}"“ÎÒÔl»4[.«å~ƒÊåæ\oÐKüÒoMWošªD»õº«úóÙw°ŽaÇ£ßqal£³¶ê÷-ìt—éd´-:ÛVͦ¿ÕëGKEß·‹Õnßô£å«¶Ýµè¬Ònfð|[b£aša®˜¹s~[¡õ¾Yõõ®‰`Ê3œÒ}¨ X)z´¬fΚP™báQØÔË$¥T×·›à”ØTÂÁÝZoa€±`>]Q°à£äÄo8³á•q¬ˆ»ü tÉØç ʘ÷¹ƒì˜úA7ÓW—ÕÒùŸaêoÙol^ô5iŠyl?ÜÌîö«UÕux–dœãT)S›û®j±„CÕÊ,ÄÍq¦„ŶîP[u÷àI½ÜVà»âïºÙ€Í¶²èÁ`­¤šÛº…B ðòT?™½¹|„‡ L¸¨NB—æXªPã:›:B¡¥X(Ù P?p™ ,Xc[3™l¶»•õú~,´ÐïÐò)v˜A@*çÎË)±Ã`“æ>Sµ¾¯×ÆtÊíQ,Ÿúªs%–0¥ ÈRŠÀPoÆçÃÒV™ Øj£udjD¥˜('X!χN •8eÿ ôÄ[€ÚŒç¡e¨þJk„E³¿[V-@€´¡z9ƒF"”¦Ó½Fæ(6Æ!ݾTRoÔ‡†Ñ…a\ÁqθòÝ0ªË4Ô¥ë $5”qÌÒôíz¬!I…ÏxHø®ý!&qú‘IgÑõcêÉ걆tphµ»»¯·öñ¾©{|TTÄŒ¾“Cá`îPÝËD¼8¸Ät #7>~Z\}œ_ÿqDãxIøVÑ5¦µÎP&˜‹AŒ©G³Z¦yzÌAÓ‡nP0´%ìgƾ#¸ÚR0ÏaEð(wu×iÒúqî@¯¥!at_t”j­íèÿôfSÕ”>9¡Ö#´ß„sŠç\xN÷8_]_ºŽ@Î)&Üз ëÑÚBï–öéjÂsÂÌÅï ü~‘êO~mÝ ëó³_Û­UÙ¾ä,Ç”’ÑÂNšy:í`’›*jÿh¤gΉŸÑ¯ÉèU*½KÝín¿-a u .ÂÌÉH%]:·Y*+f·:¥€‰Í=0KóSÓº†9¶Öú§û*‡3(ºåt±¸x÷îúês|òdáË:·Uƒš0g³©Z oª üo ÔªÄÖšB ’MÑèNç˜ÙFŠ†Ï¨„ꃩA8 Ä5*Ñ%–¾–nvƒàÏM×)H|è:›¯Ù‰”îù¢/6#ø6OÁ,¨S±V4ŸÒïÖ€¬ «HÃ;îÅwÐñ³‘ ÿ±Ø®½T׿b•~¨µˆÄ¶½Ö‰m莥ޯ½ÊYï·çQx '‡9pÔñ&!ÕRëé—Ûò$ŽèõHrƒ˜¦ƒ0Vsƒ2çBÄ¢[{KxÍ£¾ØfÒ¢k'©ÛK<1¥8K½ø QÌr`M­6ž Ù ]S%½›Ž77µ©g¨2å¨ñÜ#ù`nˬ†zhêךb¨@@É= ª h0dDà‡óû}ï^ oÏ0¯ÂY.ò71¯ðÓgjßÈ’êÈãø×Ð+cXd!g–{ùñ+pß8xüäž0ÑvÂ= j8/€ ëGÛ(0Øþt¬`Ÿ©7Nsâ3±N¢Uk ïQ‰æŸ2âŽÌûÖG@«]Yý;²b 2Ÿ¾QÑ! ïû®Í´UÍD‘·“ÌÓ7q4ä \Á3‘|Œ ­o #à·¸y‚Œ´{q_ ¡•N×u(„~©¡Ã69îx¤ £ÓœïÃð%8GY/pN޳A„ž¤;ái^È+ßµ€NU@'Ù0Ÿ'•ûo3ȑֳ:Oþ¿¸&·l¬4ÃHûôzä×Äâsɲ1D0<ù¥xBŒ0:œ†™œKüÕ/&¯æ“_áç§fygendstream endobj 965 0 obj 1788 endobj 969 0 obj <> stream xœµXÛ’Û6}×Wà-”ËDˆIì›Sv*ÞuÊ•‰²~˜ÙRQ(1Ñ2/sÙ¯ß@@Hã™l*5vI%6Ó§O7ø%˜ DÿMŸåíâû« íúE‚v‹¯ b¢é£¼E?¬ ­J°"Á¿Uµ°+ ¢©ÄŒ£Œ¥hu»ˆbº\ýnÀ˜P,eªíVÛE”d(Ö¾¿ÊaÚCLá3R?f˜ ´º_D)¦ s´Õ¦<Å £¹upÝ]µÞ©a]l–$ÁIÂI´é–ÿYýsÃI¤Ð›æKA§=ÕÝ<˜$Ëœ«u¹¯ÛnI2,sÉ#Õ¬«C±»‰n–ÆœSNçŒ ‡½RŠbj'&̺ÐvЦSw“SïKïMsœ#paÂyo¼3ÆÈ®y«ôãO‹ SãÚZýZïµEo:5Œ|3>ß.¿›ö·Fº®íÐ¥? òïæù‰íÖ6hй”fáj¯P56åP·M‡?)$2LNؽt:ØÏ.wR&p.§lE6î>Ø‚AL”¸-ÞY¿ÿôïõçž²Sï¨h bN8N3êÁìÕz§SNž0l Sœ{á ÜU„£ŠŽÑ¼i?$á8q޳¹Æø&ª+4лڄäÌ59Á‚$ŽœwJ?dv”`ÂÝ¡›âD\ŽE*]°:†W'”å§-wîêB'ÕͶ.‹AõF1 ã-f R‡ ês½ê:ÚÖ Ý×Ã~²6›P–ïr_ô¨i‘ãf‰Ú.¬*œgôtª±ƒƒé¬í³ås ±%çpY†ÐÔ³£ð@¥˜9=€ aOüPèY(øS( ‹ÄÍ/c©‰—Šèã€íC™ÂðJ`™ÿáêêóU€K.ñJbC… M/„AH„'ç^FÍŠ˜eç:*þ^ÖªºÇõf¦ÿ‡lz'Ïéãý­é­@BÕÃÉê¤?´íUõaPݺ‡C­º>ÔOïå òrQ C·nÆ[mû ³ªíŒ °˜_mýʇbTßuYë²múÁÄ[CW•éÌÛçªWºCÌ|µUÚwa)°0=oár×,ÌrÄu:Wüóìúâ• æ‚{ù̦$©š0lLsÇ# ^½¤HWÆ¢æaœ!c˜d sVãnìD"¡¸„–:™êâê÷íxØ¢BcoRއ¢T–¹” ,éyÒV¡¬çÏ·NzéœPŸA@-Â$éïà:R+#E§PÛÍÑU9 ÛM'0"§ÉaÏ£¦" šª(÷¨ZBýÈ< ÙP*E˜ÔôÒÏV2~*ÕÔ~Ãq?ËÀ½?Ø]1oÄ uäÐ10$ã-ºW“b¢CÓv©c"Ú©.L›Ž°TÝPèÏ¢‡n`ÂSZNL>S#¡ƒþa*—4¾âEWìºâ¸×M ¢ÕÓtÉÏ}Ao8OÀØ2Ô|îXô“úüWu­NŽmÐjÇ3™L_M0ÙOÐñÝ)§ÓdsÆ9¨`!LI x¡ÃkíºF5ÂPaoï—P’q¾®ÚŽ·GCüj"‘ù_˽*ÿè§£Ç}ÁéšÍˆ, eI8~ëA+PÛµãnõ­õ£SǶz;ß™Ø*(ÿB(ñÍlÊ%j§DÊWS;uã 5_ϨݴMìé’&»ÌOî߸Äq¯ ڹϥ‘·:lÏ1ƒË!?Mð/‹x2(?'È \jÅ™Ä_äÔ5s[›nµ$¦á¤Ñ®ê[¸*\î80á”"uÓ”À"±íûc…ú±„†ÖùÞá¬2ßþÜ& Ó> stream xœX]s›F}ׯط O´…Ý–¾¥cgš6‰§Š¦™ŽÓÑ „d2¸€äøß÷ì $Û{bGܽ{?Î=÷àÿˆOâ«/û3ÛO~™ÇdÛL|²ü7 ôCbd{òÛbÂÉ"ƒUÀ¾›‰9%” óˆ,öoƦ‹ïpã€Ñ$‰”Ýb=ñ|IfêÑŒœÌÂHøþvþ‰Ôy{¨Ë|MŠFàŽÄÞ‘øC×_—Ê~YìvEV´Ë¬*›ÖqaÍÜ™“ê£q‚Ð'Þâ>'»*KÛ¢*ÉCU”-®l+²zÝN#Ù[«Í¦ÉÇ·‰K„ L]!Ôw^Ñ+¯-n[=µ9©6S&`-=åÿÕÒ¶­‹Õ4Hð$ð°+Jõ`úïâÉ,H" ³@(ÿ¾ñ®Vu>e!õ}yÇB'¢îËÔ/TŸd°ý8ñ©Œûœ7‡R[Ø:7Ó7'Éúœ†IÒ—øúãßËϷ˛ϋù?£¬ƒ Оma2)Êu®ì¸¹4›„>e Ñ«MACW3ï!ÏŠzÄ8…t>5 Huh›bkÿuZnuv8¢Md<®L_L)„ªfcÊ W¶j而¤«š-•‚ýt™úÑi™næóÛù¨FèÌewy]W5I˵BÆÀõæjr¥mÇPK¨ß;²Rçó¨,£˜2?týKwÝŒ™ÀðùjäL¡¼“’–YNwI0„pÎc…NY¨ëQt#"kä."êsfûrç=¦õf¹ÍÛeŠ:ûp-oU´‚E’P5X4 ]¤ùqH~ÛÏ—yÙÖOß¼oÓQ-*+Ø3¿k.oÉzp;ºyt.4|$í³¼Ö†ï´‘éüñ­2R?ºÇ_Š­&àöÇ[d XêéµOwr¥ µ,{eàžÚÃW›ªÖÏìÇ·œ1L1øôF·Été¾9á)¸I5 Al ¼P˜í ˜¥eYµ‘äzÊ]ˆØ»H„Äü{ÔMá¨9wc%¬{ †’¯÷yi±…vp\C픺kæÃ æ1ﻉh»Ï˽0ˆëÑæÛËvH`·ËkÔ}uØa‹6»WôxhŠr« oĽ1brcv¹ïËÕ<5öò\ù¨¡ d)#Wé˜&˜bÞ‡ iY–7Íæ°{; C20._ŒãRdÖ±„#’S×B`Èüà”InÿyŠC8êÇú2{̸„ÊåðßÁvä-’Ttwú42ËÁn)Ëž8F”»ù…K &Õvʪu>Ú]LÑ@¢é–<ÞW]}æ0° @L8ùQL¹Ï¨`‰×4ÚR# ;-aIüêf8ÛÔÛ€®Jz¢G™ó¡ÈÞÂ@•a½F¢ƒ+jhö€Ên[œL‹©ˆ:†>ÚU§ŒG!íGKZ&îÞ@*Ÿ€ú¨xw©ÛIda¦! i$äNîDÙ…·ë°ÇÖûצu‹5ØBìM!»°íýð%-¤º2H‰EÐݧho\aFþ@2³—@øƒBG2é ­| ¥¨ø]‰œ9 Ö•‹)ö{Z‹ŸvØ\qø²°éÉä,›9‡ØÛèçIJ„x–¡C¥)•Ñøh¿VIä+KÃèÚËzEÄ4ü„¬Sþž‘u\êA€a!O.Ïï·ÈÅéõ­ŸWx'ĹÓqFd0B`†gõ<•x<>•xÏ×'®¾ôœLhG_NÍMÃPõΣvX ¦„Q0À˜ €;Y%ÈäVn•÷«™Çön³+¿˜“Û‡¼6m¿Ö¸CNÑ(NœdÈ ]烺m—M[;Ü(YЦФ*wO¤Ña4M(ZàèÙ»ÎÍ&·KÛ­Úße޶•ù 3Æ QŒˆQG5"ÆúÐcEY„®žMn4ºšØz3Uâãé¥Yþ+)ZÓw.põ½°Ù€CH—z¤Rß*]ñPW«]¾oôƽƘI»«IÑ6ùn3èß3jå9Wý6^—Öë²L÷ù%aëN¿ l/z2*m9lÉzµ}{¦w­î»O¡2¯Trúà@òâå` ^Ïôè‰õ^‰æLí0ÈÑ(fެElîÚA¨h-zØ+è¤Zcé&T«ïðh{aþ`]t ‚s‹j×)u·Z\ˆ”…Ìèc|š²M÷?}P*Ø’å£ÅµÄRêø™sK>iÙjÙY!ªþ*(]1bßcŽb¢¬:Ôö…Ü9´q‚/…á_—Ò ZžQí¿O$%ØÀnÑ]ë´*„Þåxãn™y_ßõs‚ëÜ Þyó÷µ.-³Í"¨{zŸ*t˜¾ 6”xÃÖUo·ð;7³içHt3Ë‚eÈF”ÅŸ|JŸóYПŽñ‚çþú_zn“¿ðõ?ÂÇê™endstream endobj 975 0 obj 1801 endobj 979 0 obj <> stream xœXms£Fþ®_1ß‚3af>Þ•ª½ó­+^]®RvJ…`$“ P­âýõ×=/€$g³µ»å5ôôôËÓOwó‰(#þq?‹ýâ‡'Evý""»Å f^÷£Ø“®‚¬ bœÀßÕvaO2“ŒŠ˜(‘Õ~„|¹ú Ô€0ã4Ë”[•‹ ÊHˆ¯BÎ e‚#šE)YÏÁ©ªkrèÚM¾©ßHÓ¤ÈáÉðZõd{lŠ¡jº ¥’4Q"ø€ï²ÑFL—$HÞ,]ýk!¬ÒbÁÓ˜²(v÷¿ “a‚ò8ö†U{Mòí ;¸L“»Š¥‚Ê4rÏAÞm×wz³ä‹ƒãÎÜŠ<à) YlÜAW‚ª©†*¯«/9ÚLÀþ²m4Eµ,R4ò #ýIÃíußâkˆn梃›Iĉå -Øéa]VzÝku“ïõzó¼,ÝaŸÎwÐÜŠ$m1 ¹yšÒXqsù öÁ½0 e4¹º½ºªÙðÞõ"†yÛÛƒîòA÷b†Ö(–PRóØ=´taŽÒ Âìn|¦åi™Ñ,•Bí¯Ä@MЩ‡§±ÈŒS¶æïéE¡uÙß.¿›;ÈÜ"½7 Òøsዊ(™Þ‘Ú÷`Ã@†–ääÐVAþbí%§jx5V´›ßÀV‹ûtert˜2n³à¼!x=€¸<7¿Óñkú‹ô0Àv$„³þî뻇Ÿ×ÿF©_kÓÔCâ…„bŠªTùZ°0°E"Hämµp…ºÜvÚdqôõµíµ‚õÀ£b1yÊ5ë.-0A¯©Ô$¢2RÞÂ[k!ž2,gÜ£©kΪXÊÌ[È¥MÛ„÷õÖ¾'Õ€xhû¾ÚÔgvû¼y“ˆ¡ `”ÿ}x ­u%Mì%Î4JÍ u˜Ì7DïÛSL¥a$*¸ÿx@!¼é oχº*,EÀ«Ní®©¾hÃx×xロ‹ÕÍs`]¨ê .A”:¯-ÎÀEÐÖµ‡®‚B«ß–í,‹E0¯Tá*Ãã­l¡*‘iõ’á‰DVýð.üÈÝ’c¦I€X[²©0~^|\ß\=YBdTÆ&£"ŽhÌ}F¡cÖBÿÆ‘£BÈYÝvãá4ÉiÀGÝumî`¶þ¦âà)§I”œÇýÓÓãÓEugUÂÑ1C0ºPݽ§ª™æP(ÝÎÁ!¸1Æ]h3¾sø²‰?s)ùá)%ÐQ¡%s財€g1<.Q1DbŒäœŠgÔ;Úç¥]t}GHy~Ïñ”Ž­ `¿;¹fwÜ‘r³»5mË ÑˆO"[(²í…Ä*#w¾xÍ;rscËßD³3ŸªÚ/9´e]ëåå3É{“t^ðò»y|Ck¸ÃO ¨üÛnÆ"@Äu7=â8Ù¤Œó.Ä Ÿ"òäsο3MÀjTäau )h—Ù©Ëà\Y£A*GÚK-d½€ü(¡ÝΘîÖŽSí±yðEsÄÙJwûªÉ `aU¦z"ßYn§©)ƒ²È»üšÛ®C0ûyó7¦d£,N½qlùW‘ä–`Ú­éUPMI2É9nET‘þ ‹j»d ÈFPp6o®|¦1…C§I}uX<^—c'™¯ÈÊŽ!fÐ0ºwƒÆ4V„REj U·Ž¦m-—–éxs&›ZœòY/ÙHf„ŠMɵ‰þý_Lfö½,!‘ò‘K²ÌF nf|>øn7w{cçn;¿„ò_Ígšñ«|:#óðóåsÕ¯¸9ƒããR0%LX­gSK ÓòÔú¿gßXœ)ŒrƽÂw«'yG7 _Ô¯ô£b|ê ¾è® ]Eù0övx…—ó©h?>ª¦0ÔšÑnµ¬f‹¤%ú ³eÑÓÀ íYw¶Y†©Ÿ>ñ€´Yž·Ê¦ý–o/ †áp Ósâr=ü—KªÙ ïôÈ´ÏbË»+–´maíÈ[Û0ÿŒÙc£Ø¼ÇÝSÁ‚"ü¾Ü^`FÁa•²oêçRú9òù|Þ e–À$)0x'˜³ÁÝ)ø¾К±5rÊlÜÇAýœÈq®»4ØHÄרžC:…ˆŽÐ¨p+‚ÚÉûKK|þ®:<ƒ•“sõùƒ1ŸÅïåOyï ¶ì/ò—Î ëzâlÖÜÞu†Áœ¯±¿Ç¤¥oaÕi @nPcy·„>û]°Óäó’#}±,Èë£Ù›+C¦Y"¿°È³Œ}ÂÁÙRbf³Ø0KŠc(ð3™$Ÿ,{ô™Ê/FàÑ„ 'ŸJÍâ ÿë/l ýáqæ2'SÌH&&F^[ÔkÛ4ñÛÀD¡öRÍ¢m†i¹mê72ä¸óä]—¿õ€Z³-¼ê¼Ô]ÿ²4[ĽL0d—ñ²ØHEfŸJAÅÖÒþµ=Ö%¶šùèVjœ³>›—Òž)ÎzÈÙ"ó/4Žø-9öv²kÀÖ~›X{bˆyÉäoJ Ø[Û`¤ %Ô%Úï¥O‚irÐ`8ñóÄ)Ÿ/̰éûݶ<î¶›3&j6Ìpßh^‚Ö~««ßaçC,¨@v`×l†³m²h÷‡Zãþi¿a´àO}0«ZãgÙÕc!'ýXæ°]âMI¬)5~Hêak'[°Êu<ɯ÷E¸bêü‹Üe[5%n‡ œÍBa™àÇjw´Ó°„i,=šu> stream xœUÛnÚ@}÷WÌ;¾pU„*U õ! )qUB²ÖöÚ85v²»†ÐªÿÞ½ØÄ`H›Ý3ggÎ\öLÃS|Êg°ÖnCˆ©fB¬½j–Ü„ò¬á³«9àeÙÀ¿n¤)K ìÁØpz0tவ¶nwÜgNÃÁ–mŒÇsC­ÍÉt±Å)Æ%…nÆ ÷r“'!à7´~I1e$Éâ<Š(ftÙžn‰¼)ö‹B?^vÕ÷Nkÿé\iöÈ.8O’1 ˜ÂÌ[+­ñæŠÐs‘Ÿb 9S « ó=£Iœá¶ˆ2zþŽa/È‹ì, ¦“!9,Ë{$=VÎ…•¿àÌãÑze¬ž"DA€)œÛ…w´Û’LËŽà)#O¢¥âšÀôÉ›ÞýðîçÞìÞ]ü\v !ËÍ5Üç@‹`¥œ†ë©Á¬ ™ ÕðånóŒÙb1_œ9à1_c¶â™ƒ„“lIžÅ<‘¶ÂJO—ñ€Û··§;JC‘%ÌKq³LÒ~ RŠ-‘çRJ"ì(p·•Á”F€3FvM~c¶,û‘xQE?1÷Ý`[Æ \•ê¶ÙŒH’råh’g²Èý½U˜®ÖNؽ 0äâ_dgÖ"9 }ƒÒb_Ó§ÅL>äù ö3üÆšµ¿l‹r?Îw«–>ÞÍdvk#¡ÕL¡ l·Þ³Õm•"w[¥j ÑPà ñ‹4‰àÃä7ȆÚ`1Jl^®(M•j´j Ÿ`ôë|C6½¬#}¦û~œòIPí5£¬í­äœg¢ØûêÀT)qµÒŽJo=³<,¡, (°\ý„«á Æ.ˆ±K¹ƒ!Ò¿àJqÉrÈøÀæ¶BLi‘ñw>iÊKCrä|Í퇜ÒÄOwÂtì:ÿ²ŸOD’¼ *%:Á)É‚ ÒñA¯æ¸’Œž ÊùùWrÖnJݲL£ºcK£ûò:µÃtªY±qÞoÎ~¹fØCྡྷئm½-c<¬,ÿ{çÎ\íÿüñ4J†endstream endobj 985 0 obj 804 endobj 989 0 obj <> stream xœVÛrÛ6}×Wl_Ò1‚wŽë—V~HêÆ­£&Ó‰;Š„$¦i“µãï.RW×{Æ»8{öìîÁe\ú1óåàÝM ³vàÂlp?àê#˜?ù~ |帋{€¿£é@Grð¢”ùÄ~£åÀr<{ô Óàfî±4hߨXœƒCŸ0EjR8Üç,'ŒÔŽiÝÀ­U^¸çP ³ÉBŒ²ÅJŒózUÉsxû¶¼µá_Jã%,‡*²-\@ñ˜5Óq+›q=¶B¶&x²—U!¾ßZm-Ïʳƒð}”¨d³Ö1g'¢iêæÖ>§ÍÎÎîrŠ(éÄ.`øe<¼ú<¾þå(¬w§ð©^ 9/«”-L²b±†Ç¦®f †5´ÝG§ï(šâ®¨¹jªsûÍÞÉO´'fÈÝ£J>¬qKè"…ŠbW­÷Iá±”ssåé¢8‹úÔ™ÄQÅà×l=ðmÕJ¸kÊJB)Yï%’U )ÆýÀ 1Y͈wU‚ã­ÌO‡ ª¥g›ÖÊL–­,óV7ìä1k¥(°Òá 9Ö@ýñ5­»x¡u[$æŠ.UÓÍ(Pç/ˆŸÁo†0@9o:|æº0¯ïÍ?¢©U&d¶ Sk¾u²¾‰ÝQS¨1ZõK ,ˆö?KþÓù¢nÅßš»,ÏEÛ1Þ3øf‰FÐ’·M‚X”R"¶»Z^A>ùߤ@­ŠÝ>¦ìu×Gç(*Ô\A…e“z%QekPHºñØå‘bUî‘6?iŸI€ûÊf<ò˜˜>áÑ¡Bá?h~í "æú^b|J±„m©þ‡¤[{ßɺŽ·M ÒQ¼&ßs UÔ ŠÉLY–Yü„Y®M–‘ÒÄ©ð"“F¡#Ðù:à’(„SüÀê¦.swHxÔ!·^¸' » ¼8`Iäëä! "­š¼™’5Æ]v¿€9W9õ¶Ð'›8S8zY”ªH-ŒÔ² ÈZ UíJ¡P£ˆ¥]ï0:VÁ£9ú™9© G®ZœXÔg¶X`’I+¶kmÐrêªUº”RÀÜSÖ¯žÝO"³ÄYÇxZS¯fÚj§«*§Tö_£ÛáiÀ¼Ä8ˆá¸ßå!ÇÇÈõ|abåÜŒ™ï÷£îjˆ9Ö†ÅÒ0•’ÊB¸žÈò9Ú¶‚‰ÛžË\ÎËùù\¶½€¥I˜XÊÖd˜ª ]\ p`x¢È}¯R4Ê~ªšº1GãSUŸ‘ç•ú³D»ÄòN®wè1®Ð’a¹Œžywù ¿à¢~?¤,ò^¿ZèÖvšâ‹‚§ÖçñÇëñåÇÑèp E$ôq;‰ÿÉú§ˆÃÝ„¥h\Ý|²(>¬ISc—„ª Í }È©§ÎR,ëf7ű"`HçøH %5pév±¹K{ˆ÷òFcÅÇRıAx}Ó‚ñ½ýv’,6°t“âÄ"3íKŠØ—[ 8vf}OS~Ú!5b‡!sÝ µ˜IÖÛ'Ù%sü#ê=ë¡/Ý42ߘh¨]ðF)]=<¹OŸLúóÆ ·ï"æÅ€+øzÏõø&:æªû:üÅ'êåhð;þü> stream xœXmoã¸þî_Áo•1O¤$JB?µÝwmºAsÞÉÁ%ÚVëH>QŠÏýõ’²¬ÝËÀ‰DÎû<óŒe!,Ä÷Y¾.¾{JÙÞ,B¶_üºô’¹ò•ýu½ˆØº„SB2ø]ïö¦`Rå<ŠY)¶~]+¹\ÿÄÀa!yž+<·®ÜZá+‘;+)"¶J½¯›_‹˜­Au.ºÝ¦<¶FoLßmÚÝÎèÞlúb{Ô›¢,µ1/ÁòO ™ñŒ­ðVµH9ˆ=/‚tùG¸öè®­ñ³—«¢/îPU¦x<9ßumÇ>€L‘¡$k¶Æ§/Ë?;ÓåÕtÅV’Î.r«ø±af Ûîf®*ÉÃ(õ±øcÞ½,gJešò4ب5"­»NkÊOÇöi¹ˆ2®’Ôé»פ$<‘Âr<¶eÑë _¯¢<æa8FSðS 0b¬0¦-k<ÌÎu`ýA3°}({vj!yð¼oÙö2s\JÁSåÔ]0ó,U ,Éݱ¢©X§û¡k ûˆ'UÊC•Ù·ÏÁO›K†<2ø÷æñ|ùËúï`¿Šy–ÅÞþ§qJöÿгڰá„¢Ùeq<êÿƒ¨ã“™Í"ÎyÇß4: ΪþDe6$ýÓç‡VïX¥MÝ銳5(÷ïkCA—2†œÊÑh’14ƒ¡Š-мÂE˜a\lš)Å"JyœúB½´“ûPo¹kОc½­Î9\’P‚l0u³Ÿ¨€Óçúxd;: õÑ…W$’Ô¹ª!Ö‰ïM¶ÅÓ(ô%FÙB“%2rᢴ±¶aÔ^”bJŸÆ<þÿ  p*#Ç2žøˆ .c۾ͅéÑw(·0’l4Ñ¡Ö6Ã~¯Mo0ãÆ’xÕ¯mwaeÛué¯Á8f# ^Jž%·‰y¶pÀêf¬#¾\%aüؾêþ€Á4º«ÛÁ°Cq:é²NÑØ=€Íq>–d£jF×$jóýú¦m/ÓipzÝ» ®L6Îrèi b v–¥cbý§ÇÍý§õ“K+…¥Á{å»,æ‰C—ŸïØöÝGé@Þ™¡Ç*¯{VÕ• î¯äWùä´mv8Vl«YÓÚ€];Ò¢Pñ"q÷’nU-fGÄ0WB\ÎËœçâ ¸,>TQÀm¼Á΄0yýá9øa¥¦Ù*MdÁ^÷Ô ¨”C솦¤ì£)®& ¶!À^„Yè¿¡o_‹¾ÆÛ€;D íܲík%·Þ ¨@ý+ßN€]ÝÔæà‘þ‹ Aï®XÊ$ Lm?zë%!=Ä+JÆ\wƒfííg-µ¿EïÑ0y‚Q†8`cöÝSÆ` ãtJáXR”qi]ÁÞh[Q7ÆQV9Íið‰i0ž#¤›“Búûw‡IX8™1uUéæei™­Í' éRR¡‘ý¬¾üTœ`ù‘ÍŽ$3¤kléÆèu5ÀAyׄP0­ã÷øÒ³%LH©ÜÞ` à0—€ÞÄ6ÀL¬š( j}¬ (8uÚÜ`âìØÙµc?΀@eó1;t\r•öìl ĉ&[BaàÑÇÖ‡æü²œ²7rm9Nz3ÕÁòÌÿÍVù£(2‹aùZù™™\ù7Wrqwœmõ 1‘¿C‘nha§ž—=>Q N° Û¢ü¯^i¨I$Ù‡®ö‡¯ìÄó§8;Ù0Ã%ãÙ/Ë„ª,<© dá"a½T¼Œ§!O¢ØÓÞ0·´瀡 ¸¦²;ÚÑ.=~ ày¬!îæRÐ> stream xœÍX]oÛ6}÷¯àÛä¢âDR¤$ìiCòЭk°Ìm1$ƒ![t¢Â‘8Ì8Í2…çÅ,`‚„øLdÎDÈñR™çûªì–[]=tËz³iu·¬÷»Ñ;UŒÆÖà]P¶N‘®&Ý£†ë®¬+Roæ<¦Yš¥ßÍã._m5yÔy¡›¹”4Šâ, ó??ŸDd„ÜÆl.-Û.oº—bâ1W"šÂÇÅó‹á¡w~]Þ4ùÇØ£qª›1Ú4WZRVp§l1ŒP$’ª,#!žðÓI1›·³@W]s\¶åm²øî$‰HÐTdÞa$Rãp’\Å sWMc}){Z.!XÁ]ËéÇ <¢B)ß¹ÇrýHÀvL6uCWeç—Él’'$äh$ŸhdklãÈ«‚¤Æ”ŠÇ¦<zSÄ•gÒõà ›šs^–T@«úª¤ðñBks†ÎbX3¤Ú?­tcN‡ž•5EPéDøj-æ$”Ålè¾é˜ª«í‘¬÷M•·pL’Ôs,ß–…Tí„1DE¬‡Ç!|0qÓ”3Øî5vENñú³ž»¼(Êêá°`R“òRŘ2mrf ßøÜ„ðÏuCsP7௔©¯ÛŒAø‡ ?1Á*_Œ 5qÝY'ŽI`_° À¬{×fƒ©$uQ¶ä‹nês0YÑ8à¡åºÞWݶa™´¡0*2u©JF@8$Z©[_™±Z˜Ê±2–-ÞK„Øy³ LbE•LƒëèhÈLÝFù0!h_Ή„L„0R4é9¾:vñ¶®zOIð¾Õ–ˆ«‚)ë[¾Î·[Ù"s‘Ñ4í\<çÍ$¹q‚ܺJ¯ŽË²*ôçûà~>‰‹Ç1íÁbŸ¥U­›gàŸ Ê \` .Å(n<õi»Ÿ3`q”XðžÆ1ÍÅÛr<²¬+Ë_Ï Cá) qe®üWnÜ•…!L[w¯ñ0{뽯Úò¡Ò1Ö^§^së{ôôºi@T_iüq?ÿáÄ¡ Ǧ"h&­LÝT¤Ý¯×ºm_OdD%ÀZ?c¾©‘’ÑDz±kt·oª–\™.¥T&iæ»ôqyõúa<ø°¼ùÅÒB@iO8Žãð¹åçsæô¦©ŸNI!£h]àž9çåÙ¦Îü±¬v@— DšÂ}O-“ô$a¡Æ° A)`¶]7®y/ÈòñÖ¥Tä­Â@0=7‰…¢¬èàóa¸Ó¤#{ nÞh£p@Sï'ÝdQFyæ¼(z$$ oI˜f|²>†,á0Ù†~ÜŒÇ_ê3àöî3.ˆvƒõØ·ÊmêlZR>í`2nu×akPJ`ã1²«_øKbT®ŠgS c*‹ºH²¶ƒa{tCf$éèQvh¶P$]e^U€vR”&ràõÏ'd ¨Vû`¥»g­-ZÚ#$ñDš}Uaä6 ƌÒăà4¸\}Âye×CµOßÄÒM°˜ÁÅatè^i4 ÅÚÁ}]ÜÏA!zðƼë¼"+M½«8EvM½Ó TAIär«2.ÊîsV]>‚&ØžeTùÅï.@úe™eLJåõíí÷Fì6 0³Û¨ïÕ…dþeÀÄ’Áÿ“(¤ÈþûåvdN ˆ¸K1X“ã—EÊù–"q6Ü,dž_ÿwÐõbö|ý 9? endstream endobj 1000 0 obj 1798 endobj 1004 0 obj <> stream xœ¥XkoãÆý®_1Ø/¡ŒÕ”3ÃçG§v€m5⨠ŠÝB È‘Ì­D*$µŠòë{î<(J² ÖŠœ¹sçœ{ge!,¤÷YîgyIÙ¶Ÿ…l;ûu&ÌKæ>Ê=û~9SlYb• ¿ËÍÌîL&9WKU–ûY°óå˜Áb!yž'´nYͱ½ZH¡Ø"Nè¡àQ”²åi<7¬?–¥î{V¬Óñkzö@„Hx9+¿¬žè¡’\H•Ù§Ÿ‚®žÿΊ¦b½zöu.c†‘ŠÝQ÷lxíÚãöŸš §ù¿—›Eöd8™e|4´‡‹÷ –$¹}޶u3è®çì¯ÅnW7[’Š£Œ-$V+®TnV9ö+6ØÁtQƒb½Ó¬îYabÕ[ŸÉòšû¼æ!Ï3wnPŠn³jôoêºU»ÙP„+cçsðyî6û¢H)ÍÙvó©Þ팑€Krô/è´yŒògjÎC¤@¹]_õ%‚‹Èå&¤€>!£&ýqÏÚ CØi.Bd;Ï‚¢LDr^ X‡?J«”UwÅ€Œ]•£×åP· 7E™da!á\Нø‡ñÊD¼*Ûc3ÜÄœI.=êÞX5ËÈ?›ïW]T¨Óy¡;xÙ·lcqÝ<ŽÖ( ¬' cÔ-x SÎïψ§Ë”Ë´MSÄ…ßær”Êl^¾ê^³Í±1@éÙ¡kMè¡âI(Ù¸:²~EšŦíöæ V¬Û#8çÈŽÜ@4‹,–<“™\ B©‰ù}ƒFš'¯ôú¸]ÖÜM,‚òç8˜(& t“&xB{ò”g#ŒÃ,·1X«l_œ¿åCɦ•3ºÖŽÎ"m©‘ 硲¤9¸l;œwh›Š¸W¶ûC½3™YHmUkKÔ²½Ò‰ ò8ùsM:Ë·«ìr+Ú!âÔ3$‘¶˜Lz­®/HýÉb® _Êà—ûËQcÿüåù^½¬Þæ¤gê ãÁÏ@ÑUäU²g•îË®^ƒ”ÇÀÞÝCuw„@<º7 ü޽{jÛÿ`ª/Í;n ¬+ƒõÔb]^À޾YëQÂCÒU'·$Õ[=xX¬\ÍWM±ŸŠõˆ*¿ÝaÞ†ArY}ÃÔƒyÿ@dÕzûž Ç)I¢7h<åkѱ»;Y³Ñ¬£O3gâ±ëZ,Ñôÿ¾›-¬'ºwßrämŠ´#öðÐCW_÷êÌ"ϯp¥x„-·Øê‡)æ"ϨÐ.F¦¤výþ@²(‚K)&«"›ÏÝØe9 .Y ©œgXã1ÄãÔvxèÃaW—F]à—NE9¤n¡RTœf–¸K<ˆææ¸c!oÉj—m•B U6¶¶Ð3ª8jKdØri¨±ð'ù®t~D‘ÍK:Šà§`hç*Çú,6¥1d²'3dÕ¯f+ 2Ç®×æ\—Ä«$ÕÔrhC‡?³‚¡{؆ú†½'FIöMöNE™»© ¢¼ G!Ï~lihºÊþ5*r6Ž•4yžûÎ`[jJHñÍmI?ÐêÁfȽ³TÙ5¥é'‘GOpž`ÄO¤Q#7fž³`x ó›VkR4Š,Sç’*F([Cxk4ßßm‡"¥jm[,1ïi&yä&È6ç>J;%몲N§Fó£\ßyÆß°3®Tî&r:#³!tÆÂÎkÐJó#'¡ôT¯¤Ø)>„­<¾TO¸~s#ɯÜw“ýíÌ›EPB?€>ÐO=­Jhο¹z$˜zÜZþ`«è‰”§Yê¯ms©bl–„ÞWÛŽ¤M§- |¬¯-há²`#͈3—fÃL‘5®ø•Ä%P„0õþÐZi—¹E¹ô¬èš+˜Åñ¨^2¶åG›~Üm\âÍÝÇÚ¾¯I›&~ûºy—,g€øÿxzb­ %Kì!ã=E&©­e˜™Õ©ò ÓûÃpvÆ1.¥)štBD"y;¸ÑÃЉNŸ°•^uºl·Mý»65¸¶mÇPdy÷)°!Ô»‡H0Ûî,ÎjÃý®….¢OïÎóÄLæ*˜òƒL8fx¼U­¶š¥ç‚v$*ø­î‡?„$LæÐÉ,±J9#\#?>¯?._¬ s©CqT„~2öùñ±j ÿf¼*(OxÛÙË8NÅi£iµw€Ûú"‡Ä]$ “kr<¾¼<¿Ü°ÇTEltÄêüx+¦QñfQ©¢»»o.v¸±Š!el0ž±¹^çÁäV üDAOb‡®ÉÀ$10QçúÓ‰éÿ’>oæ ?”® {³C’³A²ê^ý\o‰Gw#¥Ü9ö:YøfˆšÞk¬;#ê‚vÜq|GX~ R¡òʆ¾„/?g&C).ÑâòÔïüæ·<.g?áç¿=Äïbendstream endobj 1005 0 obj 1991 endobj 1009 0 obj <> stream xœWÛnÛF}×WìSB9âš{#—HóàÂn‘6MPEmQX@‹+™E:$•Ô(úq%%… XäÎÎõÌÌÑ'a‚"ýqÿ×»Éå»ÎÚ(1ÂF^B¬ ¾dèî¡Z4¡1®ë/»ÐªÍÈóÔÃìÚÀãÊØ×RW‰w¹ˆRaÈU³®‹Ç¶ª›ªJ€!$BeëûÃt›4Æ$é5pŸ‚Óã1–œ“CŒÝÌçïæ#× Hcbd´BúU]Wµu?±Ç¢C,~­Øq£µußfÌ£÷¤‡P'FåÈ÷ïV7oó?Ç%Nî6( 2k…Š•2h#)xAN` O?,~‚¾8f  ¾XÌK[€[è}£_>ë²ÞÕ)ûØ×‰`%Ò×£93)UÙX´]ΥLJžC"…&àÒÈüPl÷u§˜JÌEWgÞëåÃêR|4&}=oþÎvjò/S¢Ó’$Á©1«ƒN>°åIìk|®Š)§léšñZÝí·(¿ÛÚ9ü3}®=î;ÚŠ½/¶03Ýè{…¢—FxØÏÈÎ{ø|èa Ú=[ÙÝ4¶uü •ºú•=±@À·zfgÏŒðh4,§ú¾EFýÒ*y…º…±œ¢¯TtÁ87ô|Yö5œ~gC~‰^¼(N)»¼@ûF!ãÝmñ]\šId]²Áä Ú¥Z»@¼äÌ:yµºš_½ýñƆèþ×äø¬’NÛ×ïgïŸxeË D(Ð2}Ä0µ7Æ4Æ åZFdu•f°Ú;Èù rvVj$Œëº lÎêr&˜-œýV6¶hÃÍ=ë±uÁ¯…ák§q´øgcP^ 05œþÖIÀBS©¯S¢Dà¤oìãÈ“˜0?¬Z;”`<ˆn=i»¶Þ±ä~…Rév€3“^Ïàì,kG¬Ox ÊpÂR½áµû¡³æüÒdÎò¬Feõú"ÕͨµôŠá1kÁ¾60di&iB0>áŸU?ba pßÚn¦mqp—ÃŽeÑ·îŽK cÖŽ?u˜Ó2‰a¤‡dÈ,?àÜ é]–ÈnqoŠ)'“˜íƤÈxBaQt4ÑR^ÛV°k™õ{šâ„ŒÅ€Å¸/ý&$@¿á'ƒùNGž:ŽzjŒkš˜~é(äa- Ê…5¶ž¤ñAŽõ”xÒ?zbù5þòˆâ8¡ãðO‘<Í?)ëÈ#eÇ4ϾµT/‘#ªç‰ù=t†î‰¤gùž ôÿò=cÒÊž¢| /üŒêˆ~O¥,u‡¢3Áy­*ÛúiÜ_0ždOÎöWÛß´§ëÃhBMc·g‚¹ê)ÓÛ«e½ZásK¿dOˆF”ô¡áÓÄßüæ¯Ú›ÅäWøüœ‘Bendstream endobj 1010 0 obj 1474 endobj 1014 0 obj <> stream xœ¥—YsÛ6€ßõ+ðfÉc"¸x`ò”Œõ Ô®™IÛ‰;Z%6©ðˆÇýõ]¤$SWŒlS»‹=¾…¾#‚)"úÕ>g«Á›©æÕ€ ùàû€šEÔ>f+ô>pÎ@Š2?a:°;)bžÄ\ Ÿ{(\ †…ÿ€¦ Kéi¹0 ©‡½ôf ʵ‡ÁÓq¥^昹(| =Ì<,P¢E…‡ gA«à).Óh®êhÖDI¦¢"M+U? FV-•­gN·Ïaf'1г¼FÉ1Zƒëcp‘ cìÚH¾+ã|®PlWZH/ßÀ_pQ+µbwiŠ.KU7e®’—ª¯F­}+:.Ë¢D—J?Foau'¤ŽuÁzMq ³3\(”6ù¬ÎмwT/ÀÜem€Žžn¡Mîa´Û}uüÍ »BtéRŠ{Ƙ‹ •²ØPO½¤˜m´'ªš•Ùº.J-åp0M@¬ 4#˜{Ü3®P–¯›ú Åy‚²UÍl¦ª*m–È·ê;¸˜ŠCD×7_¢»ßzÞ¦kÏeì1k¬@xúJîsÌ)ݔ‘ÌöC »¤çY+.ñŒ‘º@5¤¯HM…,X@·2¾–ù:ÔêàìF'êqD%–ÃfeyZ€›&ù FËŒþ?@ó0¹›»ží Y±ZgËXopš<«ÑõdŒR¨:­~o±TëRU*¯U‚ŸÌ<3™8º¡“àh£üÃ$›[kÐã2Ð¥:·½&yW ˜¨)¬E|„`]ÝNL,ò $]Üçœ{˜3¼Ìùx:½›öÓ.që3±Q†ø™¶¹ºŽé›8îàˆBû "Êý}$¹'‘d ¡ d¡âD•¿§£Ú^©Ó€z¡÷4£N!JâÀ“çE‰-Ô>¤ÎǬ3Ê|a ½W—Ä?¬}byGäšCmÑ…~NLbŸúgà@\ÚuÂQ$‚&Ò‹àõ¡ ”˜áÓ”„‹½ ”´ÌI(±3Pâöw¡ä»Þa(Y·‰K‚b¿G%cî• ó7$Û£’@Æ’oâl{bRI04²çºò5$:!‡Öˆ«+0ÚÂEVmú ÅIQ˜Ú3Úó1Lº¢ùAwÎ×~†…{…>4¹ºBŒjG™¯wµ6\PiSýÒ¼OÔl—`Êþ¢Xëãå…®†eö˜< $‡ùý„öL¦“?Qõ\ÕjU¡ªØÃ.µ—˜èvòñ>ºÿëöýÝMôq:¾ÿ"Hq’ÍâZ¡UüŒj*m"Þ@áe+… TU«r•åJ·V|±­ø‹öì;9o‰_Vm}n½&Bh¯á“üÛˆBó Á&¸€ÖFñz½Ôé 8}½šý‰am:zö†w``|Ý›ÐI#}¯"R ‹èÑÀÏù™‰¡ûR+ùßs¢]øœWÙx‚.+5_AÓé‘pl-‚ßò9ª²ÕÛ­Ø;h'©ãòðæ¥ÊçõbgÉ̤½»òkGÐ7ªs®fÀXzluQ;pMözrâ>"4ãØ9ÊÃLÙ0ÖP~G™¹pÊu èãli ¹²YXÇ»ä‚OÊ¢™/Ìʺ€²Pe…-ØõW•áTwˆ¥×uÔQƒ óüs ½È£[ÜøK¿ÛyöÞ8|‚×póÎendstream endobj 1015 0 obj 1270 endobj 1019 0 obj <> stream xœ­XmoÛ6þî_Áo•ƒˆIñE[$ز¥xÛ‡t0d‰v4ØR*ÉMÓ_¿#)êÍ^Ó­CÚ0Oǻ瞻çä(ÂEæ§û›?ÜK´kÚ->.ˆ=DÝŸì€Þ­ ­2°"Á¿Õváž$ˆŠ³I&Ðê°Bº\ýnÀ˜Pœ$ÂØ­òE@$ ͸H:!% …\ØóFïºl; W8’:1B¢Õóâ!(Ô>jÔè%á8ŠhاQy“\oŽ»uQn«‰ïQ2éó¾lÆeŠ)IPŸzlS×™…º«GVžŠ½E?<–Eë誖±˜ÖòêæÚöß¹§P­Ÿ ¬®7/§•¶å0E¸µØ×º=Öe³|3Î:Xpî‘¿úc}uûûúúþþî~Vf•`OHD×uU a’frì§cÈUimýg¸÷dï}žíw L9;í08Ƥ9 :Š à–Èv¤ÁíÎÁCðœÖÛõN·ëÔ‚cj»¤fÞ%qP}>,íÈOTï #²«ô ÊÏøæRPøWÖî­k;gjó0Ç·ý1” ]Øyp µé>ý­lŠ] …½pM7:ºÛnÑŤGF‡×Dta±„”ÞŒÁ ]p]6XPb3Z=Âèô Òy‰ÀTøJœM~½±ƒª¹¼µE?Õõç0)â®B‘51eú©…hRó âÒi½/ŒKÛE®[‚9›uK^i#-zL'¡Àx‰I’ø{Œº‚õ'È=÷±ÀÔŠ#§Œé‹™Š®qìäÑä]l?âŽ;@ÏØ"­8ŽÌš)ÇÏžžý¨K]§{s1àB‰öÖŽkš™iDúYõ|Û¥c*–-(ì±ßBpá`ÓŸ{HFól7`®0U¾•Ÿ “@3ë»ðK*&ÜpTñu0œÙW¶‡HDƒçp¯ê{ØI¤0K|zŸ\pó²ûtL!bâ;Ö,0ÜÊÚÀ Ác£ína†ÝS]íêôÛÇ1{ÆBO.XP’˜ÀÏ0? ·fT77”™FêÜà°ÀŽan¸^³kˆ'û¿œ®_¯ŒÎ |³³ƒ*¬<¥%veuv?¥{èú‘ƒËµçoê|çØw>Uªë|=éªñ"Æ1eô¤åÏcÐ÷¹€k”ÎëÍ|ÜcA(™ ÎÝ/3Oà(R2ÊœaKG"›Ü×o—Áé^둊û€ÆðÍîK(æŠwù2à¯c4¿ízxÀ¬M›— ˆxj¤ÜNr”…ýÍ>-«Üh1×`tcA9ýæÎz“,mìR9(©;Ê ôªWÓ‡à²XrØË9!A[[:Û^¡†ný„8 uG°‹dУo‘wÇ)ƒs?N»5lä–ŸÑžþ`•è׆n+çK»•«nËŽ¸.§ÉœX òŽH0:‘ªfc† ¨òtÌœ¨ ±{²É Fï¾ß“l'¡çdžHUÝht(š½NsóNPlQî^Q(Ð6òénuݽ\°T’~2H'ª£e ™e­™k‰ º¨‹šB-‰¥¼O€¬H¿ÊºH¤™2óYùû\L“¼ 8‰$f¤³Þ§Ž“î¹îÝËÛ:xe¾‚w7'á3³çÊ3ÑWç£"5<…ËݾßW»n¦öt"é–0É´õ×CS‘~<}>_òx‘hÓÍ ¼YCXx{=¶¶¤–dÔ fêU6¤‘r8¹ øÌìÑýhcc†„~IJ¡ßøX4Ìv Ÿ¼‡µ™F” OK‚ÿÅÓëßj]¯¿ÂÏßGª‰endstream endobj 1020 0 obj 1825 endobj 1024 0 obj <> stream xœµX]oã¸}÷¯àÛʃ˜+’’(=v):ÝlÍzºI(h×–¼’œÔýõ=—²­x>°@1$©ËûqúƒÅ\°˜þùŸ«íìÇ[ÍžúYÌžfÌ„]dþÇjËÞ/gŠ-WØ%$ÃÿåzæÞLfW Ó*cËí,ZÈùò7˜Áf!yQd´oYÍ"‘³-ÁDáM,¤Pl‘fvýúׇë›=|¸½ýtë÷…£ò‚'ÞJÙT¬jMÏšv`½&u#¥ô›ß•UÕ=ôõÍÄ ;8-,d"¸*$[ÈœžÆ\e)[¾Î¢å³adÃô=#3¬3þkLÅêž XlíûHcnÎ/´7ýbމ\$¹{NÆk¼+7›3ëWìõ¹^=³UÙ°Göu¿1eU7O¬^³ª^“=©b^øÖ¦3ÍÀ"‰S†EBK‚gZØCVívWoÊ¡n¶oê¡gÏå¹Ï1œ‹3gRòX¹÷^ «Fÿ¥à¹(B!#[e¬Ü³ãyΧ³°z›dk®„ßý\6ô0qïù¼Ñá/ÇÌ[* ÕzÿñûJòDê Þ·—½?zÚl¬„ƒÍÓf,²5­`3ËtÈelwÛêïLÇÌÙñIÊ… îýçrÅï¢Õ~(7¨ïã\@sí[Q™ò8–”5*óYÖXÙÀ¤¥m‹¿ðû¶møüßË¿ÏÐ6\æ± >÷fÒ <Ëâà]õZvë‡'3Ö¹x¿–©k»v]£=jse;2çcßi.­·ëoåfÍŽdwÓ¾–Ûõ¡ëÚŽ½3ô^þpZ†…3.=t¥–#-­÷ÍŠºzRóŒ\øSOy>Ò¢£¹~b[ižËçùúÓOK±£@;ý~µ{ ­“±µxV6"¢u°¹%ÕiD‚ÇùH>_¦ôÆòº¡µôl»¶›4T»f`VŸGJ:æR©ÀÌÚúò±÷†¶Û¢XXÓÚj¦žRÏyà]Õsç`( ÅW œ8 ž\Ì$øš8¦‰ø¾á©úOÀ»oO¾³E¤ŠžM‡ H˜Nd*zmˆÅ¨º“6T¹âY˜îêÄÏ…_?q xvsvpêuNaë4‹ÊCñús‰¼./³ø„«ÆîžbZó‘mpöï ,ÎãÞæ‘ÁÀTl^¤°ä…9«Àõ•yؘG!ó -z™°~1ÆæâÚÖQð$±s g[õדšó4ÌÓ»èö¯)ë ªì*ö‹±„Â4˜ J*‘ÅÆ@¥°Êô«®ÞÙU”úæÃ{fr¶b/s™ð"×yTnö4ê§,›%7}ýÚMÓØ}oÖÚýðRn®@£Þ¢iªÝðub½£–¿6+³}Ä€—1ž„²mùû\Ä(³Ö˜$lS?vew`ÖqBóKmá-¬í{Óõ6{TÌ÷8ª»~`C½5.7t$'\No±þ¹Ýo*¶+Ùºqî†, ‘ñtœ´ˆÊÞ ×GÎ}­‡gTo×"Ù0ì¹°FCÖ(&qahXXbÍžÂ&ƒ™s –@¥êp/èÿù§sÕ±zW³‘ÖQä ) ȤT8º’LBH06D`% ÅæÈxK9Àç m³ØÑ/Žw°`DõbQT@,kŸÌ7R-Ä @*gKËë9¤L Âî^A“¦d­ Žcx—ý'Õ’þK™Ù³¬ã=ùуÉÇÞ7Ú=¤4xÕIüöñ7<kýýœD}»E­SçR™Â þRNýCXŒÎë†8ø±G^<ó†ã·bòàêEDnH€gíDF¯èpÀ‡|t耡#³Oã`?·¤Ã9~1Ä¥øå Ž\$Á¤IÂUªóc+€ ¦¥Ð\íÜû Ë9óD}¿ :M¾Æ¡=ÚqiEŒ’Âe¼i›E³ßlP<ßt®¹(ëN‚P&IáóE*3®³èãà¢Î§œ"4c·©¯à†1¹ä­w`ï™Ñá'—§âàKø‰5WÜ÷=i¢õy•+3¨ ª2–;qRxt ÑW?+¬]Vž¸fo”çE±”_ œ°Q¸£äVØøô¤E~1" Pn[Ð~ã$ŸÝJ¤'¸>’Äã‘ S»Å?§ò[¡Fdlõlot ¬… \9 ›ÛnŠÃ<Q¤ßÈŽe-yïôò3t‚ˆâä;•ežeÁtâ¾yÜ‘d·¯ï÷[7ó‡gðWÓ>¶ÕÁ+-‘d‘eŒÚ2/6qBµÕ~µea¬â˜çñøå·ÈõÞÓ+8ârÇ޴ȉ‹ªÊ+Ÿå¿Á&ãøµk©aH¶£ÿ´g¡c²²ðp%Žó4ŒÁ§ýÖ9ERlßýzë«°ƒÊ]V¶– Ç‘ öÏ77Wî;q4à »œ**Ò=VWŒxÁ]ÚE5;áib zƒ87–§:J夢[j*w±V¤Ã…[ 1€^j†?~†³Ð1âx#×ôe*¼ùÍot–³âßÿ¸›dõendstream endobj 1025 0 obj 2001 endobj 1029 0 obj <> stream xœÅXËrÛH¼ó+úfpCìA7ÞGÏÊá]í8–æ¬Ö†$š$Æ$@ã!…þ~²úEòH3§ Ûa[hTWgeeeã; ¹`!ý²o޳Ÿ–Ûõ³ífßgB?dö¯Í‘ý¼šElµÁ*!~¯¶3ó¦`2-x³,JÙê8 r¾ú a°XH^)­[U³@lARDl‘¤ôCì/¶zš} V{Õ)V÷¬iÙÓ\„< £,(ŸÙ¶íذWìP¯»²{fCË*5¨îX7Š=íž™óÿ­þ9“Y ‘Ù”âÇ?(£ŽÞ×»FU 1ÇÆü›SR"й”©M¹èLcñ(BÞ¤¢C!Ò¦<°ãqìö­ii¡†&‹xZHiC<•gRÀà4£:cú³i»Nm¶›ÍP·Nç§eÎp ¼(BžæqÌQFïG\jÀ‚”ËŒ'¬¢åqÊÃHæ~ënûP©M[©sćƒZ ™ß÷sÝqá^]Èð|ÄÏÊäv«QÛãX*Ïåüòþ|Àœ'‰=ß×`ù„õCÙTeW±ÏJŠe<Õ…,ÙN5ª+¨a¿éê“~ÚnÙ݇Ÿ™j(ç …”1/ò,×Uë¹®+’.\ÒiÌóØçÔÍÀªWN½Ù—ÝßþwC)˜箢Á­~íWK½è ½ŽVܹŸíóvËÃÍüÝÌFUMu:àúî V³‰´|lحڨ㼑!~:ìAÅcùÍð<ËÕ{~ë3ÔÍŽ=Ö}lˆðîÙØ«®÷±Ë0¨;ðp¨ÊÀD[Þï3©K *ë·X¿oÇCÅNeß³º1é:@(šÇ~`0a Ê‘eXmùU{òÔwj½V'S7õP£®ëçAQAu˪5kF:6LMR„ y”¹íøE§Ä`´oJU0*ðjû¢!}“ŸÏ?á"‰\~¦$“#Ä…íÉs‘it&G)¤\϶Q‹ýÃt(‚b‡zÔDBk™Ý5ñ1‰³œ­´.ä\ä¡ËëùTSç?O’ÇñHe¤?ÞóÏy,Sé@ZE›éÌ{J¼lˆ‹”do{î>¨·¬S¥&S»þTÆ>ëïç$}{D­´€êEiÄ“Ü)ÄÊ Kó+ütêÔ©ÀPxÆnTÇ–dšj5Í‘o­hç2A1b<¡ÙAÊѰW€†FÞ>á¥q³Q`ëU¤N c×ôþ¦‚Ká”éöËÃíÝ>ýk!Í);•„@¡ŸT#Žy”dù¹ ÓRd<;Ç!”_Ò1£?‚ˆ$ ­Q¶cÿ85ý ,0}<š¡?ì¡ZM»n«g>¸ÔÅar~ÓHœVŽZK0^#e§®­Æ²¯EOC/Zý ¶£UYH+ÜS&¯ Ü¡rä7ªr(o ‚Z (ÆòS×RãPdôanÕè`­ìÀÄž)wÂìÆ#R›R øm¹Pš#œ.äÑKb¿üzww£·ÕÝϹVvü@ª¤šRuã§®)…“Œç‰œH7‰¹,’áP^º¬³a¾öãïf)D-‹|]½oÿk¶ cñª§<" §®;®üx,þO~<¾öã@UûqoÇs¶,›ÒÍ“‘%vŽÄäùéß«‡¯÷Õ©V\XŠÈ7á…¯–Ê‹Kc}ð öLà•B¤Á¸{èæ‚Ê(dÐìu?`´;÷n&„Ó‰­\Áì^ë[W–«ž:KÇ £$x¬+²u¨îQçÍÊ5‰nƒªêh4wúÀXTÁÚ (äú™•ÓãŒô—‡÷«óƵ[!\pá;xºZË!‘Å NåÔHŽÆa–ìöã8-äcó(ÁX¯í*ÓCƒáÍ¥’ ….z%#8 E Þ¤G…{Ö8ù§{é§é霶³^ú>Ö@Ȉ©5Ûuíx¢´m®4àJ¶Ç| ã òOõÁ =ÂPcjh! ö% [ íÌì’XÏôˆÂxò\Îx»ã‰ÜA¤q·¦‘™ç°(—5 ‘2Kº)èö€U#—×cta¯“—Ãþ #C)¼oÐM—¹7ßüœùa5û~ý²ê»Cendstream endobj 1030 0 obj 2212 endobj 1034 0 obj <> stream xœ…TËnÛ0¼ë+öV ¨X¾ô`o-’6-ÒC]=$E@K´­B–=âæï³¤hÇí¥ÁäÎîÎì¬QÌ=á]í£w«¶cÄ`=FÜ_BxU{øXFÊ £¸ü•›hAr™¦RA.3(÷ID\þÆ4ÌÕ:sqeÁ qW‰à’4s‡œ¦ ó#òÃVSÓwSQ@mÇjhÖv„igagMmØ80Ïͳ|IéÐÊ£ÛÖ#lú ¬L·µpÛŒ”"Uز‡¨3Ĭ[K¡ÜÙÁº¨LR–)þoâcÓ¶0³iÛgXûÈD¦Øv•'¶7;WTæÂÑvõ X?¯r¤”I]œJøèctGæj“kg| Mc¿·0ÚÇÙv•õ'NZÛuÌ5 *9™·C·m‘∑^8ÿ*¿F’e4ÇÖÎ%¸gqƒ$áh¡B`Mµ[x(Ajyâ±èì®pÊ:LY*ª všáÕÑ ›‡U¨ýpƒˆv…Ô4Pd¾ö=1pè›nÂN=˜úƒAr0NÃ\M÷1]2€¶À‰q‰.‰¤"õy24ºõ³¦¦Ûzè^:e E¹Luhrè.X°”_ôsG‚nµ™ zJ(çQA¼u®¾\{/ø$:£}‘¶´Ã²0¶r×8õ'è7àémbÎ(cº ¦Bë†>æ.»”ä©AKƒ©ð|t*¸‰^ùR §Îjè%‘öÉ6??¼r(hšûÞ‘Õ§ôÕ …ÒyÁvÓÐØ°Kz‘ *q5Ã3LM5·fpœiœ¤Œ-.AN8"»t.$ùcö‡Öâ  è¾íÍÜyÃç-­q1Ú>ho®9¾÷•Ó<‡ò6"+¿Y¾Å“y’{ΨÈÿ|3Ï ˜à.`æœêü„üï溌¾ãóÛýB—endstream endobj 1035 0 obj 693 endobj 1039 0 obj <> stream xœ­V]oÛ6}ׯ¸{IäÔ’IÊ22?¤ˆƒbKQÌÓÖ‡zh‰’µÊRJIq‚aÿ}—¤d9J‹ Xa’ÉÃs?Ï¥¿q)õiŸÑÁšlVÔúbQ½ í#:ÀÛÀò ˆEà7H,s’›/]o oÁÁ²6 þDSæ.—s… bËfµ5Ùø-ƒCb1g6×»,m¤Âh[Ìw§3ÖžÓžvêzÌïh=×ö~ÍÌÎ'{ýĹ7»]¢33j7i(‹4Ϫ’R¯k™íFŒ¸„Ò©ÝÔbôGð“â[ž¼ô<×'spèT[ÌŠ„¡î¨B¤ 2líÛ#—IxÓ-h+cå'ÆäŸˆ ê·¢ÊÒBÄôÈóFŒÍÆZJtðJ¨Çv¤N;/Žÿ5$\¸èðѲ'W=—ÂPB¤“B4àÐ`ô;õ^ÀíÇð&%/RQi Ö;ø1¼û°yßEùèO·V‰(,“¤5ô†ðØ=Öê©–<ª1¤D–í‹ W“Ñå •H)*X¹VÇÛ„¼ãy¢\ÜÌޥŨ;×®r& L±¨Â¨lŠZ‡€4/wåq EYë…‘Öûjb:¼ê¥\}ÂîŒJ+EzÌ÷Ó½rGe„Ø8xÔDw]Ý Vë´­îÅ0ÉDW!Gœô7F6¾èw|¡ZNCP±m¯Œ/Nõ5Jýz~Í^{¢…ÙšÐbÁó¼ŒúðÌ,ê‚R&”Ïçš4׆U°Ò–7÷kLU¬æ"nå}v ;¾n|i’8ÝêÔs‰×Ýê^«·×¶í²à÷üa´?¸ øg¡;ù¯3Öõ ~þl…“endstream endobj 1040 0 obj 925 endobj 1044 0 obj <> stream xœ…W[oÛV ~÷¯àÛäÀRttŠ>th¶nKQÌðÖ‡xdéÈÖ&K®.q‚uÿ}ä¹ÈŠœnH 9ùñûHæ Ø›~Ô3;.n×!ì»… ûÅ—/A=²#|¿Y¸°ÉЊ9€ÿ6ÅBždà±åzºlŽ Ãt–›?Ñ 3ÇŠã€ì6ùÂp0麈• “ÙŽ€éÂâöÎÒ–CÞÔnnÉœy°¹_»–§½Y~·0ÈŠÀ¤¯ñÈ?db”l¬É9¼} ï?'ëû»d—vo nz¨9Ï¡o`è8ôÞñ=žÉƒé0ÊO]yH9ì8¯!Ͳf¨{¦e•î*.™åÉTÍù”AZçp(÷úˆS&F Þ©p&¼Šþ¥¼%œm^âÔ5GÞÊzç²?\E°’À‰Ý `׫1™~8ÁUâŸÓ¶Hr4¯š,ië}Uv}—Ú­A¿ŠOKÊÂhy?´5Õþýýïɧ_¾‘Úí:ÆSiêÒ+Ç }‘V`á † ÊÉÖCl¤µÈûÁÁ´Kæ[6 bCG³ç}ÒV\Eµ].ÿØü<•©Ý˜Žp„îm ïæPvP uÖ—M øé&hÇk*5Q ¢/JèN<+ ŠËñ™‡0zcÂ[™AÇ{h P@¡›¾-àôtªž©Pè)•œ“2†òÍbTw¢+„–µg[vdkÝ#Èï6I›Ö{Î;Õtºq€eTˆ¥=°n#/6†ž[sÇ&sñÉõ.ì*ëdíÛ×Q†÷âí;áÝÝ´ØL*.>“?iý!­ Bõy\©Ž6¾ü­îÊ}ð“§ä1­VD*ùn­ƒø€—à …4COÔ!¯}Ü(äÑ´í•Õ¾jvi•4E…ÇH?’±PÃÅõ]ÛbW¹áô„Ÿ2L&-éeüXŠãˆDÇf–¢Šñ(ÔèZ~ª7ÌSª6êtìñ“ê°ÈòG•Ýt­ÀuePtóZ¼¸c:\âЊ˪ïCvØ®–™'EÑ äüŸÖ¡h›#Ö-íaʧè´ k*h…9‹‰†ÊŽ){-üÇKn˜³íDLk'rcyW5pRéŒþ«‹d½í¹t6äó¡ÌpÄîÖcËÇ›¡¬sy³'=e ÇC¸Ç$ŸŠËÅdâ«$ Ìh67Ϧ_F©kú?Í4Æ(07ºd!iNsGÔÞcòK@dŽÊ³ã²Ù4ÅoŒcD>ñ\š qvÜ`zPŒ…©;®´Æ%Q̱Ãå¼çí±¬‘3Ëùêà8ƒËxE}Ww"'C…škE¡HÓ †'’CÎ…N”õÔ`gá-`,Ý ›ëÖ8ò´¦æXŠ„LíR@JJ?([k¶ï[¡íN*'çÏ,ÒËõ´ÇíÒ‚wµœ4Èܱ½ê+ŒIœ%²¿êšéÈþqUKäqªF”C\£ÈÓ)á/,”Ì'Mò²–b;¥m_fC•¶¨ð%#)„¡qÝ·†Þ˜¾dŠíO?õ4qºC#ÂpåµÙÂÃ%2ò4¯ÎåE#>™hÈrxØÛ$Ó»ïËËí¬¥Í.ÅÀyUÑ“`M—PÐYéŒ-cœ¶Y;d%⇞JdEÚ“öÛfØDGÄkã´Ìä2fÑ.fÓ:Ž2ü©›—ª\1Tøk=¶ÅÁN¶ðQþ®ú÷UêzÂÌ8$f‚jŸ32D× õ|¾?WýÃÑkï•'D<ÆR;£ _L©o{ Õ¹¬*‘<öǾ²Rb÷ Ó. äcŠƒjbÙ¸Šx94Å «Cë%œÚa>Ê S,Aª¡Ä]Ró^ºØåÝ—Š¼[¯?­çá£ìBÆ(äx隸Àº–Ó–"öEc-§œ -ÞåjÎ>º2O±œð›é38¶Ã.§CZÄôñÿýCën³øþA Øendstream endobj 1045 0 obj 1536 endobj 1049 0 obj <> stream xœ­VmoÛ6þ®_Áo•‚Šã‹^¨¯Eì¥kÑLÛ0¤ƒ K´¬A–R’Š›ýú)Érœ¤Í¶ÂlHwŸ{îxwŸÁû™«½÷ÝuŠíÔxŸ<ê^¢ù§Ú£7¹ÇQ^e¾ùÖ›<)bI†y„Rž |ïù! ò¿Œ)ÃY–X»¼ö|ÆQh_…ŒÂ¿8q¥RƒBm¿Ô¾4í€ÌN c³ÃÖË–ÃX‚9ü .œÛl²ð‰8^Þ;ï±Þ…lzšï¤’¨Õ¯Q5*%{ÓÝ[;—HqÌÄLõÆÝ,&þ ƒ?ó§`XŒ“DÌ´f´l{`Ž»¶Ú¡Ö CÛuHI3ªþœ}”búLΗ¿—o+Þ½/®Þåל…A‰xOŽ9DÛ§¿Hy†Î(& îäTJµ-jYvÝPªoºV]ìdYô?g‡1HQ”ųïFvƒS'ðÌÆL0O¢£*p’âŒ1Ô_•ü‹8›¬øÑ¤¶“¥–P‰´TÙHäH•FÖh³J2™iC:EXê§+ˆ8رª¤ÖÛ±CÀ!›Ó¹X¢Ô.^a[?†í/¸&˜ L¡Jjë9ad))ÎêÖHS¨€FàÏbÏiWlJÝVÚIh?Ñ0\€æ:s4oü¶7¨>@‰XøGô§@¤E˜¸ñ/%˜Ð8rŽ×K¿/d]_O.`þÖË/9üÚë¶éAç ¤:YTÃØ›ÉåëÆwSü”ÃåÔPã/ò[¶}-ƒKüÏÅtdýŒÍ½‘º0ƒ);€)€Êê5®fÃ6`ÀOáo5ªÛ¿gÃS«²®”ÉüöÕ9ˆ–S1÷›=t‚BCµVP¥'p_f;8›¨p…JàªDÑ|‘îäZÁÓH,E¦ d‹%žN ÛÂìZ YêÍÄKDÔÿ<',¤eÏÇ ©I¼NöÙ= ¸GX‹òÊ£¶tÓ™ž-g¸%óÍ0tè‘$ÐöÈÒXy†Ê•Å-H,maÙ>—X¬—x¾/¨‹ôí(-yÿfÔÄÿAñfåXËM@¡%ˆÌ}¦¤Ëøå{DO ?[ÎWnøNÃtîkáÚÇ"R¸Ø`p¢íØWvâÍž”c’ÒìÁðy¶Í=?œàè8ïìt° oŠŽ2Gá ]»— jÝ*Û\§ ä0þè*–Ûœ`u«o»òÞ  ­Ó%ó[ÙÕZˆ{8«A2ñD“5»Ò }Ûì ÚHëG¨ÑÁª‚FhsJ›²¯Û¾Y&!ÐtÃN:¡P]šÒ[(¨šÓ}:drì—‡GÇŸï<Á·Ãà„9W7þ6ÔõRÖP SéF¥‹U•}#-¾£…ƒ0&Äú7¡yqqzX‹æ·ðå§ì|yÿÓË$zHòd"ó,ÆvA|f"ó7‘u”Õ}}& s^‹òËã™ÚV ä®åq÷ P¾|é$w|íÚñéÊYŠàÉÏPLŒ0ºz§géâþÕÅ÷*÷>ÀçNJ*žendstream endobj 1050 0 obj 1147 endobj 1054 0 obj <> stream xœXkoÜ6ý>¿‚èkR‹I‰‘öC»qÑîfԘ‹fÄ™QW–=<žýõ½|êÛ)bĉD^ÞǹçêŠ0A‘úcïïWßÜ¦èØ­"t\}ZýÙ_û{ôÃfÅÐf«Eð³9¬ÌN‚(˜Å(emîWAH×›?Á ,& ÁÕºM± hŒBõ Lk"¤„¡0áú}Y÷¨8çía{”ý¶­UÙõÝVÖ}{ÙJYÝ6¿ ” šá …$ÖûÞé=·nýO2/Ð þºV+Õš÷nÍouWkY m³î¯×W«`pOßèÇ•¬÷M!õ£…•7m~&/½ ê…össv ~hš ½)än8nó¢h·C?æe•ï*}@4YûÛäøæ²xþ óΜE0Ÿì¿iÛ¦…Úön o'u Mö¨® ÅÉV.BeÏ&ŽyCÚ´]t8I¬—Á9WË,½Œ0œ¥`Û¼ìÚ±‘bÌ G¶bz5'û¡U(Ø]^%g‚ºCLOù~ÒÍUÉ­j‘»À1OcH)ÃÔ­ù1èOm3O(G ´©l×I ­MÒ¯ÿØüs¥°]ö¡FÝ ábçýá˜û˜ßýwûîý¶þµ¬_Šm"?PûÖE—×…ÁdSUÍšªsœËúˆkáˆ8Ðì€òV¢Nöȹ«¶Y‡;ãhHÀ@ ¾Xøê—%U}Ä#:P‚-ç’y„mY‚Ç|,ÁÍ\Tƒ£± ýé>w—^vר9èÄUICPWÊ >‘BEYäpÖU³“"&¼³`kWgàYÈâ—¢L1‡—fŸ"¸d)NS–}!F@pkL>ly*>”îç,Á©5y½p 슔X¹}³íú¼íŸ`O ЖáÄ/¿ :¹ 4Œ‰â8hÓø´0”DØeãnmR¨½’A5ÖÅ„ —5@ðr/ÀÆÓ†/efç¥ìGjüÚäOºA¥?ß÷ߣÎ<ŒlÜgh2×;-Y¶y}”žç/è.P³ šúÚðvÐáž!I©0§[LÃP(k(f^îW),c©ÃéS1’À’̾`Þ–|€bC+@-Ðj1ÀÚÞù [ 1ÁY»¼“u~/ýTÚ5ý ¢¥ ´µ¡yfh¦]öhÈ‹«,»jªõ:N…›(ÊfLèæ‰OLln¦Q“8ÓcbÒûž| àVœ¹LD> WµÈl¼ÖæŸlU,Àz™È´sª« Çg)$&ötöóáóv"Ô”ç¥Ç²§`’&Ì¥š0;I²À¯¦ÿ/[Jå™,‹Xù²ì7gDⵉ&^j’e@Ù£’x¥O"–˜Œ{PÔM¯1tò0TÕE›îÔ ÌUÈõ¤ƒ,ðØ/£Š Ô!oËNÁMîsØ­Å èׇoг.M C[8–k ¤ øBxHqLRn°ûSî{hD@¥Ó ¬¤æNmi’ìÇn²à±ž‹ôff)w˜î¤Qs甕ŠÊ¢Øi”̈¹r$ø$§9D»R ½‚ŒNSyx¦ø!cP:±àÛ-äxÛ—²Ø»ã3ªƒÄ)ŽRîëäòâ…èy ‰iƒ¼ÓEÛƒJ’ƒ††î×YÚ •ÓÙ0å2Vuõ›2ç|ÈÒX÷ÐLò\)Э ìŠÒ4Å•-Ž`Ī}^+G ŸàË~¨ò^E«§ÅÕ|X@NÜM(d˜qÃØ¶9Ðë'JJ¿82Æ¿<,a½È÷æ~åˆâéˆðŠQ«g‰áéüÚ À VÄæé^iІvó¥½åz…Õ*ªZ9°hçw•‘åÀ€ŽD'¸ä®d†KÔ ›Ý$1jEBœžÔäj´#ÁÀØi›‘å´¡?‘*ÒtÑÿ¨{€”Ø— Ý~öO¢SK¼ŠtƒÉê±L^?5·“Î’=TH¤?›±ÉR=5ÕíBx“Ó©ù‘^í§¸+·M:J5[ƪ[¡9½Ëéšs{(Üg0.@üóÔ!¢ëïa’nXÂÓ’Êv TZ.‡0uŒ“)7üÝy³ ‡›ä¦‘šDx†Îa‘¦~Üìû¬~»):#êøz©)æÕ‰˜Á^†Ç §Õ‰qÊ¢‰Ãóê»þ…»ûxÑ ½B©æ¥åõ@Qµ—Oî.ùˇíÍ/›Ûß—À!d4êèФ’ªÖнnRW>ÓŽß÷è2.Í~z‡U£ÛWÛ|s{ûávq*ŒhèÍÉÉõœÏàz=~§-Ÿéó|Ö¶³ãN.}t7ÿk´3‚!Á`GbÛ9ù¢†SJå^ñAÞëéoë&b}krm˜W³¯p¥áðuž´ùôû„ìE àðAb“‡ AÖÍwueæ«…¾" ¡‘V|0ö©OÆÇ`üúgG“`ñÐÈúL˜¬•„•H^:›aJt·rlÕ»>õl§Ә0Ð<ùw~A4¢dܪ»©ÛþÅïœ7›Õ¯ðç/+#¬tendstream endobj 1055 0 obj 2108 endobj 1059 0 obj <> stream xœVÛnã6}÷Wû*X1")Q"úÔ"iwÛ-Š.Üö!) F¢m5²ä¥${ó÷’¢ì8)¶q /s9sæp¾ „P”ØÏô»Ü-n>çhÓ/´Y|YP·‰¦_åý°\p´,áe¾—ë…¿I’ðå\ ånc-ÿ3p˜2"¥°ç–Õ³ Åv LÈÉDÌ(Gq&Ü~ݨ:*³^mô°2í¦©û¡_év0Ï«u­›ªÀÖ+Hbšº[·îÆçpúƒVÚÂ÷ö¤=ó)œù£íëM«+ä,¶ãî}tµÀcX½vËn/–Ë®ÒnéÂʵQGú_ìͲëžtõö%¿çî1J‘c8sgLg ]ÊIXî>µnÝÙ§9É'Çád<ók‰îoÕà kÉÑ„$Išc`Ï!bh! ¬šQ÷HÚn°þ˱Qƒ®HgI‚o;·>öÚ×a=¶åPw-‰þ^þ ˜ˆRÇ,Î œ˜sëþÌ:‚á b¨rÐä„%t‚õ;U2îÊ•‰hF*$¤²=é¨ä$ ˜™hì2=Ó‚ÙâKCoµý͵ݻ¾yˆ¾»`€5ý ò`é©AÖFë©M†Î¨ tŠudÁBÏŽyWç2hÁ³m3åú§Ñ§,/üÓ”$õÁ¹4Úòšÿ¹ ˜;™z†KòsIŠP£}Àje™¥ŽÄ¾ì ÂÚaV’{üq@]Û<#£‡Ñ´=º˜)§9þkuû)² ’Ðÿ¹úí—3æpëçjNØeúIô3 Z¤„òL¾ 5&"ÐÊ/…È1ô40(-Ó@ §Úµîf §à9É}/ßû2÷rY#—÷Úõ eÐ&¥¶" 9*‡3zÀà¢6ú5G™Å0 íI¼è„Ú_â aÛ&Ю½Ð±¶Ý8xÈ@å\t³ÜAeôZÝ–ÚF¥Z§ ~³\€NL {¾= DAF'Yâ³­w}ïBã9á9ŸprÖåÖf BPªÖW{oàßÖ+ŒQÁ¿pn„­hªzáŸJy2/<öjPÐaÝÎ[GÌâže¸n4AË-äiŸG>ž$•Ù€»³ÑvèèU®È±z†NOÅ´dÃ0ƒ&DªFÕ û"è¾×½§'K‘I:GÞIklWo¶zÔ3Kt? zž»ÜÛ!"OHÊç磦Þ`aä™ÂÎ9dÒõ¯• »EÞŽ£žÑƒ—^ 6¡gM8 _! (Çñ¤ö»=g0h?ºÀÀVž°ÿÉQAÂË(J<7¥UöB‘îñ»êxê³®ÆÝÅðµ7X Tq­šq|ŒƒÇwÐN0EØBØw<> xãÃáð¡z²µ“y&°—`Ǧ Õrj½¼¾Ç0a9‚~…&d 7gC 87¿9ùß-¿Ãç_{ž[ôendstream endobj 1060 0 obj 1438 endobj 1064 0 obj <> stream xœ•VKo›@¾ó+¶‚LØÅ#'—ʹ´©ª¦´=Ô°P* Éb'N«þ÷Î>l0Æu",­Ùùæ›çò€l #›?j—Ú凲Z³Q¦=hX"µÄKô6ÐÄ … ‚_jR#âú–3Bžã¢`©C2~ cbù¾Ëå‚D3ˆ‹†ü |1Ä Ç®8ÏË¢›hy_ÐEO!+³"¯Wscö±4œÑÅ:CÉ"3åû cCç”/óÆ#ÜjÆŸÁ™F&Ö ùKù/eg%MP\­ÁÒ5²§\I˜e´–gÒùö€LºM„PQEÉ–f=787] ›Š×S¬òÍ…ò›k4ûÎn¿†ßÏè€-£«5+9%Áo¸wøWPNÛb6èzá¡öˆŠò4¿Šw ÛÖHí §§èâ"F9²ïXî± ý¤QBYX¥iM›`áàO[éÏ˨(” ëü7møà ÿ#MÏ-!‚Á¤"*½³3%aéfEMUJdVÐRåÐ÷^AóâÞë­”qì,O¶ÁúÎq]Û6¦—b9Ÿ~ï¤Ïß9v©ìxM{#% ¤³î:‚ýÑ.=ÿuwÓ$akš-i ‘§W;ÔØY&v“»Å~W *Å`Œ=‡þé­RU;aÄXô|¬»é4gõ ú¾Ì¨0sBã>é"êUééÔ TT£ÿrÅ.¢:UÛæf· õ½0õV•›ú~mš­á£«Â2õvÒM½7Wܨ¡wg­Å=ùž˜í÷E¨=—öËññ¾½v>šÀ´©žu3•‹e´ƒ‘Èz{ÿX)dEµˆŠ°‰ÇcT¬i§ `V‚g0ù(ºê©c>ißîØjA7ÉVWG|Xxqoå)óy™Ð$+«¯k;7¡bÄù^iõû{:§ñk’OÕMvw´ rrwb¾ˆ/ìX¶³/NséÕžE</ û‰Mp£èaËßÝW'?ní<ÿÙ|Žendstream endobj 1065 0 obj 771 endobj 1069 0 obj <> stream xœ•UYo›@~çWL_lÆ]0¥îCå¼4©¬Z´}¨+D`!®049Tå¿wv¹|¥Q…­µgæ›ùæØá BÁO{†[åbå@R*$ʽB¥Ú#ÜÂGO1Á ÑŠ2À+ ’³]bZà˜6x[EÕÙÈû…nИ2⺶°ó"EeèB….ÜÖ…î˜dúÔ–/BK-ðn‡ þQQ/ưÈGçÊÔ VãÆò2ßòên“%0¾(]茎Â<¶ÁÓzÐ#›‰Èæ`Hˆ¾§yù·ˆÍ‘zävñ±ÿ5+7IÆ#ë"ã’W«ùáç±oвò‹ K8Ϫâ¹á}åYtý , °ç˜rVAÁKÞdt~L£ê4‚ý¢ÆyE‚Ë‚—0™ äTÙêOyÖ±éâ`æÑ«|è«ÖkÚ„"i`úE–¤‘|Ê×jt›hí¨«]:ZŸŒ&‹{ÖñõLÓÎ(~™Æ‹"/Ö#t¿ír’$wsX|÷7ßüåµ, úÜ3-xU™lÂk#5ƒÉ¼¯_Ó?9²½úÃЊS=hcµ„®V«åêÿÇø ÑAåõqu^š›=JåÅfx§¦P1âLåµ ".œHØZxÅ ÜòRÿPe_Ó<ˆübD-±6\µép¹V×£ÑOïÓÞâèà:ÛÙ bò£O½ƒ£5ƒ¶à·ubxNݹq‡÷üÎ*mÐ+1#0nGå;[±[ -˜-©-3 ¬Ã—e\§i U~°)nLj8íÂ<™ Æk0ýžZÄb-FtdÀêŽC\gaµÉÅ$Šþ•Ñ\‡Ø¶5k£õÍ=ðo[¤3‘eÒ-ÌÐu]ÐMGJW\ˆåÛšÄ0Ûžªæð"˜î.o‚Qò9xf0: J\§ƒ¿ù¹ò”/øüńѷendstream endobj 1070 0 obj 719 endobj 1074 0 obj <> stream xœX[Ûº~÷¯ ÎKecÍI݈^€´ÉCÛ4A·n‹ƒÝÂ%ÊVŽ-9¢´÷×w8%YÞÍ Š ²±9Îå›™oò•ø”ßüô¿³Óâþ!&{½ðÉ~ñuÁðô¿²ùãf!È&)Æ üÙ {“I*‹ˆlN oÍ—›/ „§RFFn“/<žµ9Zs&È:ŒðK­Zm¾½²×Ëe»´jªý±Ô­ÞfuWµ½è`›ÈúøÏÍËÂ{òÊ‚¤UNêêx!e1{ìM’Xö/|ÿ_P9}õ—šTuµ®ºãñiIÚš´Eªî´S :(üˆ‚idmäÍ=%x±.Ho•UÖ­²¶¬+’ÕU«ªVƒ’´%Ê(`!D”EöU·%ÞþW)yg$DBã€sg—“Чôx$éÉxBÌci›’¢nˆJ³yH«½"ËJ‘Qyç’>éH›ïG£õ~œ8·•ÕM®rRVó &4 {Uùn?‹#h'Cý8F©&)Ñe®ˆÂ$…æKç¸+ T”|ªãÞÅÆ`1¤ðXîòô(¦ÜÅmòJS—sHÑAÈcbàHʸ½t ¬ô³"éˆ` ^‰¹ÝÞ±Qi~!ØÁh¥¾#»%÷½®5xûÏæ/€–PƒyF)¸5§"éù|,³ó_©+£AÃ!'Ïx&ìU°Æ Ý5Íh%£’ w ¾v ð €!ÏLíÙe–5iTû¢?¥¹ÚuûmYõ,`Ü¥× Ê@ÞAøTî-”DKvŠëBm¥Ãë¾ä(EcðçâJ Ë^ÃPÊÚ®©4yÆbˆÆbHAd£¨š ùÚ•Ù/Pá¦Ô1ÁÐMf2RE?ÜMŒz+û¥Ó-Iµ- ŸÑÈ -ȕΚr‡Å`í>§MºoÒó½ç ö’ò©Ï"Ø>–¿™š'€­áé>ÎØ3Ô‰²Þà CZï¾À¤0BËÀ+ÊZWt••ìË(ذf’ÓPJç¥÷þßÛ÷ÿµýôyûáÓæáç›Öè@esm>¯9~ä¸óY×'ïWØâö·‚ALƒº†.u2¡lóf‰>åQ_­Î´ŸfvIAßEÒ ã•°á¼RMS73-  磭v²Ø^ßcŸFËb¢/lh¥µ’s]B{oHféÜÔ s²8¡ô,s{3Â.@o©3l1”ü þ6!¼ ‹}pÕe!>·-ʪԇ'ïiy“®hìæIÛíuT©V­:Õ`f;Î[ÃqL}\ùùèÔ©† æ2ˆ2Ç«Öí_J&m#ïq—˜&Ò” §qˆ•Ð6)'98@?²ð衇{Õn›%3yèÙÙâýÖnw©.3îÏÑítõµù‚ä|Tû†¶÷(ñÞ%Ùv‡YKh2V ü³Ò徂`¸ûe•«o(mä>ÞÈ­Èƈj¶uQJïÀc ? Vô8ÐWpÀ8$­Oµßêò¿êÎÖ^[㮚×'wÁ.ï×Õ[×Am]vƒ™3~?'£æŽÜ¯HHV÷·šÞðefPšçÒúÿóF«ý ÈÓVŒ³¶nÞÒâO옄¿$hh.v$àÝ7ë¢OÕ6mšôbö=Ù¢lM¡]øÄwåÏ)ÈÓ› ›Õcçv”ÕrÍ¡÷x÷¦o­îŸ–¿uPw¥¾¶Ø´8g4ˆ,ký\ÝeÄújÊÞ LIY̯ûìç¿Îº PhhÆÌ¦i³ãÐÆjÒK6–¦îöÛöún˜6h3÷9M¤ÎûΤÒ\!‚_§ïÉ«Í5DyÎ>ót|ðuþ銧™{|µ¥¼6 „»k»ª  ¼ 0–a\¬½wÙÈÉb K†oo˜(në™ %æŽ÷Üð¡¼ÖÏÃ`ŒÝ£‡Ë¤W©\èeš\êcž¹e»6Î$âÞ7dˆùM›„ ¡"ïýzw¼1C«•2–&Ù³x¯Mœ°ßeÆq!âF—Ÿ–<Š`6%^ù´ C ¬^ K˜÷{ù^I~g]ûip·ß½„ æl\Ù@ þ‡ ü7H #Á‹T3 -u‡ s33q¹žlÀÇ|Ato3jö&ŒÏ͈”!ÍáSCȾ d$ †ˆÕ1`¸,ôŠv±ÆÓ½XZö2V QÀœÝʶNñ;Øaå•N}_’8Ým}3Rú|ÈÀ2ƒ6èhÚ²c >­¼"/‡2;Ø 3@Z ÕUg@FÅÂÀ¦ËDè"yy¹*°¡y†ýÓú—ò|VùÓ²ç¤Ô.Në0;¢÷3f RΑ§E0hêÆ'´BèD=gbVþÅ>†R0+}\s¾|\Ý÷V·ÓfŽ„ˆMR¢k¬aLCgº×\BÞG^öJ¡öï! Ù>›Ô¼V¬°J]¤ÓªèÌŠ…žåik{Þ‡.¡ &ËÌ̦ ¤Q¸\]± Ì`dï©Ñj;"æSÝaÛÂiˆìf™E„AáÄÁ®/v;³ {×ö¤\ieª¹<©k¦-¡œÃ„ßY>9PCã¯W{ $þ°u<s­÷ ÇuÐça±6$Ùt¹ Älj61}EŒÚ®b>ü-½Àl¼3*‡Éÿ«ÿ÷a³ø;üüé^nâendstream endobj 1075 0 obj 2042 endobj 1079 0 obj <> stream xœ­XëoãDÿž¿b¿SÕ{ûòc%@µH@¹B8¡+ŠÜx“»g;}ü÷̾lÇq¯‡R)­w<ßÌof¶Áýqßëýìí"AÛfFÐvöqFÍ!r_ë=ún9ãh¹)Êü,73û&E,–˜ ”ð-÷³ dóå_ „)ÃRÆZn™Ï&Q¨Þ.RD©Ö2ÊQEú˜á¾gAŒYŠæ(×Â"ÁŒ€=£âCð˜Õ›ÕVµ«zN(gQPnwEÓ®ªÍ¦çE™«§ÕÜL¨`A¶;¨›àf>ÿsù£v^:çC¯8dF51¶‹²EyocRµÕxa¤.Ôía‹òÛí¹öüNQH…‰Ö üV6ŶT9ZWe«žœ#­å®Nä¬-U¶õ³—}s"tæÄ¬3«êÐNKmwÕm¶[}Bø²®«)ý ½æ7´ñX|Å)I H×%jëµj›ÍSJfqêÒýy8‚Q«Ä[e2Å‚x%µju96rŠ“¸ûýêâê÷ÕõOZãHÊQ­Æ{•çM_ŸüM\qª5' Nº×»Èb,9‘Nð¬ê40†©L½êΣÈ(˜ÓžÙz³N>BM·jïz˜3]Ñ‘45‹ŠÒ<]dåV¡+€-ç‰Ô|J‚ìv§ LMÓ4Á)@á<´ÙP=th¡¬®³gSv ß9N»lg=*vÆíóÄ CÖË5!­Úª@,SéÕm{ˆ$&Rxì¦+rŒT .€…Îq„T£ÖmQ•Í3q£àï Ï™¤í€À¹æì*ËóÚ˨Pâ®ÙÜÌ+0@‚Mk´g©kiĺu§:W„sÅ&ð0ÉÄæýšmªu„”0±Ž[Á/Ù°$Sê‹€N%3ð7 TĈ‘À"Š<²GÆÔ€·7ªA!»ŠÚ¥"õ‘gëv÷Œ²ÆÂí‚ø £B"ƒBírtŸ5 ´˜¶:Á›¦)–´§æiðŽÞfM±n¦Z€èÙŠ" íÑ«¸á„Ëaƒ¶F]m®ýv\Š\`Îzmßu³¶µM 2ôŠ0<À«±ut<‘Sö×Õ¡S!äP+óxnêj?R)"ÌhübÛÆ[7ôt\CäÏ÷¸€cÜèöZTVåm`„´wY{Ò¥LtžŸèÀ°Œ± ç XÐSîs2Ƽ.;Ô¿ùš  Ú×Wcú€gŸ› },ž.JÔ×È‹OW%ù$›E’Án›À ‡Y²=ì¡ gÕa}§r;G4dWЋ¸] 4d€U­t$M‰]Wu}¸w#]ÀVB׋Xwqàûo‡C¿vñ}„ò¬Í´Þq™&B.y Èåbq½SšÀ"Õ­Fûb{×á°P@í¦é`K)OÚ%’ß.ª#C@6仞¿nS0â(WmVì<º|ıŽ6‘L]@Ä¿¼€Ô»/¾h/Ü$ޝÓ—GÃò°¿UõÔ•À¶Û[¦ÏóÁá¡»I˜÷vªœz¼úX:yÿpÖî+§¯‹°ÿr1\GPѺòjP†M»: húb@çÅÕåÙ¨ž"è§>ݵ2å°Y6JAÂæR/uúZYoðÝÍ|´5øt‚ÉFÀ ÷ö(E/ÁAaµ•óíp}¨k@ ¹z±ùžS½x’8xjOÍ•Þö0û#Ó©ìcv¦‡[¶Þe£ÔoÙî$´×ËN@Z@Ź[*Ë‘˜ƒoÈByê¢1Ý»˜Oú'8ø§G̫֘Ùé_LlöÒç@¤8$Ž:pB£)®Ñ©îS‚tÛÀï£_¡µ#øãçì1ÂhÿbB±ì.‘¯þ÷ãr9û>ÿ»±xendstream endobj 1080 0 obj 1531 endobj 1084 0 obj <> stream xœYkoÛ:ýî_ÁoWb^‘Ô‹»H t7·Åz½{±h,Ó¶Z[r%¹ÙÜ_¿3CR¯ænŠHó1œ9sæÌô ¹`!þq?‹óâ×uÊí"d‡Å·… /™ûQœÙ_6 Å6¬’ÁßÍ~aw &ÍUÄR•°Íy¬äróŽÅBr­\·Ù-²~GhwÄJ ÅVqBßߘªk^N¦r‹ü=p¼V±¶§H.ðžçÅç 1ݵ©ZÖ ƒ]‡îÈÊŠ>ñÙ.eÈC!¢àzxjªÃ©l»–µ¦èʺbõžÖ]ò¦+‹ë)oXcŠºÙ-ÿ³ùëbå/\‰¯Tx»Íì8ûÐý‚’;bÍ“Xº¶×áåŠ'IfZs[³c] &9ÃSñQ™¥ˆyÊ(øoçì`Ïew¤Ç”-sÖ³¢®:XO#k9Y;öfª¸ —áÈ£_Ëj7si;“½Krã,: ^%ýëî~Z?ÜßÌNŠì‚ÏAu=oM³Œq[–Ö¾•Ð`•–Þ¨+•’GÿQŸ/ÚØ²cާ¯”91¿d©ó"O´Ý÷Ýèj =«XHÍ3)´TX÷¡5›Ý}1M7Þ²s žÝ› õ§Mîíü:Iö¥x«ðëâÔ®{®Ùè~ų,ÝŸŒïgBÀ:¡e;ÓM¹-«Ý#³§¡ò8 `ËÁ´KŽß¢7,¶67ŸƒÑ#=žlH0¼õµCØÓ¬ìa§³áŸãHªŒGñ(îwÿzúøééþãfýïYüEèPU+%´·v”Iz±5p†0ˆ["|tLÛQ¶Îo‚s¹æ2^vÎOûº9CzÕÍ+w_ðT&neÄS½ß·¦›]ˆüùh·Í{¸R¶n FøÍ>2Iy*|\(Á9ñîœÞÇ6)'Þ¼_¯?­ç÷'>•¬/]g o€Ä‘€7SJ"$Ó• —š­ ¸>Íx+="àâ ýÔ²;²\ð„ ž"Åiºßßó%’™ð)½~¯n#@)1ª€MZ$ĨŠ:þ +˜EÎpñOÀ¤ÌòßæhZÃöת°]šÚUÅÁ÷r ¬0Œd.Ë·ˆWDt¾Û5¦m-p1»²È;öö…ås䢻ÈÉï6ÎÆå/³GIä+RÞun”M`HOuP8ëákg|ŠÚëóÆg+X`«ÍnP=R™Î Ýid‹N€š¢l èÇ%d).´‡ Fd¥Ð¥°ÎÓ@~7D Ìö‰ê6`ªÝsFÞÆuIÆEèQ‘ù%CòËåô‚µÈ$Šlé†J½(óYð`Àc³½p倡?Û‹æBEcÖï#ÎîóâH(–<õY˜õKŠØÊ:f\ðÔ–D ®Ù=çÍþé`:çñ§ü1Έj–ð´ÔÍ<€æã7?ðµã€-S\'Ë‘^ÿ‚ƒ6 Ѓµ¥¦H//‚»gŠwÊe˜f^å(Mx ^oSœµ]s-:¨Y\…\þ|,á¹@‚¯á]-ÔŽSV";&:°X@âª ß PjÐÊýoo~µ6§1—–1å}vfO2+2(+ʈyF‚3Ok§rKåǹ‘“""dB»¼ŽùHHŽxfÉ ÅUŸ¬ŸƒçrR€2TwNs8$ÂcÃWin‚D{.QÝ2 ¡žÁÓ>4ÿ/n_IPˆa½‘ ˜Äv¾¬aÏK€Ï—+èNò ª)¿icÉgC@€OÊÑ„¯ö¦1UAœ9;„/JÓÀš?”Æ^å9ÒÄbE)Y™}_JR€Ø²¾B½ùpß:èu¨ý°é{ÒH/‘v­B4hÍfFF@(QöFñ• c_Ê“-V× ôÖÿ¹~E¨z}˜Š^Gæý &² öõ`Gãi›·fN;àî4ö<õ§•ÌÛ‹•ŒžF@m©®Ú†äǶ’r"êg€á(aŒEè@d`GŸòÓÕà•À§  ˜ž«€iY¬Ôf:t¾ƒŒàÒ=æ1xÇl ZS‘ȱ¢yŒm@G©Ÿö'”cïO¼ÊJ’Éà+@GcNua#¾'¥ Þü.R’Êç¼ÛAÚDHÑ”´¿wé÷Xûj ]D¨­'ÑW®‹c8Ð*öª¦ve’WYÆ3-|· l¦'ýвgR¿¢{НÏã,Ê¢È+Ôü«Û$œuCY ¬fö½½HUÖŒ¹ó­UªŠZ´å[8Ž…‡që‘o¡Òa®’cºãµu]b¯÷t;ÍIg H“>=ïªvâ‘LP}É ã‡ õö ¶Ain¯A°Ù"(T”΢SY}e]y6¼—È å•M.à¬ü´Â'!mÉAÍsÁ¨U°nIïܹ¨q¼öTåg3$}úúݾ³}LÕ±äÑô¤;úú+Ûm·xnœòµP•pqÌvsƒôJiÛ|ß47€a¿,Vö?xÂÄ•Tˆ#¯@S5¥™Äa2tWßPˆ”rà4l;Án¤RásVc˜‡èî-ƒiЍ¯#h#ò%ŸÌlÔCeЙ%'jZ@TC›²¤˜;ÃÖð’*êóUg}‡TÒ$æÚšýõD$ã²Rýy)h¦•y…|‡Tzi0°4G¢P8bT7Wþ&ÀíÕú'œ{Ò$ìuTW/• Îâ`_ÐAVB…½V­ðÊúÚ´fœ'Á#¨²Ú4´ù¡Û´´K¸1JÞÖVãîÐMbɵù_Ú\þ ':S¿!?@»¹…€¼aÔNÐpÍ7Bv¦…C`¤èÜPaÑÄ}P5‘ø+Ë’´GU€†~õ2‚äw"ýÀ,ßw¦±/âõLS“‹l¤C.#-Ä8ÍO”]™ŸÊ?r?ÙÕ•±ÓN…$!s˜ºô¯díµ(ŒÙµ·¶-f$p|ì‹×Ïì¹J\)-|‹©ÌOHZCãLt p„¢L …@”â,s„KÒ!œ¥ã!zÐoÒa9!6˜ïšªy­É ÉP£B–OsúRÎçÖ PŠo7îlÝ"(i–öa5D1¦%¡·ÕކHûÆØ,ðo=ÖÎ ® R!ýKLq°ëGÊFKPô÷½tÊä•\M`Çý˜Qº¶¹®V÷§½s|‹c?¸öR·m‰Ô4²ÛÇÍ›dsÿñŸÌöÈ«,±—ø¹8•ZÐÚ «K;Õ†\1çK÷âçËU ]½L0‘Þ.~ôé„·²¿ÂË¡*ÿ0”¢„kPÑ8ØYÀ­r†çi_"5žqÈNøÍo Íe(E?¶'±Ö7oþÅýfñwøó?§¸§Õendstream endobj 1085 0 obj 2582 endobj 1089 0 obj <> stream xœÕWÛnÛF}çWÌ[(ÃÜp/¼ìc 9EÚ4FU%A%®d&©’T÷ë;{£dZi’ÇBl“³³s9çÌèoˆ …XÜïÕ.x>Ë`Ó1l‚¿j^‚ûµÚÁOó€Ã|…V”þÌ×=I¥’pOa¾ ˆMæÑ SF¤LµÝ¼ BN!Ò¯"F9DIª~÷M×UËj[õPÔ%”ªØÂ±êï¡ê¡ØïÛfßVE¯¶“T ;ÁC2ùkþKÀÐëë`~õ!|µ†þ^A§V}ÕÔP6ªƒºéAM¨>‘òðKÕõÆf}¨­Q«úC[w00Idž§áûÅôõ„Æ1‰©ß-ÞÜ.nÞÌg檈’Dä:#.b"Xî2ú“ ©FþMÄÌ;J8O`~ \t­‚ªÃ¡ª{ÕÖ˜£jÛ¦Åt{ [•£ÓÞ±àҜ匤qê.Ÿê€ß-nf³Û™3ô‘1ɰ#C ¢«Û©¾ÓW“ø¸ÔŽÑ æC%E»^lT¿h‹z£º»ðn2º=ò†3ši¯Âù=–¶2yAÓV›J—wUl·P£c…'Øh™%iØ´Ÿ`=¡ºï2¬jÇ{Uƒ¶_5»}µ-Lu…µº/,(X¨XúÒ&Ynû¬ ?¡>'YÌ`ˆÒšh€;SøˆKJ2É|¹¡6•°(ËVuÝ¢«þQæ6úÉÓÔ»ôÖ•†ùŒÆ3`XVjTF–Œf.º°0=–„ÆYN}o7‡ª‘. ¯*úÙÒ‰ñPµ®P³~„ZGKŽé‹Ì]p«¡or± i–»puBxj3³!tpzIØ6+Ó–» ìŠ~uon>tØðõ¸ 'TúÊ²Ë Ø¢ 3W»¢Ô嘂êàéü¯Å%¯ÂQ0$öÍ@ý)÷”ü;¸qñ®1;r‚9¿çäЄb,+” T®oÖk À£Â%æ"{V}9qQ*\:jbY©}¯ùˆáì*”ýzsQ‹Pƒ³áZƒ¯Y¯QºFIçèYæ;RæVœ6" ©Çœ;<]C×X®·ª(õíS/ïØŒšÅh/¼À¾qNéħ©o’ö¦ÙKÝGWTžÔë?¿yûX6"ŽÊä þ_©•@öZµîUmH6}uƒýëŸió̾]9'yÌ=Ë»úä+#ÒkOˆ#ÐN×­ÒlþdÅB;1£\fDÐÁøx&`(Òü„5×éj®[ÙZ7Q|LO€œ†º?^,t®a9aqxèa­L5¨Ä°‡¨V>Ô%¶2¸Ç¢Z¾wV¼WE«!cèá'Ï‚$#§bOÍT-(—›k£©B¯X s£µ¸]¯Á"í]øc•ÔQý$>³™ÛàêÊ%{:ðGµ©q _¹)®JÙª9Ôçžßb‡Ç¦Ë‡^=1¼1«‚ÊHÆg˜o3µ´Ç}+ŽöÍasïi6*\žâ14â?†ìNÅ0Ì8v”#.K¸+%RÏÓô¢¦Ú­]âÐîÐwh¨õÔ‘A¯ˆHšáüKóSÞŸ3Jæ@iëýbö’]ókÍò#îJÝ5uG.*ªøE=Ÿ ò+Šjc¹ˆ8<®r?¶3³«³ý/p¨ÿÜÏŸÓ†0*1®©)•òÇ&µ4ží‘Ëk²À9'Þ­[“oc‡ÌàȯÆOFZ¥ò´_¬ä8ÄUÎ{fDäÜêyc¤Ñœð:YvKTøŸ[üœrâ—?#ïwÃÌ<6N¹F¨Ká3?q(9§aà“ߊ`1£§ÓHB9l‚ßüÖv3~ÇÏ¿wáÑÿendstream endobj 1090 0 obj 1411 endobj 1094 0 obj <> stream xœYÛnã8}÷WðmåFÌ/ºpÞÒHf‘EO›ñlc, ŦmÍÈ’G—¸³_¿U¼H²ré 8m‰dUS§ª˜¿IH ñÇ}®³Ÿî²kf!ÙÍþž1ó¸õ|^ÎY®á-Æ ü[ngv%#¨¶s.!X\ÛF·óÿ.ÿ5¶^€Q\úë­y6Š'HAýKt9Ãa>v&nû¼!Û®´!ƒßKc­8å4ô/ß§lΣ0h*ó±eæ#üÍØgöŽ{žzˆõ±Õ‡G]òºðc傃ŠÅdÁ=ƒ)e}l# …VÞ—w¿HòÏÛßIs,òv±9ÍUi$¢ «·Dφ,Á÷V— ºòõö‹1m!¥A¢/ìÆ MtÿŸÉp8˜ÅSÙŸmÙ˜·{’ùN@ÉÇ?[$+7†m®7–Åàz’$Ãà!Ðg|P€ºdnãàûë|æl$ÄF·º>ä%,ÝÖÕÁ$” l'ãÜä®w §¢±§P°º´é;PшK ðrè: VY£ûÓLœÉvÎqä…îp¹’F©5—L†«À‰?”îŠ Ÿ.èòÜ7PÁ HV‘ÎIQë¶«Kc°ÝþñAÊ>I¶y™CŒI%e"ô «¼ð,0\Å0ö, 7CÈ! <ö1ßNÎOñ!K~xþBDœ¦Þm+Î £]Q騕UbÝšdÇÌþ‚á’®]~ºn¶¸$×W¤k?³ÉY^3à#©ÏkÐÚ0†¼n+rå[Ú¼N¬ð‘øv9Ö’(ò@ýx ‡Œ(ˆÑp Ã'ªjà <ן²qú…½þ¡’ØÂTtz ¸žotÙækH?påµê”Ð8I_èûXÚc Îá6ƒŽYÓà%/".hÄs2E.7™m!ÛÇgPF XÐÇ dCš¦V;—/jGU²¢xFl7XKR•šì³ôêæšœPLÑ眗4àIô± åi¢¼˜¹Šlt+,ÄÖ¡8H¥<óãDù´¯€sOs¬ßŒñ ChÀl¯$îk£$¥Ö½y˜c,Ã\Õ¾i÷¸s<‚›@ãÈ…E+ÒBr þHߣJ#ÅYƒ6Sgµ Êão¯hª)wQ™z¹ßœ aV;Ý®2kèCð0ŸÄ‰˜zf]†³DQ9œ´|©WMˆ½GÇ}–}›T»²&>$ ­ Ü»îì'Í¾ê žiÏ'â…l*â ôPðä  ò#=›9c RÐTxtN—+_AŠºÝ./wä¦Ü"Á ۯ˶~žÇhwÊ OQóLÏø %$”Âã”ë‰ÉÆyž¾?!«%ïÇO½¿(¥±ò6\®\½°$†æk°Ä‹†Ôh»Y£ÔG¶ó]¦¾­¨Ì6í>ÜÐ :r˜ÎdÈiÅ™j]•m–—ˆ@‹Šcp'˜¤´è'SЬ)wðû™<¦ä³^g G¦tb·Å{áT̶[:[ïáÃ1/,¶] úˆ¢•·Ð ™ž8)˜“k ØYç.iœ:G²ÍJa³jòÿi׸(É‚\ë€l ‡IF…‰Ï’ú43ÿXM3¾†}²ÚJMVÖ54 =µÎ6N‘l½çdÝCðkÕøf{Ð… MÇÐW.=îCcÊûé "³q#Ú@0Îö}‰ð-œàöí'`ã¸öy8ì7Ù`Gæ»ó~™qÐ)é™óÆüt@X¦°]QC yRÁY—Ÿo âEQ9²€¯>N®ÇÃÈÄ>2& Ä¡+ÚüXôæ4+,t{S“£öñ£ÅaçdY¨/䯴hîÑzƒP‰¤°Û~#ŽG)æYîwúýË—qyï›Räã•J£¤×—­c/(¤ÖÃZ ë²­˜ÂdÊ^]ë<ƒ´-Ĩú²¼¬êMãZ„˜™¦$øZ’¦[#‰/ÖÐ5®€¼lÎ’a™q~zU×r!ã¾A*Ÿ1'2òXTë¿P &T˜ä™Hݽ5ç{7mÝ­[°·²£ðB$1Mx:KŒ€Oc¹‰EŽü–¸Â‚eÛ±‰ê8ëëø'ß+®Ÿ[½ZW]9-¸À'³ã¹Làg؉•ö‚E„À¬pÀ0wíâ-2%·ìÌœ2'bƒ“µæAßµ:ˆOæ>%ûË¶è‘  ¿3CŠòdô±¹&± †0~I?Œ»ÑAÛãs|Ϙlùöìt?šHàQ¼ÿüXdë´ž§òŸÛ– \ûä•àBS œ„RšÚn¤^rß9¿ìCÔPj>†UbÎ÷·U¡œŽR=h/‘@j+§Âåy×ú»ƒv‹] o9—p3 ¼ÙÊA Eýdñ!Ûïpó«¹¢XB Âà ×VÖp¥‘†+K´`­k,ßdÓŽ`4vÎ0ý bCŽ L}eÑ(«Öìí†IÁ¡“ˆÒ÷<‹ûÂþá¡–ÑŸ qîy×x¤!ÕNT=ãɉ·åžŸM›SÏYê ½m…ÉL]×gõÅj*šëj¯oßVW_þ³º¾»ûz7½K€yÑߨû*sA)}ÛÛ([žoÚþ¨É¬Åb¨Jî¬Û¯«ëÛåÝSÚ@ÉS¾PùÙÔ?Ù6Np ó¯âuT 5Õè„F©ç"lìõW½¯|*ÿ±€žF¾;¹@ëŸN/9,V5\½&Ù 'Ö4ýˆÝ1õC 3–Ú7RoVsy(l_öK¾ëêþ˜/û; -Ç·<£ËÖˆN1pŠ\[Qí÷ƒ¡Q CãÓÆ71Ü61¾/Ýj yä݈é¯éüŒ¹à [ÎP*¶·-ɰA‹<‰ac̺þóköŒwÅlX˜`áô+ø·„ëåìßðóù\“éendstream endobj 1095 0 obj 2445 endobj 1099 0 obj <> stream xœ…VÛnÛF}çW \À¦lsEîòÚ4/…“ mŠ ŽÒŠ¢ ÄmíE²¸‘`úsÄ*r™'F‰ç™LRL3%ô™@lÔ§·zC³À÷ÍA6ie½zHa× N²…¾Á›5‚Þâd8Ö—û8¡ïY',žªF ÑLÛ6}„´Î¡GÂõ°]ã+›º¾²~PÛ§¬)F%0ꈙ‹1H±†zßCÑJE¢ª(#Oû³Éy‚G(m` ÕFP‹tOÞÈ&cúªp«©'˜±¤pá]¾Æ&†óC—õÞ×¹|€f'ÛT5îXǤ?2ß÷UâWÕïnßñpRAše²ëTT¥ÅÌs™ë&±v=TMs;ì O×RÎ%F<„‡ö¦Q ›|MÂn²Œ®]ß´j¾Ô³¿¿™YŽÀÚŽ¦¥®ï´%‚¬JEêˆI±ÀÆnø=&þ¤ò •X8¡ñãePv¤ü@¾r\†#·˜£Sü±‚¢œ½ˆ¹ 7`_í¬”¸‘³Fj3/°Êþ…J•y'#W‡£1 »J¹׺ÅÜ>jDvš)'µèI)s™3 „âĪŽsI„£í· Ù’#ªOg?á£1ì6‰h܃T„ 9ò¼T%¤sKÞNJ=4#œ‡ø3À챓›¾ßu?Ïç]3´™¥SmÉ”Þ<œ6ôýþÍž`ñ¾­­dM;Öì¹b|ŒÛ*V¿°¢Í?oêJ™©É:º=åo1¾QpÓŠç“î¨ó;rß&ì¦ßV?QΚ$ñ®{(Ÿhíô°÷ãÈÔÅ®}C˜' ÏÕ/jÕȬ dÑä=y ë§…™fW•=m©¡­hwÝ?A‹°·†›ÝìöhZáÒ¥Té@°,­qrå!l|Ð衵k•­rØ¥ ß=ÊFþžÇB”ûÉDÚiP¬i«'4ù) Xšy/ÓaªÛéj§fâ´œÑsâXÓw<×£×rÂDi܉ä8 i¶>oþÀéÈ]îí#%‘ÉüßߤoÖŸøùôzendstream endobj 1100 0 obj 1284 endobj 1104 0 obj <> stream xœÕXÛnã6}÷Wð­²±âŠ%Jí[‘EÑv»‹¦îER²DÛjmÉ«K.ýúÎð"9Šséå¥ÈNLÎpæðÌ™á~&e$Àû™fo/%Ù¶³€lgŸgL/û‘È×ËYH–9ìbœÀ¿åff,áqJCAd“åaæù|¾üÜÀfÆišÆ¸oYÌ<ØããÒÛË„°=ø>ý(Ååòˆ,og^LCŒªÀ­"¦AÈëà6k6«m±.«BÝ­v*+Tsí]ÏÓ!.ßYù\ÛèöÊ+«Ž·óBJ¢Ä;ñ5g y£Ó‹Û9 àKëj=çøw*¼~KŠõöÍü·åw ñ™ÀC®œ ‹„6ùÆúÆm9)i,#—ËÝb;ÀÄ…ùòÊâñîŽ]3x¤ˆ­>|\½û°¼4:aüpÂòí¯Ý¨¨PÕ.À,ìäQ¶¤ª äWZ<`ëà'EJDnû];ú iœŒL0A#"U])ÔG|Cú‰ ¾˜§IÏw7ìd È @¾í „Ö ·ïñ!F¨ƒ\Xú À$ñ ¼Þ]^j]dBz l'”LR*ƒ(:eø„!4«!ó·í¡Å(‘\€b™gÒ¶G•—–ð#'Æ©¹.m hÆ!\åyoÖ§ ‰Ä-ôú}Á9\.ŸÀ wXÃÍ9l%êph±5ˆvuŸïTaÙHY;XÛ>ÏAE7ýþÍ3'œ}U#Œ´?<ˆúiõñ{Í ^)Üq¦÷êÇŒ´T车]¸ˆ4yAE0ÐÈ»ÉF|05±uo8uŽå¿©÷ûÚh9O½ÛöKÛ ­©,Sƒ Oà1•<´9baOä ÒA³¾pÊ…}÷!cÒ8%*#O²ŠÔÇìs¯(Ù—ëÂNRj Ò‹U¶ÅǦõ%C9!¶ÌÜÛ»O@˜l]uŽ%t;/XÂh óÅæ‰)̲¡%k°"!½÷ÅÇ&7kÑÁÞçQBS ˜…šÓÄèó•ÆºQ‡¬¬Êj ¨ë Z˜‘Qw‰ô™?$£Qj+ÝÒ>u»¬Ó&‡ºíö÷ BD§Zƒ69»{ÿØè¯uèΡEP€Ú=ÎŽÇ=1dJÉOJ«bôuZÈ`'õ¬P]Vî÷}v_C³±UÏÏ:6î[£ÿ*Û:Îìn)P,®ú^` S×Ûž$ÿá¿©U$B£¬C³ ]¢ <04âîFåuSÀƲÒÕÝûi¥¹&{:Žâ`ŒáÂ*†&sW%°Ãé€g(>öMD¢s•N¶gü2&‚Xœa"lai:a¢É/… Š¢WÔ¹¦=¤÷ˆ­ `Áèë”®nÅÒõÊ*‚–ðD%˜´ W0×âÆÌÌ´âÇ"€H˜a†;l#uñ{À†Lj4†GÀ »w»“¾îZŽMäÚã×sJÍ”“B»bxÍP‘ˆ‰ÐE4}Fæ„¶°¹ã9µÓÙ (9î}˜¤™ bP‚xhž" u$è b¶œŒ"zŽ4øÂsr{:Š *sºcF‘ë¹Ã0ï}Ëÿ„r16LBãàÙ _ îGÃAçuŸ õ¸˜¾ZÎÁA§pÓËŸ¼3ÎÁ€×I 3ÚÁü›ðó8$P·lq$§?S ¿?ÀÐ(ÂìÉó‰bî6,&¯°sx©OyèY(B"BýÏ à écJ4@Èa¦~ˆc#GÍÌþ#0&OÊÿ&r¢# …Ÿ)”䵕2}¿T)Ceþ‹’a/–Ì#d^¬—Á<44øÒþ»Mâô­?ã§:Å^UÛn7÷#xÉÛh&t0ù¢ Ÿ´Åßl¦E„!` ס^»4ÒkmÆ¡î&|Üp( üÝžØhA¤ÒY¾øŸzï–³áç/å{qðendstream endobj 1105 0 obj 1813 endobj 1109 0 obj <> stream xœ•TÛnœ0}ç+æ¢ââ 6¼VJÕVi¥Vô)[­xwI'\ré×wlpHö¥ªX Öž9çøÌŒï!!û¬ïª ÞÿPpƒŽÁ}@Ý&¬¯ªƒEÀ¡¨0Š2À_q–L Læ„ P\BÑaÌ¢âa0˜2’çÒÆuòb»3Ê!N¥]¼‹“†CDsŒÌTØè¶Ž~_,O¾òˆœ*W‹¹ŸG]ï=êáA×ðµ&š¶†6#Œz‚ÉÀ=⨩TD"XÌ\LBÒ$ƒâ1Xe`KIÎxæ1¬ž…ÂËa“”¸u55¦ß÷e§ÏÄäŠÐ-r“3!×e{ss‹É -¥‚P¾J·²r'«i5¬ ``’c}³oúÚ±QÎѸtIã/iO»ˆÀgÌ)I’4_E”ÎÁ$‘ŠALÅB·xЛ>>×¥ÖVP¯KåŽàÚ ;•x¤¹:Aù¢Ñí!B*XX¶³v‡îšãi‚ ß~^]Ö…;ÓôΑ²wE=›¶péînz†qšþˆ Lzèš¾œt½‹ÞÁh 2µvHUef= ‰'sù‘t¢TH•­ÿUP\üêa0ÃY¥…|Ýu½™ì©—ŽËÓ· Ç„rfÒƒ†G´çd\™–*8’2÷õz,ç—i¢‰ÌWÒ-U5˜ƒ3Þ:ŸÕ¼o›-˜{W”=›Gë]Ù¶.pÛiz0½½tJ‚ùs>•Ý]ëÖcž¿m—¥*]ù;BÓ2•‡&JİZÓ±W#³Õ¥ g/‘8ûÜá„›ãìœt7 ˈH½‹Zl—ˆ œeþ‘ä|â׿/7ÅO0ÂeâÝÇh.s (Eú¶F—76N2EW“¯Ãá°?êi#ç&ŽÚb2|ÚŸtYëas6ËУ”¹‹-ü±)AÌÄvøÀ7./0øçkù ,atKT”äÊgþób½,‚ïøüW4^endstream endobj 1110 0 obj 735 endobj 1114 0 obj <> stream xœ­Ußo›0~篸'JZ ˜´ù¡®/S¢=¬?´ˆmš 9àORÛIšUûßgHIB“£_㼩ÍîàK–éÆíº¾¤]¾¿d;a>r;åxÍ9†HÃÑèyT…Qt Qöèuõ†ìúâxž1£Yk*f fb,0\^7ÍÙœd‰D ãz¼}¢¥V3†7cëHÿQjd-ÓßÀZUîVI5Tõù«.é^˜©ä¶Š-Ë*Ó¿ƒ«+Ú(ôÁg§>Â*ò±¤I&ØÑ¤©š–ªí¥ÓÉ|œçþÆe±½° U°²€ íuÞRsþÕÄŸ)}­ËþOòû*×ìH];*„<÷œ¶¯Fz€õyŠÚ®'W‹^µßÎÛrÍõ» _ñ|ÏGïŽ]äö»•çÉCwßäõ…ÖWendstream endobj 1115 0 obj 680 endobj 1119 0 obj <> stream xœÅW[oÛ6~÷¯àS#1Û(C_†C·^°@kP$ƒ¡Ú´£-‘RIn ûï;‡%;NÒÛ0ذòð;÷ïPŸ£œ0üôÿ‹›ÉñYFÖí„‘õäÓ„ûMÒÿ-nÈ÷ùD’|R\øæ«I8ɉЖJE2©I~3Ifbšÿ0 ̵V£\¾œ$2#3ÜÛCÌ2I ™¥Ú œÜÍjþKÕ–ëÊ-ÉbS¯V­ëÈK¾Ã\‘üõžX·#vð̵«ÖÝÕSûÝý­›ãsÑmh¼‚é/Ùà“àT÷«Þ¨™P }@ã`­q-(ZzëåDzZº/sTÑÎÁ²íæ®êšûËdí·n»æQ„ÙÂ(^Dß^tãÓŽ¡G/\ÓÔÍå´·b`E.ƒ%/ÉÉùüäõûù»Ÿ.§ä=ULJä¤&m}㺫²Z“»5Þu J÷üùíKɃX¬ç¶¼Gû¾êøÌ.}ÝEfÖâ$)%ùÝ$ÑT2HØ%•¦L Óçi×€> EÓ†Ëi_’±ªgñìLøÓ Á/’²ê «S mR“l!NyJËÒä!ôÉÝ”3Ê8â?ôâ¿æ?†VÒ@ߨÞÈ/ë±mÒ°v‘ ŒÕTSiräA ÜÄ Bì¨_–õ¾sãc³Sð‡(eS*y,douè_3›Šg‘E6 Ÿb!X#©–6~§BÓ¨!®Í´ÇȯYmªEWÖÕ‚0)5:Â-ÿV"…T±èbWü(„¦JEF‚)ZRV·›Ž|öQá”›ØôÅué‹i¦ø‰‹!«©z<«YFu–F“¿Ü>’ÕŠÉ5ÓëFÙ„†lZÆø*¬ÏùUyí )›¨ãúžÔüœo åƒ.lt\•‚r¨-2Âpƒ$@Ê–4ø ¡®i¯êÍ5 k;²ªï/£Hå H™Ž‚x ep>zc!Ñ"z„š-ö· æí»ùéÛüÌ»¥ +3<`pH°ÛňdÀBÍ â`mµ > E5g6jòNr†P êô,¨¤U–õèïÎHç—5hN-ÏĈŠnä¼ÖAg|„m:à?×@”z ’T©l‹ÜCä¨7Œá4‚XAðÕŠ´›Åµíjs}Dº­¢îCÞ‚GÐE@Yú¹œ…L¡ñ‚U››`Z FÂ).nKô³ÊÔ“Vdšz³¾Š²ÛÝ¥ö àAA‡,ß>Z¸[¬Ìµé ú=b–ßLÌý|ü/ˆ¹‡î[˜qý 1§ú3pjÕÕž(ú¶÷sÑç$â€wÊÎÓ÷#æ5µ[~FÀ0À;Äb¢”ôhÄ®…â¦â^[lh´µ£¿+=-=|#§©•»L¶ÅO°ñ ÑœáKDïTh¿ÒZFÉ"C—Ýã}ÅP›JþÄtÙdtcüXÄ}=å‡n|5€ މaÌ‚8¨…âpîdQ/qàø¶ðÕ(L.G½¯üî QàÓ@ërjYFy–ó i^9pƒ’Cƒ¡z^,  2¼e…Ôõéaqˆ'ŸåÏ…àS¸êÁÊ›âž&øx2eã`ýúkßi>ù>Ì|Ç~endstream endobj 1120 0 obj 1338 endobj 1124 0 obj <> stream xœíX[oÛ6~÷¯à[¥ fx“Hbo[‚¡[×`Û¢hñeG«#¥–Ü$ÿ~ç"%'v’èžqlžûù>ž|%ŒrÂðսϯGÇ皬š#«Ñ×wI÷6¿&?OF’Læ ÅŸÉräOr"rK¥"Zædr=JÆ"ü j@˜ jmŽr“Å(‘†ŒñјQÆ‚K2Îr÷ôäcÌÒ\ ês2=y›Z ЏM>LOÏÏÓ¿&¿2C%·Ö 1j„!“[>;'íU±)HÙYEŠÍ¦ÞzIšúº _Êjß.P$ÆZc/òð´œÏÚbA.ïQ„|s¦¤b”—>ŠÙºpA(n(cWÎ4ŸlŠv»© 4°©·«+g¤!k6d1°Ú)s¦;ViCä7uYµÅ&Í2°¤lB;c.-j '&(g¹3~V‘f;Ÿ DÒïJCNP=‡”JBøˆ)…o%œ²óõdNχéÙï.KAÅž ¸¦Z„(æÛi½\6Eû è ˲Pþ‹SÚó¶¬+²Z×—³µË¤„x¸”!“I½Ä¯¡lÎb…é Œv° ¨ì—÷P3BÅe* F,—Év5-«e}‘^¤ƒËØÐq-©VÇ×Eµj¯:¥5Úî8î÷XÆôbª„^w­.-£¹1Èo³¾Ý9eÂtiò}´ÞͰ‡H× õž“ŽŽÃÙ1¤NK*| s*Udâ*§LÆbÝÎ6Ëéjq Í^ÜMÛû›¢™Î·ë²i§³Ífv‘xÏé ]Ë1_ ðˆ,nSM“™d 7娱:Kö8¹M9–Kkwè×î›5LJ»õîxˆ'Rfq>ŽzsÉÝM»9:~í'DhPÏûdƒA¬’¦‚é.Ðo˜'´ÿ¾jÊí‘(Æ|Î}ßh+Ë…¦™POQ"9u ã,Xð!àøÈÀÑñEúSÔkTL¶¤ª›ï ôÁr[¹ùy0šS•‹QbxŠv¼†vöÅÅ¢h¦T˜_èÈbäͶ`„ÇP¥Ìˆ‹å¢ÃŘ’Ï¡Ò^•ë‚Ì·›MQµë{RWðËc 2”G[{1Щá='DD¯+¯«z»p/š–,=p÷dÆ ¢Ô é^FhïΦ§ï&žÔL­Æ•…Ü~`…Mp׋ƒ·Ö.F¡hÎY$ãjÀ8^JëN;0&‚ý¢v5åÔr-zý¾õ=Û«²Z~ô\BŠË%)J¤ZÈ’K„0ЪJÇøCæda™ÞŒKéGâÍ2pÕr»~í .´ö€¹^9¼OòÖ^º"Õöú²pÄm°) lÜÀcÐ3•FíR·âÇä)úv*3€…GÀìåÆJ>æì;cø¡ÀÜpÝÑãæ“ók÷Ìï*ö©à¡w!:Å»SYÒ!5b¡›ãà š?jç®SÛÝmT$‹›eNó|÷rö(š÷‰»Á¤"CÖîŠáýÃãoG“£§Î¶þ¬‚l>õgŸ9éŸâ§4máO ø«Ýàí>ɳ!8úäapŒö!Cmøß“‡¢Úê§ $‘Ü sâÏ&.`;-ÕY”€ñ®ìµ)¸¡ÆI­ÚÚÌd8fÅ:(ãÐÒ†é‡!ˆsa¾_eÈBt x…VÒ±JçRt×t7G/³Ílè®¶1÷° ±.»œÝ#t‡rÚA±àÐ8¼†-ÀUÈõh´‡?߇p£1:ÿÃåÄÀ–I~€´†üí`Œc[|žÇ¦ýÔöÀ#@$\µ³q%$óz<7/.£NàÓI߸§Ñ¢À¿"‡/ËÔ2M¹NÓÐ5gPGÅûiâcܽ$©CÃÊï½$ØzÙ‹·^ ë.˜–àp¿ÿâòû¯T;ûï6,Àâÿ¸ƒ¼¾¬3¿±Ø1FX˜ÍúÊ€}Ô p\‰w#1 .XñªÙ؈5´-“ÏnÄþze%ͳ,†üÃ=nÕ1ÛŸBÃ9Τk³C+ð 'KÞì®›:Ô©{ tЙD†%ÉŒäê²l}…½<8õâ½¼<ÜÛF`ä!M»ÿ1Ïsn5UxQ5^á¹S"=Xáͯ3ôM>Zœ <þ˜ÝÁïÝÛpÃþŸu§“ÑŸðúÞhF2endstream endobj 1125 0 obj 1685 endobj 1129 0 obj <> stream xœíXÛnÛF}×Wì[)#\s/äî¶oEŒ mš › ° A)™L:$+ýúÎ^IQ²‚ Í[a²Äݹœ93gä(Á%úǽ®îg—×mºY‚6³3b"÷²ºG?ç3†òœ"Áo¾žÙ›ÑLaÆ‘`ÊïgQLçùß`Š•Êô¹¼˜EL¡X?º¼–ˆ0m!¦ð§J?f˜¦(œEf ÎP¡ò 'ŒJkà&z\¶ëŦx_ÕE¹_,‹¢‰“$cQÙuKûŽ0•ËÛèv>ÿ+ÿepìÍÅÔL´¿›¨ª{T<ÎÄ*S|ÌI ÖEYgƇ6ýüqNx¢ìéî´vg@¢Là,siï/Çx0éºt.7Ñþ¡o/.Ÿ±¾À¡˜pcü "0M„ƒ1–vÿGÝU›º,Ð…9‘1â_^Œ_l«®_lËzÓßi_p:&Tà”òs®8 ®®Ú¶i­%qÆ” ~JýèâòvþS°+y€š`®lyó»­wõª¯šÚ²(WŸ Pã.…©öîPR{#PLÁ°½Ñ/?˜à9N9wf´ãÌÖ¹ìвCUý°ëѧ9Õ¥å$Zn«AÖx’0œ¦»qi5­¥Õ,K0Ï|âû‡¡º™>áÃo€Vek°à _©Ç8±pÖjË~×Öê[Ô¬Í;—6ÒyÃm³ÛÜMТ<ÁT„`O—yŠW–b»ØR,ÁŠ«M ßË5ªúás}XJ¬RF<}ß-ž¿‚>€F ÕðWˆ+ÅLªIcžh½Sè TÆ¿®ýñí÷fcqT§à!Nɱ@ŠoÈ…Æãów”IïÀêA¾ñêIR~¤žJ÷—i°›ad„Ñs¨›s®Å˜§‘“O-MÚÀMËŽÕӄ뇽®. †ec¶e3ˆ1Ú6Vd‰=06BmàÕ,¿8wû®ÚÜÞ:~µ[XL8´œ¤:h}Ißøá0wuJε0°Ãn÷R®8L[!†6–”~QÊ5I }JÊGä›tˆ„)OÙAOÌó'p:t8î›ôæ€n†³”G{ˤ,°4Âs“¤kS3X`b{‚({Ô@/uÃ:Pe"‘I lÝ7ÇÊ~¹¸©‹;t(‘ÆŒ±ìOc„°[Ž}‹¡š 7ÿ”móÄ3ž;øÉ)8h(FdZ2à?Ø)ì'£";»Q|‡}âÛÖñäA™:Þ#$ûâAÿß#þ»=‚a%øWî ¥\œ[#´Ñôô‘gD•ékoÛ„ñnpb)ÅB ò3žä“Ì¥ ­§ >ˆJÿ}ÂÍ÷ýÄB–øÂÖcTäÐì\W cÏ£½¨SÝœ!ØôÉä˦fئUÕÍЀÄ$°¬‘ÿvÌÅéoÇJo$¾æÑ¾"Œ‚ºD»®ì+ ³~Ýlµªr½ƒDÝŽ0»‰Æ[Y“×£ø™^e|^ìÈU_¡¼ùmùÑ„’á"¬jJø›_üŸÆU>û~þP¯endstream endobj 1130 0 obj 1444 endobj 1134 0 obj <> stream xœ¥W[ÚF~çWœ¾lìfÇsñEi^ªÝVIÓ¬º¥‰ªP!/6àì1—UÕÿÞ3g<6dÉ¥ª@<ç|çþá#p7¯ös¶\ÞF°Ø 8,Bû1[Ãã„ñ ¥øÏV3&L*ˆdãõÀ ü p X’„Fnœ <ÅadŽ.oãa¨„‰$†‘IäÇb±­ Ù1SZ´Ú¹êa“"v°³ ½_Úž¼÷®éú~•ûB±$Ö±·_dwE™åþŸãWÖDœ0Ícgã¨&EÈÛ§½mÉâ(Hœ…z>u˜1 ï0M³¬Î7›´ÎÓ‰7ñÉú—¸¨…LJ†Oð»ªÈ ·¾:ïjŸ"üOíoè|ãŒQ}=ðþöŸ˜4Å–Uú½Ü‹2Ï`Ulšé*/áðçFïSž<xEÙºÝý¶‚×u]Õ×µ{.b2l%3’qžîžáÂy1¼@ ‰o`Zÿ‹9Lë»põnzõúíôæç‰âº| ¿Uë¼YåöuU.†€TuÍ2‡#Ëðô’ªx¢þÅŽ /›¼N£TWÛÅòXŒ63êý¼ª'ø5bÔ :b¡«ú {Ï‹ïWT\êŒÈuQìs(ž=£PŒ7ç_¨Rµ¿Ÿ}¶DËb±tÇOζSÛîük•™æeS?Õ§~šì rhxa-É© gÈH{}!Oóüùz"Æÿ+(Â6Ûº|l“jKUÚì»E4gÊÖƒÓóeºCPØ¥+œµã‚¥cYçíŸ îlì‹f EÃ\sQ7œ8pÆ'":iF^G¦Û%šœ ™4Ý¡Ÿ*dɬ#šã¢mÖwÕªIïVù4­ëôØä”ìF`$úhßÓ0g{?Aþ5Ä—ó”fœGÚ;‹µ÷Žç:òŽÈ§çKxêÜ=,z^ìH·3ãî›ÚWNioH #)è'Ø ËÇ£VJJÒI—?%)tMízè=º>uܲh–C;i"bZ¨/YP¢³`ùà“˜…2q±åæÀ´¸ÃŒU—dÁ¢ÈVò¦Ìa––8ÁÕHjÝ£´BŠM y puȸmJ¯á^j—ML Œ™ ¹ãj´£è0`rž­šã«”[°ÂJ›ÀŒé‰mÚ1zTm‘õàSƒ¿qõ-‹ó=SçÈèHë÷ZÇhRQ˜Q)»ˆã€¨ÆwGÌ6‹P¦kd“´Ì(µEYž $ ˜N‘ï p¦û¹û†@Î#nšã ãÐpZðD<6œtµ¢fÕú¾X¥MQ•°-‹fƒOÓÆˆÆÑ=­dùœ:çÕµ _œlQæ¤éò4ñòtÖemI– D7z:ÕØ’ÃÎPn Y1÷‚\xó¼F„r»¾ÃWóÇ~Ñ\±bcç8ˆ4KTÐÕœ*«q7…¹Èà]bÖ¤åb»Jk a˜øtS3#ôz XÈCR2 :ß–3c ñ袙œ»Lgÿ…ÆnåŽ/šôƒ½81­”ë`Ó[Ty¿m`G{Db ¸)4ËÂvkÐñÉ{Ç‘Vç92ÂÝé®{îÏpd…üœ×¾6T¬Ùœ&Â*¶,ƒ”G”¢—sÜ=`÷ß® `³DËÀšUë›;”÷vúæfzýf|K°èk‡¶ç9 »„þÑ·®(¢ÛKmdÅMëbS`Á±¤³*3=CœHI”¦ÄŒ“½¤Ó΢0ß„sr^ø ÇÉŠ<Ü Ý½I†LIgܳ1¶Ã( d¤¸IŒìý]ŸÒ9»3`’˜$˜„ë[›Ì$‰L.Ú1¸¹5Ù†XÚàLë›k|Àš2¤Ñ´D‡[jÈØ®£‰rÅ o”Ü=Єïl'HÜs:ìi›·$ìú“šnóîßæ”ËŽÿ壮±#ÆDøä—ôA¯‹9é® _ýv=üНŸß¶Ðendstream endobj 1135 0 obj 1485 endobj 1139 0 obj <> stream xœ…TËnÛ0¼ë+öˆX¾$J=)‚¾P4ÚCRŒDÛjeÉÑ#Nþ>KŠŠÝöPÈ€`rwvvfì`”sOx—ûè͆í1ØF÷—^åÞ‘„¢Ä*.?Å&š;9ˆ4§R–)ûˆÄbUüB,æ‚æyêêŠ*"ŠCì®bÁ%ÄIê{;N}k+w}7mwø¶®çäËÆhžÛ÷] "2Ÿ/oÉ¡«ÛÑö«$¡Œ©œÐÕÏâcs™;„Xø2®¨VŠcD>l`˜ÊÒÃfj.ÝlØLm9Ö] 3³®Ü4¡*eHüX_}v§RP.d æaSû}ýõ˜¶zÅ(þY*ZS•äså1‡çýhî×M=ŒëƶÛq÷×–§¥ó(æ¦Ü’3Éàuså$×§Í]SXœ\×^4=óöpªÃFžŸ¤’ÉpÃÕ"yk_’¦èõÌb®Æ}MSWpuôM8 †ÓoÖ×Õ}ÝVâ§ŒªtÁ:œ“¸Š%0a¥Ð¨ü|ðArÙ' ó1創JÓ‚ñ{l;Ö½Tû¾ko,˜6]Óx4Á3ʲ°!9^0…‡)ò ^ ÊáñïÈ4Ôí.ÂêjÍ•ðÙ¥9°³8wìŨK3Z8âd<ÚÖ+áâ*È£ƒšPM¾ÐÀ¡ïߎ»iþ^aŠs¤ÄÚƒ+u?ïòbh(,™²O'Î ñ1û¢–]…¡wÐY*51uß<ðëúñnõ6„hî“lVåf6ÓÃJʤXB$ÏŒ gThÀ/_Ì3&ø©Qsšë¥ó¿ÿï‹è>/îi0šendstream endobj 1140 0 obj 624 endobj 1144 0 obj <> stream xœµUMo›@½ó+¦jC`Á|ÈÉ¥JZ©MU5¢í¡TÚlkãfÁŽ­¨ÿ½»ËgCzh„%ÌÎÌ›7ûfgï@× ÐùS½ãµtvã@šK:¤Òd#T¯x o|É?f^öó—Ri²=Í´À1mð×’¬"ÅÿÉ`˜³4ϳ¹ŸŸH²…@妳·BP iÖÌuf —·$ÝRî#r!—Q­ÖÒLäÖ°®V‚¶¼f•åj­¯pƒÇ“¹z·O¸Ae;€huµ‰LÍu ¯4|—é2L“ɬ0 žk#yæ‡õb³*¢Å ‡¥Ñ!Eùá¿ç”¼¦PÏÓlÇV±H²ÛpÉoÈ—÷W‚ï¡Ê²g@Œ ¹–äeÌwÄm0Ê /YNÒ 'Àˆ0áŠäE¸ÂYZÜÂèsŽpìJJ˸6\Qº¡€)mÖIVÅyý\A¡\IDLÍñÔÔ¶é1åÑS’ÓË(‚§úÈ™,!)_]Àå·ðòúkøéC Àw}äIq±¥Ù ˆ?ý[nh a”M(>s4»–öBWl]—çä<Ú ùº÷žž™Lj*ª¡ëƒ²dÑo–˽ŠÄÛŽ»>ãÓ.<Ÿie7Y^@|Qxͳ7†gÄYA» ’“¶MGêSQZ-èø…ôì)¢ $KÃÅ!,¹ táQüÿP¾ i±wņVm5À¹»Ë£¦†iÃÿà-ŽMÕZ¼ÅÎÛFœÃdÂVêðlŠ ¦Îb[Ôåä Ëá×ÓݬLw81úÊ.1”Þ’³6‰ ÿË\k´!Y†iØ–ÈÇÕ6ªuU"dÚ™>£6~Ú@4ë\pªkkì*1‘ˆºi/8v_éf=´vf{Õw›†`£ m ch^3îž½Á¯|é3{þuÊUèendstream endobj 1145 0 obj 704 endobj 1149 0 obj <> stream xœµWmoÛ6þî_Á}I¤ fĽE¿ †m]‹e^‹!Y¦m­Ž”êÅI6ô¿ïŽeËéËÚmH€8äñ¹ãñ¹çÎïH@ ð§ÿ›ßN.®c²n&YOÞM˜Ù$ýŸü–|;›2ËÁŠq¿³ÕÄžd„GŠ Ib‘ÙíÄ›röÀ€1ãT©ífˉ'™â@¨bªbšiƒZ·]]>C›)OpƒI³ñ—ðó‹ILáàýÄ»8#§YÛÖÅ¢kusꟂ3N¥u“¢!ÙeÛN“û¢ÝÀǺ¨º†e«ë2Û?JÐhð³*ôvÙ¦"÷šè‡»¬\’v£‰]§äìâilµnÈs²¼ÏêUº^.Šr©Ò¼Ûé¼­ê´(›6+sZ´Ô„3÷œá9âàöw:''y—Z³ð¢ë^²ó“æñvQmÓ·°&E“‚‡¶È ”w¢ëzî?ƒtŒ£,Vs`¨ß<'—oÒ˯ÓW?Î}òד>ý˜÷Ë 2t«ÛMQ®mf1GûÀMžŽxÿÀ,]\'„ ¤0ž\Pš¨¨"K— Ozf“oÔf‹-¤½lëǹ7÷{â9îNÀ”ïsã5à)}´MÂÄ;€õYHƒ ½âû¿Ï~º{Üx—÷> hÀBi@¾ëAÐLaeÄ1âÐÅÿ°J†÷Õrã ~½‡»¶ö%À2ôÎ ÈT%Àeb@yq™¤¡û_˦X—zIL¸™¢2r!þL™ˆh °}ZŽn3À‘½\§ÕÊç’*oÕèÖÆh vvö©óÀðÏð¨ž-ÄÂ\ó(D8ßN ·»ªëª&gÒH(—VX ¦Ð%Md»—4 l‚fXà]™·EUÉS,h9´å—³Œ‡ IKq›½µ:FC)(BIf(Iw]Kv¸ >YÂûÝl[,Mô’ùOÈѤø)Áîöšœ³.¬5$¡2¢HPð²ÒÒ„ <á1UÂ…ô0÷LœPÑ^Û1ÐáÀ„„wdC »Ã¸‹ÁCElÈB£šü©ë Ô¤®ºõæ¸Uˆ@Ð@˜éÁ#À ¤Û¢iÓ­.× ESvô,dÔ?÷©¥¹Yë©-(±Tø~EŠ–XlÈ%š& U¡+INH=æ^z¯Ó—¯Ò«—³kKöÀ¢Àå`?Xó[»/m&¡ê76ºÖÄ´¨¼ZâÝ [MfÅ%àˆtPô{³‹Žbƒ‡Ÿ¸‹mUø*€ÊµÀŒS¨g)áØfnfRPa|LeÀ*|¯$oö鸞œxy…ÒÈ\þêÚ^‡ µ]Œâ{iùó‹ÖÆXÛö ï!»½Û ±¨lÎ!!‰-¸r7 pF6õ;ûöµ‡J9ñ6E¾!]òÃŒ- ÁÌÊå~$ì_‹Ž'HؓɆeM@óÃa4¹ñž †fºàIÔ·;+[¦yà­g‡ô3 úqyûùŸG•5ž`Ô`¦Ì%r@ÿøX0eAr¨]ŸWвÔu^uåhDùï§‹ýüt‘ô‰}8 ÇÑl!ƒ/ž-ý¯Ÿ-ħ犲t> stream xœíXÛnÛF}×Wì[)#ÚìK.úVØ-Ò¦1ê² »hje³‘H‡_úõ½š’œ8- ćs9sfæØïÁóåÿ¯¶³—gºêg]ÍÞϨ}ˆüÕ}WÌ8**°¢ Á¿b=soRĤÂ\ ŒKTlgɂ͋¿À S†•’Æ®XÍ!ÐÂäCÌ…10I•{9s{­;ꕨjWus…t×µy‹òè“û"øÄ¯ìÓ‘™ïXHr]ÏÉ0Í’¡³©Ùà\bÁCðÄÕh¡ ˜[' A–àB…µ9~ûˆ¢Â’Ç¥Wª„“3@šcN•±ÜTwžœž¡!–ظâP»F}»Õè]ݬð|‘Bh —ÍÊûxž8kxìêªô ]>tkƒr.0>ºªÊͨmMÚNHJ!g×Xm"tíxum#5ðI>AëT@9¶aB8®7mÝ º›§)D*Á6ŸåÊxX0k&°ßž[ýXUºï×ãæ…­`=6ÕP·Í.ã¨âXªÔç` ŸBû)ã>3ãÕ‚ èŸþ„ hÁÅ%1ùXRÝ4º[VíØ {…-xÊpí áÊĘ …BÑð®tÕLñÀÊâ‘/@?ºr˜R O}6§\b1<൭5ãöR[Uíö¦Þ”±ɽƒgB‰Lt5´]Ö­w ,g»|® #»®|0ÞnmQP =æÖʹÂèWmËH3@ÓçDÁMVzN aÉ}¹½ÙhT^¶.4¬·Ü@’å˜å9ãÁÝìßjt·³hÀÅåx]W×h쵩² ”Á©Á3Íc,… ´“©Í³Ô¾.1‡ø­lê §œåÏ»²[/¯V—0Yú~Y·s3Ò,÷è-]_ÊaèêË9µã.’qÐýEr1·µMéœ{â{h€-hugçižL"ÚV‘,M\h‹žäO…ffÛòÚíÚØÉóäø2X¤ÂºÿÁ»7fÊâžÁRKÃÜ_=¢·zÌ(¹ᚦr÷R\…¶IÀjF2ïÊõÏ„ü­éë+³WL!`¦(RDﮤv=g¦b–¬{=ø0”˜8ìcav#X`l²Æš"ÂAæfñQXóæöL‰~ž¼qÈÑѽÂ`¯„›lSã΃b…_ïWÅû¹/ÉÿRñf°y <)xunqX,6a±‹=€3©ö‹·9™Lڂêž\NÃYп;º7wªYÊỘáTü*Øò‘w‡‰fö<—h6õnˆT c¹ÙöR§{ÝM„ÊŠ~Ê[ýÃö²Ý,Í9øóº_BƺrÆÿ¿4uíi îRÅž—¦{ÜŽ”Þ;-‚‚Ò#cª9%JÀ/½ópÖ…Üë_iޣפîwª IxꀘV™QÆq;NehøkËŽ=,]¦Ï¯í`á„S™‘Œ6§ýôÌÚ»l8&<ÊC~˜ f‚~.#Œ>¾˜Q¬bœgÿÔyRÌ~¯§u–8endstream endobj 1155 0 obj 1716 endobj 1159 0 obj <> stream xœÅXÛrÛÈ}çWÌ›‡.a„™Áu÷iÙ[›l¬Z™^×–”bàB \\tÉ×§§ç¶¥T^Rv•ea0Ý}úôénüIBÆI¨ÿØËÃâò&%û~’ýâÏLJÄþSÈ_V IV%œâ‚ÀßÕnaÞäD$9“IeBV‡ Ärõ/¸sÁò<ÑçVÛbèGà’q¢™²,ƒô—©Ò©aìšž\éƒYÆòؼ|K?¯¯~]ò0d!èïë×ëwV7Ë®þΚ[À ¸W"UO R¶ÛªÙÕum§s鯒ðJä®b¿àSm(ÅûôOÂù¶«–y˜2!s:tè• ‹d&í&2 dmQ(X’ ðÏ\}ž°ËY"½|žš<‡àßݘÀãŒIžÛ¨‘i(oéõ |Œ‰Ž´;Ò·E¾TÍ–-ƒLKžÒ¢ÙêÃö2£æ4¼ 窲Ô–lžõò€F¥ŒXÙ3Qõ¨0¦’†™ %Ĥšt*m¡kÇý=Z‚ÓÀ¢Ü±R–;˜}f4“¹áØVÍ ºeƒ¥(§ ý ¸Ìõ Àc’å"rŒêDzT}¿ë Œ`76åPµÍ)ÏxΙ°PžÁ/!ý\ÈÌÙþ}}ýw¢±roâum]·K¡ÝÉ8}ÔL2ñLjæÏ02‰€%:i† ±!ö?èã:¿.è 0{3‡ Ȧ™+«r\C¦Ô“e–þ¤L%ã¦:‚¥,Ì÷ä‰8’‡ªz«“¯Ñ×"æa¹H2&¹ÏÇSµYUÂi3L´Ñ(Ãð•@'|k~Z$‚³” —ñþù°iëµ.äï%=LÄâÕ¤‡p³Y‡ØE]MBDŽîÁÓGp3¶QDî(ù·êZý^§zÕ=,¹®Qµ½ m£åÇ(jçuÃi]1©3-ydnx‚N éâËÜkä–¢.ÏA0IÑ·el% Îd©˜ÞÍûø –ãúïn)BZiÏ·jg›«`iìšXbn垃’¥'J—MTЕ—j*èªáÕTdì•IÎ Ò¥‰#nÕ¯û*¦|!#‰“Šhžñd®m†µ;'Næ¦l€‚ÉÄ%úÉj ^‚©â‘o Ûj)ubBIûýLShÞ>Ùu»)jÌÅ †£¥¯›ÕV=+$ã¾Ðm“ºÉLC…u&vLÖêí-ý¨ú¢°r¹HèSq8jéÛ´¦†œgù h3½z>žLX^¢ŒîÝWå½N¹¦!Àîš/3U˜!‡¼Å" Ds+çHMš0 æ%1å#X,…à±èvëývƒâ é@T×›çu»Ûõj¸£w˳JÜûvJ0‚Ì‘íkw™NÌüdÌ6Õy…oþlß$îŠãÐ]àTaZ„9õ©é«½„Ìýæî à¾ÏEÙ6ÐÊû¢[" Cúö­=¼Æ±OM¿ÃIí-ÜÂuÝÌg¨»ågcTÀc˜r\ü1ËB“ÄÕl,:-M ³zÎýט;‹"‚ù7tÕ9_ *,ž$¨QèAó8 SðL¦n®iªœØDý[ˆÖ`kÑþˆOsÇú‡úKcçúÓq.¢< ½Tãq=\àÔ…%ZœË —S…ÍÒwn KB1]ýõZs~5àãñ½Òƒ§ßkþ8ÏžÐÁ”ÛÉñ»‹Lbé•(f©pä0{Œôõì”Î÷‘B©<Ùc >E˜|½ÇÌBi9†aá4XS®oÎÉ`­I'esg‘|{]ÑÌ¡ ¤h<5æ”t·MH ó,<.¾½Ý`mýæêr6êIUº%í[^d2Ç}]‚Ê;'âࣶ½Y_J=›¹¤pËZ=¸!3É®kxö J wlÛúÍ d¤$9k±Ž”­¦*J¦°­Ô+ç€qj«:Œ hÍY‹“Ú‡#ʃir_÷ÕnkUHí âÖŠiÙ…aMiÉ1ÔD¬ëÚ«ûÿ¿³E§Mfv4t“Ÿ?|Â:ÍòË’eg]5_4”w”í›q½U›%ÇÝ?¡ã^?¼ ¬i¥Ÿ2 Ôk:Võ6¨¶wKÒU‡kUïëuÄÙs}ÉØ’+I¯Ì~¼UEÝOS¿•\µñ¬=‡ì¶ð¼Ðë/NøæUjãÛt9Qf’(™Fm³õA‘ãNø¾þ¢á êóOsÝŽ½ß¼?E‡ÕëÂ2KXcß³©2ã”c¯ð_¥ ,»;–〫ÅÁÎdN«Z/mŽ.føL€…ÂïÞí|‡I½üÓ»´Ž8Î׌%‰~¢6Á¼çç×ûa8ö?\^öíØ•>V£YÑ<óé/ój U£(Σ0zï/¡[_¶M­‡ö¶ìñ¿-pÁ•²Ì±÷‰RhÂæÉÔiôç+Dç=€Ñ³ûáPã<hµ\7za. óƒXrØÊã“‚8Yo”ãI&Í€OÛÌ-}Ô_àu)hóqö ¼‘n-¢ê8¨ÃôN„<¿Äo„)0GøµFÚÝë¡êN4Ì Qv¶«\—Cknôç¯þÔûÍ N0€¢PèçŸzÌfµU}ÙUGGe݀氈qºªzf¿˜á$x£wiÓz–?È)±ÓZ‘øÏ? ÚÀ=>‰d yE~õKë»Õâ7øóšÝ¸¶endstream endobj 1160 0 obj 2276 endobj 1164 0 obj <> stream xœX[oÛF~ׯä%”N9^û”Æé¢Û4A]틸(q$1¥H‡kýï÷œ¹ÛHaÈ3ç~¾ó¾’ˆ2áŸûÜ?ܤdß-"²_|]0ó’¸í‘ü¸Z²Ú‚ãþW»…=ÉO’¤"!«ã"ùrõÔ€0ãT©åVÅ" ñUÈ™ aœàȪ4%«Óâs°:èN“ÝPoû²©;’·šl›z«ÛZäTö²[2S”uQÖ{r½üsõ¯EȨ”hó˜roî·“cnŸ£Å-7?‘"ïsRÖ$KÇ»¼Ã`Ž1žP®{DŒGÊJS޶…bx!båì• Nrxª$ ™´æd*m€uC~¿«Ê>¼>-YD#&U·;°o£ˆ(7Qd1¢4sjï›) FÓ$rqÕ=¾P”Åq–øØd[cºxCúCÙøÏIQî–\‚_± và}Ý“ÓR™)Ƀü4;Ò¡ký7’Ê£B$Ïg“Ù =*Êkb²ñ° åÒˆŠL:¹ÿéóp˜ôan‡>ßTö P)4ÔE ]4-éÐi6_ô¶§tÆBÑ4~îI­}"­aóÞåÂ*›YoóóžÍ"èspiÑéÒ•Ç»JÚ8ÛÐ(ª mѽ!M]= àÜ Sá[驸1FÛb.ÎHGn!h›É©Œâ1+FÚe£*7mÞ‚£·KŠÂ?Üd† †4fdõ¢æ¦/‚„ °JŠåë…Lh$xæ=A+®÷õ°.ôÆ–þ*ë¿nƒÛ¥‰ †_¹áýñG“;%4Vq®É+¸6¯ñ)6û7è$Ïhæ£áŒºð! ru5]ßåýaÝê~@0çðÄgp¨»røàÎmÛí™ðëgôšé~=Wzµʪ(‹uÿp§ÉszQä^Ò"•®÷3«LRy®ì ýêžUf%¶ÍP÷r.ÑïÛ¶i¯ˆÆÛå?àÅn‡6ñ¶nG¤Œò¢…ÕÕÙ‹š¥™Öë?Ö×þ³þøiýþãêæ¿NvÜ 0@¨ÒâPa¨Ö%~'ùL;‹¸SzÑ9såQL%ó-kG$t[!f8‡vöD› \Ί6›…ÔÍc ƒ¡¼×´nzŽPÓaYÌý¤wÃë…=ñMè`¼Æ+ê U%Tñ)õ©äƳŸÏ²„ð‰e#eÿD5˜LiƲËj¼¿¹ùt3óR!ÀŒ‰Íë‚tºŸk“”õº2¶gzÀžòYG§™qî®Á‡/÷xÏP…PÖ¤ ÂU!¸Ïϱ/âcGUƒ6°úÇc†³¸õ©&ݰÝê®{&/QJY4Ë˧_fÁ$t†aÏgÅ„à¿ÐUÏÚfØÌ;«n¡@)t·mË.\YSÀB.Æ87ºj\"R³@«H|s;q'à~Sr#ô€ÚˆqÊÝ`žËILâ€]ß‹¡+cý=]O6G«5‚vµÉ K.Wð-~‰\”°†£>6í©tþ—)‹"ð=›lgÆöǦָøMó› 7î*H´P¾ÆAK" ‹‚Í÷X3T…÷½0æ„ÁùËá°Hæ+O`#á{9Ãæëk”-$n× í£8•U…nAÐG;%Ø¡ã@O­­¹/i5à¾ÎÒ¡€é°ÎS û)„†;–uÞäw}‹äÌŒ‹ÀMÓçw)`Œ­Ìu`×›”2hÄŽ¤Þ´â©Ã~M6½¶¬ûÈʾÓÒºâ|°@\ÏÆg8mê;ëÉY‡ÖBVˆ¼ä4ŸƒÂrÓL"=^[ Í ewÀ¶FÛíPWAàJƒÞ¹à—[ xDð)ó9‘!&‚¼»yGî gÎâ,ȡȔ%›;^0Lrî*ô¸KŒ¥o´È#2kx–NwX³6É ª ¨£ÎÝ–Ì›Å`:o&ç (zL€‹ aJˆÉªí¶9b²g d@—Ç~Wxp}Š=ÑŽ-S7P`ÓHÞÖæƒ!ϸ¿>€ õÜÉìå9@i5ž=`‚¦þ¢À§vl ½`Üý ZÂ7·ëÿØ¡´RI?†p 3†¿ ~çó½÷Æ…¯”ÄPòóÕq¾áêöóv:ƒxIcé_ UaY%¯a’gáZ`ÐÿIœ\Bõ»¼ªpšeã7ÍÌeÅñÊì—Éw%†ù± ¬\×i2Q‚È­¼Ë½0£sŒÆ™ÃËtNÐ$õ{-r—Íó-±± ”öBðÜš8g žöÁ^G6x*Ag^÷'p wŽk—¶mÏÞ·}D."¾½ºä„JÞpsªu»F4yºBÐÙøcJ”Y68sâ‚~{•Ùê:m.5 /²úåöàÓŠ¢)îz×r{õÏÿ~Eɵiò$¡rd“*¿Íê×`k+jþÞMhý‡> stream xœ½VÉnãF½ó+s 5Û½Mò˜ 9LàÈ@AöÀàÒ¢8¡H ËþûTõB-3F–C ¢©îêª÷^½ê/„QN~Üwuî>¦¤™FšàKÀÍÄ}UòÃ6d[Á*.ümwÝɉP9•1I¥"ÛCFb³ý a`14Ï®ÛÖA§$Ÿ"Á%‰e^‡¶ŸõHÚ‰´½ù•QsP¢h–$¹Ûû\œƒrÊDæ‚>„][“¡¯4©OÎ(cyãîi·á9ͳ8Û¾öáã—–“yʆn>mÆšrWS¤Rše1‰„=÷}¹´]ÝÖO£ž—±×5¦q‰ä”ljM&¡)º=çh¾âÊì¾à¸G&Ò3)È4mߢ¯ý»~麈:´}1ëšn¢$€¶?̰Æàñ,§)ëR¢Ra£÷Ãx(ºîb aåÄ$ ÝÕˆ¶LŽìI;O¤˜ª¶öÚÄŽm¬*qL…+ëew. (WnìÏ áTJ~pUœQ.s·3ã>³™ìF­@f@Kƒ:D,Â-ÐeX²åI¦hÌ2_3G£Æ„‘Ù¡ü¬«s×Ý΀‡oßT¸`œf"û?-b@fœ®?ìnägf±ðÀ¾?ó~zSô¸8ñ ʬäáäc1!}ÅD~ýýþ3èA;ÄÄ"UÑUKWÌ-äæÛãPÔqúJúBR•‹³ôm:Õ°ôó›I%«.˜eÖ)wÔ;=jÀ¯.I×–FDÐacw¾Œ¢Rdù?DËÔÛ>^cÓ""}´âóÕY Uê?œ~ÅzB¥ÿE8÷28ަuxB3®ì;Aѽ±¨çÖGŠq,^ÑÆœÐ§h"k y+œ÷FŒE5/Eg­Iˆs#Ñ<6.úm»¡ëÌÑIF¥?—Ig¯`N&&ž ²÷½fjÃ\.oòíi[·4 3Fá᦬(8)÷ƒ uŒ\v¦©`tò «S<^ýDß }Mßk]íÞ`n鎡әz›îÂ&·¾Î¾åê)Ôä…Ãí®fÆ}(!äÇô¡ošÐŽc…#AžÙˆ-Ãa­ºGó!§}[íMí|Ú õ(™†À?íA_OÄz5Ï¡¡ø:bPO˜ÌK;͆)ˆ·7ìJû[¨Œ*&=§Ã%°„¯"¿ÚÅq@z0^›3Éå¦n(‹Î¿/œóÌ›‚ÍÇÜ'šº©ñ ®Î$¢˜¸-Fƒ&`º[-äþÚfåë-Ë ÍÙz“©OèÝE]?Õº\š®íÿ|jLŽO˜£W PÂÒæ…=xî‹Ër…LÖ Í>3ÙjRëÝF0˜ÖüºqéàÖQë©ÛTfÇ«’Üvšk“.Á[÷È4º|9\aÉá:‹ÄO3m‹0qn˜º¹Œø=¨VLÍyéfÒœ™Ã¹öîn™Æ;ðï;ª‚Α2\šw®û‹Ë{•_ê‡/cëùÂ5Hà€u{ Ì਼0Âë¾|`ŸnMS@é¾8wÃeT(¸FÊØ–ö}½~œ;áKq8v[†bg½ Ü-½i#ç~"¡Œ+žlv1Ör„õæ;{ç’2é­úY^èÁç"Rÿüö,˜à¦w¬Ypš§~çßÞ×Ú¿Áç/¥ç>endstream endobj 1170 0 obj 1320 endobj 1174 0 obj <> stream xœU[o›H~çWœÍCŒ£00ƒm@Uve÷a·›¨^´Õª®†1&År©Uýï=3ÃÍv¢­lùræ;ß¹}‡ù¡`‰Wû4sí@Ri$ÚÊCh¿¢üák6ø¢(|û;MyR` Ø3pìøM7ØÔDSFˆ¼ÝŽC4å¨éi^CÉ+tEx6Y´ÜY}iŒöÖ7ÂhP:G|K&O]´K¸éS žÂz?â¦à ~Ü›‘¾ZK27y•&9A…ˆÊîÀ’ðW£ïš,“Lº˜E©:Æì¡º³.ùƒª.3ž÷ Øm“fqõóWÇÍ¿ùØf:5¨kYz *Ž9/ƒ<<´H!‚ó²;¾´®x¶ë/ãa6I½¿Œ(B2 )²®^ #‚¨hP»’Õª,‹¸ü¼ˆ›v&æ µÉncÏÌð÷i…öŬ¼êfZÁcSÕæŽ!ÝA‘søœG©G%Ú ¾Ø!²¨÷¼„§,Œ8ˆÖË¿¯ßB±}äQ]´~ŸaË \™MUšYº5åÌ®£†M]Â:Â,{5T¼&pcâOc¼:nËÚÃ8†±'Y± 3©íŽ{v+E8ö½2«âÀMhCß^ËÎm¦­¾Æh,|#ÃývËÁòÝ¿ÁÃ_›)|?çµõä¯÷ižÈ²-뢻Dzȓ[D G>É2ÀA%—Ñ^Úz½UùÂ>wÈÐò*ºlè¸IÞ£gެÿôÑ¢_Ÿ>nG£¹ÆÅø1¦[£×ìíz©ãñFX†õ9ªU9µ©õP6©øÑO%~eègv.Ž~dwýÈVëõÃú¥©‰q- ¨º‰Á1ÅÕD-·Ë¤šluSæ—¡ä^ xÿ¬îýõ2æä5¡ÜÂnáót$ª‰öPáÚ¤EŽ;QÁíâgKdŒ4>»¼ j!½ÍdNkÞß…Ô&–ÝÝ…_íá.l/;0ðÏ߸“Ìbtpt(ñœÎó/畯½Ç×O€Å8Rendstream endobj 1175 0 obj 892 endobj 1179 0 obj <> stream xœ•VQo£F~çWŒ"E‡sö†]0˜¸}9%mÓ¤µh«*>! ‹M@Ž…æ¢Sÿ{gwYƒ_¯'[íÎÌ7óÍ·³|‡Pp䯦Öå*€­°ØZ-ª6¡¤ð.²\ˆR´¢ ðå–ö¤Àü¸®Ñ£eÏØ$ú à1e$ }ie–í…0“["ìCÌ(󉳹/-캲­º8ã›n[Õ‡ Z8Ž}q9yýhÍØ‚,`F=¯ám×TKòpã¹$ßo-»ÈamïÃÅyW–OI»‹EÛ”¼ZOàóä5öVïѳe?5EÕækûlï ÒóJgÅ´uYçb½®Î¦†´ZOú¼”aÚ9Œ›6)`Ûv'MÂe ù¢#_ëBˆ'wØÙ¥{ŠUºzµI¯àlêí¡Ý`€¶s¤vmð=8K(à;ð–oß Ò2®íMW”Y‘Åš´½P{Sh_žø²ëS«23HÒ}håI¤w=Rý\ñæ› ÄJ¹ÇUòø5LBy-Í=›—/ÐÖ ©=®’2œŸž®×Ä×·¿Ç7«Õýª¿Ä d蟆!ì!©â¡¸PWRxBpį »ßnoñM´<Á¡‘CRõ:_æ<ÔO¼:º,ñªDÒÍm:bRÚùG—sî§ùA¸¯/äv¸F(3ߣ㣟TUÝn3ñ)ÊÊTl¨¹»oî¢ÕŸGìPÇPHt¡aHæÎ âùªGö}¢KSÉYapÅ0upv…þ!ðýOG¾¤’™b@7$É[ÞŠ³¨¶Ðîô<ý—ïZ¥PBb§u“ñL6 ÷^}³Œó¡UGøBTñja¶pÕÒŠ}qåêMÿv‡¶ÌÇ!,\ù9yÁiÌèàPÆý«ß_7‘õ+þþÖ-®lendstream endobj 1180 0 obj 1000 endobj 1184 0 obj <> stream xœ•W[oÛ6}÷¯à[åbfERWì©«S [×`®±`hC–hG›-¹ºÄÍ¿ßùHQ¾4m1$€éãw?çП™ÏóégøÌ÷“W‹˜mۉ϶“Ïa^²á#ß³_–Å–9¬„dø]n&ö¤`2J¹ X¬"¶ÜO¼™œ.ÿ ÉÓ4"»e1ñBŸÍèÕ«E„"3‰ÏY˜ÒkÅeȖljq%¸b™÷•L¬ƒOÞ1k6«¼™Š„û~*¼\É{ï~:ý{ù+%–‰Íܱ™4}ã·¬:V ÌÁ¹ùg®×ý–ëíOP&ÇD`î«¶ÜVº`ùCÖ°— çVë~c ÉäýdðqÓ4uó’iú¸Ÿþ<}qÞ¦™õiSÜ”Igù Yžívºaû¾íØ!k[ÖáaVÆßõ†e,`ë§Ïš&{¢'—)••íçX¹ }žDÑÐð!_²‰7¸šlƒÁ’¿>Í,á±LÜÌ*3†Y RL2pÁÁ42UPÂó#Ù¨«h˜”74ÖdÆ/Ö/¡ ¡â1¡„Ю£fë11éó(PÎ$H­‰Ö«šZr,»‡«~$Š‹q<;ý²*»Õ!ëÌêXûq¥eÈx¶ö]ÍÖšõ­Þô;N–Qă8Þ¾ÛØÖÈË»ÖHckôE•°L]Þ}j¹à"pIæ}—­wš•-«²½.®*J}îk§þ¢û«B☠·VÒü‰”>™œ6StÒ÷•òJ„ÉëªËÐ’ ƒ©1ì˜1º÷ÞÜÍ °f‚fuDòÐw+sw±2a8óo¯2ÆòÄ\ÉqyB«l:EÖeìX÷»q;Lí>•Ä ‚&ŸÎD…1 ƒ¦P_êfä<™ô,¸ ’ ¶iê=Û•k3iÔVhVÛý O®YV£à*¹Æähùò“·ÔÈ`›¾Ê»’¼TÏæ¦bôÇ{_®›¬y¢eiÚó¼Lq¶Ä]ù¯Þ=±J?ó&@Ùq î*¹­XÛç9A¿ìX£»¾©Z6¿[Íßÿ¹ºýͤÜêÎ’„å…–jЖä…#$ÚÙ'ÇT ÿu–gò~—Á½Y¼aÙ®×g‘ßmž‰øávuóa¹ø‹Õ{t³XÜ.X[ï5:SivÔUwŠ|ljô˜²tÑͨ:$Ñçº8 HÜ7öõ˜µÄyÈí6ïê5z#}l¨!Q'*¦s—0*û9…Xgm™:!¢ÿ§#Å~%À r¥ N.”ƒŽîtu®n‰ƒ¾/mB>æõþÐÓÀÍ8›Ûx3¡JÇ.íŸy—cÇl@9ÒÛ~Å—Œ‚ “çœD'^‰­ óššÊlÇ SB NÊOûv D+F¹ £ô>±/TÊ4eP©'ʉy2R¦ÖËæÆ Àg24ÈW£q:‚‡HÃP[÷MŽ]ÄŽSc .Üé%|gæ*“Ð{×¹­š§D*D⬭LW»´Á‘LÌÅe£ó ARP17¯,<|GD—0A4ïP±{ °,‰ˈÉæØ4ðxdd(g-:£q)y0*¿o´x2⺩¹$|Õö‘Í*3„å€5nr=§=qÀÂ¥dè8Õ4:LTzíº«?eaÖH8•#ÂË©¢LýÀ«® ð)¿/PÈÅ0½)Øê’å Ú‘a%H¢Ê gfEg"ÎĨf$þ¶ÑCœ¡Äá²¹«˜¸¶bº"iY{Ø•]G›V›]ü!gEcrxÞ´ç—ê(J´@Ƙ®IÌu—îXýP¥CTµ!!5é`K3Ìà5P f2aÈýÔÝvpWøiÀR|º 1(¹)‡ªÈ ×Ü0"…án±¤p¾ç]š–S š«4p£ä˜üQ83]µ}c¨/i,ÍÕeS÷0Èò®§ËC%k觸ÆÞGŽÙ%³j™¹Ž«çwç-©[ «¯©Sm‡T²¦àW__œý ¼{õäøí¯0[Ý­\›„/ œK”üJ¢Ì¥‰&g–KÙ¡wÀÕ©Œð¼.c†'¿ãV¶§Ó¸¸ •Ãñ~k»YNþÀÏįÈendstream endobj 1185 0 obj 1590 endobj 1189 0 obj <> stream xœ…XÛnÛH}×W4 ,–2¤6»yŸ}ÊÂvf3ñ¬£Ù`a/ ŠlQœ‘H IEñË~ûœê u±³Ë!«»ª«N:­?˜ÏóéÇ~ÛÉÍCª~â³jòÇDè—Ì~[ö÷Å$`‹VB2ü[¬&f¥`2Îx²$ˆÙb;ñærºø ÛÀXHže1Ù-ʉ 6§WØ"³[Ì¥Ø<ŠõûºXyÈ»Õs¥†çR-÷Õs¿ß=y·úá-=`岚Ñ&2å)›‹V꿇‰5üG¾Y±k2RòÐzÿ¢º¾n½xn^¸å‚Ç'Ë?móÍæõúº§`vµUÍw/ol‡6ŽbwìúÕ«z£š|«ÞXêŸðkÓ×U£JvÍŠµ*~ï÷Ûg,Ô«Èú~c嫈¯§=sçÇÝ]×µÝ5Sôñ4ý›­+¤˜eM9ûqe'#{l'Ö 8\„©;ÂK; e£,òVƒC7ƒÌð(°VK%9xôÎÎ#2ž¥‰=NÞ)öñ×pž¶­Ìs ¤íTɧó8IxœJo“ãy¯=Î…¢÷äyÁ¤§n*Ô«ßoúkÕµ[l_÷¬ -ž(ÅÚŽ• Ú‚ë£û„ºÅõ#9£5BÚ QXyÏV-ÖM%ܧQêú.+áZp=I}ré>O}ƒpDV*“ÿ˜§™”GƒÀP§ î¥brÆ>¦8±(&YÂS‘9BqFvŠÈD¸²iäXÔ¥uÈ&v3­pmêey˜¢BYfz‡•-ά²º)ë"”M~òD¤çÉwQòŠ[Î3#Z0MÝÁã43À¡àØj“WúÔm³y ¬_·ûMI)Ù¡ÔØ0‰¢„‡gDaf+ 3§á›‚‰KMi?téLiŠ Á÷¾8?õIuUhÛ0å"v«gÃèQQº‚¬u¿“Npz3éG¡.=þªûqúˆà5—ç\|ÉFÈïHøHo³ßlæû¶nàÔ4th›ËÎõ2·õ)i_lŸf'óDSlªa=ÃYØòePýŒµ+ý¢Ì‡ü’PcAÇ» ÷oŸ@7*Ü´:Þy Ìrç£÷£ö¤Iùd#WªŸ…ž™½ âb@«¬j²Î2VÛÝðr™b&ÜËjéþãýóÝÇÅÃ.‚BÓ`¦q™Ž2Jõ66JÁe¹‘ãq…ߺrIÀ3á[Ò ÓдÆ×|‹nšQ̹~hZeݾé‘d~h–RÁH•ã >b9‹ŽuQÔk¦D.9%˜ DcEÛuû=~š¾;>`Œ ârt÷ðpÿð(©L\Ëcœ¸frÉ¢ž¿Ø?‰(T› ïú­ùÆ+ÖŒ… RãF˜iÆ`z†öìêëþв„ôõ#z¶Ö] ¿à©1nùô»!†ù-Bqá‰ðEÞLEXß²±Å¿W¦,L·AM-lkó$G~À…9– 3 o[ s½šEQ6vì1"ôɨ‘0åy÷ð>:B¢S+R#@þ§Ý*ðVã ÍB©iú°ÅZúÔ€A¢Ÿè ½J¯§?H˜j¥Rçs©¶ ¸:Q#8„4É\è¬ö­n,7ÚTo®HÇe¾“o£€]lTf€_WÇDE0Ž^m £«F©ÒÈëʲëè&C]U´J `#À3¿õ'´t`â›`€µËßP'¦}S°NkÂÎ*!d9-ÖV•äUÕ¹zúºžÂ”3[6¯ÊOILŽÌŒy UÑH4ÿ…$\Ú3€0íÒÀ…¢Cí5 zÃþֳç-¡õêÖÊUš÷¡ûãX@þc«çXU7U¹4bkoMþxh¨Ú%GnÆ}~wŠÚ(’.Ô05èdGäG’~4jLk%±Ëô@F§m÷Hñù(<#ƹ_RÃïòŽ4•| ®Wb¼`¡¨&½¤g´´‰³Ø *ˆcÐ ¨šÑæ¤Ô)’7z“QŸX˜s}©Ë}¾9ÖQ?/&®"Á(ÙÚ»££Žõã‚lðf ¬¾‰'dçú.ž ‹¨¼/ˆ˜:ÿk*€¡í¬ÃOZ+.­Äï[3‚Îx3€ÚO—°¯êÔ÷x×¢= [û!_Â'5¤Ö†4œ¡‘Ãp¬|oópšˆ‹­õ­h ¾èœó‘t† $A` 5˜û…xˆîBè äÌåÿ`ô² HñžÑÝ£WµmyÄ_ÀO¥5§gæ@Þû–h !ìW-áHÙ^w¬•Œ\"BcŽ“—eMQA'g˜ÕŠ]­‡a×ÿpsƒ>äU³çFFH3‰úYñXÝêßë›[7‰ÄiiúvøÞç_®f&d‰Î(ÞÚÁ­JžîJkE(©ë͘FôqdHbtu5sBhnmÏÝÀËáp˜ÆúR‡{Á2£ä¼QÃÍÿ \µnÐ?ÚS,‘§Ð)Iß=æÕÍ;0ûFéVÿ‹ôßižÇ·u^uù–ïšêÊ0•V•:»×Ù {¯–Ý>™ôE2Ó ¿ 6¤AŽÿÔæa£™E€«lèô ¦ºH –ÌwÄ¡ïï~vCê8*;µÑ×´íí9ãeØ8ÜõÚ%‰K}OòI¹ëÔ(y­½cEóõžÆ[YvOÞ¨‘Ç‹Šè‡ãÍò•Æ C0’£KïòÛBÚÔ*Á×[KÜZÃÿ³5®¯X"/‚=ù.røöætãwãÓÖD?±_œyj¼ýBSønVz_‚“Q{"…=®Æ“ŸsB‹ÇÕ .q#'÷»Ö»Åä_øùþ!Ôendstream endobj 1190 0 obj 2376 endobj 1194 0 obj <> stream xœX]oÛÆ}ׯXä>„2¢5wù<µq¸HœÜDFdC ¨•ÄF&U.iÙ-úß{ö‹¤¥öÞÀF‘»³3gΜ™ÕïħŒøêÇþ-&—_²•Ÿl'¿O˜~IìŸâü<Ÿd^`ã¿óÍÄìd„Ç B’1™?L¼ŸÎƒ,fœfY¬ÖÍ×/âd¦^Í8 È,ŠÕÔjÛq²ðæ;A>|þú‰ËvGZ|ÚårG§<¤Yš¤^¾ï¹ó6uCrÒˆhDUÒÖÓûù/Æ`*R§ôºBEýp(÷y[Ö•ñ Þ¨- ކ‰õÓ»+ý0£Id-++Ì ÖmɇRJe¡^ý& Dái€èúx _¦8Ü÷ãÈË‹ïù_ïÅÝT6 ’û1 ç6"üi¾\ëe¹>‰hD4ö¹CÃ7NôÉ*%S†|e>÷žpG¬‘ ²§G2ѤO’u·ù)¢Y@ã€r@`«…Tç$iÊ6 Yoü§¯¢«‘OydfIHý(Ôi‘m^­ófMÖB§"æðÒYRËqY 9p4—$¯HJVÏ­p„,a»²Ø‘£@²»ýštò Š RšÄ| Ø1o6ËÛ ôª„NAJ£8=-?ß§Ž#ôz y„µÎcnö)+ÙŠ| v @òPËvÿLT)µŠþ2߈öü‡Ÿ*r†!V¦ŽÒÄ”E™‰)—:†€ù4ð¹NNÈc'/ T›®h»F¡QKaάòq^o,ä#›‰oçe–¼¬1Ÿ‚ÜõvÕyjäÅ›×dßc~Ä<°‡Ä4cV‚êú;é(ã[5døÎ‹7S­ .k›Øw·wžTÂÑZæ§1˜_ÊVbÿÝ” 2åbR 8јÅÀ;ì °ÖaoE»\‹U·Ý˜_"]ËïâùÎCéóÀ§¡=äÍz$ÂV4LŒ.»LEê\‰½P€˜hŽEeŒ»ê9ÒÞÒŒg ëÅ ©RS7J¼¥(jà²mj`Xo+]E<ôÊaWdœÉ ”ÑB®BIóco[VUYmu8«gꪧn‰´ˆ§å<Ci ŸÐ ¶5Lâ¿Æ œ¬lº=)7¤çÓL•pݬIäþÐ ’¤œ!ëÄ£ȓ5Í ÉËÖøb’¯ KšùNÒÞS=å‘ï5††“á¨W.¼Þ`*ƒÅ™A´V›¡'9äZ;¢A}Áš“ai„ÞÒ§0¡ÌH>HH“„ ²‡ ©ù’äêúýòMý†ˆ¶@¢ÁÌÓÆTÅÈîp¨›Vuƒ•.™4*å¾U”¨ÍöOýv ©=ñec©¢Ñv%‘ðïpØ—…ýÜÉ.ßCÃŽS¦é{uõzÀ‡¥CE[g4~‡0ý©“ZçðïèÄùÞï©!QJ0´húL…I”…mDãV£nˆQ,׳}5e.§È£íÕË/:¹¨AÑ,ßÝ:–÷mÖmtSƒAã?ë—ÅK®¦úÄ3ýóúÛ·ëÏ7ËoïßÍ—ï>ßÞÌaÌLF@ôãd~±°:  fZ”uV­3²Qé#Í”2öX{º”äOM(EhµØÕá幪µ*#¹ñªº%›F˜.‚ãQ×”\·h†U›—ùUѽ"hC¯Úî%—Ú8lX»Æ ¿6B”yÊÆ'´;Ð ¿ê$)ÔøSŠ7úSq¾œß‚t¶],Žt‡rÃA/¥`j¸ç_¾ Œ‰)ë;j?H•z2óˆez5@¬9 duŸ;–û=äÜÜ~üH§³È÷=„©Iφž@$`ÙåMïO”h¢™c/£oŸÙÞš„pCËÜN9z«eá D¥"ÙŽ„déãj†#AHÓ¡C<Ýyÿ2ñ7y¨˜ª°bÑb,¥|Œ–ÖE¶»,:Òæ«½Pí³0×{$VXk³N­ÐþzX&Ë?„¤Óׯ3Œ§AßÙkuxõM~&Æú Ï6¬þ!šúe”QJÃ>ïTÍX³ÝKHGóh:= m&¿IB‡/ôÕEb*.ó=9tͳ´”¸Ñ„µ³cfgG´"gŽéI«]Á’ºN^é³ðlM³(ôÆÃã=›¤˜MÞ“ØðzÂÊû¶Ä´È{nâÒ[ÕðóÖÜI|Ú߬^fæ=euJÙដ ÿ^cËOkxááoåcè|ët«äâŽêº®ÙØÇ¼`÷³EzOTÿ¶R*)ÔxAú†‰Ògz²aa@}„÷4¤—Ǿ(<™ÿ ÿœ˜˜vÁ`(ãÇÑ^Fý>Î…‡|Jå©ÁJñا/¶(ÚíÎ2¨®65B¨-­&.8§¾ƒ”Ú‘÷Š;xƒQ˜Å/'A=h)nÊUßX:õÔøÆ4Tá|ÈábµE…â~Ù×ø4zj]ŸK•¾šRò«SF確·óÿ ­GpébTáu£"Æ\©&Bi]¶rÀ+Qµ}ÛøÑzpʲ,®¦êƒ4ÿ±Þ›‚QýóÕYÆÿÜÀRWaY³]Èßž5’¿t¹ª¹á£úž I‡ù¼¿…•j|2“O#ð¤"êâ­>PÑÈá;ýbÓÔDà‘hˆu¡¶ª¸«ÅxäUœÀ±‰½I¤,ëçÔ1/ôÛ%ìÅ1U#‰›«¼¯£ê„Á^ªƒ3v™&EyBðäSþL¸ÏÙ°;ÁÀÖ÷ûÿûíÔûùä¿øù¬,endstream endobj 1195 0 obj 2135 endobj 1199 0 obj <> stream xœ•XkoãÆý®_1Ø/¡ k–3|£ŸÒÚ¶ÝÄ©+tQX…@‘#‰Y™THÊŠóësîy¼T›¹ô¹ï§™wÚ­‹ÓºªK5ÿïòïÆbñÌ"üÖ_BAä^ìóžUËÇCU䛃b}ÃrÖUõÍó±:ä}ÕÔìTW=kZÖ¿•þ×.¥)—·ÐçY’²åyæý-?TÛ^¿W—¶§º ÈŽ­¼N)¶Q‡†°¤ˆxH6e輚³nßœ%dSä½Òˆ]ßžŠþÔ».Ùïªmè½åÉ -DHX’'™vêÉ£›×^u¬ªa‘Iä-¯ ÷9Ha[Ãfdöƒ» KCËÝy;’ Djž“µD{^©C ˆã˜ÇVuªî¯ ïÔ©’3Øì½³^'<ö¯=ZÞ¾hf2.†˜ù\ú†bU²-"²=i—Iq+ÎE1­žM×U.¦‡^µÞÎU^{¶iUþg›ªÎÛWãŒ5iyòH P¦:Týë<y–fÒãš )ƒ4!í'ÿ< ¸Œ´‡1´Æ%+çß͘û´=yç¼Ý®ËJ­·íìù¾ˆ½æy Þ÷ë®ÚÕ9<4/ÂÐS+o5·–†,Z8D'=áªîYyžgH 4J½ÑÌ wç¹ J½îÎ%T"¡X¹ÙÝj£BŽ4Ø-" õ–U»”ÝÌBF¾çàí®¨XÞuu׳bŸ·ÃR¬ZS&™¥„úÝ á—~b&ÄÚ­JݰVÁåZ•t˜[!·ÜÉx| "û¶mÚ¦èc5ÿ‹‹±Ar—j 6P.¸,¥•`=³¬Ç1b ï•çwéEÌÌf2).`Ãj ê´ Ÿ°SV­*zf—D±—¿’lw&®<‘¡;,Ô'„v• k2ÎʼGÖÒ£|â7ÌráÖñ»/ë\·jK§?…DM¶‘-Ã#rm .ÂtDý~¹.Ïͺ*'ˆYÈ!]A_yÈÛç Ô"ôC'ÑPë$J{§‚lÒKÀËÀçjÞÏe,x„rÖäwš9]ž‚˜'¡påCƒPª|º·\1^žì˜_ó"o’ ¼ µƒMïM_qˆ$æqf-{M3Vˆ–\ز…wó …×@ jè•w¬Kl‚÷AâÚS“À!cg°(T×i ‡>’@ׯnz֎ǦíQ"_U¿šëfE2ÿ<®h™ºMáì]§›òðR5IäľÙMåŒò–¹àŸ÷U±wj£&ÁMBݱîζܜ¦i@uËþ¨êZm•ªßq´a+}ôÀÈØ«£?y“ Ji™¾£&Ô‡-×n¯Cèu4_h(¢Rg¤@q¦íCñ¤0.\Кºf¾ˆ@T9$ÛR>Ð,C.Ãh˜IL1’×°W’'yï6?nÃÉ,Îå PÃkÆâ0T&Ý5M¼úÁWS}ÉS1åô\uhÔ„u¡_Ì9»ûtoèÜOu‘ zÿ qð0MÞ!mÒwçw½a"XBèòJmÏ'ê+MÝç˜fº9,~èOïªÄ¨Qm_©­ã¹é&™q,B鲃„¦µÝA¯§p˜ó0~®Å[°†XÌJ“̓£nJºz#ÅL&B3~¨x¨‘°:©5ªë=¶ëu“¤Œ¢±‹P•¼ûüïõÃ?¦t¥TïhDìTßMÒ2DÃðÍe“ð˜g#¹ÁàÆŽFf& 1(‡‹4±#'ò2— ÒC*—¤-B-¿÷‡ìEDÃ,6~Úêåú:§Ž3= ,ç8^\Ì¥ÔiRO~GUTÛ¹@‹…«Â`Ñ~=£ñÔÁ$½“õ4âið­õâmëZk¶ï ®ßœ–7Û·Ïm42è î¡Yäª#õ9<3ëiXáQèæŸ«Nc…qN®»^G·J“×)ò£ÎuO˜LLB­ºCvˆŠ‰¹ãˆ:-Žëf¢À Ù/êèI‚öbi- Š|¡{ùõ%%=ŽàýÖˆ ‡Aݨ¦3Wv •Eƒ!²Ì„÷Rym® ”C”(ø§íßVÖd ÆÄ” \[•Ý?>><ê(cWí> stream xœíXYoÛF~ׯط’†µÝƒË%ѧ¶r€´IìªjƒÂ.†\I¬iRáYýõ=H]v/y( ´œã›oû#"˜"¢_î3{˜|9—hÕNZM>N¨yˆÜGö€¾YL8Zd E‚÷b9±7)baŒy€$ÑâaâM™¿ø Ô€0e8ŽC-·È'žÐT?š2ÊÑT„úðÖ+ªå[?ÉHD^Ú,“•ê’\}ðÁ„’ÀëWKû^ѶE]%˺IòBÝy³­Oá¡¡¹:+‚óKÿ×Åw`Mi`Í89*+w¤>yåÔÞ¨&ùö't6ªÉú¤î;§ ´¼™,.Îô\5MÝ  *ñ”þqçe®Lµuf"g8Œ@Ávâ-Ö -û*ëÀ˜†ÐŒš´29¬òíÿiØw¾»>$ƒñ°Bl¸êú¦jQ5”ð$„Š–Æ»Xâhv˜šÔ„C"FÜŽtžÀs°l”eõæ(Sê«¢3‡³×W¨hQŠ6iÓ¡z‰µ.ÆŽÂ! ¯~nõ3Œöw³=c",hÛÚº4ÖµþêÌþ§ÚmÔo|±äŽä>s[”%4Š6}P¨Qm_vÖQ¢“ë]W@–‚`WƒÄ3d ©ªíe.oj ¬Ê§ ÓnÒL!#W–;p°èŠ´,~W9ö¿çEã ¸í³Lµ6£V—#= ! 3”Ìì}2{ósrýýI¶Ãó0¤Ò*‡´êH Nô @•e;hK‰îªÌ[È–!Ä 1T-.ÞÅX '>Ha X) ‡å$y‚þºÈÖ¸²N[”§]j`'@4Sº¬^/µs³ªÑÌgº!Ò{ƒn|*´ÇÂK³ût¥Ð«¢„,*‹â“žDÄ ” ŒŽA}w\½[Ì9 ‹Rj¡uq´{Vy¥JÍ9ôÏÈð–c)˜»ôIíùL1 ÃíIÉÇP±b4õ<ÐÀ*ò@7¨öUW÷Ù؆®«r§/E@}:I:HÞz8ßn 6-zšÀÕB:l§ƒ K×¥´†>ó 4&ôÜ„.Ñ€î6± Ú Ð.W¶‡°3Ó{´°²P÷îV—ÔÖ’7åÀŽÊÑ4Ýz‰Ú*¹­›îo'Žƒ“ºšÏ¯ç9këh¾E€»¿,÷@˜tç§, HøY HÌùž[Rq®²ó‰thUwÆ/Ð;6SïÂÀv¢2ñÀZèh«"K;×é•­rh«*«Á"$!ÇVG„`Œkÿ™nÚྠZÇLÿB 4õfgÑ0¶çSžÚ)è5€ŽSÞ‡B€4Ðè“{;èCOíÌüs5ÎF 7t‰k}ÿz½¸?)ŽÚ"¡vO&÷ÖÛo$Rm$Ö–PþauéöPHäó+ÊÅ*‚Íbp‚Y[5v¯ûdä!l»ËÑCXEbèÕÁȰ J¬CÙ:Õ«‹#°ÕO ¼Ç¹|ÄàC݉žºÈXåÚéϸjäÉ]‹ÿý®uï¸öYv-KX=ѳÛV¡—ÝÎíÆyØÓbœë–‹U»Õ¼ Ù—!û2dÿGC–Ëó!+ž²ûûØ'šÉZ¥¹jžègûÑIí_åÞÜÀÊ]ÑÁ³n¾‡û' Ù‚“·é1Âèþ¶„BÊê¯ÿ5pµ˜ü¯?±ÊW–endstream endobj 1205 0 obj 1294 endobj 1209 0 obj <> stream xœ­XÛrÛ8}×W ò2¤+‚ € Èݧ™²Ssqœ¯æVö–Ц ‰‰tx±|ývãBQLdoÕn9.E$€î>}NwßHD‰ðÇ}ûÙù"›v‘ÍìÓŒ™—Ä}{òÃb&È¢€UŒø·XÏìNFx’Q%²ØÏ‚9Ã1°˜qše ®[¬f”dŽ¯æœ 2— >¼ ʪ#«§0ƒ•©Lƒ¼Y/7º[>÷˲ZéIE<ž—[¯ts\<…,‚‡,1‹/ô}Èñ{ý†¬î7oÃ/~ÛdÎbk£¨«¶#Å6oÈY8—Q´ºèʺZvŸô[r~FÞtýR7äMŸgçöØ~5[œÝz›LÆÆæŸýò'ã\L³4ãàÜÆ9¨›éö£XL·C<¨Ô’Ò„ë+Ÿ~êH£»¾©ZrrÈTš$ÁË‹+@!ƒß—×–—׋ƒ¹Á†I åâ¯2ÄÚ´îÌ  — ,î f0ö©×m²)[RÕÁ@Tßÿ +È:dXn$ ʦŽÉiD³dð*²%Ó‘ë¡„¢©’Áè$ˆËô”$VʯúpƒæîäÑFO¶¶Þkò¨OM]§I’È&Xì€vu‰Œ^•EŽQÝöò‹¢©z1ÒÇ^eY \ʸ4žÜÔýfk,àãTÇ;è‚6Æê$Û"ó9ê‡û[œˆ‰9¡¥œ3(B¬}Qè¶]÷»·&¾DÃË26p .<œ²AK·ó‡_ŒèüNs\½ÛÕÀL ž@ €©Ñ©@ ÒbXícEˆÆØ#x¼¼Ûàr èÊÔ6(¬#Ð8ƒ¤EÞaÛ8­¾1òâ[èër·¢QÆÙ«ÞÆæCiéÛü~§‘¾5ˆÔºÉµ–ÜAQÑä^»¨çÁÓ]è‘(ª$>Æïcas „ý¨ºñ‰XS•&¯„¡¼m!öá œfÂdÚ×°)£Qª<(χŠ'iÉl "zFž%þܘ/ÿ}w8 ¡±J&ˆgS€Ôº–ÍMp ÚBÂýÊ?¾?‘R)}ZoÞI×.'äÆä±§8§ÓÁì*ß»ÚÀá&Í8hßûpˆ—¼E‰ó‡º„íŒôn¤üef¨üõz4A"F¦Æd:E hd±úšÎE(‡E½ë÷Uë«ug¸eÒ•uòPŠ@™ø¶c¼£ƒ¢±l§ç_Pc»rCÁÇj$• f„¯* òÛÏ…“ÚsåQ£cÀ…ì%áuâ‡ÝñPx ÔSÉ×0„¹!’/c¸(w¦Fc¯8v¸oÛA iæ­>; ¹ ÅÿÈëÿHÀ%UÞÃéø{²TA‡‡éüõRÅÓ—Ð4–Ô-~ƒ·ù”V:h¦¾X^<îÿþÚ?éaÂúÊhªŠaªj]*Æ' •Ø©½ j‡ʃG1êêžÁ Køòæg‡ ò;_ý;Ìåbö+üü÷M³Îendstream endobj 1210 0 obj 1787 endobj 1214 0 obj <> stream xœVYoÛF~ׯä!%kÍ=x¡ÈKauáØ¨ªU´¸ÙH¤Ãòä¿wv—KQ²@`wÎof¾Ù/à žúõßÕnr>aÓL<ØL¾L¨¾„þ³ÚÁO‹ ‡Å ¥(ü/Ö£I1áBÀb7qfÌ]ü‹fP˜2Ç’[dÇ`¦®ÎçQoaF™ ”1˜áù¹Øtµ’ѾXD„ÏzméÌ ÂYdÍzÄ=Äå÷7—Oéîa+{‚yVï9S3D€i£VkŸq…46wN½N6²Mžº¤(3éRŸx”ÎS’Ë4“õÒYºî?‹_U,±ÍÑ¥`F…6þXH×óҹاhôBÞwÈî7g°ªÊ¦…UžÖ0mŸ$ZÄ`”òõÄùêþ 0‰kçSPBP4ð®íÞAUû~§çJË)ÊjÙÀð~DÕÞÛß]r…á?%¿è¨á©Ë³úDæ²)6¥ÌàQÖMQ•IÙíîå›RÕzÝȶIVU‡.•œO¯U/e»²8•„¯‹æi“'Ͷz!s$Yט¸¬áQ„F®ZBº“V‚EPN¦­Œ*{(¨ªÉ)è ñ³QUÞk•˜óþ.svŽ9a`N35§ãÈÍ &¹tU³£Š5,M2àâ¯äâúÏäæ6¹¼YÌ?-]øª‚=í›› šn•[tˆí™Z¶]]¾tñÍtÔKG—óùí\{yÙœ¿W;ÙæE¹}]•›ÿé/0ºƒnÑæÐæ²ïÔ\ÖHߦvX7S±d]K¹t´àk@}ø‡«éd\UæÃb?qÂ9 C59f „Ó±¥Ñ3ê˜)QÐÌêϘ¶à)ûwz ³½#+F~䤯ŠÇ„sj^“ þw©‡´â g4Ñ.òbÅÌ9m—£¿(`Ι±cºv<"†E†.;¾êC±·‹é ÷fþ¦j+ºr3Sñšäѽk€XÄuWjƒ=b–(#Aü[ÀFò;X3/$Ü·šmúÙÌ&ñ…è©^é°sÓŠò¡k!…G-‰ê>½zº-²“Èf!³ ô*…*4‚4² }Jìú"WJJX)ŒOÄÁ°YÚÂå!V?Œ¦Òøéýð#ëMP£‹Y”Ûgè¹î¶°Ïe U)!ÝÖ˳J/Å,çIÌãä°‹Mg˜ý‡ÉÇ=ãq0d|ß û“RžÍ¨­Æ{žs¿ÏÆ31JÈ*„»¬Zø\Vƒ Ì’6îœ}á2ßsÖí(i”àÖIŽ« ÿ©ÙsŠ7Õ’[U»‡b›ª®0gz|†0ãÐÀ&ÚŒ·yØ>éiOC€±“5ú~e„RôÕ µB[5p¡ëLIÀ|¾¢@œ5 ÂHWçâ+è¯~?âÁçàýùÀv˜­&K$Ú&¯ºm¥´•Èe†k3·óÕɧe¦(ÿ¤‡i€é¶´šoÞêaEz¡w] @„Ä‹™}Ò9áEŸ¸Ÿ¡­T«´Åa2mÁ8ö‡žZŒ+z·%à#˜Ç3@Xxò1}æ1zÐÆ&Ї ~÷½|¹˜ü†¿ÿ>C endstream endobj 1215 0 obj 1263 endobj 1219 0 obj <> stream xœÕX[oä¶~Ÿ_Á·H ‹I]“·` 4ífq'I O0%ÎX©FrDÉ—üúžÃÛhdo¶úRØ€Çyx.ß÷ÃùÄ”‘ìßú´ùú&'Gµ‰Éqóû†é—Äþ©Oä»íFm «'ð»=lÌNFxVR‘\dd{Ú·¿XÌ8-Ë ×m›Mæ$ÂWg‚Di†oõ ëö²–yÐÖDŽã0†iJã8-þºý놃‰AS–’íÓ&øþ@Ô\×R©ÃÜ]‘é^’ÃÜ×S;ôd”Ó<öм¿Ú°¢¤,O­¿ìß@§Œ‹Â>ýyÿéo¤ê¢ä¤Œ©¡ë\ÈDLˆV/ÄÓ}úSÛI5jS%Í8+­©ã|’ý¤t”¢dTˆ75˜Ø9ÝÃ|¼×§< m?ÉQ}ƒË!¯¥Ík0½<Ⱦ:Ið‘îŒS‘Åö$FsÈ+ZlúM¦AÛTÓ¾­ –%Mòܺ8Íö­/#dÈÛ †qµ™å4OÝæúO7£SÜ„9¶oÚºš¤v þ‘¸31+êM™á'‹ŒÛ๠<*D ó‰gÁ¡ští5”R0Î܆Dæ¾È0’Êd;Ë(dü2Ûõpzh»J£—_6oS«÷ø SNcîàð(Ïøe”%…s²{ 3%× (YŠ˜´ŒDÜXQRƒQ—ñ2e… ‰È}ʇàëí¢¸‰ ¹áî7°D!áh‘mU6Æ5š&ÙÙ^®cÿNÖÕ¬$é‡>ºîÖ"§êŰÈiY$.a `lÀÝÁöí"uÕu€UršÕY¬‡cßþÅ­&þôASOù`ʲ}wì‚?ä8ìB, ¬ÒTp–§‡éÅ"Yórº‡ÜÀ/zV½j9Ê^9©H0’ôB*‚²c£³£î‡¹kбÃ(å.Ø… Õü*¨”%eFa¸@“ 9i`M’ÑXpƒ§j<ìrÚ?Ïû{Y/ûÃMÊRðÀØÖ޾0¥š9c'Ãmy[±‰-(Ò<…¨")cMóìXïo‘Xš¼&R¹&4)xœñàÊØÑê†&¾Â†ÉãÜÃM“Fƒ?A X"× Y\R_Œ+ƒ$ž¢‹¢õÂ¥Eƽſ·Ç‚¼ÃEL!¾ê8C®— d£›¥ñ3*sšŠ´¼¨Ù«Ð½§ïBÀvÚc–B¦aoû‚2QÌWÛ¯Q”q/çih‰>ëÎYr8îø¢äÀ¬´|Srþ ¬LµùÏ+Ž>?Óç¿©=)Œ=Ùÿ\|À ” >:ÎTëÈEAEîgT¬Àók² gì6ÆWsBT}R'†ì@Ò ÓA,èšjì–ÐèbD;éa?J¸§wðX-;Uìáfxƒ,Ž’`_‡scèívØ]«L2¥Ë¬."ú£öõ0q#¶Î™8³dü±]¸ ©arèb…§ÿ-Þ Úi1ÿs$©HÍÜÏbÄhãþÇOûëÛ½Ž“Á\ç]ú§:ljÅÔž$?Œ þOã`¦ìˆœòÒ£ŽàÜÝP.|ÅpŠHs?H¬¼º¾1Ám*;ëŸnˆzu²Š^é;Ü™Ü hxg‹ùj œÆç[Ë¡õƒü”þ# C  œçS7Úë~¥q"DFÓ³lU‹.¯€Vn7¾Œ}îÆ¹6³ÿíÝIüxù³Ó«QpîËK æòÚ—%w6MnÐ{uP/§»¡Óó;]«Øq¨––¥°¯ ’¼yªkdyN Vº\<·Kˆ…Nõ°y8˜ÞT0)}“À‰Aßá‹1séJr‡ Òœ¦þ¦Å`Lò¸¸¦µÜàHãI·Ìëe”9ŒFþ®‡Š¼® Ð<ä?MYN…ï>¯TQö:} -6 áiæ1à%›ué`ŠŒ…¿®Ñ“0,¬'¸X$î[4%Ô7;åJú™6±²i97ƒ‹NlÏÞ,ç[ó?4ŒbÙ-*õ†|Ý2ÿ ÆáiÿV×ËߨCa<Ϯޜ!ÉއîZ/#´3Àsÿü7VzxÞ¥ÌÝÎ/~¡u½Ýü?ÿ}endstream endobj 1220 0 obj 1899 endobj 1224 0 obj <> stream xœ¥•Ý›FÀßù+¦/$fcl]òÐè\%Õ5§ºô# â`±© ëì‚}wQÿ÷Î.ËgŸÔ‡ KÈ;;3¿ùäx„‚§óÎkëbÁFZl¬oÕB0¯¼†÷±@œã-êþâÒê5)øó% fsˆkËv}'þÍàeê“år®îÅ…e‡ p•Èõin8W‡_ì`áE/²ï²z¿cÀKè$ƒ’ïvÜñCây j%q¾Æ?#ÁÂ,Qâ/(¸~ïà§jÓ åA“ú 2 }ã›…OP3(­^@‰Œ£ {É{ÕÓ<@qt–È…s;eºamz×¥ÛLnSÖ´â>±Ǡѥ1ãÒÐ' C¦3íèÀ«˜1™ØpuT¶þêÒMÁîÒ,+˜€»n[ˆ©BBü'åþòï¬6 +@»–;ÞÊ4ç]Ó¢{×±Ê÷S#A°£e_¼>ÓWWiH‰É–§ï ÖvBy»½×Ö©ï“Ù£ùâ8JE¥CØêT2¦ ƒì–×çp²ÍÚ*79ø­Ú,à ®°Ùî²'‡øz|%À„€wà]:¯,eæú<-ƒØ(—iÌ)¾ÞžÅ§oÞ$|×:gùÖ`c¨—Ýêè×vÕ´ ˜h'Ó æ q.ÏZ•ôNÞÁÕŸéÕõéj½¾YëàN» ;à†ï%9Ëo6CÉL´}¨Xtå'žÿa“åS27cµÃñ}éÓMºú¯?XÊâˆêc½çRV·¸z„ÿéü‡šÕy½OFyõÙô”@VŒ—ɨú‰Ó–=™ eƺ‚i…Œë«kpYõC *™Š…9oڪ阂?¡›qüÀS¥žÍŸ¡„¬Z,±3ühþa£qݳ`/KÉZ©µv¬Ù´[‰´™`€¶ªBo;û}×B»eÚXËá–Á>“R·2ÚDöC&*ÞI(»&o+ÞHØ"#T²÷íRÒé†fýY\/„ª7v ¶bDUK!o¨Cœ“ K(ÐÒlN<\˦‚ã9‘L#¤MV3©Wíó…íª..u¥¼fß(‘1zž¾á8ÓÄO~ÉîÁ÷|ú¤Q²ŠòßßµUlýŠÏ¿'[> stream xœÅXÛrÛÈ}çWÌ›—8™;€ä)‰äZ'Ž]Ñ2vRRŠCYÐâ"ÊþúôÜ¢¬d+µ)¹J¶9ÓÓ—Ó§OógD0EÄüøßÅqñ›ëíÚA»ÅÏ j?DþWqDX-8ZpŠ2VÛ…»ISæ%\¡Õq-Y¼ú˜Ã”á,SæÜj³ˆd†–æ£%£-¥2ÿy•U‡6§8ƒ“©L£¼Ù®wº[?öëV]YWë*?êö6Šÿ¹úXDK*ÜÍËSL &T {ëïýú}µÑ18K3=®ÐùF7è±ßoš˜Ã ©bÑ…³6>,Œ‰7 š`F’ÔyÉ(ZÖàߪ¶ÜUzƒŠúЫui¬ƒÿTRìOG6" ) $ ¾»æàÔ0MŸ~‹ªþx§{–¥XdÊ›õV…Ä Á*1n¢¢®Úû¼Ao߯KÆ$‰LŠ\`«·ÏsÕ45œõGuÓÜÆ¿³g—&›Ì¾˜âŒeÖÁÕ^£m_ÙÔ/ à™/xʰ¤"”ssz¹V·±¿°%Ç’û›]þ“ Y`)‚9p€Û÷u‹ò•Õ}ß¡=؃„cvÜíüPnfŽ-“ÜOÐ@0s‡ÊÀ£µÈq*]ìyµAùÌ6à†'<Ô{…Ǚ͌c65éê]o!Š}ÞîQ{¨;¤«®ùŠn#ã˜5‹ ‚ᦆ€fð³m¨© |;NàÄý/qz“ÐF£oº©áar£nßÔýn? ”2…Y­·ÛVwíº¨{hÐ%'¦8ä6ú°¤·ñmŒ­ûœQ¬’Y7Ñû-*;Ôè®oª]ÆÌt"—Ñ—õåªAªˆ>¯?~Z_}\][dÚ©’x舴cŒ s¯ºÛ—Õ•-:5uµsPeÙà<Á˜ÍÇÜ8 ¯pºôfîÕÕµó\‰Äç6útÚg/#Ÿn¯çy•‹†6½h]$˜‰¡Ô£BѶ"N0ɆL0¾Uó8Ô u5´Ì¦,ònÄÈ’s…刣¼=OÌžWîuQncšÙO¢²@ÎWðž@«D8P†»é3 ]MeÈlÛ…nÛm¸0yhäi¾išašH¥M·ñ˜ah‡€¾ÏëO¶é4t¶êá¶×9ÉÀ Vk‡”Ö )#¢·•nÌfδ%š’ˆ‹í”ÀÙÀ¸€hd]e‹a&G¦ÏÂÌ”›-aÖ¿ ÇTáHŸ­î4VìGKI]Ç2Ç_f¨`лvKP:œÏ 7Ï(e¸fëº×e.@é Ÿ:Óÿ?ÁÛX¦Í`ј›èäˆy-SÜ(_‡]SMö=åûk‰iHäÚõ¯V<àÒd3jb$ç쬳ٖߴ¿ïO>ä¯ÉíúœàNpFØ«‚FÝÐgõö‹0„»Ch¾sŠÛx@_’ÜP{6nnÿÉ ú8“¾&€ÍÄ,€/hnjF— iêÓYÁMI¬¨†Óêg|B«IORhDùÚêñ3é£iXVò»úÉÄ S5zÕÖtÚ‚½|ªµæóæLÈ ¾4B¿³fÌymI­zÏ(…0>?qbªRRåf#ÔÕ7;ˆrÆÃ¼ ½n¦¥;[,¸œÄ7Ý8`4)6Lðÿb߀íV‘æ¾*öñ|Ù5.Dt}£=СºÒ¨oõ3ñ²ä–‘_ˆh)tÍqÀL½‡eØÁݘŽ»˜'–‰ˆêõѦάü ß<¥¹»¦;_“Áh¼lLþi\ €{áHp—lôb ÕÇ $NÓaº'+QŽè²nÊ]Y9Å 6@ý„ôT€ae Ô`ØCoÌ23‚IDm7Æ ƒuŸpW!Î}ÞÙÝÉü6ãÒÃÙi¡,ÁŠfWßÑB¨í€CòfcKá„ % ˆ.¼ºd`YOƒù6vh”ŸJp:ø0:ný,j” [Çãvj„ÑG^?#©_ˆQعÇ(³5þu^µn©€?U ¬{EÑõùÁ›Úû¶CwÚ/ÌÎRð¡ý©¼¿×Ë0nù!†Hõ4äÏ@æCåYŸÙHo Î²0S€‘aG†VmuÕj£0Ûþ®kÀÛ¯pÝîl–)<æÌê<.œæ47ÝP_†—žNßüp.°j;1T`—EË ø²im7 _*˜ï°ÆÎ<Õ±ÒÛ XY2Yo¢½}ÞîH‚Y)ѺU!ìÃûRêÅÅ+ìkI÷Üw:IŠ©ð¹/u~Íïsü·9Ò°,D%¨k¸ÉÄã°l…K|B/a>±Á?þ’EŒ0:^L`¹KÂÍW¿/¾Z-þ ?ÿ˜3Ôâendstream endobj 1230 0 obj 2126 endobj 1234 0 obj <> stream xœ…VÛŽÛ6}×Wð­2±âE”طه´i1„ÅnaheÊf"KŽ(Çi¿¾Ã›¼ë5Pxcɹœ93sèo(Çåö¾ÛCòóºD;“äh—|Kˆ»Dá«= wuÂPÝ‚¡þê.ñžQ!1ã¨dÕ‡$ÍèªþaÀ˜P,¥°võ6IEŽ2{•QÂPV{ø~èžÑ¤æÓ4ô~E%–+Ò?7ï?®HžãœðôͧûÍݧz½ú»þÕ!¢ÀR„ЙKN£á|<¨y¯‡Ò§qØa€TSIQFä PÑ9yŒ! +ÊÊ|¸†u·ö€ÁË2¤½_#ó*5j†-š÷Êed±(0u¨i'1Ç”_ñÍ$à?oÚé¥äçr¹°Å0WŒê·6¹Q3šG¤‡­n›Ù¥wfŒ \T(#ÜlÌí¾å6ØCzT­îVDº›T·Ècôy^È;²è˜e¸ EdÖœÚVÓú7–Ô†vÖãð’oRILÊ"Té趈)&”….ï÷¿9:¡6ãc}?:w–cNBÿmzîÒŸm'G-Ð(.4îN5Ì®ôŒI³Ã"#®ðtÞOãi·wYŽ£f5™_®zh‹ý˜¤Fµ›±ëÔê'›ð¾ì`çòÍcºý|rpâ±Î<5F¡×â¿Xâ’•2éãJÃq\q’ã:ãRQ†KÎÊhæÃR¬¨í&8Ù\ð¿»ÓƒžuÓ£v<uߨŽe'8ËBÇ+» "i³\ú‰Ù«f«&è‘ïòÜ|…ÅøU™ªuÓxp ïSYZ—6ø2Ž VFÙžíÅÅ‹ã‚óx9Ž¯Ò™¸ó"¢JŸ¾ŒêP´µ®*L¡õ1BgÏ`F¤ˆÞKMžíGnÛÌ«5ÈÀxõÊ‹hK¿¢ÈPÚ ì+pKX¸7ÑÇ ð€¯.“¹÷ {æFÏ裸ĹƒÖUËDU^.ª` éÕ°›÷¡Ýn‡h…ó(fÖ‹û†Ž“ÞéFấ„T±¥¡>'ÓÞÓJ2ì½U£³ˆ«êÓ\:¤ÝV%ÐýQÆaAf®u)E®°æxìAóžzµ 7ñˆÆ ´¤ò»AA‡šôûE' pÈ£òLççè…Èi\¦½n÷/w‰FPF73Š2A%i!1-—÷ÇN* ¿Z'ªEú£9{ |Lëý\/$……®–Åh¦n³SóæÇi Þ ÍA™GP„«É ”`Ic¹ ¥×Æa±„Åž‡›Ñ½*Ý ¬-o¦g§-4=/$8“ŒÃÛj㯟1Îp¾´ü;{µ¾ßÀ ‚“ß›…wñâ]Be‹Òþ﯑»:ù Ÿÿ³P‹endstream endobj 1235 0 obj 1035 endobj 1239 0 obj <> stream xœµVYsÜ6 ~ß_æÁ–œMR÷¤ypk7i›N§ŽRwÆîhh‰»R«•>ÚÉ/HJÚ#qûÔÙ=àðô(a@ÕküÎ6‹ÓËÖÝ‚ÂzñqÁ´Ưlß$ ’ µ|'«…±dÀƒ˜¸„nÉfa9ÜNþ@TfœÄq ô’|aáG‰N/£Áa<&Ú9~ U¾+×C«t´/Ï磵ô·°qy4Árb@·qùFrm]<ŠÍ]%ÿ?Ø1‰£Ð-ѮҵìÓÇ!ídÖ—MÖb#»ëƶO~PPñ Çó<ÀÚÙ}Sæ 'ØëüAÁý6¤ß×¹|LßJ‘ˇ"o—*,L!šò‡º+׵̡Y­:ÙwiÖ u¿„i©CBgæïg€/Ú¶iA¶-¼úJ))ñ»ÏüfMe4Ž!Á4ÉɵuzWÒvJ­¡“p¼ݱ&†SFÃ-UfV+û¡U·OÊFË´ï'ò¹p|¶·vÊ SM ͪd¢ªˆI\YLHWthZÿv¼ƒPÚV¾‹Zˆ®HeÝ·O[L89Ŭ÷é\!i7ÖDŠfçëýÚè×/ä9êwk:³(«d=ñŽîꮇ¬-œ€j¿Yr`T›YTÖ=&ÝMÿy¤«kNöR?èë±÷#Çœ–G¨¶<ÂÆ¹±_}Þnå éQN¾z çWéù»_ÓŸü"·­~áÓN/þK´†óçÂÕEwØR‡ªË#äóz¼ êv¼•­Ä uvîÀƒ„BÜKè ©½¿ø6IMEE­Ëw+õDsÜm#+‰Ò¿ØÎ&m­­ûO”T·ÐÈ ä¢ îîª2·zk4€êqÕ}!zX7=Þ(0N¢?t&ª{Q ²#¦õýpçB}z&k=¡=5=]5—ø:×@ÍùDÁP†êF»1ñÃi3â{Zïì œÍ—ÞåħágIr ²Ï4Mˆº¾-ëuw0Èœ#4òcp¸6ö‰Ët ×VRHÌn5ÔšžÔ$÷6÷ eœ[*gœ¡È“щíÄ.$YKcm–ƒïúX™U5mÆJ>Ó»jJ¾8·]j]¥‰>G¼HçÐó¦töf»ªySî$ ?8V6we%Ó¡.û°.upk°(ĕç½w¯Á5¶¨öÑhÕýÖ‘K8£|Ú|ªìš ê1Ã}d ¯D?KЇ‘äresŠ Ç†}Qvp §¸¨ƒ½ü¶!í䈓6ۉœ@`7:Oz$Œç–£¦¢]Rteõd*læYÄ,3å°à°–µlE¥‚Ü@ÙaFT /ÕÅtG—Ô©s·¡ŒÏá!àŸŸÄpÊÙü¬ÁBFâp²üÏg˜‹dñ ¾þ~€endstream endobj 1240 0 obj 1066 endobj 1244 0 obj <> stream xœ•WÛŽÛ6}÷W°y¨å…͈¤®MS`›lÓKš £E‘- Z¢m¶²äHôºNÐï%Y›¦-vÁâp.gfÎŒÞ!äë¿ö™í'oc´m&>ÚNÞMˆ9Dí#Û£¯—†–HŠà¹™Ø›Ñ(Å,@1‹Ðr?ñt¶üÔ€0¡8M#-·Ì'^DÑBŠ´U± IŠadÎe©P~âõfµjõeSí…ÚÉrûÕªä{qçé»4Á ZÀ\8–Ü–"G÷¼8й>×'/'^¶ã5ººjVÕQÍgÓ‰w7{ó‹jMÌhòqHÀ‡ÓÄûnƒÔNŒ¼¤)Ž’8mÃ0ÆZ §¥FƒxëxÓ€W²D²A”ÕŒ€K½S9×êÑæXfJV%ª…:Öe3ûmùýÐ IcLSÚ|þËêùËŸW¯ÌœQ—9:< âèP–¢Öò ÆœÀ…4‚ M¨ª2¾ð᮵äJ FÕ€78®ª$H0e.“Xƒ·oõ]FÀ°ó/»b >‚È¡¸ë­5©Fq%3xT5ß‚WxVÈŒk  %'q—Ó(1¡ìB¥IÊJ´9㈅]ÒÌ!³7 0† iÏêM_°$|ç|-„È:еTLq:­Úô“eCÒ€|ºl@ƒ“ ÊJ™‚± Æaœ¸3¨œ±v§Œ&—5òêõêæÕòöבbâJ{;¶îDn+$ñq°®­û‡¶ÀÔÃìs¹œû‘6˜F(£—Ù}˜ÙºÏ,À•Rw¡ ìÚ‚‚sq ÍÀj¹—rmiÜy>îš}+JQCó4ºš¾·¡*ôýY ¦ã0ò@ZψþɈw”EŽ”Ü ´>CBx®›¤ÁSŸ°DKã6Ô°0[§(f‰­ºë¢pF«¢0UÚÃl3À¡‹÷¤z b-âr¹d\YÉ­Ì‹ó…Èc>qÁΛY¤ØO¼JÏlgÇ8Nhߨ¹P\ ª6Hðl‡x-L1Ôâ ©ܭ͉íj:uP~@lù^ó9P5臗Wo½%XÈv•Ì„60uC`j´êv½·|¦žn9¤Îà“z§¸·=îLš;OËfUÞ] öÂÝì#ÒÒr´/¾sE({7½ÓÎëµT5¯ÏFÜTd ¤ÕÁù´Ë„®ƒÈﺲTSpçE±ã¥ÉHÚq³“êêfÈ­]ÕÛþ¢DǦ-q³À[]éqgg€ÆjT;Œ¹?g³ BnZ$5ÅGš<˜3j NP Ü‹Q×öºx¶È̼7ÕÜæ{FB(ì òþä`HÌÍ]]óÜÖ¸žL‘fá,¶'4°D¿¼F/ZlX[yñûÉ<$r¿c,ëIlîk—MÊ ¸ˆâ(í(²_C®Ÿ=»yó¦Ý@îfcb…Õ'uÀk3‰#?®íèèD]Cô§„F°t`Ö`÷´›Ý–`I`ÑèÆ›…ù$¡ËaDÃd­0+7H*diÂb^ññLŸËµ,¤:»ªÖ°R C´ÍÉŒw:qÝØ4˜ÉC—÷f„ µÖ<7sx[U9Ô’˵øÂBt”éSû[¥¼oäöXwt ûZv¬öù †…á1®¡cœÖÍ÷ktI¤&9K[9ÐíT"ê†Âõ‹ÞZ„“n(ŒsÙ“?,T$é×ËûJæH8ûwæ·½å}€eòbÍ€ð²k'‚鈞"ÿ‰Õ[m ýd^L[Bó_!Ý{†·Oítª«r;GyeÈR}†®Ã¥v«µjþ¡6a.¯_¬€¬êóÊ,€óÏÁ»øÂ:i² f_Uf©†—Iäæk›ò¨»;„}’j‡¦`rŠ ~§ Ê0×"Œõ(jï÷‚— os,°vÖ0ºA¦¡‹tpÇ^yšå?ÄåÉÍgá}Šº=|œ ßBtÚf{ñ0|¢¡1·?#HÆ ‘Ú¶ûR¿®¬{"zôÐåGãG6Bñ/Ñ9q›…W€ÑîÎÿ cÇíþµÖs@UÇl'ò¹&ÙŒbp*©$/ä{˜è¹!H¢KíZ§FCª.Û°ãBu± *`øjøéEA>õÙí`scÃŽõͺo #øñ#?# Ò_Œ Ncwó_??o–“ŸàïoAòendstream endobj 1245 0 obj 1674 endobj 1249 0 obj <> stream xœ­XÛnÛ8}÷Wð-òbÍŠ]ø˜MÒ½ [`}H,Ñ6 [r%9Y÷ëwHв|Ú `$¢†3gÎ9ú+ò1A¾þi>ÓÕàÝ8Bójà£ùà뀘‡¨ùHWè·É€¡I «Eð;™ ì›ÑP`ÆQÄB4Y ¼N¾@XL("Ôë&ÙÀ éGïÆ1"LGQøB?f˜hòË d•é¥<Ä>£± ðà½$åìi.ë§ëax77w÷÷Oy²’Þãpøïä¯nv#÷·}üÁËzSæJr”¤©¬*5UKUoQZdé`ÃQàû^½(‹Í|ê…t‘E™2ŠCF›ªª§bSÛ²Ú½™p¯ •ײ„t±ïsáá&؈˜`#ÊŽQ ¯¡ 8Ì©7ùêºTÓ!õ!CƼM-¿ °¾Õ±N"Áz#q÷ÃP iRITo×É Pù¼/!]V?Oj‚„Ÿ€¡ƒÂííxWý~GÅcAÃc.dY š8 Ba Ž. wuÊqPÀšÐf“IÆ‚-_ë‡Ì=$1bÑâ\¸‡yÈq ¸óšY½3!6Yùv5À¹Pz)U õé•# Ì}p#ÂM€"_n›ìÛê¢nn·Ÿ¼‹\”C(Ô¥ì•É™•˜àžÊe†T~ˆ^”ˆ#?ÓmÅ‹ƒÐïBs¼l‰R~š8Aoýܼï/ ÅâPD÷Ÿ>Zÿ˜-“ù‡ Æˆ½Â¡ûÁe1é}ãS,ôŽI4ÙQL‰p\ˆDK…]ƪ²| Û~àø`éɼV¥\n¡Ì[³Š`Îuà ÄTPGìÏ×»²uxß#9$ÐfÂCï¿Zæ•*ò#ˆ8Ž90ùd#ËpóÇŸnÇwûº…ãæ µÌ€°€êJåI 9šö¡Gïe¡Ò@„*)s °n J¦ÓR)ºâ=+ó†^’šW³¤N.i,?hc={4¸ê’ 8¦1yÅJHxÒIÈ)'Ù#å9H_+=7 ’v\ÑYFšd¹sAÓ¤”i1ÏÕ7Y¡YQVW[Y]ÁÛTÛyLìRXH°6Ì,%ö®TSþ¢ã@K´!¦QãÁ†zM˜€tv„ß¼¨Ñ×2çr ÔЈĺ³4ÏÀÿ¶ù®Ø@¯h Xä£o²,šèÝì´’ 4 Jy¢é´"¢0 ’¥V.WJ€CîéãÁ[ÊY6kT(]*‹Ö£—å*Y.õ˜µZ«¥,5–æYäJÕ€åsË!“T1ƒÙÒ¢¬Ñy EËãÃ<"ÇÕY›3Ì.‡ÀKȹ·Õè›u‹:éÒúàá0.‘K¼æ>ì‹cbs›!vÐ2ÿ×Î9çã8ämÑ‹&èÙ³ñŸrp×Yº&28Ò%;>QãçMs´TÓìeŒˆðm%e­fVÎ>mŽVæ^ö’´ÆhbkçމO¤Ü’ªNò,)34ÛäÖ%¬ív ‚·0¬{ö³8#]Apò[£±¾•¬×2æ}ÙTÀ·©™FpŠí˜Lâîp}6ÙG¸<&­eØ¡„ãv&”µÇU2kûA)ô‰×À[Ùõøn°3rJàpò„àŽ¾­…~äRÓ;š‚9ÜÊÀ«:ÁYcš~lq|ÎÐI½{ è='¿> stream xœ­X]s£6}÷¯Ð[a¦hõ$xôv“tòѺÌô!ÛÉmZ¼o6ÿ¾W2ÄŽ×&lì±g0 Ýsttu寈`Šˆý´×l9ú0QhVš¾Ž¨{‰ÚK¶D“GI­(CðM¦£MOŠ˜Œ1‘â%Ë‘0?ù` 1e8Ž¥m—ä#O†(°¯>L"D¹E\Û×3’'h`žç¶­`XpµO©™>Ìtópqûé¡L—ú‹÷Åß@¾Dt]æ: zïMt³6eÒé2/à’U¹FÄ!^37Õz6GÍ\ûÿ$¿[ȸ…dD`Ë6ˆú¡Z7{ƒòxóòÞ[UEÙhã c·`[ÊaèÀÆÐ{i_ÞMnÞÏ{Z™åO°¦±Ä’³3±æÂf-úYOÆ7CiS æ _˜£©¾;̆ Ñ’³}¸ë³+ÇfœN I±"}b„Ä¢t^ï6jƒž8Çœ‹V3'ÛeauÁxs]k”r½«ê²AUÙEpB°´tÁ*Кaª” }•š¦ÈÖ‹Ô ñÇ«_Q]¡u¹Ðu}€ ¬퀹UÏ÷øÀT €n'x]ë5šéR›´ÑhQ<æO~ ëdô-Ó&ƒØÑsµv!8 À¬H†¬‹·ueãHÚɨUˆ´øÏ§Ê#O/žíX}óihS÷´yFÄt½+ç(Ó¦I‹º ¢8d^UþâÆtb³˜ã2Nóè3A<½q¹S @¦Ûʦ0vÜtµ2ÕÊÀï%+Na$qlåÊ^_¯ ëbê3‡pîÚ ,­wú’WàÜèLËXIvXÕ/ÁíõOiðJðGyŒðž·c…»y?=kI‹u˜mÔËöz|ûùtÑ"-gët6Œ/#À—‹0¤E v˜qÜÏøzp’Þ÷8ªW‹¢ 6 ²¥p eQe‹¢nÚ<Œ1=—Ë#›‹zE¸,=ë”b)»]¦É¿Ii— #A½ïÝrT­œ8âXÉ3IÄAŠÓˆ¾¡Ñ_gÕhW¢ºÝ!5o(³·‚BŠYt¦Ä9Åqxd1v@˜û­27ã p,½ß®n/ï¶2µsyšNË43äR[¦MU<±·e²‰æ\*Eø¨{•þGDšøÌ– *ôNÒ* Ø^²×¢yŸþ~U¢Å앚ãÉ¥@%5Uä|™›«‡êHqÂúwœ°ߣݽϦ3Ë&Þ÷•BÕªW­lyi Ìi‡â\¦„ª˜“cK·ÿŒr7\àíiX:TõÃbMIŸQermŠr6¬ô‰ æ ϶ ‚;•z¬¿ÚMZc(8Ù$Ç$Š»£Ñøó®3ÔöàsT@j7¢úLH1¥?º3ÐÃ6OÆh;.“˜ÈîÊý†´‘„WÅ'H ÁÃþ m{>Í-‹à+z9iã[}º#f ÁÍ 8‚F·ì6ªëùæ?/ÉèOøüMzšÇendstream endobj 1255 0 obj 1148 endobj 1259 0 obj <> stream xœ­WÛnÛ8}÷WÌÛÊEÅŠÔû”m ‹4Aoƒ¢Y²DÛjeÉ¥¤¤ùû!)ùÒìåaá ²ÂápæÌ™3Ìwð>ö™ï&ïæ1lÚ‰›É÷ ׋`ù~[L|XähÅàÏb=1;9ˆ(e~±Áb7q\1]|E7hÌKÓˆìÅĉBpiéÝ<î“WàÓ SZö™añŒf茉 ²  }‘_œçL­—Ù-?]ϧÇÒV:Ûí+ —S‘RÆÎÃ1fóÙÕl>»}?{œóÆš¸)IÆš¨/0;1`ê 5_ HÂ’CȄӥÞpÕ¨Ýò}•µ-¬ó·dI67'ßf Þ¼Ñäz;ýe‚¥ýg¥ëJ™ “òõZ'a‹!(žjè¡lÝAc,p14j‚M_€ÊꤢÚ*üÄúÈg^ä[^>,/o>-oï–³ÛÅüóí8"ÄK(®¿êú×”›ºQ²=×C&¼`ÄèÕ®²„Á‚%ðõ¸­ëjyBÁ™?Šœó¤ýs¦8Jä!ZbØ`q8Ô û‰ŸÂ0›ÏïægÑ& ŽãÕ=èdy$˜ÀÞvÛ cˇp/ó®ljÚ', )qîöRe´Ôž÷ø`7ö¸ˆL?]×oeþ­¬7Ø„ gA@‰F ãa8¸~¸8 @¾Ä ^ó+êöª¬¿M¹ç4u.¡5ñ!_…š©¾×ù‹ÌÙf-¬¤¬q­ÇR÷­\÷‰Ã6Ól 㣶ñà¤.út7(ÁØ*!C¡Lr©º C±§»*Qšd͈ ôLÓœz)WýŠÕæç‹ˆ±¶ópÓþ†‰„#k%½ÙÞ==yÀùh¦œÒôÅ«GY#˜HšN7F‘í² v{œ­øU_ZÐ6Gc3à0tš¨Ü3ç_Ìpð AœüC†ƒœã_>d/ <ÁS%æ,‡ÿúßÁl1ùˆŸ¿Íqcßendstream endobj 1260 0 obj 1426 endobj 1264 0 obj <> stream xœ½W[oÛ6~÷¯à[ä¡by‘(òqE2`[¶`Û=¬ƒ!KŒ£Î–RIŽçýúÞ$YI–v†0lžû9ßwÈψ`ŠˆùóŸÅ~ñö6CÛnAÐvñyAí!òŽ[-8Z E‚ÿÕÝÂiRĄ¦ +%ŒÜª\DB Ø½½•ˆrc!fð§ÊsÌR´:‚æ)f¨4¢‰À„3é üóön½ÕýºÓE_5õºªï–,Å„¨$jÖ›ÓºÎ÷úcôq¹ü}õƒ‰UùXã`)fÖ±®ªºGåsF'¶LŒbˆ&6¢©»÷y‹¾ *Fô‘42׋èÒý¶,'29|{³¼‡ïë®ÚÖººê/=¸jÛÔµù€„.¦¥]D>,IbóYÝktw¨­9Wé¡B`&’ЊגN=8d<Á ¼8õV÷‡¶îf.x†)“ÁÅå¯ëËëë›g–„Ä‚p奪;Ôßk#'B U†n —“m+++Íh¥ “q´­ å”`î(¦‰Ÿš¨Þ óU#cN³øi:=¶6xf3¨'‚…\ŽyÂ"…r,3»nD…Ä\Ižpâ¨Ö5ڜЮڔG#›q—Rƒô £Û](¥„Íít‡¢Ð]‡ªuºŸ7)æ) ŠÆùl>g½RC>—ÿ`Ø7¦iè±jûC¾CFÑ8Ì;?ÑþóÊ cýÁùyiμGM¨ >C?¬s‚ÅHôÑw_Â=ÄÅ0Ûbн,åÃfO¸ÏjÚA™ò«îÞL¹©k©ÑõÕ;Tö˜Ô½¸ú˜[Q€ðMS9#ý@ol޹´‰³b°–õå­Fm³¤ ìZÉ€åˆ68(E¸/°Ì(§“‹y©/ld6ª`8¤ÞM¢‚Kàpu]5¡Õ€r“d<{ªpáÞ21ÏæÏ¨Ÿ+0žKjoYT7_¾¬gë± ÆŒ ‡l<,гU6å hNÞy€À-êµt•ʳMéÝ?1®Œã°ñÂ…ÉtÌ㨰L<4ui@ã{êîJöòO5Þÿˆ›ŠîA°©aU™EÔbsš—P@OG¬ &'!rŒ~TæâÌ>>£[= ì+2ì²G>Ù™ÁË|ù)?!F3ŠU4_}_­¿ÀßßhO+ÿendstream endobj 1265 0 obj 1423 endobj 1269 0 obj <> stream xœ¥X[oã¶~÷¯àÛÊAÄ”¨Ëc‹m-zAw}p6,Q¶ ItuÙlþ}gH‘¶ïI‹"A|9œË7ß7ÌŸ„QNþ,¯e·yø˜’øaä°ùsÃÍC²¼”ù~·‰È®„U\øÝÕ»“‘ä4ŠI%d×m‚Plw€XÌÍó×íªM¤$ÄG3Â#´ x eŽ#*$Ù=Ã2%T —Æ e‘ÈÏÅP?©aèÆÃc𸵶x¾¸ºÅ¡0Ë™±Vê~œHy,†;R­ àv‘QXÏccþ½yüÃ0è(üëp‡v½µÏi*RsÆî¨H=÷åÔèþÊ©$£œ3±PÝŽÀ'”I*Á¦]<¨iú‘䤛~R™4|èç¶ áS×ôŤ*ë)éÔ8…CžF4‰RWLEœ ŸŸƒqšþ@J= j<é¾ÂO`u‚¬ñ¤Ê¦Þ 4`{ÿ²ýßî§ËxDœSÎ’ÅE³Ïä̲ÂGä–ÑG„`T¦™C»¸4õÜV¤×ÙÛ("HF’Å. [ÍJm«Kø<ÂÆ«tg Mä:ÛË–›évÀ¢6oylvC•m}#<ó¶{åè^DVS©\™TwÒC1¼,«é6LXN%ã`¢˜H3Þ›\ÛÒÂÆ¥²&ËxØÏˆªXà©»»ÏAW¼€áRwx|Ñ*ÒÔäEϤҤmöÕó6‡þâq@ ¤„8G¢{<áUÙdDsßGèïÕ~>\¥$ƒe±p l uоTDƒI€ß±¸†wE)Í<ÔÞxLÓܹa¡saÃéy̯›¥×ÎTϳ+”åvWÆO¸(r‹8€!ÉswZy¦%I#‘¸(õi½‹Ó,cΉ—é¼+¢Мå»úÙ@؆ëò裼‡zO[²7 `þÈÙX !Óࡇ¸¤<Ë-̵é„JT_-%õ,0¨®hz<ê‹¡°(¿¤µ &r Ù¢m^pŸ-žÇK¾À‹íþk¼„ÎêšoBFÐ%,fOö¨™ò•šT‰íZô–b¶RRÆ%‡¦³‡z10–B ®Wj½¡Oû—§~îöjø×ºpiê ñÓ÷M©+õ–HäLþ ‘ˆ“ä†FÜŒË7SšÒ”ɤvÀÔ”§ÜEYO}Xi y[-¬oN4¸a£oG$9MÒ áÀÜ¡;™=~ÕÓ’ÑøµvðŒJOGµ´³¾…8™\iÝJXÈ¥~€ÿõ TeH:¥,K‚õMòŒ•<}íú¥Ç ™Wžû 8º0 C+Éhá!ôШJ®õ`²9{ w][á‹9•2Y †SLMéTÚĆÅ^¢TÝB›™a×Õ¦Óe$ƒ¢DÙñŠc›.„±/³rŒšü¨·ï`Nàq¾LmqîE`/ǹŒ ˆY <Ú¢T#i,Ua‚HqÍî"¥2ZI™µn@;dÇYvÎfÓ—¶k¼çQü”:šþ¢ÎN¢c™÷Ñ6_ß( ãÈt:‚9ׇ¤UÓ¸L ø9¿Jú˜YŒ„YÍÝ òPš°Åš*ØÆ” ]|1ªÑæ L¯;®Wg3FË„:@=¿¿œŽ€¨\PªT¦½x~Oô_ ÏÐÿ Wß¤Ìø›”yPÓÈJSôO¥>½<¹dümêü¢AZƒ»ê sšAîªýáîáqkÏX±ê£µxwO,)ÛO°eÊ»‡{2ßpZju°_·ªGcÿŸy[¨à¿GÕCå ÖHÙ(„Úù)•0?õ“‘Bµå1<Á×iÀÖ±‘…V‰q#r«Y”3-<˜Ý„laf<ÊŒ¶Z¤©u³Ù/P_7 *_t4lX¼öÄöz6s4˜¸NÒý;Sh»ß 7©Ÿ_>SµEê…v ôd¶[¤¥p/‰ý*äŒÇéhÉ@̃¯Ew‘³·Ã ºTE‡ßë̦È@A#L£½rŒ5EO|#Ýè!(ÛÁ&@=\¬ç¾oÁêªäZ&ç‰Ë!¾µSY{Á§…÷,/K ú¤+‚™Äîñ ,ÝËÔ¤1¥‚¥®q^êË10–ws YŽU;÷¸ªTeç|LŒ¼L¦Í4ª¶†û‹§ ìûTžMf~b¸„+ZFÎß70ÔÕäÐΠzaE£s¡€Z³È‹GP7Þq`‹\ð|5«õÍx4žþ¡÷÷¦–ªÃŒBBþðÙwŸ~ ß}$]Q±Ž«ú`@òd2ÒÒ‚Á¹´dð[Oƹ$–‡o-V@`æ(1n[YaWéUAVÿdXÊ`otfMŽRºÐòeÒOê%˜†›vדw}ÀÑiuAKìvÄy¾<~X]ÎÊ9½³ˆZvÁm$åNÔ@Ðç­ÈŒëÁiZÞ®{4‚›£¸¼+_‚UÁÔïŽzu 4ö¯;æÙÙ®.l3¸ˆyOa*"ÏÍt´R7*‘^Ϙ‘±™æÂf7”Œí‰uÔ½™`PúÀäí:8|­geôøÕK"$/9»ô¦*zE„ :™EѬø¨> stream xœ…XÛrã¸}×Wàm©) Kà•·σ“¹ÔÎj“JÙ)MA7éåÅçësR’•JyÊöˆ`_NŸ>ÝðŸ,æ ‹éËÿ¬Ž‹Ÿ¿çl×/b¶[ü¹HìCæTGöËz!ٺ©D0ü[oîÍ„‰Ls©X.3¶>.¢•X®ÿ€N×:£sëÍ"Ê ¶¢G?/X"ÉÂJàç*ÕôXr‘²õ+Žq™ñ”mè¨Êx,Eá ÜG¯e·}Ü™áq_vǃéûGÓuˤàq’è¨íu?{OUÛô«à‚}øÀààØïŸ‡®,»®|»YþtbâkÌ+ÎB¦ÑÇCÏ{TËB3G&$ϓܧòbíKgž(Oè¨kæôq" ¡’wå¼âTy8X˜o›ˆ‰í*V[VÙ(ØkÝï jQç¶uŠJ:SÀ`äEðüÖŸzεþÁXí=ê–Bò4S,®ov,ßlXÜ5„e:’¶TŒ¾5‡7D¶¥²Ç-"dÎ)ájhWV3ÊÞöhÙYø 9™îÆ#²p²:ËÔ`3`÷YGï‡^ÈpD\jº\yÓ|=s$çRÈ"”L»Fºæ|#î¹k—I½ÔãdÁùr<Ô®ÿ“´à:“ÞÇÍaöÃGè«CD-É‹"žeaË6-`%M#g8‘\©p€<»²£Ï¤œÚYzÞr¶vý.‘ôœ÷íòh¨áÈ|ÝÔC]êÿ=UÍ ÁÝs×ÎÈŠøO°ɬÄïh@Ff~Côûlþ„Âj°˜90ì»ñr¬Ip´Äõ,µ „Š\´Jèó.ø­n*0æ*v(ÝÙˆ:㇧(Àå²+)òKåwÃjŠ0Æ\ÏC”·ÿx¼ýü÷ǯß?}]ÿçE¼ j¦â De³ñ•TÔÁ!t(}!ÌgÞÑ ©Ö¹ð-ášr°jg9” äüFÉA-Íõè/V êxþ·¿]Žý§(®Ç-Î ¿FbƒïeÚ[âT…xù¥ïÈNcpþ|þg¤×¾¡îÚi.x†\ƒP…é Å!gWÛ_»w1¤àÓ¸:mzÍS9õÌ|¹ûz÷õ÷/Žm«äÆuA’r¥g…åŽF3×'Õ þ° 4wEr±ƒ_>Ü…²3SB’ìš,ag]M]ÝécݔଠQdÀ, !bg.È×zØC ¿þþùóÔy¤)îi’âªð‡hv­0Å1Ö´ŸÐxn›I)𡳡t¦7Ý‹]3LàT…m$É<‘ø5;ãaI›†Î *Eô ¶w;­(€µžfóu Ðà˜ºM¿Z!ìYÊÆgÂ[M\¡‘þd|#P1ö];îöç‘X>,gRÅE1©x9ãBº›ÏÝÆÕl®AÓ›!¸ h@R!$¸“¥¸p³õS•£ïZ÷d`šÿhº™f”–ÅŸæLHĹǼPWvEZê¦#Á+m‰›®}~¶€œêÍ¡o'Ñ  D ¥+Ô)Çô´l”Õ0–ßœ¶N×–œÓýã1Ø%–^%C¯ž^.ê®±wÍëô.äÈA­Iw² a:Ѥ$N½&ÆTŠ`¯û»aU¢µ}ⵕ˜JÔŒyæVæèSiÒÒÚ¾» èN§â9TžhRGŠaÝ:™Êt(|m«¶—µ'5Kšp-jølþ „Ý^.RJX^®€ÄбìýÊŒ.xW’>ÌHv(é瓪ÏN©ä´ùMšvÙBç#ë?0ªuUšÏ²”çJ†ôI.[Z¯_–x'JDØQà©¶WC—H“.2ý˜âõ8`æé4IÝx±K6Ê$ Ee™›(Ý–³[ÛžØâu2-ìámIýù¥ WÓ4ͧ=±Yh´át—Ô饭ønÂJâC©9D8Χ«Ëܳ4y²°å`¸AÍÆdõ[Iž©énór&S±Â>ç (9ûØ>÷©5‚C$AëßN2¸&³¬diÈ%h*®#oíh/g“Ò¡<18ªp ¦Í—#y@U¨iêÝzGE”4†Ý6 Á“ŽšÁ¢öy#6¦¶7~—õŽë ûbǶ93§\©ÐꙡöôëdÖ fÃ|5¿œ¯ežëBEN~è¯HŸÑwƒn“þ^OËÁ‹> stream xœ…VMoã6½ûWÌ­RQqù%JBo‹´@ŠöÐ@·lÈmsW¢võ±Nö×wHJN,$Y8ˆ‹œyóæÍJP÷ZÞën÷á.ƒã¸£pÜ}Û1ÿ–·ºƒåN@Yã)ÆÊÃ.ÜdÀUA„„L((»]”ð¸üŒað0ã¤(”;W6»H¸Gîr`ÂEH8¾'iá ÂS(ÏxŒE4î¨T„ ž‡÷ѹÆŽz˜NÕеzô0Ä,'”JõçèSÿWþµK(árƒ8Yã%<@úÞ?ce$S”‡TÔ!¹LÍ9.°!‹èä.çÍõ©½9EH…Œæ#4ûãoBE.%$L†ŠjŒ¿‚Õ1—€Ñ9„ŒU ð,%i*J_•³cáOsœÑ(sd¡íƒ³û«hÕ =P.NÏ— È]?Wfî#ç³>Ä 0/"cC`\uVŽ4ª|U/nºPR Ì-új&™ƒ‰Ý_VC0ÝDpADºQ°í§°ÈöONù†³ôåW‰·Û¦Vøn¡íTù-é¡3‡Ud'ü¬E†8õË÷B9CÛÅ FÖ•ztçáøÅÈ„³ÎÇwñüýaU4áà?ÿTOÀ)gÏ3FŠl½ùÓoI”»ñõ?B°ŸÅendstream endobj 1280 0 obj 1107 endobj 1284 0 obj <> stream xœ¥XÛ’Ú8}÷WèmÍ],ÉÞ7f€[\`“ÚšlMà`bC¨ì×oK¾€=!IåcK:GݧZóL1òÏùÖy+´J‚VÎW‡Ú—(ÿ˜oÑãÔáh:‡Q”!ø;]:ÙLŠ˜ 0÷âM·ŽÛdéXS†ƒ@šqÓ…ã*‚šæUgê|p<ì£,ñü3£ßÁ`îc&ôb>·ŽçÉÊ“3¹Bíaì×HQ`øH*ß²šü3xõ{Ohh((‰•ôrbTaσQ'Çm :¨Ý™<{什Ѱd[rS¼Î-r[“`™†®d)™eÙþtŽ]€%gCA‚Y†/í~çeØAÃØŒ^˜yÙ bßë$‰ôÙ%Ÿf@ Þ¤þb¾Øl\â ôÏPôÑB™d¿Š•FñÅKÔ¶XâhÖKæiÿÔ:ùXˆèÙwQ´[ÆÉ6<˜evºÁ„{ÒIãßé_NSXPF ¾ÏîaîÐ&š-NdŽÀ “e6ø¼K&0–7véA@ ×b—ƒÖ{4ÐÛ8ùn·ê¹ ë³» ÷hÙ Ê}7Œ6ÇD×±¡|¿…-ªÉìw:è}ïÃ•Åævß—aÎÂQ†ÍëÍÙ×’+LaC· y5¹Ãö䚞݅ž5ì—ž{\¡TÏ úžïS•çaq‰Û¿Šën¢.ÁÞ¢`a°.Àzm4Ö_:=è…… BYrE†ñ…iÏ£0ŸÐÆÆØøÖh¡Óyí¯Rq§¨¼`9ê¢ÞÃ(_˸„±OØŠÊ'¸Ë°\(–i±¦޽·”A÷F„›M<Ï•UQê·ªáU¶Z¨WæÝ¦“ ·s(Ťt™œÞ&Z 0i€£ƒA0wuÜêÝá•dVâ¶d »ŒM»ƒánµ)T±ƒ¯WÌ*Ú­ÀC0kÁ¾¼'9… ú7d¥³;ng:É«¢¸·fÝáu£ÎÊ5;.@Ïu€±Nmý$z©³²`KÅø…‹Çl<Þk+ c䂺fõ·ù8·gÒ×ñO¸>»QÆ/† ê81"Ù„ aäG<<‰ý›4rpûÔEXv R˜ª‚|H«[N•fyÂÊòÕx™è²ÞrJbÐN8Ÿë4­åÓ;øÔ¥3=ÞHÌì X¯è˜ó7‡ä•µ€¿Ý(Ÿ*6e62k.Š–àW•ÌeÕ[:£~uv‹" µvÆœ°…¹m¢ô`k(Òõ €s‹›'-7‡|%}õÈ« þÎÙ—=Z¡eú'û"ÊYÞâ¶GÝnÍcÃÔ'ô~!I s¨žeªßj°Õž 3šü<7WârO6ž3ˆVƒÂ‘øÒŽ-g“i.B¯òý=|B­Ù,;T•ªêxß"›­´`„Âý^‡I¦hè¥ï—†ç’ãn^v¿êo×òIEžËÇÞ¸.I«ùºiôŸF{hiÀ]VMX‹3]9ë©}ÅmOfáÂÆ§r÷aª~/+ž˜»OýÙoo¯×ªßú~åŽÇ ›ú2&={{êF«£=v¬¨™½â²ájqޝgj¡»‡Í‹Ë«™(4Ó>eý¾È‚Ò±7«§¼Lð4ðq ¡Ãá6ŠÐq)e#>]›ö`ZvÛ«§pÜމ±÷Ù÷.(àà0ð©ÊÙôÍõÆÜjªœ¤‡‰’…µNæ,KV¦D0pã@oâ\jæækJâ s¿ñ1áÙÜFÓ2$PoÒ4¸µõa֑̹n×ä üÀ ÝP̉ÈMAïV‡µÞý‰àïtIh­ =™¾ìá¸Mâ-Ãóx»ßèC†ƒMI|°áNâ­6á3‹å!4KLÞõlè |”½×óhÙøÃ¦º¨cžuôsŒ&Ú0WY÷^õ°âé ßd÷aa’m¾½Þ6]½XFkË¢ÆÔ @JÓd›2ò³*ëR}”C¨Ë®•ŸÕ—ËËÅL!øa~GŒ0zž1ʦÿ¾_¦|pþ£¦Qendstream endobj 1285 0 obj 1534 endobj 1289 0 obj <> stream xœµXÛr£8}ç+ô¶ð` qQí“/Äã)Çö2S»É–‹Ø²Í† à¸ò÷Ûâêq2[“ ©$vZ§OŸîj¾#¤ËŸê{}P®–6ÚeŠŽvÊw…7Qõµ> ¯È_ƒ¡~ý­R®$ˆZ Ù†…üƒ¢ö¨æÿ 0`L(æÜ’vþFQm‚zò–ë+_†tˆÏð'­Ç aÃÔD–Ãuù}Pµéù•Hñ~Bíjé\"ŒcfrdÙŽdu§zÝ æÓÉÍ4–IÔþ‹îÕÈÖiø˜‡IŒâ$GÙ>ѤmZê)F{‘jÄ– ¨*î5íÿsAÃ×6.ùVW~η§c©Ö«r6Ì-Zè9úÖêɱeÐJÎÕhê®Fƒñª?·ҦAíU†= Óÿ…¸öüb1ÁÜrãØ¼²éûíZ†-‹Ué¼SWîr© •cQu¾,”i)8‡}4…›ùÈ-x0ëºcþ.»’Èd6ñW}S‡C×óVß*`À³ñò¯‰\!»ÓëÕÀOfÛ—Dß 7v}÷ÓhÙ¤;¬T¯F•±ÝêÕó— ÿ ”¾tä4"‘L®ÞŽ!q×óÕèv Þ×!3®ún×f·Ói‡˜ýÁ`é~=ã­CY·¼+]3_ögc×ûQrB:¦^9é˜ût2s/4ï¸V ]³ž/Ô¶;& :æ|Ó/7&j¨Ã‹ý€Já­ãh·ƒ™Ï|Ή)ÏÞÇÑKwÇ{òÇF ¼—óðv5ugcÿS{Úp^9m¼ ó«»ô&óðÓ¸<¡y\´ÏQf¼ÓAµçί¯=×o'Ö+Ç“·áŽFKy,ñ&·§bÙð,]¼'wì¤ÚãhZ1ƒ šÌƵÍ0AFÛVû£®wëªÈJÄpÞé¢À\TõdA=Mçã3uW¿ßÇìöf5_¸ð¤yµ@ÄêY*. îµÆûa"¹€ê+rº¼öúX÷ër|ÓðçØâ"V9’^‡»c*.FXêÀ|UWª0Ïg ƒ:õ´jbyã|>3kF§¦|‚t‹( â Š‚\¤ÈMÓ$EÆÊ2bÍ{F¡»Ž™a"ÿ¤¨þ>ÌPf9J¶HÈU‚+r]'‡ÇHäâOl6¡œKƒ¨6ÙU7§Å¢ØbvILÇ6gø“@MXTǦCkf&wª±Ä¬õLÃÂÄfª—„ä“ï ’º„J_ݱE­Jž'Ñ8è1pá˜f]\RR9)Y‚gô Ð1>f¥?ž6„«n{[Áýè‘;˜P³¦nؤŽ.o“fcƯm*Ï*ÌAqïP£M¸•«äÙɦN»€ ¶"qŽR‰ Y‘|Æþv õÂx]Ýcº ƒªÕÆk–²Hg2ä*©Äü˜Æbƒ¶ir@I=ÃGC)Áœ6É3 ^ŠökîU€ ГFÌré3ÊA¡øxx€ZƒD¦Ù½ñ•ÒÕ˜ 5§¬·;Uæ4KŽ)@‡yYj©D{–.ä~¤Ó¤h{ŒPž ,„:Ÿ"H×{Y… è^u…6ã¶Qé…›ôÃEÛXDÖ|SŽÜ$ŸŠ øÙjTWCh¡ä˜—QÌÄLwÚ(($L*|ÚCš@•Ç ÍÃõ1 Ò3½eP;‹:qS$ê;ŒÕ ¢âÖª›&¿àªø\ð!Û­dâýEP=j@+5üÊ Räº}¡ö²,Øê"G§0ßË7KiŽÎÞ7•eý©¢.…öG¹AëÍ£ôÉhk½jC†áŸèªSÒìlĆìÛõÊ_{÷EùV¿Èöendstream endobj 1290 0 obj 1394 endobj 1294 0 obj <> stream xœXÛnÛF}×Wì[¨ÀÜìË]ô­p ¤MÔUÛ‡¸0(r)³‘H‡¤äúï;{£(Æq ÎîÜΜ3ÌD0EÄþ…Ïò°zs“£Ý°"h·ú²¢î! åý¼Yq´)ÁŠ2ÿ6õÊŸ¤ˆI¹@9—hsX%)[oþ…kÀ˜2¬µ´v›j•ä ¥öÑ›…(·7¤ >ÓLÛdz mW‰Ä\b…*k*$&œ©pÁcÑ×w•)öû®¼Mn×þ2ªC-Ü2"°2¸u9ºªûk/šÍ£ÕUqn/Çd:ݺ†¥²UeXrî¢s‰! ä®qÆ€>çGÛæg1ý“9{ ˜ŠØþeÑà¡<ƒcÖBk§¼ó‹rY°Æ›³…µœœ@pEïð`’:Æ´;L;.X$,šÅ¡¼“Á§¤PÑ"ÛŽ5Í0!L$;Ó£²« T¥×ÿl~]¥œÂ@¹#6‡S6u€¬ ¡Þ nk ·†Æ‡"¸(QW»ŸûàLeÉÎ>»Àƒµp^ç È$™Z‚B:‡Ïcßœ«™ƒ¿›ÒGƒq GÕ+n ÆšLèGµ2cÑì4‰…‚á±uûfëdQkÁ±TÓÌ¡ëŸÐ¡halëð‚yr„2ŠR;œKöÑßdÓÚnÝíÍ–25ã öAÚ8h­U¦’gnº~\Sè)ÑþéÄ/§5öÌЕëø‰È°·¾Fíöi4ƒ£¬¤¼/z4c+ér²vÃÃÞ´·ëŸàÇÔ^ɉsý]rÊÁJ\pÓEð‹P Êu„€³ô=9åXjûTìfIJÜ‘xþTì÷³ ëòÀ€Më|”0Æa,Ó˜¨h÷)IúnMm- KNMe*?n3a›r•á ¾Çên£x`¢\’ˆÁºžoÓat G0޾éËÜ[ô Òi¶æ0&ö £vÓ Õëð:•T[Òp­ i:@n!îtiZõÒXY|‡*Ú|ÑÖ>°âšEë£ËCC rª¸ÙÃqÑ8eD{S Ë4(!8WgŠh½”FâêåH,¥žŠ¼ïÚöÜfÕ–bf»±À#pØxìÛÁ«ì9å”Éõßw×ïÿºûøÛ"ØMã1ÔÆs¢eÓîÐp,KcªÁ…@9ÅÙTÈwõ2é 3*_ΙÍ\Ù®õ Sðͳž$ØJÍœõ>… â¦=Ón0®–Ô¬€Y¤üöææãÍ"¥qØÇüoM¨¡©\ª)Í3œÖmÙÝ‘{ªxWOS4çÊýÔ[@¨Šë&|YÎ- &“ÙËØÎó|Z]r¿Ù1Í5è8FÃO‚.`&X»Œ˜é»ãîÞõ×/»g'Ÿ–• ‘3Iˆ&)l"_Ih‘Ó„ŒYŒ<§ ž°_†xôG¥aqaTˆ›ð0 a¹ÚsH 0eö š6ʹq Â¨Fÿ=»Z†V”æat¬í÷©~ Ë #‹Ûßb)Ñ  âÛBütNÎ⼆ˆð¦a<æ&Èåè—¦µ#à¶YØ4•žG›|ðÎ{S|–H‹æ©P~WÌ”ŠãýÔô…»çürù2˜ÞBîÜbyWï‹ÝmB¾‚5Õs-°û=Œd`î—+ÒÊcüI=ž»@°¦ziûj°¶xæ sE¿µ/0eRçQ·h@ Óê­.QÑ´ÍpÿÌüi†I®‚+x7ɵïzÕ»—W®2õ„S+¦a$*¶È½­±ÅDo\é ˆéÓ‚ÂjnhšÀK0þ~ð{EtwÉõÓ¢De‡·Cñ„@g½€Mi†Á-ð}Q~¶4XunΡ* û¾ëó}7}Î3¬d æžÙO¦²3Ž…ŠÈ-*ãEÃÊÄ3»º7òäÆQ/¯z“4žø¹Ù“˜å~ùÙ0ÂèùtNY§å{ÿAðv³úþþKendstream endobj 1295 0 obj 1659 endobj 1299 0 obj <> stream xœWÛ’›F}×WÌ›Q*Œ™ ·‡<ØÞMªRvœØÊ“r! bÄVV¾>Ý=€´§œÚ­bWÌôåtŸÓ­¿XÄ‹ðg~–§Íów);Ž›ˆ7m½dó£<±—»b»N ÉàwwØø›‚É$çJ³T%lwÚ¡Üîþ3pXHžç žÛU› U,ÄW¡ðWœÐ‡»ºYY½3ƒ?;ƒGÈU¦y’iùCp.¶2Ž‚ÑÒã 鑼Ùþ±ûÙ;KWRËÙY1”5“‘Œ8Ú{þ.cà‚…Îxe,” *.c¶;o‚„«ÀxeO}Ó6ݯ‰(âi¢¼É}Úf_m…†ÄtA ÞÝÝ¿ÜæðI¿ÿôƒ ˜n€ ;¡$K’k¥¼µ]mØa QFBåA3ŒŽ9k[DÂY¶÷o¤¦¦­º>“#¡“]ŸW3Û»Ævãâ5Ÿ½J­¹Š¶ºÔ”gxdáÛÈMÁBž™û¸ºè:Éf8ùîZÔ r™Í>ZkF*¬ÊšÆøRð [|ŽÍ©o/˜QmÚž¬2{¯Ï‹­éx4~¬ýÅr#ži½ôÏ÷×Uœ/µnCÓUÌ̺ú dMe:×.l´ÓP¯3#+Êr gÚ ÚJWGq ½öõdÅ Bm|/­‡@JR¹dÑÝp1º°îŸ¦*!”4›+’øËè À~½¸2UÐeö8'ö1 2»¡(?ó~Æ—[¬1èÛd1W> stream xœ…UÛrÚ0}÷WlÉCÌ_(”Lyh íL'^Æ}Šó`ìuPc$WIøû®dCl.íÀŒmùìÙ³«³Öð½|ók®ÙÚ¹ú9{åøpïüqûšK¶†±Aœ*þqáÔ‘„ã©`!^;î0ìÇ¿‰†ÀAèM§cƒ‹sÇŒ`h^Å´¡†AÃ7cûþâÕÕFÉ«%ãWÈ¡Úê•à‘‰˜x¡¥A|C¸ýËš? ¼qC.ª­d÷+ ¡ú0OYïyŽR Þ¢Ú¡a2ã½ÔÕŠ)øn“C&rz\¡Äåª2Í0Ƶ½B¨6Ë’e‹uÊþ‘¥8•EHØ(bMùVp„‚Vè–He%zÇ|áÛšï×)>…Ŧ´$ã9ã÷V!GÌKQœW—ª=]´#£pŠ*1}0DiYŠ,Õ¬ÛÉhÏqë^°þØ÷]®ûwñ—šk®i(Â*Ý*f¤ÄÐYm%[æO©,rÔ˜i!Ûä6z/±> stream xœ…T[š@~çWœò"¦@™Ae5qšn“6Ý45¼É†P--—A»¦éï9ÃxAM7‘9ßùÎwnó žËÀ£~¦¥ñnÀZ¬gƒ)#èGZÂûÐð!LÅ8à7\'>™ºþaiX†?‘ÁŒ»Óé„pafXÁ2!ÅTS8 }ïÀO¢^­`¿3¹ôŸÉF~1¬|dÉ+Ø%E–§íl808s'à#+)ŠÚÎ=¢!’hä‘äUY'Ì<" \NZ{|Í<²ŽY`^]*‹†dqüú<†n”½Ç' )ftÜ;Ý4J‘ùa»)ò4il¥ÀTÁ´‘Ê6‹¼¦M¿]L­´S7¸%®—áÛk©Ë ­C‡qϳšáSøÙpF>ø¿dbÆ=UÒ.¾2T£Tõº@‡W¥\T&­«6¯¶B íð;eÁ†Åq•”"Ž©Wƒ8.“¼ŠãÁ¬ wt$Ah!ªÈ’{é&Íz‡Ý½v[Ê8à–¬›¶ÙÓ$ô±yAÐzCÄÊÑ6SW´‡/©Ø´ðéëCÓÔ $J!e²×ÿHäi½-2¨ê¾ Gd3l=tÁÀ¤ÿš© «ò/920U^,mÏeÇnåA®²ÍòêL¿.4öH"âÏ_]‹$ýE Le¤œm²wÝ\azRªØÍ%”KÙß?m|3ï¯ãÕJJõ˜Ë2iÓPWXi›ÀN‚*UÜ.·nyó^;NÍûÍp qÜÁWbÝ„ÎØSu¸âZ¨iV×%ó]ÏçzEwþéfë3—€/ɸÇÙÉ1`î48x¾z§>„Æ7üüõëŒendstream endobj 1310 0 obj 638 endobj 1314 0 obj <> stream xœ]ŽÍ Â@ „ïyŠõ°q“´»Ý«àу%/ U BE|{wÛH` óÍ=1ú2U‡ v}ÄñG˜« î mÈ æµ¬IF ‰´Á¨m‚“­ÝsM†Y(¥P8»À&tÅZ+´T8Éê¢ðô×b+I»„bîjö©ŸÒP€õL‘[<ž_(^ø':R¯ü~ª!»ô÷ÔÁà”ç ÉÃ9ñendstream endobj 1315 0 obj 169 endobj 1319 0 obj <> stream xœÅ˜Ûr£F†ïyо„T‰Ì‰Sî¼>dZ[™­½ˆS.d2Bvùí·‡:¤œ¬c]¸Œóõ?Ýý÷ðÄ¥@ÔÇüNWÖϳ–‹ÀÒz°hóO0¿Ò|ˆñ ”å/,}æQ—Gü€A¼²ìÓéu|~ß8ñ_Ö„†Ì%^Ÿ@<·þ°©ëLán(|ûò:ž9‚ØÓ³/§ñåôÚù3þÍ¢Ìw=h¾¹ñ“e»£üõ5#¥¸â„z-!u&!RDŒÛ§åÚ‰Ü( =û¹Ê–÷uÃy.3Œ#±íêå QŠ(JÖS~ÞVër#!)æp“–k©•D 8¢”‚z¥}BÞž•év%‹>f›º¬ž5 FÞj lVl± É…ÈK÷í¬Èê¬,6z—CwüMn ›Å€^8}t¨P9زz̤ÃÔ_Ô·Ÿ4&?{Lv°Ë~OzYËÕNï“b)禚iW*c–3ÐPo´^oŸ1ØgœÉUÙN°ûEøåÔ ›:7Z>Jõ8¢®Sì`A`®ÏÕeÆ\ñAã&&á†ö!Í0%°Ö¡ù$vé ‹}杻ŽI?ù‹÷XgIÀ‡¼LÿÖ04q™iW9¤=ÕE•¬$L×Xöf§å\n~3·hÞ~“jöõÛ´ýzÒ¥­jnÓÌ.€©ÿ¼-Œ~(Eióc‚ÔÛGGÇ Ê1Bj/ëä[.áq¤ãÂû÷ðjÊíÖ‹t „8žŠÃm 8ÜÚ‹²ÂûµkéÛ}âúüå»™¼Í7ŒZr;OjYÁ­ÓHôÖeô’ˆap<‚“áõ2B£™–,ÂUÙ?gpÒ,Ãùñl û@¯’´*±µÕI–ovºnÀÞÔÿ€SzóäÁ±cºN¶²õdÁžŒÓþ;¥ gfÂlÖ1³›¡åƒ“ú—øb¦®²bÙü {Xczå]X1€=¯*LÁ˜L9âIÉ»9CÖc'w1œg²ÞV…œÃc3ÂSAí$ßâœPßKXl‹Tõ7/³ cáP•.ܳ“TIÌÿÑñ„®ø{jz5¯ð¤T=ÃUR$K©ŽðfZñǦ„©$@#¢I ugÀŒ‰W¹Ýý½öÝ7otÏÔÅóØú?ßnÞvendstream endobj 1320 0 obj 1277 endobj 1324 0 obj <> stream xœµ˜Kw›8Ç÷| -áô˜A’`;M¦Íl:ïÚAh1¦@š´Ÿ¾/;ÔÆöÂ6F—Ÿtú_}Ž #ßú3ÚüÇ@ZHolÿú#Úƒ?·âˆÄ`›jÔ·1&>  íÞøhRÛÚ¸¶=—š=Q“Š0wEëÄòmß§™aÄ­ÏÛ¿ ˆ±0³ ßfl Ӿ ¸žµýbl ôÀùLÒBkã!jû›wEÖdažý %4øPòªýV+TJ%ãh{<ÜÚÕ„-œÄƒ;6cfühAÇv Ã̰J‚LÐeØÜ2?YŠÐõm ¸XOÕZ@¡—¡‚8¸(éWî20@Ť,N ð2ÔnÀÁØFë­“ƒÚ…­í ˜»6`!gu,…†š²?A#³h5o‚˜až¢ ÉÃtàô/ìi|ršŠ6xne±ð&-Ïû°ˆs^D—…â‘~É.MI@°S6OÙØìZñ|càcÌËŠGaÃc€ènYqÎbí¸ôøS.ïE®%*ÌÎ^A@\E¦lLËŸ…JE` °Q6Ò‹Ö˜KYžVSÇÚ0‰Eýç¾ÉxÄ»Q¬S´HX›âÀYœôš8tÍâ$’¿°)â©í8ØY¹`õpÂò/º®nª¬H£{}èÝÕÐ Ê?´^[Ë€Žkþ(9¸á¸v¨´0'ìJ=DyTŒÐ‚*×Ak©@Gž-ñ†ƒG»-ZÐãÇ8I<ÒqÞEzP¨ëYÁ„þ¯¢¼«åI[ÅúýEÿup'Í ^ðȺ •ŒAýäõšÑÞá´–&8Òw®·Œ³ËUaÐBê¹§~“«ÇÝðyröu€d¦™r¼'‹gW7÷áSpšET/O”·DìÉõhÏA.þ͆´CÒ#'HóÙ÷Ò$‡ÿ¶W{(ÂFP½'ÉàÉ„8jðV´s;QÛµ ‘{…Ì;…T²Å?’ dÁ•·DlŠjÍ4«.Êh; ÒÐÕ”y¬Ð1i *4Û‚ªE ºE îŠäÔ£°Y”ù£åº®8hÄöxÒn¾ªÍì8žo3Éøãö)Ü—¹( P  5YBðöÍ0Ò¿â!Ï[2w$¥ól§g&{ 1³öâ]é m:a­ÏгÉC‡ä¹á; ¶—Ð|HS1 ]_íÕÌn‹¦ú!$IžµðÇ–gÛÈ@³q'Ù¾sù4G^‡Èv˜–,¦:ÚÅ-m!ò_=ýnˆítô…Zg|Fg^ÌÞL0Óªä1̸XŸYµ\R£'(óyUp¥x©g>5AôÜó0ågMÕ¤¹˜íQWHryn.Le™¼|»5þï_AT—endstream endobj 1325 0 obj 1200 endobj 1329 0 obj <> stream xœµ™Ë’›8†÷<…–°0ƒ$Ðe;“,’M*)Ïj2Ea1)Œ oóô#!Œn9± íªv4‡OGGÿ¤þ ‚@}úïtïüñ‚¼q;?ØÝýWº®å@ ë­£‚BècL¡¬÷Î?.ñ‰z+ˆpàSêf/ üÔMêm\ †>焹¯mœ>Å;‘d¢ŽÓïîwÏûwýÙ<’×™Ã}õ‹ãúwü ½õg¥¢­`¤âi´èf´Íù¨§»‡ PÔCuq .r+×™ŠEQd:–AF­dM±)‹*?lÇ9"ÈfÊÔE4د‘Î@!Ÿ HC…ª‹j@q+Tº+Êì „ˆªì¹ˆ¦`:ºAoEáS´ÃÖC‘»Í 1žÃ<\Q&[Ô'\T„¿Áv&ÃxV2MG4ŽmÒ!+ݳ‡ÔªÄ¡›”E–´"VIìëoF»“ö„…ðÀ(9T`rI29Ïa÷ƒØx+y€îSžËwƒOÕöPï“¶8TàcÕÖoàë“¿¿EÝ]m4ÇþmR (ÕH„˜ÅO}h-þ\´]f IÕ¾EoËd” ïHÐ@"Ÿ68}ž=iŠ´¹4œ;†½g4ÔÇV’v4|éÜJ0†’Ñ (»1Ë)êÖ›q·h”f‘zÅž“,«cUØqÑÈbÊDǶ’í‹Ìü:u •ÊéU¨WÝ äô”e-ÃòRŒð=£”ëâƒt"µôŠgýBe• U§”9‡!u_ãöÐ]>¯ßèš~Ò@³û¸ZžýŸæòÉüS6ƒaÐúhšÝÏÚ¤.G+7â³&`ÆÓ1 <»³ÛzÈÜ4iÑ mÇ@ÕE3×nê’h´œûéŒóbºbHèöÏ–SÅ'–·#ù>é7ë4„èÅ8ì Àûu×I•Ÿ[$›ãû ì×qxe÷} U%{±œ:2dUGˆ¯æªíw ²N_Çò}—ÊýOØÂ«lÉfS Ý2…¡û§‡l”CTÀpoÃðB]`t™êÖkQMúÞÈwBROš<ä&ž¼Ihÿ]‘±UžõtáD5=]Pvé×P‹VµVÚUÕWû½A¸x¸L‡Dm²ëþ¹a‹MõˆÐŒg3›ŽjÂÙM`óÖŠ¦øO,æàì}Gvùß­I´@1kÙå_r©©T¶,½keÜÚ—!»4uZ&£!ˆù̧˜ŽlB\1‚ºNÞµq’‘™Àz&¹‘ˆ(ã`¥þ9 ÃE¡.\;_åç=n]äendstream endobj 1330 0 obj 1096 endobj 1334 0 obj <> stream xœ½˜ËŽ›H†÷ZÐ@Ý«CÄÔ[PÆ ÂÍ^= €”7©×ñSÒ¬«zûÍýæiHŸkÈYà$¢Ž€˜èõ)iÇDSùš êH¤£Ž øO¡â¬¨ó´íÙ¢߇väé"püIœšíaU£—«X‰Trê|ý«B+Ц¬VIyα;¹Ž,iÄ"¬,iµën¾õ‘pEêH .¤AyÉUD¢>  !ôû_ݺÛêð(ÕÚc( Üu“zQ,øÕ]ˆ$랣C>é¼h²ÎI– ;OÞ9— tÔ“´—:oã,_yTbÉÀÝo⦭ãb—åõ±”pÉÛ˜QŠÙÄHr3c,±Ä[ÅÊKI[—Éf´ðf†Ë\¾I[xÎE'¹öHÉ@kÙ¨ŽHqÌÃ&yšžyµß·j?å“X«²J¿?$M%MþtšÀiì6¿(˜*6ÑÃD!°‰ '¡`þ•b ê¾=×PÁ0 fê+$C §#Žé„•NiVg(Ò2išY§ðòñD#+LV4i—EÓ>¬‚ÂZAù¬|×ÖÿÆûžL°´œ¾ñ]:ÜØœÚ¥|ÈÔ<ŒIÊQ«‚“ý¦ñ¡J“¶¨vè }zÎëîÏæwô%鈸  ü„sðŠ{£à( äÁiÎOI}u~¬¨vÐ{‹ÛÂ"yÝîr|„'ƒ!'Ö‘²J²ãÝã*ïîEâfRå˜Æ¾‹¨)50ÊĵÆOøî[¯’¦H{Dæ“«pôa¤/Ù÷!òƒŠ†4~ç wñ ¸E7)÷y’ÿhZpÕ#0ûF2+Ë|0ÁÝ:Òó†ÏÇB/~q.ªã\ ¬¼[ÌÃCƒ£ßô»¶¶ç¬÷S]xZr™<= Cv÷5j®¹[=¼Ôêpw»ù28YÞ¤Fß²¾sHt¢ÔˆƒØíÖ9H:µ€Ø}Ö°@O9èÒw±Á!n²€b/`Lc7Y†¦ëç¸zîæÚ™ÊnȇÅâþUT=÷Ohìîê—u]mã^ŸëyŠÅ-Ų*ÒEJaLÊ¡ÙcÄ¿Ùì‹ndŒc·T‡üì´ó¹ÎW>À°{*ÃÕSq>ë&Ú‘EšL‡>‘CkveKõ°òvRÀ2ßÊ3&z=S¼š¡Í™MÕŽ|5Q2#¿pÌÒÁ1[ìrôq¿]åõÀ|šŸÌþ%7piõ†cCÛZ¦Ò†£¾‡‡ç,^Ôçï–ÎgxýzŽZ endstream endobj 1335 0 obj 1107 endobj 1339 0 obj <> stream xœÅ˜[“›6€ßùzÄ3YŠ$@èqÓt;ít:mÖ3}Èv ²ãƒp’ý÷9BŠ‘°ñ…u¦öÎÚ#ÃÑwîG<#ßÃÈ—oý™mœŸÞ3´j­œgw?"ý‘mÐÛ9\€ ÂÍ—Žº #Œ±Gi„"FÐ|ã|p#VðìŽQßcw-ºGð¿Z¢?Ö¥hГ».³b—¯Ëj>͸ÇyW¢­JTÀ5¨M…hžf³ç¿;Ç^»Ís‡{,Dó/Žë/„ ™ÍÿsîÔ…w8”—jÒ£ä_fØ÷|ì37­—ISgr¯&Y<¹z'FjKþõ¯=‘hóÐQž•h ”4"k×U™”éF$˺Ú$ùZì ‹<žÃÜèËmˆà¼Qº}å׬*[1Ãx‰`÷kÛƒPvÈŠ*(u« ž‡jõ:ŽÜ*)D‡qÌANÞã^L‰&ú,äV~÷ñ|ÆÔú·ª‚D›ªaÌ<àSºõºÄüP—è¼.¹H‹¢ÊÌèãñ• ˆ„/Ó¥£‚L $ò8¡®ÌCôsïXÆ@{ôN´éºùùNY|)Ãbù\“ýs¿7,Åx¬×ß?„¨i_ êÀ÷"NO¤í ÅJ!`´ LÌ 3,²†$ÕrFºØ Ýe#ŒèõãI–î©@€ÍtA©ù ÑæŠºôî݇¯p»Å¤EÙXãg•U›-™úv¡¨y”›ç’â3ò+„Ø]CHÖe~ë,ôþî¯ÇsÝm:…à'âÂðdBªÂu2Ķ*”¬*Yµ+Í ¤ÐIfîÉ”›ì‚4 ËÓ65Š‘½sša2|è}6 ìfIýñÀŒÏ£©ÁEÈ\º2 W¹P°²’ºÑFáסX&"4¸Ê>= Ü8¨²þ VOs4»Å¶®VCs@ѽÞO=Šº}@ƒ/§±-¢rwBòï}d¦XßRißRιÃ>`ÏÈÙ>JÞÐ7ÙK9ü¿àúf z1³Ò ZiŸ}½É|lAaæZ6°-Û~¨Q¶}¬vu&ÐÔô'LÈv1ÙÇÛ¤iÃä¢cÍ48m,]¸XW·z£Q>¹ÈŸŒ¢£QÚ¶û­\Võ&•G t¿¨v-JÑ#œ½À~Ý8Ÿ1IA…^S&åôä±ëW¨¢ ¸l»…'ì&#lÑÏ¡«uÙ´i+6Âê“Ø›jÁ«bclK”y#žw¢Ì„1­Å“Q,%ÈÆÕ$NY1E_93ኗmƒÏlêÄjǾ ÊÈ @{8%ΆŸÂ$\šçõ*` „ÚDãÓ—$’G8ÎŒ^RGÀ˜våa"ŽÏ_šy( øÍàz°N¨ 6>}u=¨Îþ{Ob]á‚ü§e«xÔV'æ²u“ȈO̳.ŽÈM¸z¦Nà€i|:ƒ‰¬¨V;‘@AMDkx’OÇ}Ì ä°F}¼Ï2QˆzJŽä÷¦Ao_ºÑU[¹QapUÇÁaÞ‘¦™-ðAõÝ ô|ŸwWÊG¡‡œ“ô¤ÑëvsP9áOBÉcZH÷NƒA´sZ-Ú]]&b³m_’ínQö³ . 'Ã$Ã8rk2ºµ|º*ªEZ4ÉG(à¢ÞŸý®‰„_ïþq—íÿH”üe)§Ç††Áû649áÃFBO{N½‡ÐÏ_åC{ù¨T®ý2wþ†÷7/Ú}µendstream endobj 1340 0 obj 1288 endobj 1344 0 obj <> stream xœÕ˜Ms›8€ïü á­¾?ŽétsØÃζÃLMÇãØØÍ®“´Ái¦ýõ+– Ä—Æ3ÁcŒxôú}^^é;@d_î¸yHþø(Á¾LØ'ß\î°yïróL¦ ß%õE`N!¥I@þ|NÄH²+‚1äT§Û× #ˆVéúy·Úžî×Åmz›e_ò¿ÌÍÜŒ–o %ùk’¹3’åÿ&Wn8s´¶@4 ´>¬¶÷Åêi—nÎp‘îÊâØ!jÞ"NC38´Æ©/â°s8›—–F³! ™ƒâ³ƒGKÑÄ…A­”¬HVûû äÊ$6Ãm ‚R7úQØÛ¡êHÊúóÏé£ðk±ÞÏ͘šðÁì0ƒán†->5ÀZÒÑÄï0‚<—Ö˜&!p}»²½_uéÄ”hQˆ1·ÍKd¥s4ÆIM,„N¯7›âP<¯ÅØ÷e þy¹;þüV”íߦ®Ááun =ö„Bým¿9˜.ò’[Œ9v 0ê†áræúm9…ˆQ„k˜£XUÿ¼J†™I(›PÈZ÷õ!G¸x5]õ <+6†EÖ,õ…C–pýjXZu<ý=wžXÚ;A½¨øê°¨:Ÿ2©Mµà<-ÖÿY*'ao¨¥ÂŠŒ+vF WCâÙÃõä:r‚C¹ç¯†cŒ°@¯.—¢Ðа@–ÂæR5(éŠÏ†2Ír? ?¶¨‚ñ+~Óxi‹ÔŒŽ¤%!R—GS÷æåqãg,^\ó» H= ?“¬;Qžl—´‹‡ÛEÉ× Åå@"}+¤¬ñ[›q²,gI0gy$g+'…dCDÉ®/ÂÕGªÅÓsë‘CÓyZÂä)}DTŸ¼ªüJ¥®S¸ˆF4 ‘8£Ñ czköÒpöŠˆFã¦é­ <ÖhØ2—[Ë4âADD£3ÝÓb‹DØ"±hJ5»¡s0„Q¯¡óe’Q™~ÔFaCèÉt¥H¥SKyÆ*ŸÊ³‹éE+Éuwõ@C¦°_އ1¥K"©RØ4©÷à2Aëg¹©isù:¬QA”ßzL±þoñ’Žëð’NFÔë‘õdr¸þ_²=å°ˆ`'B£ %jBÓ¿­cà&3µh] oÓ÷õŠÕ6 3-­PŽâÓu»B̤´jöO>ÞðÛ Àmq—Ù˜¤/ûU§1ÆbÅæyÜÍÆÿA+o›jâBŒ‘¬Bl!°}0si(*·µã÷Ù‹TéÌ}ã¬V“yÊû_E¿Ø._ Ô®¤‡A¢³ Œ(Åãñù§¿Š^`¬¨[p{qŸ†Í¢9˜×ÿÑSIUendstream endobj 1345 0 obj 1057 endobj 1349 0 obj <> stream xœµ˜]o£F†ïý+æ¤5`˜ËTiÚT»­ºrµM…°;tmÈœÝý÷=À>LÀÉÆRlÃ<œyÏ{Îða‡ ¬>Õ÷æ°øé#G»|ÑnñeAÊ“¨úÚÐÏ+¸€PDZmzA„‡1ùœ¢Õañå;„;ž½v¸/¬ø«M°ƒ æVt܆±\ÛD8"ð¸uÚ¥ÑAæá6;Êd—†Å)”iqüþ`=Øö¿«ßÔgõ`žU¼÷ÐêëÂrÆþñ©½úo±¬†.‰§WXþ,,}D0j6Ÿíò$ó,Y4xðì5Þ8ÖeL}‹6&Ÿ…©þ7HØUqºÉ„Ò7iC³ ¢õú(mê9sÏz×ßÃ$¥M\ˆ(çÖ7c}g 0бjeÕ€6œx-Ü&‹å ì^”»,7‚í¥;+ ­@kÊó'/mÃ¥u¸È,®2'Ÿ²lß P>i͆‘ÊÁ"zQølÓ2Ppíþ$ókTåj*Á*¬Œ¦DÕ3ê;‚2ë55º³‰gEyn6™çÈ©ùq/Ü¥§ðé´.9+w¦‡õÙïŠ+p` 9ŒØN%F“pž°¾…2ŠßƺÜKÖ8ô2U‹ˆ Še´ßgüÈlYX^e^ÄéR±¹±ZÖg#XîU\ Syƒ6“{S·@º|2Ðøš†»}¡‹Fè¢Í1C÷©ò£¨H²ýù$å¯=X·åÌKˆ²VX4æ::ŸnÔ Xw°ªãïÜwè¶œ½š„+^èÁ£Â)ÆañrÁSò*¡=ÃùŒ53çWYIºCQ™Ìåƒ6·ç˜!&z‰P K¥”Ç΂€0œqP‹e*-Œ"j´"xº@›á>½‚B­l« *Ö67{$  UýÄC1aiz$ÊQŠ°ÈŠhîeº+ʉGó·¡(/ìB¸!*kÃx*“Ekqè4ÿÑoqLéÒ¾tu¶þ&ú ^ÑmTDÝ2=[Ɉp]®IàõbBGÄzaazÕgª^Ï zPä²^5H¦¬+ó°ˆÖ{£Å£SëÌï´x檰þªÜ§qrNˆç$>Eûj¥ /mŠû3<ˆª²ÂÜ~Ò°IF’=CA¸˜]ÛÎjpwþ)Ëí ÊÛöZIø%ÁFL£™?/¢c!Ó8Üž7y‰)F^dŠÊFáâ.ÃeÏh’ÃSv,ZÝÏœ­[3?ÇC•Žâ\Òéµ%½+‡a‡ ult잃hÝ~:„`rÌë¡7ÐGèvÀƒX JD™µ.œ ø2<]«¥H!²ýl×¹&^ßYœaˆÇLÝ)Œ‘܇ú¬zLÐ9¨^ °Ú<´Ú<éœhíñ¦ÈñŒC}1,C³jÝÖ»%ŸÀniÕê Åq[¾^„XÑF‡Žzlv1kØ<Ö6  2\û}VNQú;ˆȫԚûú¾«> #=T"_R¡f‘ÏHª+뛨·`”ÕwÙh$ ½?¬‘>Q†ÉÉN5 vÎŽƒõ!¸PÔcOª±,¢dŸ¿Æœ‚s*HãKÀC“ÿæ¿kï‚ Õž¡„mz'ØB8.ãä휑€è|õ½^(^ØÆo`˜ËÂë¼éc õÛ·Ã0²idå£Ú 6(Fû2&Ë@_Þfߢocq'âÓ«_t ªF¦¼a›i|‹^3A4¬€¾ pxÕuÓŒ7 ³I$lÁ“Ñ×W¿ 6xôŽüÂ'ªD«×üp¿ç$QÇY-þ‚Ïÿòe¤ endstream endobj 1350 0 obj 1352 endobj 1354 0 obj <> stream xœ­˜K›HÇï| Žp0Û/}ÌJ9d)ÚoÉ a ^V v;“ýô[M·ihl¥ñhp—Tÿzü°‘‡m$^ê=}³~û+´w…ìõÃÂÝE[½¥oöïkø&6¦ö:·ä!lcŒ=J;‰½~³¾9G°¸«"/ ¸³ýébä!ŒB'©óx—µq¾Íâ|_ÇÛ"ûî|wÝ¿×X8ò=âƒÉõÖâ^èÛ럖ã=òccŽÜõ¿ÖJ™\a_Udá]²:©v®Ð÷Öc8#¢ÎØ(º ”Y\Tù^ó¾ðÎs@’ K&ip Åg@m3ûâwÞ_í.2é.ŒÜ¹À¢jÚ:Þüj³¦ç"ˆ=ì¶žG1€ð  |ß%|­]¶Óh˜=ä2À¢«3`P‘ùTIYŽÈ^£aÿPÎcÓPò¨AE'©Q“¥m±¯â}îæqΘ“7Y«“‹G q 4&ÓJš1ÐØ$šHwø&ÚãY?» ò'©Æ:yÁ:–YÜ&øÝÿeÏEÏ¿½`.LQm‘”ñI: NR`>Z¦¡ä1*œ•æ.÷xê$ 2qf@A!{,¹0P"¾ÍlÄ/æ›Þ"x1•F‚ßÁsuÏ] Nã”8E•mÏt42èX8›¨BI‡ÆTdZÖ• ä;ɱlãd»­³¦1-yÍ$XŠ;}6záDôÈ]Å››Ø"$ÀáÊEÌÄ™ô ùrA~wl4‘³ZT m‚J(tQÉ´¢/`úͧ³é4YwÈ ›VõûÅyè-º(Ý +oÑ+©>­îg¨J—;Ÿ¼¤ UXªÝ“F ¬i}?c%m|H_ÛöHW:P2-è*qÂÐy?$ÕV‰i×»þ¡y&xôFð¦Eýì%ÉEÌyO³C×ÌŒ ¥zyý,¦ò|Xûß:6Ð+JCéý¼Oñ½öÇ÷ƒïîÏSßOAYé.«~¿bÔ|8"Wà<¬ïsÑ´ö§ªÍê*)WeÖ­`N†ölÂÁç©òÔ)橸wqx(<Äò“¸„ºÿ‹º«Ž|s„i)8,„.$•ßàƒÄ½ô¶áU„Æiw'îOt%>íóñ¨Ï‹rŸ–p³qVµõ¯A/K–Õ‡ À—>¦:>l6 e]¼qàœŠÎݤ)dƒÒ•¾<ø˜˜˜’L‡ypåùI48Ì$§ ò'’ëpÒ䘎,¡ƒQ`7X«,‹å®À|~]•î·ƒ¥ ÇO•M% ÁØ2°ŠzÉ*ÎËß÷H…W{$HµE8Ý£8l:žY\ôP—‹ zgGw•때ÔÈ È´j0­_Ûº¨vöW9Û_Y-…C•ûàåŠÑÓaÆ ¥`w”¢é`ûuAõÿ¹ñ¤wÔåxÂîè°è€Ñàé®Èàâj}8S?ÿ"~_rW-Mš©Xì¿$–.ŠŒøù7â·?€ ˆÕ¡Xò¨AÇ«–+²Néph–Cm(Àª<"ƒe:~i¹o²! ¦ø¥0œyAˆ¡^‹½½ècŠ¢>®­?áõ?nÅŒéendstream endobj 1355 0 obj 1198 endobj 1359 0 obj <> stream xœµ˜]›8†ïù¾$Ò†Å6Æø²«v«®*U;Š´3+D‚“R1¤¦3³¿~Á@BB’éä"£ìÇÇç=þ|#_}Ì÷æÑùýŽ£]åøhçüp°DækóˆþXÁ˜ LÑjë4/a„1ö( QÈ Z=:÷nèæÑÅ’Sßã¡pÓçö=ûÜMÊm\Èî¶’u×É:—îÃbñïê/‡`îqk­RG¨ÿVÏŽëÍÿC“Å꛳4-1SSÐ`´C3T?JÎÜ$’ñú5Ί6?b›±Àí€ç€ m›‡€l6`U'uVÕÙ¦²(~4Ÿã(íx|ex .–”„ž Ô}—¦¥¬*t—;‰¾|—%0ì‹J¯Ž¹¸éä&ÈM†+ôð¤±v²Ž“RQ‚¡äFAÆEòØs³À÷.84 Ò¼8ä s8º¥qH.Zú¼mô„C¤iEZ$KÄøÞ )&fÎKO9„šVŸ‚Ú<Åi&µCĈ"®ÝBŠë +l°Ä˜iZpÖP í«LRY¶t"$C:ÂèìCíhš—†<ឬØîãuÏ4Ñ ç×3Ntxf|.¥‰ØÞDÜÄpÒ#²!‰ÛôQ…rôy¯§êùÕÆ†‰0ÏŸõt¾G›Qæ‘]BdM´’?‘TO¶³@ a„¶A5ÿ¢Æ|=Ú-Ú(£ ÅÁEÁΘ³‘§ð3ѯM³,ÔŽWÙ=Áó袜u†-‡f~.$6ydE7ÅE ¤'òœŽ‡*îe"Pî\çË@ÆcUñ‘0•›}*ã\®¡ÌèÙ†ÜtZšhˆ2 J•í ™Ž‰Á…0I4:udE­ë‹ªW` ÷zÑ%öX¨õG¹áÖ&ÿ¼ë„ Êö…ì½{÷'C®—ÊõB `â>íâ²ØåP8U­i‰€W.¬ÝGèÙG_™e]gŵ‹¢4©´Ý—(Aï?}0Nx·ÔMˆß(q\‹¢Q>ÈhwÀ`!}À-”Ö@™Käz¾?¯š„åÛŠ;:XœL.®×lôºñ:©Å,=ï`°t[¸âƒ¥éœ¥«XuùoX@ÑÁ¸›É<­â¤W)ò3!ÀR4ŽA‚@zæfD"@1ejóø…M¢¤2ÉóýÆâ\ë ì”2Èe$ƒÄ-3Ö%nϦ\æEQ;pï*M+K ôE”3i:•ˆÚžè2iuŠñÐ䄨ò=ørclƽ®è>©m2S^›}Q›>œ Õ‡¥Ö,har<8F˜%³qÝl›iŸc÷EwۺѶLa8Y¢OÃqé¡f N¼~~½"Ï[†Ö©âW¤4ú[p$©5=¦Ù …c¹¨E„úÆ¢tìîâL¥y²Í¦ç‚ç4 =¦âLY9n´ß°­¥xª­gjKcž¤×ÿ‹›™,L6¤9Ýdšõ 0Ýn$ËÃÉ¡¦KLƒc’Ï÷'ÔdeŸõ‚D'Np3ÛD¦kôIE¤~&R-W@ZA¾ìg4ØÐW¾íØÁ~0=°í ‰¦ë&تðKT°m®2z·ø&c˜¹‡j&‚PìØæIæ¤,“×£—]Óöa| <'4;…¥ë³_ŒuB¼XõëwÎq›]tE›äAÂ8Zª›}x/{Q¿~X9Ãç¬Q–¯endstream endobj 1360 0 obj 1292 endobj 1364 0 obj <> stream xœ½˜Ûr£F†ïyй„ª5™#‡KE²w“Jm%6[¹ˆS$“•ÐÚ~ûô0#qA§Úµ.ä}üÝýwß¶ Âò£¿ãµñ˽‹–¥ÑÒøfú$Ò_ñýÀ„"ÂP°0Ô"‚!6cr\Š‚µñéØ ÛºqáËu|3y±¶1Á®‹p™Ì³®øÔ¥=@z%`YEy ¡­O웯ÏQž„ß-*/ô¹­¶é—QïÜ=¢>ÝCdg – U¾ çoáf¡ˆo.Ê´º&¾Béç¸M|±4¿"̨cû”™?A«,ÿ èÑ´—ù6LR8ß5·Kyî²óM•Ê“öÜ¢ð0Øáæ6[%7Yòh¡ÍsZDU¶ÉK%˜ð-wOÆée±Épj,ùÛDxšk¯q½‹<µ§™S“é›uÑè ¸i£˜ -\®6óh>G2uOfm®°¨ËÂYâ"f´Q…áë$9@Ê_å»H|i•YÜsèYé|lb1IDëÃØf> bƒîdŸý-cy Âåb×S'teLîï²wy†} Á Ëí3*Á9 ½QÇÐ8Õ3xP¨œž9Y =żŸst¬ÒjŸsž/4f£¯G¯R·…åškÌc¶Ë{Gæ=ºËÊRÊ>²‘×tÕ6lL›¯”ÌõZÂåñî é.Øâ;¾â4FÜU€‰rNúfÌÚ:Î^,)™`¢ÖqÖÕPó‡B›~Q%KùQK@•zy—gØK’, Åf>EåSXfË<ª¶EÓŠ(ãg¡‡îó°° 1l"‡ÉµØÿ¯Z@ÖÁ5ì$'r}­‰ ö‰/êâÇÐh(Ó|é[ãÔÆîÎêG3”ÙÎYá†GÑ£ sC=²‰§ymW…€1$|J£$-Z{~‘Q6Põ ºL#˜w™´ùÕ›¬V+cgu\ rt;c}§cc»…¤tÚH[Ê3/2:Àq‡Œ—m]4Ž,ÏÞÎ@¦Ù…®Û¢éEllã¢`vñÉ£u{ȦälàÐû^XÜóБýJCϰ„°Þ {ñ¾Wì¡v¨$–Êqp|Üióp„ Zw‡`‚>ê‹8gõEÐC˜ð5Ç$hì@Øž·;Õê{”V1ª…EQ‰Ô ^Ê%ªÝÛ—¶ÿý:D1´#;?2L,Véž9Þ><ÔÐJHï¢tíÍpƒ.ÍpãR4òEl^Ì KB\qõ¸·§R7ër÷²×mìê9iu¸ñ66™Íî{(þå 5~_™ñþÓRfz×ç!Wí¨ZL¤o°üH š~úíÙýíç^>_8‰í²ùpãGúNü;Ü"ÍûuuÑïk«oôüH×™NrQ÷éå29{9æä§Õ‘&4{øÉ½)«yú1ƒ=ãù)< Ž8Lç±cÀsûéê£z³|ƒw{•‡nã/øü±¿ŽUendstream endobj 1365 0 obj 1312 endobj 1369 0 obj <> stream xœ½—Ks£F…÷üŠ^ÂB~ÐݰÈBcË.¥ôHdÍõL;ÛÖB¶1ןNŸ{îå;@”¿ª÷Udü²`›lï..‚êmOžüL¦ÀÛåM`Œ!¥pA€™Rbj EPp×\ÿ°0‚#a.Ó¿ öþhvíÇË(øb~±¬¿½ß ì0H˜,è­  ¼† »|ÂmËûÇT%˜åEŸ¹l-×Í|1UÀÜŠªMâžq0=Çb8‚dçºtb9‚TE®e«G%Èñ¨ºÑ©6e9Iè‘fÕ>¤PÃ4DEq´(“áìöcãê9&£“„ =Êì …õtŒ¾© ~…çîã¤!Z”éТ.t]Û¼ÏnæJ‡cÑ©Ãëî. (Dú$n-,[^D®©r½[ò}ÏW“‡Á¾ÁÓȼ˜Â£OåùB3µÞÅØúdö ˆ‚LŽÞ•Ø:ˆW8ÃÛ¼.*.8²ô³åëO /3Wæ éÕ ¯|}/,^˜Î1½ûÒ˜™ÃÉØûS1!J-ÁXi½òVLëŸÇjf§sœUÅ"}À«ÉÕdx§€›^VË"PåWA"{€]BÍ»`µ“̃t™—•ZØèø/û-k¯é„©ªƒ2ìE»LY‰ì¯’C¼«™Ì^œÉÒîÿ %Œ7‰ÿðÔûØxylö šÐ‹@ÂxX˜É^cÔüùH-Nⵓî÷á.Ü?9©Ý÷sR2OG%¸ÆKAšÆIíŠú.¼-T²ð)R»§$R”mL¼÷4T˜DÅÄ¡*T»ÁJªÂ߇è!Hßjmmk‡¶ÖíA¼—y> stream xœµ—MsÛ6†ïü{$bðAÀ±mìŒ;™éÔfNMGC‘ Â„Š®Ý_€€$Z„Ûb­ñÈÌŃÝû®¿Š1 órïÅ&xwËa½ ¬ƒïÁ½ø5Ó€ ` Y؇0žÄ’Hõw¶ Â7wüq ×7>Ý^ÝEÙ×`A‹SšÂ"E•Á_áu½~èà8ZPDYŒYxWäMÞA #¬?ø÷^í¢¿³ßœŠ˜3•æ§ì1ã¹¾€°Ñí² ØìƒÌ&N2â¼êº¶ƒ›mYy_·[Ç(DLþFH¥³ñ½ttL÷”oîµ,#KIDæ]µ,UÞ4mñ9ü ¸„òX!!¶¼:š—,y1Ù²¬Õ‘ŽÉ ~ ³‘¼pìåpyßwõ*Âf‡ýU°7¢m/búrDedyÄJeüöBB-ÚÅKƧdNÐLÖšz×Ï®ºäǪ#¶_Lr†{úî½ÍÔð Ü”jÛ×ÕPR!YX«nç JÞ˜9H¸+(9—59Í9ÍÚNõæ2”Ërµ>fŽ“ n0Ûâ\/Fš°glÔÇÖØ ]íÚFõj€¤ø5„{(ó”ŸO‰’ Q½jêíº­FÍ](2àNþ:’ŸŒLÉØ)Yñ¥nÊ#á³ùpwlL?""¦§ˆmVZmËÕ‘4Igp[àNr6šŸ1™2òSÆß>™Û0ÆaVF„ëz`]èÙEjÂB7<½Ì¤ÅÿQfsdt­wm'ÜlF/3‹4Á/<)låJęӰéiÄZ"TRsùH~êw8š¼êñMnójØ ³î:VÉ~ù9:%øí„pIÄçZ$æSJ¸ÍífFºtXO¡¶¨Å&(f\ìUІ×,&4fL¹Æ3Ý,­ˆ–ðÙ(¦ÉOsÛXÆ‘CÒYF]Ý<¥3Iz^rJ¸:U¬#\V]»YªHXÊ$|ºÍ’½Ú1u µs­}Ø?t{©8Mà®Óx[µ70F/lµšnèÙú=•{rx£îJ/ÌöxÔŽC0?Ç¢|tÕ~¨­›g”h·Òœ.6œÔcTеiùM»Ê›cJß>àâÄ]`Äåñ&/Öýê7ÿ©Î2ªi®ŸOjÄc4_|h*ÿ6âbéEÊÓl¶y'<¦Æ7’mö©®ÍçWYð§~ýÑØendstream endobj 1375 0 obj 917 endobj 1379 0 obj <> stream xœ½—]›8†ïù¾„‹xý_n¥VêJ+í¶ÑÞLWȇ¡%ÒdþýÚØ ™ÁÉ„Lµá"æ˜ç}}|Žyb€ôeÿ³÷Û—‡@á=yxö/Û€Kõ&S°\{&ƒˆCJQLÀrã=øŸÊb×J@",£ bæ<ˆÍ¶’%È÷‡<‰ õE»N Ù§{)~tßüohV]SÉ^ÿ.ÿð("jþeîq3°Ü{>¼ú8äÁò»·Ð ‚u(Òq#Q<%úî"Zïêl @C³@¦` `z"7X2ûaÁ8I¢)ØK«O4Ú,HEE • vƒñ)Xår¬ÞÊ_êXxÝ1Šæ‚½vŒÁ™†i*fÓÁn.<åª]+ù3 ¡º•`uç̸0š½ÌØ`šÉÜœdÊÙÜÄùÚGÉl`…˜X'‡p7""nÙðÖ$‚!X`¦ƒ|EDÅu.EU5YºYÛ¤YS+TÌô8÷ýÉjs˜Üm5À‘)6$Š.+ ÈÑeÄùÉeÚË^”Õ˜ ±™æ¥ÊÖ@v‹a}jÅF‚Ïõºi7¢/›|ÙUüÞueQodÝwÇý??ÿõU¿%¤¾3Yoó:¡ƒ(Løå„Ž®Šúº•Y)*ðO€1†H¥‚¨v²¢°Êï$Œüç©PÑfe/³^½AÄì)s»Ìèʦp´°'g§ÈeZ•ݘï$¢w“+4[ùÔ$n.G{Z¹RýìUÃÇÉŒtWL‘IuæÆrô¯öH•° T*GÃT˜_Ú,š-of 'Zèè`Ó½6©nrÈWÇþa+ê<]ëTO˺ëÛ]¦Sý¬™ £Ùü€ “†$á/ÈOàªÅéquläjÒÌð¯ñåA!}ˆâØÜð¼¾-ë¢YD—cLýu'm}YØÇ/Én¶²NU|j£MtÚ‹U%S‘e²3ýIö™‘¯­½Q¾më&Á—Z{èh™;×Ö­¨‹óÓÐ{vÁoì¼ÐÑ&Ìå* Ê?D"W¤m]èôª Ñ«eXx8)©Ñc'WË=?WvæÊHçhf³ë¡ÓDDˆ}³ÿ3?fÆ¢Óô÷bÌ,µþ$±Kë[Óç©\WObÕ9÷ñBØÑv~1Øÿ+m5Jã'wJ„ÚcL.6ÓÐñévYÚþ•4E§¿¯‹{8ª+òUY禬%ó飹lǃZ˜@Þ^È”BfÃ%yŽ&zªIû.34ôoås œ`¥Aäy« ’h¥8;qFwÔãQVˆÞ¨ŽlT0zŸŠîy³j*[aÛV<5MÕë¹g?¥À¤Ç0$ƒ79r(ËR|\z«ë?²±©endstream endobj 1380 0 obj 1027 endobj 1384 0 obj <> stream xœ­ÓÍrÚ0ໞbòU»²ŒuìíLoíø–t<VŒl éÓW–È f†dгhùV»z)äðŒë²a~ΡꙄŠ=1ôA—eŸ2÷$@Ù= ›#”Ò’9AÖ°þµ®v…؈hFZiš/Eó{m¡´wI!%%|W­ëönùmýʾ3ÂXv9³’1×íïýÅi”=°Ù˜Ö­Cb9d=µ<7z‹¶dK†ŠDLÁÄŸKŸÐ—ò±äÈåûbIÿµ’R ÞÝç•Ýæ‡]^·¥Ƥ‰æ‡|e‹ÒvÇêQ£P’®.H'ž£ðRqx^Ü_(÷ú(^œl«¢_å¶ÝvÏGÐ[0#(ø°qD âE„˜¼õv¹­7mÞíO(ŠÍU. (lš6© ÓÝÔ)eຯih3¡&Vcÿ?~;õ?ucñ22žïõ.¬‘JožpW…QNÍ…*âWU|ÙGÆ ™{ì°èºMŸ7¥íÃ5“ø¯YðÍeð…ÔÓD}™HP´%¬‹­íιÚ\Ýñ ¸0î:¤FÍa¦†«y¨#7ÆÄ1ÿãÿk‘±îù©¹0¿endstream endobj 1385 0 obj 461 endobj 1389 0 obj <> stream xœ}UËŽÛ6Ýû+¸«TŒh>ô —N¦¤HÔ£b™,h™²ÕÈ’#Ñ㙿ï½e{€"0 "Ï}œ{ÎõOÂ(' ?áYËuAvã‚‘Ýâç‚ûCÕ|(’)+¸¨‡_õbÂrµ iÁI®3šKRÑêc\þ Áà¾ÈhÊ™€›åvõÝx:Ø|i6ƒÞÈçÎÙ¡6•%®'÷J8UÇ…ˆ÷´ºL)“Œ‡ƒõ,×P+O±ª„çœæJ“DHšáoѽyi¶dÕmíkªUÁ£±ïâïåŸ)=R(Êt¤·úðX®W±@ŒŠ>–3BÌ® ;(2 8xph¹oF²í+è¶sdkÇjh6v$¦#ï9æŒ2&dš7¤ œô5©O]å ËŸT•G`³=YŽ4H#þø¸Z½£'Iy£N¸¯2ÚÚ ¾åŠf\"SZp…¥G§Ý®évPe݃Uhahìxw™ÐTÏ•Lýº ¬}àõ´ØYÒÀM‚; eKz·‡ù`F¥Æ8‰`9ÕP×\ùýÓ%×´`EHÂ|‚ÕúA,å2]f·ÁŸc:U ´ŒŸP%dµÄà—Ô¯Jš§˜¢fEhï<^S£NDHý-²aTç}Sí} ÇOŸ“ñh«¦ ÚÑJGMEž#·ïÇ)UÕZ3´o¤Ù·p G+ÀGL‡|PžšêkìÚ!@ŽoC*A•,®Ã  mbs_­$÷èGg‡ó¼·•õ¼ƒ±9[2@ƒévC“㶆§qäÓ×Ènèëø7SÜkM ûóÀD\™´zöâá@vM ×~[ÈôFŒ/¾ƒKT³¢˜YO±ä’j Þ|Ž2…Jp:›ÑbB¿6›Ö>Çä4"e®ïÛ™q½ƒ€)L²(¢Ww‡ïF{4ƒqvÒ.¼8u³¤úC0jÈjä”§Å”ÅóÝ-È­Â %'×`2Sý00P/,Mcºåi3©ƒ)X¤Ùl*©ƒ[;w¢äi"Ö¿¬iFEšÎ”Ùýu\9Ís­§,hŠÑ' tö]˜ vãó†9›[ëeYÂD“ˆüš;7n?‰KPùµwUèkïÎ˸æªVaçFh·mûX Ãi=ù¸@ïÁ›7_ï¼0g x»Oóͼ 0eù;ˆÂ¶­ÉÁü˜¶®V¬b qÙÐÖŒ ˜Ömg¦¡äiôÒìbÁ¤é4o°hmÁ ’ ¯rç•Ë[¾ÅüFEÿ›™7t ÷ ¸mKA©ñ‡¿öú‚'”‹¿áó²Rendstream endobj 1390 0 obj 1034 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 28 0 obj <> /Contents 29 0 R >> endobj 33 0 obj <> /Contents 34 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 48 0 obj <> /Contents 49 0 R >> endobj 53 0 obj <> /Contents 54 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 68 0 obj <> /Contents 69 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 78 0 obj <> /Contents 79 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 88 0 obj <> /Contents 89 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 98 0 obj <> /Contents 99 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 108 0 obj <> /Contents 109 0 R >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 118 0 obj <> /Contents 119 0 R >> endobj 123 0 obj <> /Contents 124 0 R >> endobj 128 0 obj <> /Contents 129 0 R >> endobj 133 0 obj <> /Contents 134 0 R >> endobj 138 0 obj <> /Contents 139 0 R >> endobj 143 0 obj <> /Contents 144 0 R >> endobj 148 0 obj <> /Contents 149 0 R >> endobj 153 0 obj <> /Contents 154 0 R >> endobj 158 0 obj <> /Contents 159 0 R >> endobj 163 0 obj <> /Contents 164 0 R >> endobj 168 0 obj <> /Contents 169 0 R >> endobj 173 0 obj <> /Contents 174 0 R >> endobj 178 0 obj <> /Contents 179 0 R >> endobj 183 0 obj <> /Contents 184 0 R >> endobj 188 0 obj <> /Contents 189 0 R >> endobj 193 0 obj <> /Contents 194 0 R >> endobj 198 0 obj <> /Contents 199 0 R >> endobj 203 0 obj <> /Contents 204 0 R >> endobj 208 0 obj <> /Contents 209 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 218 0 obj <> /Contents 219 0 R >> endobj 223 0 obj <> /Contents 224 0 R >> endobj 228 0 obj <> /Contents 229 0 R >> endobj 233 0 obj <> /Contents 234 0 R >> endobj 238 0 obj <> /Contents 239 0 R >> endobj 243 0 obj <> /Contents 244 0 R >> endobj 248 0 obj <> /Contents 249 0 R >> endobj 253 0 obj <> /Contents 254 0 R >> endobj 258 0 obj <> /Contents 259 0 R >> endobj 263 0 obj <> /Contents 264 0 R >> endobj 268 0 obj <> /Contents 269 0 R >> endobj 273 0 obj <> /Contents 274 0 R >> endobj 278 0 obj <> /Contents 279 0 R >> endobj 283 0 obj <> /Contents 284 0 R >> endobj 288 0 obj <> /Contents 289 0 R >> endobj 293 0 obj <> /Contents 294 0 R >> endobj 298 0 obj <> /Contents 299 0 R >> endobj 303 0 obj <> /Contents 304 0 R >> endobj 308 0 obj <> /Contents 309 0 R >> endobj 313 0 obj <> /Contents 314 0 R >> endobj 318 0 obj <> /Contents 319 0 R >> endobj 323 0 obj <> /Contents 324 0 R >> endobj 328 0 obj <> /Contents 329 0 R >> endobj 333 0 obj <> /Contents 334 0 R >> endobj 338 0 obj <> /Contents 339 0 R >> endobj 343 0 obj <> /Contents 344 0 R >> endobj 348 0 obj <> /Contents 349 0 R >> endobj 353 0 obj <> /Contents 354 0 R >> endobj 358 0 obj <> /Contents 359 0 R >> endobj 363 0 obj <> /Contents 364 0 R >> endobj 368 0 obj <> /Contents 369 0 R >> endobj 373 0 obj <> /Contents 374 0 R >> endobj 378 0 obj <> /Contents 379 0 R >> endobj 383 0 obj <> /Contents 384 0 R >> endobj 388 0 obj <> /Contents 389 0 R >> endobj 393 0 obj <> /Contents 394 0 R >> endobj 398 0 obj <> /Contents 399 0 R >> endobj 403 0 obj <> /Contents 404 0 R >> endobj 408 0 obj <> /Contents 409 0 R >> endobj 413 0 obj <> /Contents 414 0 R >> endobj 418 0 obj <> /Contents 419 0 R >> endobj 423 0 obj <> /Contents 424 0 R >> endobj 428 0 obj <> /Contents 429 0 R >> endobj 433 0 obj <> /Contents 434 0 R >> endobj 438 0 obj <> /Contents 439 0 R >> endobj 443 0 obj <> /Contents 444 0 R >> endobj 448 0 obj <> /Contents 449 0 R >> endobj 453 0 obj <> /Contents 454 0 R >> endobj 458 0 obj <> /Contents 459 0 R >> endobj 463 0 obj <> /Contents 464 0 R >> endobj 468 0 obj <> /Contents 469 0 R >> endobj 473 0 obj <> /Contents 474 0 R >> endobj 478 0 obj <> /Contents 479 0 R >> endobj 483 0 obj <> /Contents 484 0 R >> endobj 488 0 obj <> /Contents 489 0 R >> endobj 493 0 obj <> /Contents 494 0 R >> endobj 498 0 obj <> /Contents 499 0 R >> endobj 503 0 obj <> /Contents 504 0 R >> endobj 508 0 obj <> /Contents 509 0 R >> endobj 513 0 obj <> /Contents 514 0 R >> endobj 518 0 obj <> /Contents 519 0 R >> endobj 523 0 obj <> /Contents 524 0 R >> endobj 528 0 obj <> /Contents 529 0 R >> endobj 533 0 obj <> /Contents 534 0 R >> endobj 538 0 obj <> /Contents 539 0 R >> endobj 543 0 obj <> /Contents 544 0 R >> endobj 548 0 obj <> /Contents 549 0 R >> endobj 553 0 obj <> /Contents 554 0 R >> endobj 558 0 obj <> /Contents 559 0 R >> endobj 563 0 obj <> /Contents 564 0 R >> endobj 568 0 obj <> /Contents 569 0 R >> endobj 573 0 obj <> /Contents 574 0 R >> endobj 578 0 obj <> /Contents 579 0 R >> endobj 583 0 obj <> /Contents 584 0 R >> endobj 588 0 obj <> /Contents 589 0 R >> endobj 593 0 obj <> /Contents 594 0 R >> endobj 598 0 obj <> /Contents 599 0 R >> endobj 603 0 obj <> /Contents 604 0 R >> endobj 608 0 obj <> /Contents 609 0 R >> endobj 613 0 obj <> /Contents 614 0 R >> endobj 618 0 obj <> /Contents 619 0 R >> endobj 623 0 obj <> /Contents 624 0 R >> endobj 628 0 obj <> /Contents 629 0 R >> endobj 633 0 obj <> /Contents 634 0 R >> endobj 638 0 obj <> /Contents 639 0 R >> endobj 643 0 obj <> /Contents 644 0 R >> endobj 648 0 obj <> /Contents 649 0 R >> endobj 653 0 obj <> /Contents 654 0 R >> endobj 658 0 obj <> /Contents 659 0 R >> endobj 663 0 obj <> /Contents 664 0 R >> endobj 668 0 obj <> /Contents 669 0 R >> endobj 673 0 obj <> /Contents 674 0 R >> endobj 678 0 obj <> /Contents 679 0 R >> endobj 683 0 obj <> /Contents 684 0 R >> endobj 688 0 obj <> /Contents 689 0 R >> endobj 693 0 obj <> /Contents 694 0 R >> endobj 698 0 obj <> /Contents 699 0 R >> endobj 703 0 obj <> /Contents 704 0 R >> endobj 708 0 obj <> /Contents 709 0 R >> endobj 713 0 obj <> /Contents 714 0 R >> endobj 718 0 obj <> /Contents 719 0 R >> endobj 723 0 obj <> /Contents 724 0 R >> endobj 728 0 obj <> /Contents 729 0 R >> endobj 733 0 obj <> /Contents 734 0 R >> endobj 738 0 obj <> /Contents 739 0 R >> endobj 743 0 obj <> /Contents 744 0 R >> endobj 748 0 obj <> /Contents 749 0 R >> endobj 753 0 obj <> /Contents 754 0 R >> endobj 758 0 obj <> /Contents 759 0 R >> endobj 763 0 obj <> /Contents 764 0 R >> endobj 768 0 obj <> /Contents 769 0 R >> endobj 773 0 obj <> /Contents 774 0 R >> endobj 778 0 obj <> /Contents 779 0 R >> endobj 783 0 obj <> /Contents 784 0 R >> endobj 788 0 obj <> /Contents 789 0 R >> endobj 793 0 obj <> /Contents 794 0 R >> endobj 798 0 obj <> /Contents 799 0 R >> endobj 803 0 obj <> /Contents 804 0 R >> endobj 808 0 obj <> /Contents 809 0 R >> endobj 813 0 obj <> /Contents 814 0 R >> endobj 818 0 obj <> /Contents 819 0 R >> endobj 823 0 obj <> /Contents 824 0 R >> endobj 828 0 obj <> /Contents 829 0 R >> endobj 833 0 obj <> /Contents 834 0 R >> endobj 838 0 obj <> /Contents 839 0 R >> endobj 843 0 obj <> /Contents 844 0 R >> endobj 848 0 obj <> /Contents 849 0 R >> endobj 853 0 obj <> /Contents 854 0 R >> endobj 858 0 obj <> /Contents 859 0 R >> endobj 863 0 obj <> /Contents 864 0 R >> endobj 868 0 obj <> /Contents 869 0 R >> endobj 873 0 obj <> /Contents 874 0 R >> endobj 878 0 obj <> /Contents 879 0 R >> endobj 883 0 obj <> /Contents 884 0 R >> endobj 888 0 obj <> /Contents 889 0 R >> endobj 893 0 obj <> /Contents 894 0 R >> endobj 898 0 obj <> /Contents 899 0 R >> endobj 903 0 obj <> /Contents 904 0 R >> endobj 908 0 obj <> /Contents 909 0 R >> endobj 913 0 obj <> /Contents 914 0 R >> endobj 918 0 obj <> /Contents 919 0 R >> endobj 923 0 obj <> /Contents 924 0 R >> endobj 928 0 obj <> /Contents 929 0 R >> endobj 933 0 obj <> /Contents 934 0 R >> endobj 938 0 obj <> /Contents 939 0 R >> endobj 943 0 obj <> /Contents 944 0 R >> endobj 948 0 obj <> /Contents 949 0 R >> endobj 953 0 obj <> /Contents 954 0 R >> endobj 958 0 obj <> /Contents 959 0 R >> endobj 963 0 obj <> /Contents 964 0 R >> endobj 968 0 obj <> /Contents 969 0 R >> endobj 973 0 obj <> /Contents 974 0 R >> endobj 978 0 obj <> /Contents 979 0 R >> endobj 983 0 obj <> /Contents 984 0 R >> endobj 988 0 obj <> /Contents 989 0 R >> endobj 993 0 obj <> /Contents 994 0 R >> endobj 998 0 obj <> /Contents 999 0 R >> endobj 1003 0 obj <> /Contents 1004 0 R >> endobj 1008 0 obj <> /Contents 1009 0 R >> endobj 1013 0 obj <> /Contents 1014 0 R >> endobj 1018 0 obj <> /Contents 1019 0 R >> endobj 1023 0 obj <> /Contents 1024 0 R >> endobj 1028 0 obj <> /Contents 1029 0 R >> endobj 1033 0 obj <> /Contents 1034 0 R >> endobj 1038 0 obj <> /Contents 1039 0 R >> endobj 1043 0 obj <> /Contents 1044 0 R >> endobj 1048 0 obj <> /Contents 1049 0 R >> endobj 1053 0 obj <> /Contents 1054 0 R >> endobj 1058 0 obj <> /Contents 1059 0 R >> endobj 1063 0 obj <> /Contents 1064 0 R >> endobj 1068 0 obj <> /Contents 1069 0 R >> endobj 1073 0 obj <> /Contents 1074 0 R >> endobj 1078 0 obj <> /Contents 1079 0 R >> endobj 1083 0 obj <> /Contents 1084 0 R >> endobj 1088 0 obj <> /Contents 1089 0 R >> endobj 1093 0 obj <> /Contents 1094 0 R >> endobj 1098 0 obj <> /Contents 1099 0 R >> endobj 1103 0 obj <> /Contents 1104 0 R >> endobj 1108 0 obj <> /Contents 1109 0 R >> endobj 1113 0 obj <> /Contents 1114 0 R >> endobj 1118 0 obj <> /Contents 1119 0 R >> endobj 1123 0 obj <> /Contents 1124 0 R >> endobj 1128 0 obj <> /Contents 1129 0 R >> endobj 1133 0 obj <> /Contents 1134 0 R >> endobj 1138 0 obj <> /Contents 1139 0 R >> endobj 1143 0 obj <> /Contents 1144 0 R >> endobj 1148 0 obj <> /Contents 1149 0 R >> endobj 1153 0 obj <> /Contents 1154 0 R >> endobj 1158 0 obj <> /Contents 1159 0 R >> endobj 1163 0 obj <> /Contents 1164 0 R >> endobj 1168 0 obj <> /Contents 1169 0 R >> endobj 1173 0 obj <> /Contents 1174 0 R >> endobj 1178 0 obj <> /Contents 1179 0 R >> endobj 1183 0 obj <> /Contents 1184 0 R >> endobj 1188 0 obj <> /Contents 1189 0 R >> endobj 1193 0 obj <> /Contents 1194 0 R >> endobj 1198 0 obj <> /Contents 1199 0 R >> endobj 1203 0 obj <> /Contents 1204 0 R >> endobj 1208 0 obj <> /Contents 1209 0 R >> endobj 1213 0 obj <> /Contents 1214 0 R >> endobj 1218 0 obj <> /Contents 1219 0 R >> endobj 1223 0 obj <> /Contents 1224 0 R >> endobj 1228 0 obj <> /Contents 1229 0 R >> endobj 1233 0 obj <> /Contents 1234 0 R >> endobj 1238 0 obj <> /Contents 1239 0 R >> endobj 1243 0 obj <> /Contents 1244 0 R >> endobj 1248 0 obj <> /Contents 1249 0 R >> endobj 1253 0 obj <> /Contents 1254 0 R >> endobj 1258 0 obj <> /Contents 1259 0 R >> endobj 1263 0 obj <> /Contents 1264 0 R >> endobj 1268 0 obj <> /Contents 1269 0 R >> endobj 1273 0 obj <> /Contents 1274 0 R >> endobj 1278 0 obj <> /Contents 1279 0 R >> endobj 1283 0 obj <> /Contents 1284 0 R >> endobj 1288 0 obj <> /Contents 1289 0 R >> endobj 1293 0 obj <> /Contents 1294 0 R >> endobj 1298 0 obj <> /Contents 1299 0 R >> endobj 1303 0 obj <> /Contents 1304 0 R >> endobj 1308 0 obj <> /Contents 1309 0 R >> endobj 1313 0 obj <> /Contents 1314 0 R >> endobj 1318 0 obj <> /Contents 1319 0 R >> endobj 1323 0 obj <> /Contents 1324 0 R >> endobj 1328 0 obj <> /Contents 1329 0 R >> endobj 1333 0 obj <> /Contents 1334 0 R >> endobj 1338 0 obj <> /Contents 1339 0 R >> endobj 1343 0 obj <> /Contents 1344 0 R >> endobj 1348 0 obj <> /Contents 1349 0 R >> endobj 1353 0 obj <> /Contents 1354 0 R >> endobj 1358 0 obj <> /Contents 1359 0 R >> endobj 1363 0 obj <> /Contents 1364 0 R >> endobj 1368 0 obj <> /Contents 1369 0 R >> endobj 1373 0 obj <> /Contents 1374 0 R >> endobj 1378 0 obj <> /Contents 1379 0 R >> endobj 1383 0 obj <> /Contents 1384 0 R >> endobj 1388 0 obj <> /Contents 1389 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 23 0 R 28 0 R 33 0 R 38 0 R 43 0 R 48 0 R 53 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 88 0 R 93 0 R 98 0 R 103 0 R 108 0 R 113 0 R 118 0 R 123 0 R 128 0 R 133 0 R 138 0 R 143 0 R 148 0 R 153 0 R 158 0 R 163 0 R 168 0 R 173 0 R 178 0 R 183 0 R 188 0 R 193 0 R 198 0 R 203 0 R 208 0 R 213 0 R 218 0 R 223 0 R 228 0 R 233 0 R 238 0 R 243 0 R 248 0 R 253 0 R 258 0 R 263 0 R 268 0 R 273 0 R 278 0 R 283 0 R 288 0 R 293 0 R 298 0 R 303 0 R 308 0 R 313 0 R 318 0 R 323 0 R 328 0 R 333 0 R 338 0 R 343 0 R 348 0 R 353 0 R 358 0 R 363 0 R 368 0 R 373 0 R 378 0 R 383 0 R 388 0 R 393 0 R 398 0 R 403 0 R 408 0 R 413 0 R 418 0 R 423 0 R 428 0 R 433 0 R 438 0 R 443 0 R 448 0 R 453 0 R 458 0 R 463 0 R 468 0 R 473 0 R 478 0 R 483 0 R 488 0 R 493 0 R 498 0 R 503 0 R 508 0 R 513 0 R 518 0 R 523 0 R 528 0 R 533 0 R 538 0 R 543 0 R 548 0 R 553 0 R 558 0 R 563 0 R 568 0 R 573 0 R 578 0 R 583 0 R 588 0 R 593 0 R 598 0 R 603 0 R 608 0 R 613 0 R 618 0 R 623 0 R 628 0 R 633 0 R 638 0 R 643 0 R 648 0 R 653 0 R 658 0 R 663 0 R 668 0 R 673 0 R 678 0 R 683 0 R 688 0 R 693 0 R 698 0 R 703 0 R 708 0 R 713 0 R 718 0 R 723 0 R 728 0 R 733 0 R 738 0 R 743 0 R 748 0 R 753 0 R 758 0 R 763 0 R 768 0 R 773 0 R 778 0 R 783 0 R 788 0 R 793 0 R 798 0 R 803 0 R 808 0 R 813 0 R 818 0 R 823 0 R 828 0 R 833 0 R 838 0 R 843 0 R 848 0 R 853 0 R 858 0 R 863 0 R 868 0 R 873 0 R 878 0 R 883 0 R 888 0 R 893 0 R 898 0 R 903 0 R 908 0 R 913 0 R 918 0 R 923 0 R 928 0 R 933 0 R 938 0 R 943 0 R 948 0 R 953 0 R 958 0 R 963 0 R 968 0 R 973 0 R 978 0 R 983 0 R 988 0 R 993 0 R 998 0 R 1003 0 R 1008 0 R 1013 0 R 1018 0 R 1023 0 R 1028 0 R 1033 0 R 1038 0 R 1043 0 R 1048 0 R 1053 0 R 1058 0 R 1063 0 R 1068 0 R 1073 0 R 1078 0 R 1083 0 R 1088 0 R 1093 0 R 1098 0 R 1103 0 R 1108 0 R 1113 0 R 1118 0 R 1123 0 R 1128 0 R 1133 0 R 1138 0 R 1143 0 R 1148 0 R 1153 0 R 1158 0 R 1163 0 R 1168 0 R 1173 0 R 1178 0 R 1183 0 R 1188 0 R 1193 0 R 1198 0 R 1203 0 R 1208 0 R 1213 0 R 1218 0 R 1223 0 R 1228 0 R 1233 0 R 1238 0 R 1243 0 R 1248 0 R 1253 0 R 1258 0 R 1263 0 R 1268 0 R 1273 0 R 1278 0 R 1283 0 R 1288 0 R 1293 0 R 1298 0 R 1303 0 R 1308 0 R 1313 0 R 1318 0 R 1323 0 R 1328 0 R 1333 0 R 1338 0 R 1343 0 R 1348 0 R 1353 0 R 1358 0 R 1363 0 R 1368 0 R 1373 0 R 1378 0 R 1383 0 R 1388 0 R ] /Count 276 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 47 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 67 0 obj <> endobj 71 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 87 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 97 0 obj <> endobj 101 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 107 0 obj <> endobj 111 0 obj <> endobj 112 0 obj <> endobj 116 0 obj <> endobj 117 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <> endobj 131 0 obj <> endobj 132 0 obj <> endobj 136 0 obj <> endobj 137 0 obj <> endobj 141 0 obj <> endobj 142 0 obj <> endobj 146 0 obj <> endobj 147 0 obj <> endobj 151 0 obj <> endobj 152 0 obj <> endobj 156 0 obj <> endobj 157 0 obj <> endobj 161 0 obj <> endobj 162 0 obj <> endobj 166 0 obj <> endobj 167 0 obj <> endobj 171 0 obj <> endobj 172 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 181 0 obj <> endobj 182 0 obj <> endobj 186 0 obj <> endobj 187 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 211 0 obj <> endobj 212 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 226 0 obj <> endobj 227 0 obj <> endobj 231 0 obj <> endobj 232 0 obj <> endobj 236 0 obj <> endobj 237 0 obj <> endobj 241 0 obj <> endobj 242 0 obj <> endobj 246 0 obj <> endobj 247 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 256 0 obj <> endobj 257 0 obj <> endobj 261 0 obj <> endobj 262 0 obj <> endobj 266 0 obj <> endobj 267 0 obj <> endobj 271 0 obj <> endobj 272 0 obj <> endobj 276 0 obj <> endobj 277 0 obj <> endobj 281 0 obj <> endobj 282 0 obj <> endobj 286 0 obj <> endobj 287 0 obj <> endobj 291 0 obj <> endobj 292 0 obj <> endobj 296 0 obj <> endobj 297 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 306 0 obj <> endobj 307 0 obj <> endobj 311 0 obj <> endobj 312 0 obj <> endobj 316 0 obj <> endobj 317 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 327 0 obj <> endobj 331 0 obj <> endobj 332 0 obj <> endobj 336 0 obj <> endobj 337 0 obj <> endobj 341 0 obj <> endobj 342 0 obj <> endobj 346 0 obj <> endobj 347 0 obj <> endobj 351 0 obj <> endobj 352 0 obj <> endobj 356 0 obj <> endobj 357 0 obj <> endobj 361 0 obj <> endobj 362 0 obj <> endobj 366 0 obj <> endobj 367 0 obj <> endobj 371 0 obj <> endobj 372 0 obj <> endobj 376 0 obj <> endobj 377 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 416 0 obj <> endobj 417 0 obj <> endobj 421 0 obj <> endobj 422 0 obj <> endobj 426 0 obj <> endobj 427 0 obj <> endobj 431 0 obj <> endobj 432 0 obj <> endobj 436 0 obj <> endobj 437 0 obj <> endobj 441 0 obj <> endobj 442 0 obj <> endobj 446 0 obj <> endobj 447 0 obj <> endobj 451 0 obj <> endobj 452 0 obj <> endobj 456 0 obj <> endobj 457 0 obj <> endobj 461 0 obj <> endobj 462 0 obj <> endobj 466 0 obj <> endobj 467 0 obj <> endobj 471 0 obj <> endobj 472 0 obj <> endobj 476 0 obj <> endobj 477 0 obj <> endobj 481 0 obj <> endobj 482 0 obj <> endobj 486 0 obj <> endobj 487 0 obj <> endobj 491 0 obj <> endobj 492 0 obj <> endobj 496 0 obj <> endobj 497 0 obj <> endobj 501 0 obj <> endobj 502 0 obj <> endobj 506 0 obj <> endobj 507 0 obj <> endobj 511 0 obj <> endobj 512 0 obj <> endobj 516 0 obj <> endobj 517 0 obj <> endobj 521 0 obj <> endobj 522 0 obj <> endobj 526 0 obj <> endobj 527 0 obj <> endobj 531 0 obj <> endobj 532 0 obj <> endobj 536 0 obj <> endobj 537 0 obj <> endobj 541 0 obj <> endobj 542 0 obj <> endobj 546 0 obj <> endobj 547 0 obj <> endobj 551 0 obj <> endobj 552 0 obj <> endobj 556 0 obj <> endobj 557 0 obj <> endobj 561 0 obj <> endobj 562 0 obj <> endobj 566 0 obj <> endobj 567 0 obj <> endobj 571 0 obj <> endobj 572 0 obj <> endobj 576 0 obj <> endobj 577 0 obj <> endobj 581 0 obj <> endobj 582 0 obj <> endobj 586 0 obj <> endobj 587 0 obj <> endobj 591 0 obj <> endobj 592 0 obj <> endobj 596 0 obj <> endobj 597 0 obj <> endobj 601 0 obj <> endobj 602 0 obj <> endobj 606 0 obj <> endobj 607 0 obj <> endobj 611 0 obj <> endobj 612 0 obj <> endobj 616 0 obj <> endobj 617 0 obj <> endobj 621 0 obj <> endobj 622 0 obj <> endobj 626 0 obj <> endobj 627 0 obj <> endobj 631 0 obj <> endobj 632 0 obj <> endobj 636 0 obj <> endobj 637 0 obj <> endobj 641 0 obj <> endobj 642 0 obj <> endobj 646 0 obj <> endobj 647 0 obj <> endobj 651 0 obj <> endobj 652 0 obj <> endobj 656 0 obj <> endobj 657 0 obj <> endobj 661 0 obj <> endobj 662 0 obj <> endobj 666 0 obj <> endobj 667 0 obj <> endobj 671 0 obj <> endobj 672 0 obj <> endobj 676 0 obj <> endobj 677 0 obj <> endobj 681 0 obj <> endobj 682 0 obj <> endobj 686 0 obj <> endobj 687 0 obj <> endobj 691 0 obj <> endobj 692 0 obj <> endobj 696 0 obj <> endobj 697 0 obj <> endobj 701 0 obj <> endobj 702 0 obj <> endobj 706 0 obj <> endobj 707 0 obj <> endobj 711 0 obj <> endobj 712 0 obj <> endobj 716 0 obj <> endobj 717 0 obj <> endobj 721 0 obj <> endobj 722 0 obj <> endobj 726 0 obj <> endobj 727 0 obj <> endobj 731 0 obj <> endobj 732 0 obj <> endobj 736 0 obj <> endobj 737 0 obj <> endobj 741 0 obj <> endobj 742 0 obj <> endobj 746 0 obj <> endobj 747 0 obj <> endobj 751 0 obj <> endobj 752 0 obj <> endobj 756 0 obj <> endobj 757 0 obj <> endobj 761 0 obj <> endobj 762 0 obj <> endobj 766 0 obj <> endobj 767 0 obj <> endobj 771 0 obj <> endobj 772 0 obj <> endobj 776 0 obj <> endobj 777 0 obj <> endobj 781 0 obj <> endobj 782 0 obj <> endobj 786 0 obj <> endobj 787 0 obj <> endobj 791 0 obj <> endobj 792 0 obj <> endobj 796 0 obj <> endobj 797 0 obj <> endobj 801 0 obj <> endobj 802 0 obj <> endobj 806 0 obj <> endobj 807 0 obj <> endobj 811 0 obj <> endobj 812 0 obj <> endobj 816 0 obj <> endobj 817 0 obj <> endobj 821 0 obj <> endobj 822 0 obj <> endobj 826 0 obj <> endobj 827 0 obj <> endobj 831 0 obj <> endobj 832 0 obj <> endobj 836 0 obj <> endobj 837 0 obj <> endobj 841 0 obj <> endobj 842 0 obj <> endobj 846 0 obj <> endobj 847 0 obj <> endobj 851 0 obj <> endobj 852 0 obj <> endobj 856 0 obj <> endobj 857 0 obj <> endobj 861 0 obj <> endobj 862 0 obj <> endobj 866 0 obj <> endobj 867 0 obj <> endobj 871 0 obj <> endobj 872 0 obj <> endobj 876 0 obj <> endobj 877 0 obj <> endobj 881 0 obj <> endobj 882 0 obj <> endobj 886 0 obj <> endobj 887 0 obj <> endobj 891 0 obj <> endobj 892 0 obj <> endobj 896 0 obj <> endobj 897 0 obj <> endobj 901 0 obj <> endobj 902 0 obj <> endobj 906 0 obj <> endobj 907 0 obj <> endobj 911 0 obj <> endobj 912 0 obj <> endobj 916 0 obj <> endobj 917 0 obj <> endobj 921 0 obj <> endobj 922 0 obj <> endobj 926 0 obj <> endobj 927 0 obj <> endobj 931 0 obj <> endobj 932 0 obj <> endobj 936 0 obj <> endobj 937 0 obj <> endobj 941 0 obj <> endobj 942 0 obj <> endobj 946 0 obj <> endobj 947 0 obj <> endobj 951 0 obj <> endobj 952 0 obj <> endobj 956 0 obj <> endobj 957 0 obj <> endobj 961 0 obj <> endobj 962 0 obj <> endobj 966 0 obj <> endobj 967 0 obj <> endobj 971 0 obj <> endobj 972 0 obj <> endobj 976 0 obj <> endobj 977 0 obj <> endobj 981 0 obj <> endobj 982 0 obj <> endobj 986 0 obj <> endobj 987 0 obj <> endobj 991 0 obj <> endobj 992 0 obj <> endobj 996 0 obj <> endobj 997 0 obj <> endobj 1001 0 obj <> endobj 1002 0 obj <> endobj 1006 0 obj <> endobj 1007 0 obj <> endobj 1011 0 obj <> endobj 1012 0 obj <> endobj 1016 0 obj <> endobj 1017 0 obj <> endobj 1021 0 obj <> endobj 1022 0 obj <> endobj 1026 0 obj <> endobj 1027 0 obj <> endobj 1031 0 obj <> endobj 1032 0 obj <> endobj 1036 0 obj <> endobj 1037 0 obj <> endobj 1041 0 obj <> endobj 1042 0 obj <> endobj 1046 0 obj <> endobj 1047 0 obj <> endobj 1051 0 obj <> endobj 1052 0 obj <> endobj 1056 0 obj <> endobj 1057 0 obj <> endobj 1061 0 obj <> endobj 1062 0 obj <> endobj 1066 0 obj <> endobj 1067 0 obj <> endobj 1071 0 obj <> endobj 1072 0 obj <> endobj 1076 0 obj <> endobj 1077 0 obj <> endobj 1081 0 obj <> endobj 1082 0 obj <> endobj 1086 0 obj <> endobj 1087 0 obj <> endobj 1091 0 obj <> endobj 1092 0 obj <> endobj 1096 0 obj <> endobj 1097 0 obj <> endobj 1101 0 obj <> endobj 1102 0 obj <> endobj 1106 0 obj <> endobj 1107 0 obj <> endobj 1111 0 obj <> endobj 1112 0 obj <> endobj 1116 0 obj <> endobj 1117 0 obj <> endobj 1121 0 obj <> endobj 1122 0 obj <> endobj 1126 0 obj <> endobj 1127 0 obj <> endobj 1131 0 obj <> endobj 1132 0 obj <> endobj 1136 0 obj <> endobj 1137 0 obj <> endobj 1141 0 obj <> endobj 1142 0 obj <> endobj 1146 0 obj <> endobj 1147 0 obj <> endobj 1151 0 obj <> endobj 1152 0 obj <> endobj 1156 0 obj <> endobj 1157 0 obj <> endobj 1161 0 obj <> endobj 1162 0 obj <> endobj 1166 0 obj <> endobj 1167 0 obj <> endobj 1171 0 obj <> endobj 1172 0 obj <> endobj 1176 0 obj <> endobj 1177 0 obj <> endobj 1181 0 obj <> endobj 1182 0 obj <> endobj 1186 0 obj <> endobj 1187 0 obj <> endobj 1191 0 obj <> endobj 1192 0 obj <> endobj 1196 0 obj <> endobj 1197 0 obj <> endobj 1201 0 obj <> endobj 1202 0 obj <> endobj 1206 0 obj <> endobj 1207 0 obj <> endobj 1211 0 obj <> endobj 1212 0 obj <> endobj 1216 0 obj <> endobj 1217 0 obj <> endobj 1221 0 obj <> endobj 1222 0 obj <> endobj 1226 0 obj <> endobj 1227 0 obj <> endobj 1231 0 obj <> endobj 1232 0 obj <> endobj 1236 0 obj <> endobj 1237 0 obj <> endobj 1241 0 obj <> endobj 1242 0 obj <> endobj 1246 0 obj <> endobj 1247 0 obj <> endobj 1251 0 obj <> endobj 1252 0 obj <> endobj 1256 0 obj <> endobj 1257 0 obj <> endobj 1261 0 obj <> endobj 1262 0 obj <> endobj 1266 0 obj <> endobj 1267 0 obj <> endobj 1271 0 obj <> endobj 1272 0 obj <> endobj 1276 0 obj <> endobj 1277 0 obj <> endobj 1281 0 obj <> endobj 1282 0 obj <> endobj 1286 0 obj <> endobj 1287 0 obj <> endobj 1291 0 obj <> endobj 1292 0 obj <> endobj 1296 0 obj <> endobj 1297 0 obj <> endobj 1301 0 obj <> endobj 1302 0 obj <> endobj 1306 0 obj <> endobj 1307 0 obj <> endobj 1311 0 obj <> endobj 1312 0 obj <> endobj 1316 0 obj <> endobj 1317 0 obj <> endobj 1321 0 obj <> endobj 1322 0 obj <> endobj 1326 0 obj <> endobj 1327 0 obj <> endobj 1331 0 obj <> endobj 1332 0 obj <> endobj 1336 0 obj <> endobj 1337 0 obj <> endobj 1341 0 obj <> endobj 1342 0 obj <> endobj 1346 0 obj <> endobj 1347 0 obj <> endobj 1351 0 obj <> endobj 1352 0 obj <> endobj 1356 0 obj <> endobj 1357 0 obj <> endobj 1361 0 obj <> endobj 1362 0 obj <> endobj 1366 0 obj <> endobj 1367 0 obj <> endobj 1371 0 obj <> endobj 1372 0 obj <> endobj 1376 0 obj <> endobj 1377 0 obj <> endobj 1381 0 obj <> endobj 1382 0 obj <> endobj 1386 0 obj <> endobj 1387 0 obj <> endobj 1391 0 obj <> endobj 1392 0 obj <> endobj 19 0 obj <> endobj 1397 0 obj <> endobj 12 0 obj <> endobj 1398 0 obj <> endobj 10 0 obj <> endobj 8 0 obj <> endobj 20 0 obj <> endobj 1393 0 obj <>stream xœy T×Öu5ÐU¥âÚBM q65$jD# hdDƒ8™™Ç¦›ù2Í,ƒ‚Š5*ÚD qŽ <‡¨‰f0yÎ_’ÿʺ¼¼ÿvƒT›/yë_ÿZÊ‚î[÷ÞsÎ>{ï{KB™Q‰„u ŠÚ¡û}†0V"Œ3Þ4ŽÇù¿_• S*×T‚L‘©Iã8ë™ ioÀ‘7Š2‘HÞsó«žì¹Ê{Ê´iÓ÷ÅEmù$Òj¦Ý;³­6ÄY |cå´iGЖ0«‰ä—èM!áÛB7…Eº…nˆÚaånµÂÃjÕ¦-Q!¯*Îøÿ·EQ>†ù, _ã¸Í×i»sÄâ.‘®QK¢c>ŠÝ°,.Ð-~£û¦å›WlùdUÇÖÕÁž!^¡Þ3Þ^ok—ðNâ̤Y³ßµ·zoüûæXÏ÷ÖçOr˜¼`ÊT¿ik§ûSÔj95‡²¦VPs)j%5z‹ZEM¤<¨IÔjj2åIM¡¼¨©”7åC-¢¦Sk(GjåK9QoS~”3eK-¦ì(êÊ•ZBÍ¢–R³©¨w©e”=åF½G¹SïS#¨‘ÔBjõµ–2£ü)µŽMq”95†’P”%§Œ)KÊ„K£hêMŠ¡KñÔÊŠJ £> L©ùÔpÊZCÊMFQ É6bŒ\NÏ2>j,˜x™Ü•zJ;éÙô]ææ ëÁžb4Äkȱ¡ó‡v óvÕtŒ©Úôåð á-#,F$Œøj¤õÈŠ‘¨äQÿy#áKfQfe–²ºÑ’Ñ£s¹i\×Â]➘ËÍ3ÌŸŽ±óᘽÃ,*-žÊýåßÈZ޵Ü`y{ìбhÜûã"Ƶ¾éòf©Â^±CQªøŽ›¯ã[y[eZ]O?~…ðt„ðiA®…ýZ‰0–qZ,—ºÐÑJUB¼FUσ]_^ZS­,â·ÒxP*Åt”R_®ûژƋú¤áýO”«êx˜&>áDŸ¹ÔZ‡Ó¿Â~i Ý¿à·Z³ó õŽ1²ð¡ð7—ŽJ%³ê•ÝnÂ=ºUôS’U,èz~Êh>Òé 7wW]@­hgzCÜ®˜òH´Å©áŒ8^BוŒƒ,úŽóy[…ì;ÚçåÁêw h%ðŽrà‘Òrý–k”%Q<6&¡ ìã­ñGØ>’¶èw@FDóØH ¶œ'‰—áTi¢A ƈ)ð¢aøÀÛØGºÆ "ƒI9 Ö‚·Ö †uÀ¡ŽT’–ß`˜–ó5(ÅyúŸ·z^Þpz~/:šw>mùí‚Ë“¸\Üóiº{sà ³˜î³ž+Wn˜Ãã x'Á`ÜG-éÍq¬ì·Öèúà Ë•^þ. ²z‚^h%_uÀ:Œá Á™Ã–6S° úu˜ƒù/ÏÁ FÚ¼Ä2>݇ûõîÂÉÓæ9Lœ8÷öÓÇwï<çûª¬“@yüq°Ê¥õôΊ²êê”Ò]R!ÓLc+¼O€Ò}özœq¹¯›ÄˆÁŠ˜Dë·,$i%]ÆB¨PÎùYYÿrEîÛýýÖû‡9#wv.ƒÇ ü•‹»OžQìÛS^ÊÙÊÔ²DUF–Z­ðtó‹pA,f¦<–ïf€þî'<¼å»²P‘[¢ªFlM©†,mÄÔ«ÊâãUÊ]®ðR-Œ×Âyíf­Y È †Ÿ‘bý S †'`ø‡Ó}™¾´ìg1OºA3PsÙ#[ˆ¤O®:·½±`öôgÆË,ÁtÚ#<úC¿î> ™/8äžßr¶›¹ÀiÚÔ×üþÖò"xÙh%Ñ#sXFö§Ñí/Zåø,_ «¥—q¶g¢K•5º ` % ¾Óç!]Ê Îñ¼nu?×ra(ÛNƒyί`’ Öì9&¬­Á›ç°x»X¡&º£/€@Á<.~ðN!6f™lëwß¶Ëcÿ”¢®xÞá ò1²¯…µð?ÜÚ/½vH².›j‹‡aÓg¶`ÆËz{ѹ='¿`q¤mkT º|É®]ÖK’i#džfdô­˜JP3‘–­ÅŽ›_¥iêÔ=~¸uý1ÿ玲ìxÒBÊÔ €´‚åF:FŸ™2’NLßFlI:çAÞ&ô¹0bsõ4¤ì‘=-&ßwö'z´ÈÂëÉŠÝPB€‡ÓÑ)ª„„òÔz¾÷Ø‘¿Rû™ GÏUU)e¤MÁFZf÷¨ ÇÇÖ¡ZÕ®%iùÙ¥ˆ­ÒhªËÒKc«ømQ¥!È­Ý>k>k§¤?NBzðUÑ¥©º0êþ"ÈÎ׃\+¶ÚëAB²ÈTXÞßyŸÔÁÚ :’ÙNØÝ9F¶ ¦ÂP®Z©IÔ/0W?sµn]ÙO?O¸0†~ÛùukÌ¡àz~kÃf[Ѭ²ŒÜ¨Š8² U²G>oºÑ{fÛÒwq%ªª¾»ÆÈÆ‘M'$¥¦&f“™ö­«ð;q¡¯ëÖÚýq|S\SÚ?ÒÎ¥ïIß“¸;¹: E³¾Ë¶ØÏq=xl€Ó´P¯ã"Ò\©A,^ý”¤Gš+èÕ!i>˜쿆1ü Û{áxÛáCǫϡ‡¨{s¡_nÌ+R¨ãdêÕeqñªÔhE³¾Ù³zyÔ›`)~‹wdðLØÀÜ«kZ¯ læ!©©Íj0)›,fwÒ5ô‚KkžêÔÔ¶+WVW *¶R©IÊÈÌIW)6F-NXØ%öŸâ¡¶2 šþ| Ã;@C"v$(ÀÁ~ºh%Æ(Ôhš©HÐíØkÀ»Ý€œMÅÖ¯ë 0Tfƒý x/ûÛ®št¾tŒl£°ØüžÈß²Ø0Á„tDdê`Ô¹´ìÄ*Ï•áKÇúmj%±È 2éiœOÏíôúF!sºŒ¾Øuï% ýZ(%`7Øm¯¸[°ì À–hî5@€¥^xu›•ÀÏæ0W0‘6˜fºHæçi"¡=Ò¿=Ò/þzЧ4|Ðg"œSXe~ŸLY¥g}BW‘z|5ú3ú#|ì}H•® çàÔ%pLzò55XEKfý’~Yßá,i†µð®–Ø3"Ùíýì!Ì4iãD_(¥{>Ÿ¶iirìjERFš¥°IeEa~nA…â‹Úc%-ˆíi]Ç»1Ë«"ò×›Ï^>“—©®x=é>×ðùEÒv_š,]î¹±®Íí]=m/>kÏP0¢azÂÙÆÝþê§Ðc+{±ŸüGQè¼iGøh“Ö¶ ¶Âr‹Jz°x˜Ø-4®Ä±RˆífÄ8ÐC»à Öp1ýŠo%ð#„s0¦H 2n$&’¸¹Q˜Æ¦@7g8b‡4ÌÄSðbüTmàæäâzž4Xƒ&“ìm0ÂB‘F¿ªÐ·ú ‰a5±/ˆEùˆ ²út_6Ñ5ßÁO^Þ¤e§ÜÚ;î…‘Ï_ÂðÆ”gx/;‡¬[Á‚Ã"w ¦Lsp˜ÆËNLw &ìÖCc°„Ô#‰ôÄ#ƒöN“ù¨/ÀNL¦àëéº~i \4W1ý.d’©šŠ8ü¦2È~’X\ „Li™AUÄ…NÒx>má¼ô¸´qDýÊ{1ùZ'–Âf㛽jV0¾9e:ñ3Ü[ûÕÕ­Ÿóûëªj‰\T(5ÉêŒl•J±Æß=Ò±ãö¼ü­÷ú¿îµiMŸS¢®¤i™^øÔD—}êW‚1IÒ70—;x&íûx1#sªØEa¯‘¤5§áïð øNj#&„býÚÓƒàÖëõT*b”pânÂÌ‘:KðïÉô ·C2ƒÛñéÇ÷‚H‹&N¯¤¾¸‚3pGú:¦ˆ§ªÕõüi¡P(QºñfzÝùåÍN${#'O"xõ|"Œ¸~±åËÏ%,|É †æKãø–@iád^v@‡¦© n?}rëöcÅ ”žu€Î`˜ ¥MŒ¦©¢Vt÷-¢ñi!JjXøÓÿ%#‹h8ÝÕÌÖÂ8“àÍ•0Å Œžô[b‹·fàáØ$oÿ†µªÓ¿ôÌìtµ"0Ô1j9²Fó/'=aµ&5÷oœý =B½««ç²ƒg‚“Âý1æ‡'Eæð<<¤ØÆ“æ5!š¹ð6 ÌëŽ3@?Â~[Úa#2ÚØŒ`,ÈÇ,á_UŽœ%EfÝ/˜p°Ì ³–£Oo¹t¸)KÝ¥(Î)@yˆ­Ö”UU¨K“òùàâÅEˆµuõ\ȯž#zÛû¸ÇÖ@E» Tiá¥9j!¥1‡ôÍ ìO7ÿÓ¾Kxœþ·ùºeƒhHkæöEï–.ö|ÿßýÎ+‡îBúú.ï=„îñéÓ1ùùx: !îûú|ïg,–0+V®Z–ËbV·~\‚~E†~˜ñÝý¬oXbÑ-ÿ·E3÷óubÑœììÉIæÆøWÐú(+uQþ Î}Ùºt/IïÝ_³³¨°i×Þ²OÑT§» ˆ-Dá,N 488¾öT}ñùéË7ÄxùõÜø%âšô8¨OsŽ.Í7?9æóžÍ~)>»vóжUm›NiÑeö}/9xçý¿‰ä˜ã÷$¦ç²ÇŠù¾3qõ#HÍ ¸gþùµŽ戂E0Ûƒm æüà®¶´ìe¶psÆÒžW¶KÈ%¶Ëèœ:7FvBpê¹ÀCþÕ¤–Ô\—™ëëFòÍQ‡SzR®+ëÒw%îI¨EÁìbW»YΧ.f(rêÔ¥ ˆÕqO*M”êAU2²G¿ˆº2F}ýYÇŽÏwñ!;ÃKæW¸—m/ÙQ½£*y7jb/u¸{³kƒG¡"7¦tÐÊ¿dêúIøÕ š¨‹>ô_zÔºÐ;ÒV}–LÎÒuëuFz´7çèGÙׯg?b7ÜÆ jµì%dBñ`øý„Eì]Ø’BÞÕꎧ¶K˜XMRuMIY£†ômÁC˜¨þˆWÁ®/`²9γkÐöf]:וÇ\¸£a.¶ÿÓ]Ï ÐØ¼Èah¤ô„A©81šbR5¢Š2)ü1QĨìç~ðÒà“——Ûµ’'ý4œG4½‰l,BÃØëÆwèw]—¼kïzõ¡îtõqñ}df¾Ÿ,°?|ÌÑgúè~Ï߯}Ùÿ~zŸ+(ÉÃ5æ—hØ,”J÷ƒÝ]§ñò¾µØEX+½f0bš8b߀ÿCkV&>Z˜¥û§»JzbžÁ­Jwî £et»"§éº»>²«êý­Ê½p(¡[?ßßx±Íû‚?áñµ»¢ä…é¿lj<€ØûBƒx|ý.cpO¸‹¾°æŒû†Ðx¿@ÅŽÏ‚ë+{ˆÂB6±b°CÌ{i0FÕ7BÚK_$a—¸ƒ°¤½úÛÀRgz<þ·à"ýþ¯jtÑC!QÂl(äÑÔgÀ„d@bÚaºqcKÈ1òر–ýmG‚÷è%ÏßÇ,7˜à¾¯^{^HøÝ„+,ËÍC…lEŠ&)%-#1Mïý{A¦:'eȓ˕•åÅ…UÅ:\$j…=$ZJO‹B*üB¬õ| ˆf湜©˜ÂàYw0 Ðw€‚Y üð']¬½Òt¢¾¥¥æ(jC-ñõÁMëj—"7v6ƒÜã–„­‹Þ¿¢­5Ñ-a'⮢ ºÔöß *µìlh.hÌ/)B5l•²,n¥¿Ÿ»ÏgPPTÔÖì˜l•Å£„Ru]öì†(Ä’ïÜOúuÕÅ­QEæ+B cëQ ä™¶”ưú¦úò]¨­ÿÈ(}:j~çðêå±ééé(‰DRžW–—[ €7ŽHûR±¥%ôŠV°ÿ´û´¤Q~¿Êùüq^;À;’ø…dÞ±ZîìÉ‹_|sÌÀ´® }Éþ<óÞD·•á~›1É¡(–MÑ(++JŠ« 5]_½‚Ø\^µô㸈·ßáßÿ`³³»Jmá*L¹'^Ö„êì8ì!ÓïIæPplTHfd–:ų‰šÔÚ®“íºP64È«Ë--A5¨ZU“·5/ªÐ¥á‚ûÊ8ejb|Izc–¢9sg¡|]JË#›¢Ã¢Sv @öUÅÍGý=Y7´Àï\´25A¯ïO²o/G YÇEî³<|jù)TEyiˆMV*“*’[ãøŽðSÉZÄÂÐ'ß¼¼âѹ™—=¸ÐtðT§å\³ñòI TDÆ%Å“3h2IBIQ~Q¡¢µíhÍy’„NÿåÁq!a±üŽÄ˜ŒhàV‹!yeøbÓ1ãdàЧ^ï3M†~ÝümÇ÷–z1°KËáPÖÁ÷ä ®.kám‚›(#õNs éÅ tB™²ª¨0¯¨BñYC[Ybï[i?i©Ëtï†ã~¼ªDx’R™”X™x(Š×n=“p–>ò»A´Ãýñ©c}ùþhÁ—,8æŒî®–B—S†JQ!:_}¾éXûÛ'n¢ZT•]–Q–QS„ØÊ2MEãæߥK"ü=ù…˶Ø#<„Å>À#`Ä‹;@òËüÓ—¬ØäºEQ¼ˆklÓÔTV·útg+b¯žs[8×ÓÍi¡_ûoÛt ÿrêÝ›gá0‡g÷åd§“VÏ”'‘TÕ)à=¡XÚÓ7zž(ŒMpà›§ÂY.·&·!º.É·ÇÆî <‘›Æ×âÞܨÒÔj$¯F%e¹ l¶æ‚""CBvï8È—Ó÷ìjnÞÞ4„‚3KŒ Õ {ß³Àë©`W¸KšO¢.öÑû·&O~ÝÊÿK[²_\ƒ7y.³œòpÞ¿þÏûÏ.m<·¤Y!{úqÿèò^â¶ÊoÑ¢Uí¯t}ÞÃË~ÁÍ&÷/x99¹yÌÿÀ­óz÷…s·u«‚³C¸¸ \“R‡äõHS^°ï [´™ÿÕ§ýûôÕÕ‹«ZÏ ›à'.7©P&rOXàçè°n!ŠC‰ù©…©…™¹é©Ê¤ÈÖø3W®î>y–¿y©õ–…Eö0˜4ßKlîØ?¾ÚõéW‡i½\d 2>1!$hSÌÄ.Y}ñæ½³¯ß<å7aŸ~ËnZ’RñÄ‚?A9‡®‚O¤% 9%&ªRcr 8X:O÷i^²"É*5'&[,Åû­ÆR©½¨÷èDü‰TÅä&•)+Q5*-Ë­«†‹»ºÏsÒr’Ê“«úë™WWE>¿#Šý‡ôÇ åTd¾yt H¥zpoþ•5Ñë‘NýN Ès0ƒsÂy9™z4ÆV%ÖU•Õ—+` ÔKç@íß=œræSÝO ˜¿w¼ü7†ÿ€šsòðp^ÜéÑÝÝÙÙÝíñ…+Ÿõ1wªuËÚu›7¯[·ùðÉ­‡Oðx¸0“Œ\í40²çš8Òßßp$Tàh®¢ ¨iXª,5+#';CÑ7OÊ$º¡”+ËRË óQ^¡N-ÏÃANpÀI…YE9…H^‚J Šóò-ò r P*Í(Vág°ÂžÃ MQa1*•£‚œ‚¬‚œ|‹Œu¡š ,#;=‹8è öZ³¥¤UbKó b-‚è‡j÷î<^Ñ./½”?â—²%v‹̵mOÙƒêÙOjk¬N‹iTª­,&+jä•)åÉÙ™j…:3ª"º(ÉW®v -Tså—D¬B.¬¬bv÷¢û'Zw¶íWÈ*ÂNrQAa1ÁˆõZ§ýòLó‘ör=Tݵ?¤î„»:·Ñï½úVè°¯— aoàcV¼æC`=iÍ¿-¾!Í$›} )-?3/ÉU(-#C“e‘¥© Ó4éð¯°Àä‡2=# ©ä(+/#/37Ë¢ d¡ÂÜ¢|½·8vÃXXJ–LAii±áŽØh#fÐ[hÒÁ ÝX²+°TU¡»RY˜“—UÄ»€iÈ ôúµùå5–_¤·K•Ä.)úQoS÷‚P×ñ¸¤ú—YŒê:zÝdÿùáEl´Š˜"%Cê,¾^9Ìhw5'RÒùñ2/ÿ@<Ì—wf_@mÀRnsDTpðîÈÃÄ ·înli‰hØ¢ÏUö cø€l>‘èMFnv~: kžˆ¬Ñ„I.Ø4+='e°IzëV¼o§âýzôÛb0ÚqDU–¬TØ+¸sØìHÉIjrŠ2)©8­&“³@kujNJ“ëæ)+*(/QÜùõ¶uiraV’ë’S”U”^Â/øÌÚj ‹‹Q¥¼"¥<%K•“¡ÀfRÍ4ô[–(ý o„öwãA»ušûÉÀGÙü;lÄ¿õ (yu $ÙV¼`óÀŽŒ*;1[­&ÎM(8bÏwyš:ÝÒ0ûw9—V•V˜Bø9E™œ‘›Y æØÜâÄâŒr$¯,×Tæäg”öƒñ¿1‘A$ºÍíuâlEƒÍïAØFüû'zDBµðn5˜—ï« ;†j‡/55=^b:œ¢þ/æàš endstream endobj 13 0 obj <> endobj 1394 0 obj <>stream xœyyXS×Þõ‰!竵 &¢‰Z­¶ÎV«VëΓ2)ŠÌó #$@²“!$ ažgÄYœµÎC­ÖÎÓ½­µí>tsßçÛÁ>·ß÷¾÷yÿøø#‡s²ÏÞk¯ßZë·ac‹5Þ+<:$q¡GltPŒýú}Æ™ÅLÃLg»"ÝŸ«†F0žãÙ`¼CÅ´9EŽŒf¼ûL™H8°X+wz›çíóð~oþü›cãÒÂCÃ’f,[²tùŒà´Ý™á’3ã]ü!%$*6.:$&iOxtprâŒÑ÷Îð MŽ Jø¿ÿö÷hÿãá¿1ÆgS¬ïæ8?—xׄ-‰[“¶%oOÙ‘´S¼+íðîô#{Böu uó÷ŒðŠÜµ?Ú{á¢ÀÅK2–Š—eI>X¾âÃ+g®šµúÖÌYûîÇs¥ëæ­ï}ÿù Ä,b/±šx‡p#>"fîÄbáA¼Kxs /b±xØO¼Oxó b±€ð%6 ?Â…XDø®Äbb ±„ØJ,%¶ˈíÄÄb9±“XAì">$v+‰=Ä*bñ±˜HL"ŽÄA‰H"ˆ· .1™˜B°1†àlb*á@8Ó’˜NP„€  !$Æ3ˆ7ˆqÄZb<ñ&±Ž8€7?B<`ÅŽq8æ.Û•=ä@:$;|Íñã'g’MÔ”œzEûÒ…ôŸc]Æ>yC<Ž3®hÜðx—ñƒoNSÿæÕ Û&4½5ö-Õ[_Lôœ4{Ò1ÇŽ N„SõÛÓßrù5Ü‘ÉÍS>œ²cJÄ”Œ)†)¯xÛy*ž‘÷<ÿ0ÿÇ©s§V:Otvr^ïœ;ÍaÚöi½ÓgO?8ý„ Z0 ” Ë„÷gÌá2C=“3sǬٳÜg¥Ìêõ%ÔO> lЧ‡™ic ï·rôŠ¢°ûHÇ\祒èȈl'zW–á¯æ‹ Ÿ•òO57˜õ%ùÅÂ~8–-dÏ|sœ!Hø !=k¿†ÁBjD ‹¸‚õFõœ L.°1ÜÖ§Ï¡Ësvùdf!}õÅ †­ÔÉã•æ@ŸªŽÚ.D!”z‡,Ã/—Ã#Ê/_nÖœ¢aõ}à…£Òwn<¡”:oQ¸Ü[ÌO§ z£Öèz£ØOˆ´”ÆM.õÍ¥GW4</g×ðû\”)"Ï«K• ˆiÑ¡ˆƒ¼ ¡=/J>°Y [´õZž ˆ¨ë¹åâ !d¡å<´í[63;Ç'¯\b¥ÜòÒ A°Xj:úá88÷šÑêS Ä|–¡×ä¹Ffà´•Ú_ .:4ˆ¼`¾ w\l3_ËãO^ :˜—6GÈy ³_~©)Nß• Oá>Ï6)´è7J³A*[‹ù‚zîVt´¶7ÛŽƒ“ /½;²!º.μ£ôlqEQuíôKM¥¥ýØTè°tm ú¡¯¸?~U»˜vúîbR]ðî©`_Ê‘ÃI‘iÁYÛí'16 a·L§´•yeÚ>-ÏéÈÖ_÷Y6¬õ š¯¡ñn)ê™eõ¬†¯aÉ×l¨gqÑ”¥ó‘Mûn.t„Ž?þ…·ø{ô¶PË}>4MGdÀ¶ GŽVw§cÏfÜwèú¯Üü{#à­—ìaOûfĊȳš²,92…½ƒRxhL—ªÊ€‰¬%…ͺx“_Lq*ÎGÑ\˜]NnÐÊŠ4×h¸”rE´W)Ž9Ãqß@8Ntýê}ÏÀD¯@á#J¥Û—&õJçgPFm^=ÝjPŽ„Q`¿\ᦢŽÃEL·ñB{ÿýSëÑX“ã·aóöFÁ‚NæY'‹¹]¸Ñ3Âã‘C£"’qa~çXFª¨T´žSK–ýÒÞ)= ãÉ‘í#¿sÄÌeªºpìÛÔÁ|ÞÁzõ’!!‹]:v¿µ\¹p}¨ã+ðø:æ±çÀÖO«M4ª‘O”…YQv“L¶!›†Ì5nSQá±/®e„Ÿ<Þ׳  7‚W~tÀ'Æ]¶Їe˜€v†]f&Õ³ª_ÀŒçl8Â|Ì ¨6Æ;.@l4Mº±ìûÁÚ“}B„Ç÷LËp͡ӡ¼„ÚgVÔ½4ó=%×r6¡g\˜#Ud&§EÈ¢@ˆ+JµF6¦\7iøÆ¹{Ÿ_iŠØ> ^êÆNÖ?_²™ïáÇÜXÒf@zGCÇ‘ïè5ZÐECQÏÕŲâÕt'‘²$²•j-‚ ¤¶1/¯ÐÐ㢶IJ—Ñ5d.|‡3R/"ïe›¥ºÍv$Ô›¥’͘œL5¾À¢·ÊÆzøœ?*-ä6]F‰zˆ†ÉTó±ÓõÆl…I`›³‹]m)«oI±…Å&oö~Keë<“C%ži˜%XáÌ€®1f ‘žR{«T»ä˜rçþŸ%% .ž2%_›.Y§ ÿ(õÙºœ<µC±¥¾ ïónõvbK:™ÿÂtÁõCÚ­©[D>U™FÑ:LÈRâ%ªÂ¥@Ñ–Qè¸ä¤¸ žèAH\¾ ' /Ãh|Z`OMøž°˜jU)A:«åqKQo%LJïóA¥Ép€§(¦:rÌ2Ûþ|‰1¡ } òç̓%9Eê"PĦ¶<üÔ61U¥.TTú@gôÏU(-ù Ðl®Ãþ¡ä}ƒä–]¶ð ßXÚ ðŸ¼òcú|~5qS\ôdxÕŽžÁyOqá2{npÓ%²l1 “”%}BèM³Ù âêäöCV7@/Üè·+ÉšZ]]a«ÌÓäk BµQS t]se÷©º˜}‚=Z¸'-óPHrª$DàÞÕx¹¯§âìeSñþüòÔçVPanëÄ·Ðb¬ÎÑÙòY‚$.+Ða±­½Âô6ôá=ƒã­u –ß‚–‰©Fu‘ H€L–œ•­’¥IS³Ì1Íjg1 à*®ÿúC1;8Ôs1­SÙ¬¾BÃËdÖuECBstûÁ oà ¤…„Žs«i$¸»R?<‚Ä1z pM[;.ƒË :¶xù¨ˆ·3ÿÕÎjÅñb$Ùð_ë¸ÈMá `aóâóÂÁ]_ùg@_8 7@ÿŒyá5$ÜõÉÊöù€uèýií‘çýš4¸É¶¤xg&¤'$%……¤íA@yh“OÄ/²ÁËúŸŽ »zOUúuTœÕ ƒêY¿âPqÅ^EoáT1dmì¬,VÄ” JãÍŠ2œËË«Úk÷îòŽ ˆÆd…jÖЫ#?C7Iõ…ÜÅÞ6[¨Õz¹ < áM8z+ºáéÖÏ/a†=Þc©½ŸeÌÔþ%¥ÊÌõÊ׌\‹-Ú.¥;¨Zu™¦<çŠz«/5·_7À1Ig\Ãá¾åõ 1UÊpÈráÖ uÐùÊÙï»ù"*U¢Õ% Fåà"¼Z#ºòëYõ·aÆ£ºz6Áð¸]ë¨ ѧ’ yñE±ùØVmtY¼«6äf„0>1%U&ÏÍá§$«äØ@“Mòc©›½ã#ÀQzÿ£À<®=vVÐÙTÖ :Á•=ó·€·O—h¥ÀÖÒVWØžkUë@è¶4ÕµÔ[ÚÀiÐ]%i¦‘rd*·UùXuÐ_·HCÝ×Aœe }UFK÷Ia>üŽ;TßÖßT›]*°†™ÀaÚ36ìàîàë?Ú“çðÛcØ}ÀE¤~MßG¿Ý*n/ëï¾£ó¼©4<ˆûÇÙ˜3vÖÌFï5®Ú)è jN½“x‹wk |3.&P Š´t‰¾äö‚~Q[ÔyÿæùqÀ¼˜9‡ öNòþ °ìh³÷‰Èøø©á§žþž¾ƒ€~íW“ϳî=‡{p©gX¸ûŒÙÍúS¿Ÿ_픸÷ ^¤²õa²„,¯ ~œÝ5ò´:„èÞ¬C‘H¬ñÙYJ̘( 垟eRã﫨cýeÝ€>Uê*D~”Ú%Sî‘ £ì‡6æeëåK(Å4žkå†èS‹bZQ0,àA§šó§Á· WÚßÒ³²v¦Iƒˆ¼ŸUôo¦e*6¨0ÓGMÛlo5|© :˜‰.sà rÄŸyÁ­7vÃIƒ‡ú¦…ŠãÃTóÕöÐß=øÒññËŸOqúw¨ ¹=_i´©=ZìÅca3ëÌÚ"À¯í—Ä”zc¦bk.íô9t^ÂKJŠ©L®o¬¬lhHªŒÁ­è9I{²A=á6Ç;/ ä—)N O\ú)¤Ó´ä¹,ÝYÒóÒ i§–’£G #œƒ@`zDLXTZðkú<¡ƒÛÝ#gׄ¥ù) Þî{pÓÒÝp‚¯ ‰lDaœJÒi—Uk.±8›@YŽU‰Gwödu9CúË'¯>óº†xw…³.õzàXÇ•ãÇD¡m‚¦È’øR7ܲᥣ˜V¸ktùߎ.ÿ;¸9ÈÍÖïN ‘zÚõ<_kÑYìË®2¦ã½}‹ësä©*…$K‚-UaH¯H«’±‹&¥¥'Gv% ôu—ÔÔ Û›+o'´Ó/>Ãëÿ8¸of~:Æ‚Ð|¬ÜÕyR3–¦ð<…[ÊŠôJÄ¢«I\ǹLªÐ:N5YYeÒÑçGrIÍŠLÅJ»¶ÿ+c-²±>{Î6L†R ™ª ÒãàÖÁ‡»(8íÍËÖgësù… ½ dÓ™™*™@$†12Pe :ƒÂý¼†:8 :Ô•^Sㆱ±^½„ÿêcï³;•XD>ʶ¤êfÓ¨Š[U!éÑqþ;£6àWw"­YÙ®ÒðÞh{õ©½½jQOþj¼®ShãÓÕpd=h»Õ%¨>fìhXBé~3•<5¾&0ëÏÙ“¡ÜBîÒË‹4ìÇ9:ŸŒ£r¼‹”IkÖâX×\$9 ‰§4û$’Ý9ô¨·¿ic ï¶O3HDä”+@,ÈPÆÉ¢ÑÜ6͇ßDÜϪ>°•›uùÀ¤-¶ YEÔ)ܬõ.ƒš‘~ž…„ Ì`Ë“é$ŽMÃV¼%¼³¬Ïá.û¯ýÜ'ÁBúh3Lšn¶Q@WXd0ÔTõ–µº¯2 +B4¥öPÈ=íF“d¡<¤T}†ùTcosù @_,[%D¡”ÚM¥tWá‡b-T¼.2_n]|LÁ7Ž\Zçîï¾Ov1¼nqÒU;é”R·_.ßo?Ô5¿>Ô­5fø Q¥ö”J¼°êýéò†?WÙaÀÑëLv¹ÄTUœ"MBßò~¯,Ï-Tçñ3+TV¬´ÕUEçí0ØDÔEMQfëš–Õ¼¨ ÍfÆ+ËsF+K ÎäáGÔ"êL¶%­c!Ü7ÒjGj³.Yñ/ ÅPÙðœõ¬Éx®ÈnØpÿUVÔ°»`wÔ\¥&@½²Y·!› 'ýÌNHˆŒ©Ihhª­nlН¶z!Þi“ƒxÜÓ#*_ü…&‰mX€Óe7–›m$Jû×Î-ÒÞþÖ;Ö²ª„Å?²¡ßôAGCÝ=CÐX€Æ´ ú„gGà™ÄApô–µ· tBÀ7i´ÎDS¹ñÜçÇqš A!3V¬üáÇá˜x"IÃóð[wßgÃ_Ñ:îÖÒä&ÍC®¥4Ÿ‹j6–ß·ZkµÏí×Ú‡•M·Ji…&‚#jœà¶P×´„íi7Då ZW¹Rúpâ_ž4<þ‚ ߘ ,ä:nÒœ¤™Ÿ¨,Ú¶„ƒëÕRmÀ¹³Â(Žâ0¬Þ•.Y¯Áp¸yƒ}é¸7þLßnG´&ÜOÛ(ÅkVÚ¯5ë“¢¶eÐr ¯¼«E÷; ·PÚÛå57¬ÛËÓj4·ièJåB"¤½F'Ëo.9Â;OBîbï‚ á3î¨RWe^Mêô[è=wnŒM5TàÅŽUZ,I ëM¾ýðImÏI቞šApœÍèmJ©™Y±ŸÝ:QÓq~êg»ù¦G† ¢cqÏ´×’Ãë¾¼ù* oôÚ*KˆFã[[_ïœ{ùgôã×=Â>ÂDÁ îÆ=D7GÜ9;a+ZC9ýò®yI¢m׸HIB%üÑþIsñ 2·Ùp;ó)úe@¯Õv~ÅË4ˆS3UÉ€BHÄB h€š¯ÊS6w)¥Ç:zv˜KÏß»amj†¡2ZYlLt¬D–ÒŸøðÙݺ3g„ÇW\Á]Q¿ßéÀ>*ôFÅ(zõŒC?«õ;˜÷5›ñހ×Â]´ÉëÜ ÐT°¼îƒ^ßÎÀó‰Wp:Ÿøâ(€ÜÍŸ¢±©Ê]Â:8:@.­¥Q0êâ~qj3V‹1Gö¸~°ï{¸øLa½Í"¬(m2¶Ù£¸¿1ËÆÜ»Ïbì®0B’nhnYVÏMkñ-F“Èoä;Îu† Ïâ`!Èü¹ˆI3lè]¸Ç'¬â&PÂ?+ªH>_¸Þ¼A`t+ðÓEÁ3¬áF'%Fc«ml©ªhlL¨UIýð„zÇ ]ïÃØO¼Nqz{ŠûóùÖp‹~æ2ô.b}´mÉkÌo‹N_!Öª”˜-Sß{¼ ’pü£¿> ?‰ÞüF6›{Ï»:xÒ;v¬÷|q½¢gè¤ÀéÑ©GÜeƒ¡ýà=x¼çê­ÞÀ-{âo À}Áðl¼„³Ìf®¾\W¬3–>4^ t¥¨<)Q”–”^²´ü}š7ù¹‹½ŒC=«ñ[öP2:Xozõð2®èLÃÕKàX4[ö.rFî~‰c¥=çÁh%bÏ@ âi8‡¹ 5'Sž—" ôzÿpÜÅÒKµÂ2[©Ð__Ö _SÙgN€;l,&Vsç’68•óÛÀûd# ณÑ(€ƒødÓèE”ýâ /8†LAS9ˆöúƒŒ@QœA²FqàT|ß~Ñd¿`‘Hݹ©ö禒xL,ÔXÙ¡«ûS»ºOcÿ§¼#äð?%6©l¯ ²ñ7e]Sœ¶ýfr?ií½.ÑgÂ:B“’ÃN¹•¢ƒA«-8…éòµ@ë\X ÊŠŒ=ºï¨°“yÌuŠû{ðš†×ƒß—Ú”ÐÜZÚ ÃjªU6ÇËaBÍõ‡0¾vŠ“ÿçÃK1}g‹&}|ÂçÞñŽÒ¶6á¹ó-OÁcúVH×!’ÛÕè‘°5Ä_y$&c~4±¶ó|ýÓŽ³Âºîúò&@Á¯¹GH/Ÿ#é»ÀalH´ÑN­ŸWÆKó£œ5CN®ç<®÷·µµÏžkþÜ%jsvy¹ÒšÛzA¡§½úÅ;I:½óù/Ì0· U/,ÞŸá~0ü  ÃkÚ…NœÏg]É×i² %RsvCV€ËŒ˜ùŽ;²•qT³5p^Qh„ñçà#=ë}‡yÖìxìÛ[OàÒsSœN û3ë¸(*…<]¢Ñ 0Þ{Ç ¯O"ξ€äùžãà.}ÇóôÚ[·®)Œ¬Û Iž¹ÇǬä/¸æñÇÓK57œÄ;®žŠt¾.k¼#6ñ"'Kq]Ÿ¦—û†j:šÎ×öóª{læÓôÈT7úª¢§O6µö÷·†úy…\$p*Û²‰{ ‘m^]÷I;h÷«¯5õ~qóø2N½Ábš˜ÉÜívFK¢©¯?`qa>yÅ‚[»Ø¿3®Ü›-Ç/cÖœë KL ¬u ì”É× ´1±¡˜1ö/6\P 8:ÉáÀ°#7=D*KÂm€¨@dL4óœ6˜“ ’ä¾ 4T¼ƒn 64™Ê,UÎfP’cQVÉyNòÔKNóhh¬xh߃‡§¹ÌXÆ1P#K`=g6‡PBþv´ëÇIìû'qXÙèpô Ëò°¹£YåíŽ÷¿œÓã_›|6Ò\Ê[s5¶=î~âMùð ø­øYÝåú+íwíÇ;Y¿Áßlе‘uëÌuH`¹p×t«¬»£¿ÿ%ͧŠÛAè”¶'U…·¹UáT¸Øu÷ªàÒ”æšÒÒš•Y\&”–ä#ÝÜßxòòÉýÛJ½½±;E~ ?M ¿h›]|£b*Sššÿ-¾¯ý_°;‘+÷þ©ÆšŽþ;_´ý àXß>úÓ/ƒOÆWz7Ë2xŸîª «ßP½Í´¼ fIWÇí‰Ûut³»Ý¨FQ1û¸ÚL­ ¨A¼*^©å¤9-*M·V”[+ rÍÙ%i›²tÑÊ[‘U•Zɯ‰*“•ãdTb©¬› Â#æ„Ò¬|Þ©z«¡ÏÐU`.µt•¤4Yœ.M$D'&'É”9¼ZªNæØ2JSSÅâTyž¨ EP–…[Q)R‘ZÙžZ-+Ľ_ªDœ’`•žÊv(V©IÉ NÈPÌ ÈJ—x:¥XZUjÌ·– Zòó E…yyÕö´‹–Ô kX_>dóÓ¸5(ô_C0´f®•X4íôðrJÛl2µhíLÁÒ|à ên°¡vqQìv‹ânÀ8{ÅÂ8œð Þ.ŒŽp –ÄCϰ$þ7r œ*"ÿ–ÄCÿ]ÿžüø!»Má&ÀÐá!šð‚jÕ”ˆµ¡ô¿–SšH¹<§KI ³¿”o<ש?þIÞø7 âÿãÄYF endstream endobj 11 0 obj <> endobj 1395 0 obj <>stream xœXyTS׺?“œªE%7’ÔÞzk­Z[k{ï­Rg¬â€HQ+2Ï  ™çìÌ aH „€Œ 8 âµNu,bÛ[«mm__»:ܶûÐÍzïíÐÞõzÿxÿ¼••µ²NNö>ûû~Ó1yÁ`0žŽËÊK+^²¹ä`nVJèÂ"z6ƒ~výç04¥ü*[ͤÓ0- L›ì{öOó"à3aÃtX6ƒ˜Ì`¼{çž‹-^[P(*ÊÊÈ,‰ziÙò—£’EQ¿µ.­8+#?j.þPš–[P˜—–_²-+/YXµ³ ï`~ÔoûÿñÒÿ.öÿ[ž ˆùÑùo¬]·¾hCqÉ&áæÒ²ƒÉo‰RÄ©ÛÒÒ32wfíŠÛ›·gÉ‹Q‹â/D,ñ<±˜C¼@Ì%vóˆ8b7±€ˆ'{ˆâMb-±„H$Ö{‰õÄRb±‘ØDl&V1ÄËÄ+ÄJb+±XE„Ó 1X€‹KL&Ò È¨dü8)aÒí°¬°+“·M¾Ï\˼ÍÊ`µ³Ÿa¿Gî'?zjùSצ¼0Å>uÙÔ¦iÌiÖ§“ž†áÊðŸ¦;§?š±gFçLGDdÄâˆ-Û"Š¡5œ†À“»éY~ýž—»Ó®uÉî-¡¯ò±ÐñqÃß_©HQó%0ÖËN°«íà0¨·º}CɃ…,?Š4«Ì* æƒ4©j‹–”@{œk¹p!¬>ª™á´A5æ§Yƒ°wÄôq$§‡N‚Oqwo”+$€Tiœn—­¾²›‚ÉLN«=`k¨y¦§°)uË[ÛЊ9‚÷a¾Á¯ê_–ð%ìASµ”­IkÒ‘œÌEèGæk¾än8qóò—ƒg{YëVˆäÚlu.u½ÆäØe{ 2å3i5’Ž“‡ý_Ý„ŽÜFÑA¯…Äžï#9ŸªgÁ.\‰áÔ{¹=‹û¨;¾Öªö ɹlªíì}æëuçW€<ÖU]äƒ }‘¦M߯íÐhw)IΧÐor¯ãz¿ºO|8 Ä‘ˆˆÞŒÂ k‚ÕU§?TwµyNáEG ëh¨räÇÝYÑ;‹ßI*¦²ÊÕ/™I\.E€~1Àhy›†ÁôVnHU$ çìX‹Øà9òåKñOn\kܸÞûÜ'?Ù1´R /å¦ïŒÎ™ÿN •ŸV”È}¹Ý?hýìÌêØPëq@†-¤¿ëfÜ€“ÃÆ¢è4nÜË,e©%JmP…¥Ô~À“âÈ$ÊFqh*FK ¸äÇŽÿü%®Y¾bGÞk€Â¶ŒÀYpêiøôƒ©Óg®o€/ÁàîJDà]Ò' Ì Á°08kl&÷ª¶F qÙŠ5E,›:Øð)ðË‘ÑKßÜ‚“$I¸ ±~Bè nÙŽ UëìCବ½øLfËðw€&Da7n}=ïy@î/÷4WÛý¾+T¨³ôÃÆXøØsÜq­„uE[ÚÃAW>±¯x§ZÚ—¶±¯À•×¾˜CEIeütñFåj@î*©lªªhzLµC¶×Tkòþ)SÐÔ¤sjùnEƒ¡'2ÊuB¿ŽwVˆli+•šå¾ä˜2M7 ”çh¬´.ë’ÅÊL&10b ðŸ~ÁÏ€OÏ:WûúNv^j9âN`ÓÛ•.±Kçd›·®½­>ŸÃ_ãè|ø÷.Ù Й””IŒ&uÀÈÇ”ùEzqc¹?2îºÉ1wùÜ2´‚ée¹}6›x@Þ‰›«i¬5øf?¼|áþ±Òãû†©´É$;þ®smé¯xYœgýbJY*©V_Ô@e)·ã_ºŠ¤ñìè}I›rIý»©c ¾LOîÏË=°+¯ïk‰ Qœ¿¶3àz ÷¯¬àf À/¾ÃhÕj &µVúöÖ„U‘Z£ `F³ü€µ*“Þ æ+³5¹@I–$-§:‚_]Èœ‰oI$ÀWiÕfÌ6ê3øˆù‚º¾ÛëüŒ1.>Ö°¦J @…¡L]¸­â¡£¬ pOí`sýeß‹š%ì :äÿvÇ¿ÓÁäeǺNÐ œf—Åyxð(+)${Ê*b4X‡›½ì‡Ì…ïp›äÑBžoØåªœÐŽó ô¿ÂÑ? ßxÉÉ¥b±ß,•a±Õèõw©á9f4k7š¯(zgÉñ-ŽMLÈ™-SWÖZÕl¥žÀÿ6XvHÓµq¾”Ýk Rg7ÚU@TºbUV:ú ¯ÕÞg˜x¨FzÆÍû4 N‹ä^6Ú @TF…¦Ä¨5jLøÍCÏŽ™zvÉý¼!¸¾ß„/ÝN<»iýžd4i`ƺ‚'a´ÎÎKPåëÞT‘0¸'š³ã7¿»•JOK*ÅF—[ái¼ÜöŸý#ԉѓGOc££Ïƒnú?0^æ…HÙŒûÿ¢í`ÃeŽÌµ…9„üLq²v ×¹š]¶€#@…0ú;w1 Q²Ÿþ'^vVoX-=‡[eu™= ÔKü»[¢Ï¡l$‰´¼ ½¤@.+*Ô2L­U᪨RÚ倊ÅÂCQÛ5ìž à^È nÂéÁ»à ÙVt8¯DR!”¸”~™ ^áT)HÉxãô—2Hò*>ßWURÏ2š @Ô¦tm¼Rg’¤!lWtÓT€Ñö*ï†ÁæÆmO&rgVÿÝO»¾¸4Lµ¶õÖõ²±F-×uz¥‘µXæŠk¥MA}ËÀÎmh!ŠBsѲÅâ¾9ß6úNKü×ôšË øÞŰá®ÿL­ç”‰„sYèê8éVy««íØ&›A»l ÿln‡¬gOt÷6HkJˤ²rµUåSV­E ¤J¡•ÉÝ}Ù‚CåÕ;ªáqø σzعˆJŠØANÓ3#jíØ?ÊéÆ{K©R©vUyÀ)p2Õø‘ÿÞ%X€q±G‘¡‹ÑböE£ÓJÔdÆÀª«îySqŽ™…V¢íháºÞ¤ë7O´w“R$+@I¹>Ñáþó}÷h¼Ím3Ö–ƒ x´øy´fifIsï?ΧnÜ[{êƒÆ*Tøu!)‹à$å„€µWÂÒU+AcX—š &LÍÆgðP*­g¢W$¬½_VŸŠ¦Ž¿ÂKCRË'L8ÑËÞcÃ&ÕV¿#Yôë½ñVXÅý‚µb|•0*;î àËÕN·Íl±Ú)›Ãl2 ò•–JD%™‡N~~ë[¸µ_pÞcBËÑÎD«¾Ôsû k\:5F«AOéÔ&Pc¬Iëëަ·¼½7U¸?C—R¶?o¹”…»’àg¬¦!Âu±ã\t9ûÃHÎѹôî6–è,jGa]veîkØò7–ì ä ¢¶§ˆÊ@1¹äõÒù1øó~rÃw¾‡ß}|ußñEÍ‚žC^PKÖ66W[,Àd¸“œ¾üêã>ƒOÛ@eq~E£è × ,&‹Éjª4xu¿duâåvïHyã¯ûŽ^krø¼õ‚šº¾vœÁ8?ÃùôlnO}ñ¾ yRy%LÎf2Mørè£ëÔ'Ÿ¾­Bºœš|6Éå“«Òã½â;Gµ~U?“½…-©1ëbÐÜp§³ÇJSµ;°ç³›Íæ:¨à)6ß|“Q/Õ•†:{ÜçŸ^øbugï{ç>¼y¥ Ï?Õr™{„„ŠC)²Deä|Nõ!Ÿ$x¶«åñeÁoiñ;ÏË~ £¯y¹¬e¾òs/B#oÔ×QÓÝÞÑZw œ$¿ŠDÏYÂê×ÚM•—Î!ÇqI®+Öü® Û±‚ª0œ ^öV—Öº@¥¥²²çLã]×Áéh” ç³Pý%רv¶ò“¾ôÕ ¶$ ™"µÙVD…’ÚýµŸqf$ A·([«V*Åâ ¥ jµÓUiõ:ë({Ù´°?ƒ#Ë åå†T®É“Û€“ªÚ Ö–ïEëy’Xm>(#Ó½emÝm‡¥ôina™07§¾´µ¹±1ØZÒ\ꉨ‹ïeÔÈÏàÌÇ‘œUt&ÉíŃP KZªÒ È­¥.’3ê.ͶçÎ~>zÂݵù—·Pv½¯ÜWî×J\ªÄêC ‰\·#úÕ­w¾ÅQÞâ”Y²P1æ°³ÑSéÇÁ V߬:%nÑÁ#ûñ#Ⱥ.<ºìKjùU Vü«ýÇÞ?Ö&+Š\Ù–M¶å§¿îbŒ= ò­¬ƒèÅ:ýyHtøàb#Í?,‰/–lÖáxÜË~Å©·€P…‹Þ )ZǻȺÛ^´ ÏF1åÃsÇXº¨þÅÏøá‹°1Çïzu^‡‘”$‡æíE«e‰<¬•[6¢I€\µsàNW#°–òßòÖÜr‘aõ}­'4KÈq8Ç£8^bȶ‚ƒäâ' F~r.™—BÏ5ÙñÜhåƒÞšê vÜ"•„=l¬Ô8Ýxh úþ½pâ «r¿çÄ·($ì½ÛàVU)låUK¯Œ×ðêY°ˆNdÚYgÇ™~¼DÔ2Xé>Z…û÷Æ]eÀ.è⢖ô-&,d…C«†1Zð@ÿï¸yEE9ù‡‹‚íÍMmG5ça&[ÃÇ^ţо 8ŒjÃ?Þ Pá X n X¸™.ª£×¹af5«qʃ©žiÓâ-þí endstream endobj 9 0 obj <> endobj 1396 0 obj <>stream xœyiTSçÚöŽ‘½·J©%n ‰Z¨ZmµNužGDqVf „!@¦'Ì3$ 2(2©ÅÖ¡E­Ú:¶§öÔê±ÚötÐsνӇó®ï ¶ßé·Öû­õ®wñƒ<Ùû®ûº¯k# F¢Á¸ýÁá2å‚ ò0ÛŸoñSüÔQü4á>ìû[°u‡/±§½Ù®Ÿ*‰qäÝÞ€ó¯ƒb<5Z X¶m±ó}‡\æÍ›¿Q¯ Šžþî¢w–L÷Ÿþû'Ó7É”ÁÓç±²0yd¸,"Ú58Ü7F9}Ÿ<Ü'bºíæ~ã?—úß]œ¢¨íë#6ÈlŒ<º)j³b‹rkô¶˜í±q>*ß]ñ~»ü]e{Ü÷í vÙz ì`ø¡o{-zçÝÅKÞ[:}Ùò+ç¬vvyëØ¼ù5“ÚC½I¹Q+©YÔ^ê}j6µšC¹Ss©ý”3u€r¡RoQ‡¨ÃÔ굑Z@¥6QoSǨÍÔBj µˆÚJ½Cm£Þ¥¶S‹©Ôj'õµ‹ZJí¦–Q®ÔrÊzZG½A9R"jÅQ©I”€SNÔdj ÅPj 5–G­¢ì©×¨5ÔÒ:j4H=x,£&ÊŽî¶Ž?:iô}»ev½ô ZEÿ̸3ùÌlÔzLãØÑc]Ç~5nÞ8ã¸/ìØw½öúk¯]qx×áÉ롯?ï;¾ç=o :ŽuÔ;þSä,J™ðî„þ ŸMxÁ 9®aâØ‰i?ä2©zRí¤!ñ~ñçNãœþâÄO^7Y7ÅsŠaJç”—Sg@®ƒ5™`ói~‹I`Ýlá¼PJÅx+ùz±œÆŠá>Ù‚ä¤cZ'xY˜=y1¥¨•šë>¬ìC ݾª,Å 6(;S¯Ñ'éY<`†uÂ=‡¬_p–™ø‰7BMŽwA NæO™¹€M¥¡‹…<æÑÁVìñ»HD}÷°»’éM/Ò¼Y<Àè½Ó´^i¬2ÌL`žÆˆ:X01(·°´¤„=¨«3—ÕO9Yé.Å™Œ^¦I Ñ‘ÃÉŒƒu!jå;áø–À"X%°n’èãD¸GÃj}ìúU]A-Ò Á•›+YÑ/À¶÷tߟübá%¼J‚‡ô ]:ç ;¬b²©5›2X0ÀçÜ ZôìÅùxÔ[¾GVz%TõJyÃèSå]Ñ/Ÿµz/˜"ǯ뤼.©…_Ý"°À\xæ !çð—™x*~óù,ÃÄï_Àt˜1ï椆0îrÍ~¼¿wh¯[ÜäK«‡¤#ý±Ž7  – ­{¬Ë9© ofÓPŠÓ„Fyc!Þ-Æö Öåës²ó’ê³ÊP[WYÔ-±ì,ø±‚iÏnP™‚a'þFŒç2ÙëRRßO'úÙ¼_˜Z’}…] ¸ÃµÊúšÒö|'rWÕYë˜6Á9Ø,´Î†ùœÛîPåQUDrH†mG»NF F\Húý‚ß5ögâe½’™9¨}kM$­Ô¦Æ"-JÊ‹)Ùg>Zz ±ø8vÁ °öƒ9x6øsó$!µº€}ÀGó?öAÉ=‚’¥àĂݗ/Á¦¯{Ž…nÑ{䢪[#¨É(IA>ìp6£÷IK;nCM# [ÍŸåPa±±¬ÜTW_V‡ØAó< tÛQß©–Ú°rÒ* à\í‰WîÀ2»žæ_·ÚÙ‡k™Xìk×DŸi_ ÌÍ.3´: ÃŽÿ¶'ò[—Nò/Û?’ÀK`ƒ°b"Ü¢! f¸û/–’‘RKñe}5³Fm8Χ2^‘1îÈæ¿äêMe§oŸÙrRÒx¨bZŠÄ- õ ö8½±žšò>[…’>äg· Úa¹…TÈ·áíœg‘¶XßÍòß©™Õî‡{ÃÊ 'Å„„Ä¥D ÖWmú@ ßa7%ÓV¨µÁ-ŸY|þÐ׃'ç/Kv0=•æ¼ë…¬èðP!ÙuN¿ÓµIЧ-Üú¼¸ ý…‘¤.ÔoçÐ_(˜ÏtµLÖáxõ†Là Æ¶2LüV“€'%Åó”tOvY:R¢d]Ršj#Þ!^^i&}*tB•%…–œ\Th(2°fœ«dêuºm.êŸkô{|NÜ@Ã~zMoQQK®Ñ_]ÛzÈví)Jº#«4 E#F¶&)0-F˜Ò“Y]u-­• cI~g.¹²FÉœÎ2èk¶t9i¹i[ñZ±òZà3ÕùÌJTꄪJ ›òÈ1…’iÈÌËhÜÎÃcÅfÞ€«¿â«võ4,ägWv5’µò*ÁVG a1ài0m’è~KMÕétúLä””^T%… 曵ƒØÛ­=¼ÎǬìîj2·Wd–kŒm‰®°µÆSѳ+–HWé <ª ˆò FÞ¬k¿çõKý¦óIJשΡÔbìì&ºÄE†Å%+ÛØuùÌ™¿ÔÚõ x•™KÌOÏK/ÅΠÿŽ5õ¦Ò–|'3^¥dÎfæêQ…¨º;ûss Š ‹«å±%I•1âu‘ ¥¡dMF¨ípÆl[ùÙÂN“mÞ`ÑUÖé\_Z±ÖàË¿,c¾¼ØïsJ}9Ó³ðH×|…GƒýdR(Ã8ˆoqÕ=5Æ6ĵlÇb, ß¹Ó'²åì+ηڙÿ° ¡#ÄqtÈ기 Pß÷øÕˆuµq;Æä<¨(ÿƆÞ_̧d/FЫ?””²‰ φ^ìs‰daœþ!œ’­Õ*¶âýâ°;î„PpY¡%×hÿ¾ú~£/ïYqüÁ„#ŠP%rÒ¦PŽ!WjÈ7ä£<¶9Ú$‹Š’ï ½ÔÞ\ZW+©­7u|.ü qÕ™’’–\–¬—¤¼“M~Íò‹@ÀøD%ù"vÉþoaê‹Ö«ƒÆÊ´”i¾–Äâc8RÓ‰Ø3 æÓCÛÎ.ÆSçÎÀ³°ô‰ ¼ñàbËÝËR‡ß6½šëœá›`¡ð·nm1QNwXޕɹ[Qq;Ô&ŸÁLJÃðq>Ì(èÛ™UIˆÔIÎè]5Ékl4¤±0+óU&ý]–a ø©]# ùü?í† ˜ì}šäõ¶íô óÇvðËa '§Óµñ‰ÑAÊÔ÷ôl ‰ü\»†a†IÇ3íhË÷ F˜®Çšag±‚@梉Ÿq‘€† ›3 !»s|Kç™›TŽÎ°ümªd®g•¤1‚w2ÞýáFBý£VLdz‰zpùÇ…6ãù馿ܒ?Dèm×P‘¨ ýŽC© Éš¸èØ”ÄT\ À5^¹ÜÖ¢”UØk¼)ÛV+Ç—½üÆ^¢õ‰æŽ³Ðk‹âkô·Y~CX×}¸Û®‰D£Kå׋IåBÌtS,ÚÄâË þ•_o‡´ U©Ïîc‡#½[¢†ÍÖÖÛ°§–´ø9ðç{4<Þù£ˆêØ“ñ­imYD(æÓU„v†ž>nr'9_æŒçà9çÁø¯Îµ<¿.Å•°–Ëûê®shUç`!«fþï^=Iö꿈ðå§Y·r8;ã¹XF4ë\<—ˆ9ò›üøƒ7a‰yØSªá`Ô5üöǾ®X€YÌìxAØU`aŒ”,KÒʽp¬Eð9Ù—D¶˜é-9É¥úOY¸ñmïp`>ª¨;U]šžœ©ËÈH•hÕY©(… kP¶wX,Wöv/ÝvHé)‰ JóEï±û¼.áG´Þ+%Ù3‹}%w'?“UºÖ I¹¿µÐ«‹Óгï²àÊÀC{^oÕW-½£/X`çŠß—à{6Q¡ÎÙÈ»2úÝI1žY:”š’Í‚žÿ‚«¯*kûºÍ S»’eQÑe\Hú&ÄÚfÜ·•¿uAÛâØôxL#.fJÀ—“DÛøX~&wOdDÍF/yß_3|û°!1Øc”óbúÞÚÂÒ¦z©hþ^Ë ÔÈÞ~;>ðØ±ø“ÏŸWwØø­o°6ý§«Ö<† NÕdÇ¡ãȳ:¸]U“ZßñUÃISOÿ'×Û¡Yð'ÍuÁ¾Äª¸àùØaËòË;%Ý­q÷åµ^eªúè‹î }Œ>A½ÅwXü“µ‹ƒÑ×°=Á‰+E@ÀºøCÀ5´ôl#ñ[¯Ä‡o1sA†¤jÔMŒåˆ>·÷Úñ~%Ó¯-È x¸ðÿç€ó KJJFì/bÿ[ÿðJMp±Ö ­^.iòS+°tНÔXÊšš]¨ ÂyïAÅí¬Š¤œõ6Td¯×¦®±©ª§†]iöm72à‡?µzx'ÿ#‡ ò*s JŒùÄ~×á=s§Ú?4V•œ¾VO„bË݃…ŽÃB<ÇFCÏ ÈÌçi*Q'Ë·åÚ›V¤ýCƧ§y¦’Ò²®Çùó òñl éímoëí n÷¶•’Œéä•ɱ—”8ÆM-çU¼œƒðp&-2#=žÈÙäÜXÂYª63ÙkSR—ÙÖ•yÏ&8d|fƒf‰-ähúDfUV¾.O—›2Qjj|J ž€'ˆùx’iÕWÆüG ê—¨ ÓÛÚffŽfèX ™zó÷xrµ¢ ¥9¡ä¤ ¹í„ÆÌ¤ Ì\-Ñ%P+þù ÕW‹XÛó†sVÚ$ø;,†{½BëÞߟs<ȬEFv‚³ûXH4ùÝ?Œ}þŠ^™’ãÖ̜̠©4tÿñplŸôÎÃ’ð«Aæ]h'òŒ”íaEçFž”É,û“ö²Yàt3œ—\NðD±º¼”}e¬5VO9]½ÇÆ:P÷ªÁ¹„T:GçkÊKêªÈIÄvV*ÝFŽúiÔ6-ªe~S«MV©Ið[°­;ô‡ºÊT†4:uVc ž¤´ë ¹²¸77‡øÛ[%®+˜îl“¶TyržÅŸ`{žÊ¬Ê.DÅN¨¹¬xÐ& Ì™ŒmÕQþIÜDƒ+k‡£l*é8ÿSyW]m;13ðÖ+è…,!tÙÌof!‹v€\ ¬tÃj!ñ‹8™ÌãØ©€³§ÎÊ:Û´>~ó–€ÏÂor·†3¶ØD«¦ÉêÔ$0û0ÞB®u·m÷òݺ?fZNŒçsÂ[N0ñ{¢£<áø[dës’›ÃrK[­L‰HL"Vÿˆê2¸H!žùÕ—Î3íÆs%#ÖÂ:•L¨+8 yW3÷Ž!ވȄÞH`p>ØE1Ź…¹y9%–ÂrÄZJcŽK‡9ư26Þ™€g‹¿h\€©B^œ’ŽØ”’1KÏây6vûË{'o ûNÿZ{ Ž‹ ’øûÇË×±MtËÕŽÆQ/jWÕ–ÅɉåóRí=zxM7QE‹Øh~Ɉó<ÏßüÊNÁœu@O}s™7qŸ´Õ"öêiÿÛƒ‚æ‡K˜¯#ÚN³¢[-ÕžÇ&o”yìQªJ[C$þ§#Œaˆ•E*ƒ|ø¬"Ò€†9ê3'¥±–„R¿jVô͵Ó5ÍW&?rý`¶óº#³ö¿ªŒ!ÿŽÉL0¿ oNýB{Ço~Ÿq[ƒñò­ó÷ÌwÂv`À³B¨³aÖUÒ¢gØw"–Ñ ƒóÄyëÒ>áÓA$àÇ|!$V ŸƒºDvøýþû÷é]}INOäÜÑ6ÖÝËË=:²ì„ŸÄ»5¼< ±QŠ ƒ—ƒžÀ ó3Ìx¹ó/XÐ"••†å­È·ÉM#üWZ‚&XDæt¾!@ÁNª]1ëáÑkÜðh„X¼þ) sŒúÓk¾ÀthL–&\Òs¿þ æœ`q*>Íݨ?€cû䈣ʄ’šTiB[êô \*Ì/*(Ï«$R r_9S#LðQd܆—Ð^Xag¡«†šÍƒzühâ6NÙ}OÛâkµNhvl‚×ð(àHRìd[ŒÏ` <àö©”…"B®–!/vö7[AÒgûo½‡¦ß”ˆîüÐÞÕu}ò“u‰€™òî–k»üä&û¿sËz<>BÙS§.¶z®9–âEl· f9l0‡¢õì¶ß®ž|Tz¢ëc[C5&@}ð_‚˜OJµHØ¢á`ºé¦å‹+¿Þÿ("Ö/;<¿ñŽ3ž†ÇÞy§ÍùMo<å*<+‚dgÊ5 cj™²2²dÚ„"³CužÙ¤Õgé5úL]vZf|–±»£/“áeËNœµimBDž¯<´‘ÀÊÿŽàÖhòžçÑSg:;ûFˆÁz7ѤºÏ?osi>Ñl³~™$Rówùeœ’¹’^˜‰"_|ðÞMx„ˆÿyº¿]cïl?;Û¯suñ* ëÞ"Á37Ø…°o~¹Fß»nz(Um¿ÒsaJ ê(·TËË–ncƒ8®,!21EœdHQã~û£û¥ÆÆžÆ^qusYaOkfDêaoìÄÝÇtmx«¿\‘…ÂQ°QÑàÝq ¢ÎóG­,8<ç~ÛC$äÉšÚ¶s={·ùÆEI m¸ñ¯ÇÀ>ðíü›Ü°a1o 1;úÕ R%ëR“ ì„pźƒÛ"õ÷]ºÐEx"ZhYrvMÿÆ¿¿»±M̾…%¶/|(é;ÓH+~núØÔkiø¸‹ýý:°\¨¯â†ÚšjOŸùæi?ŒCÀ¡§ŠÇÇxÜöîr¹ÂÊ™K–¨ZÏ»+"< aIÒùž8/EÔ?ÛxYÛþÃÁGrmue¹=9fTœS–o*6Ö¡j¶Aa–Ç&kÃã$Šmj@DZ®Xß—[b:U^Ÿ[‚*Ù6U]DxLlDB^J…BR럛jðI׉eµéŠ®¸vu©±rU\D 1y0KÚ—eÌêŽ×§‹ÃcRt>Ù¬{„*@^ÓT[VÜR+m<]TÔÙT˜)Ö{èRUÁÉ1:-Jdƒk¢››ëêN”ëŠSLÕéŒê¬žÂ|q³º(Ý$o;R™ÜˆØ¦ÚÚævUù<©gž:/°jDº´YsÚ7^ áCëJkþ}4mïÓ>m‰á ku$¢¤¨ø²½JFø!½‰ },$¢ö<‡ý"{LØÍÿ1öÙbÛ~Ë0ÅÃbGXxs’ÈûÞÆ{ãü§è{Ëw`Ï‘ÐÃQ­Gsho~2HDÞ²~s¦”i“ýƒ}Ö’þ'(XúRØŠ]8ÐXobMÈUú’¾XkØÃþ›E ‡·ž}ŸvPÕð>eàUI·ɸ¶|{{”Ø¿FQÿ÷¥ endstream endobj 1399 0 obj <>stream 2021-05-15T09:52:03-07:00 2021-05-15T09:52:03-07:00 groff version 1.22.4 Untitled endstream endobj 2 0 obj <>endobj xref 0 1400 0000000000 65535 f 0000522407 00000 n 0000577844 00000 n 0000520085 00000 n 0000474027 00000 n 0000000182 00000 n 0000002529 00000 n 0000522474 00000 n 0000546939 00000 n 0000568954 00000 n 0000546519 00000 n 0000563884 00000 n 0000545872 00000 n 0000554655 00000 n 0000522515 00000 n 0000522545 00000 n 0000474187 00000 n 0000002549 00000 n 0000005311 00000 n 0000545268 00000 n 0000547422 00000 n 0000522597 00000 n 0000522627 00000 n 0000474349 00000 n 0000005332 00000 n 0000007956 00000 n 0000522690 00000 n 0000522720 00000 n 0000474511 00000 n 0000007977 00000 n 0000010966 00000 n 0000522761 00000 n 0000522791 00000 n 0000474673 00000 n 0000010987 00000 n 0000014235 00000 n 0000522823 00000 n 0000522853 00000 n 0000474835 00000 n 0000014256 00000 n 0000017554 00000 n 0000522885 00000 n 0000522915 00000 n 0000474997 00000 n 0000017575 00000 n 0000020584 00000 n 0000522958 00000 n 0000522988 00000 n 0000475159 00000 n 0000020605 00000 n 0000023189 00000 n 0000523020 00000 n 0000523050 00000 n 0000475321 00000 n 0000023210 00000 n 0000025150 00000 n 0000523091 00000 n 0000523121 00000 n 0000475483 00000 n 0000025171 00000 n 0000027307 00000 n 0000523184 00000 n 0000523214 00000 n 0000475645 00000 n 0000027328 00000 n 0000029691 00000 n 0000523277 00000 n 0000523307 00000 n 0000475807 00000 n 0000029712 00000 n 0000031490 00000 n 0000523370 00000 n 0000523400 00000 n 0000475969 00000 n 0000031511 00000 n 0000034021 00000 n 0000523463 00000 n 0000523493 00000 n 0000476131 00000 n 0000034042 00000 n 0000036656 00000 n 0000523545 00000 n 0000523575 00000 n 0000476293 00000 n 0000036677 00000 n 0000039260 00000 n 0000523627 00000 n 0000523657 00000 n 0000476455 00000 n 0000039281 00000 n 0000041665 00000 n 0000523709 00000 n 0000523739 00000 n 0000476617 00000 n 0000041686 00000 n 0000044041 00000 n 0000523791 00000 n 0000523821 00000 n 0000476779 00000 n 0000044062 00000 n 0000045590 00000 n 0000523884 00000 n 0000523915 00000 n 0000476943 00000 n 0000045612 00000 n 0000047326 00000 n 0000523959 00000 n 0000523990 00000 n 0000477109 00000 n 0000047348 00000 n 0000049590 00000 n 0000524034 00000 n 0000524065 00000 n 0000477275 00000 n 0000049612 00000 n 0000051846 00000 n 0000524109 00000 n 0000524140 00000 n 0000477441 00000 n 0000051868 00000 n 0000052688 00000 n 0000524204 00000 n 0000524235 00000 n 0000477607 00000 n 0000052709 00000 n 0000055156 00000 n 0000524279 00000 n 0000524310 00000 n 0000477773 00000 n 0000055178 00000 n 0000057841 00000 n 0000524365 00000 n 0000524396 00000 n 0000477939 00000 n 0000057863 00000 n 0000060518 00000 n 0000524451 00000 n 0000524482 00000 n 0000478105 00000 n 0000060540 00000 n 0000062944 00000 n 0000524535 00000 n 0000524566 00000 n 0000478271 00000 n 0000062966 00000 n 0000063964 00000 n 0000524630 00000 n 0000524661 00000 n 0000478437 00000 n 0000063985 00000 n 0000065649 00000 n 0000524714 00000 n 0000524745 00000 n 0000478603 00000 n 0000065671 00000 n 0000067139 00000 n 0000524809 00000 n 0000524840 00000 n 0000478769 00000 n 0000067161 00000 n 0000068535 00000 n 0000524893 00000 n 0000524924 00000 n 0000478935 00000 n 0000068557 00000 n 0000069923 00000 n 0000524957 00000 n 0000524988 00000 n 0000479101 00000 n 0000069945 00000 n 0000071468 00000 n 0000525041 00000 n 0000525072 00000 n 0000479267 00000 n 0000071490 00000 n 0000073716 00000 n 0000525114 00000 n 0000525145 00000 n 0000479433 00000 n 0000073738 00000 n 0000075968 00000 n 0000525209 00000 n 0000525240 00000 n 0000479599 00000 n 0000075990 00000 n 0000078034 00000 n 0000525284 00000 n 0000525315 00000 n 0000479765 00000 n 0000078056 00000 n 0000080573 00000 n 0000525379 00000 n 0000525410 00000 n 0000479931 00000 n 0000080595 00000 n 0000082981 00000 n 0000525474 00000 n 0000525505 00000 n 0000480097 00000 n 0000083003 00000 n 0000085252 00000 n 0000525569 00000 n 0000525600 00000 n 0000480263 00000 n 0000085274 00000 n 0000087177 00000 n 0000525653 00000 n 0000525684 00000 n 0000480429 00000 n 0000087199 00000 n 0000088670 00000 n 0000525737 00000 n 0000525768 00000 n 0000480595 00000 n 0000088692 00000 n 0000090372 00000 n 0000525821 00000 n 0000525852 00000 n 0000480761 00000 n 0000090394 00000 n 0000092287 00000 n 0000525916 00000 n 0000525947 00000 n 0000480927 00000 n 0000092309 00000 n 0000094341 00000 n 0000526000 00000 n 0000526031 00000 n 0000481093 00000 n 0000094363 00000 n 0000096239 00000 n 0000526084 00000 n 0000526115 00000 n 0000481259 00000 n 0000096261 00000 n 0000098725 00000 n 0000526168 00000 n 0000526199 00000 n 0000481425 00000 n 0000098747 00000 n 0000100917 00000 n 0000526243 00000 n 0000526274 00000 n 0000481591 00000 n 0000100939 00000 n 0000103255 00000 n 0000526327 00000 n 0000526358 00000 n 0000481757 00000 n 0000103277 00000 n 0000104458 00000 n 0000526411 00000 n 0000526442 00000 n 0000481923 00000 n 0000104480 00000 n 0000105303 00000 n 0000526486 00000 n 0000526517 00000 n 0000482089 00000 n 0000105324 00000 n 0000106266 00000 n 0000526561 00000 n 0000526592 00000 n 0000482255 00000 n 0000106287 00000 n 0000108225 00000 n 0000526645 00000 n 0000526676 00000 n 0000482421 00000 n 0000108247 00000 n 0000109906 00000 n 0000526729 00000 n 0000526760 00000 n 0000482587 00000 n 0000109928 00000 n 0000111827 00000 n 0000526813 00000 n 0000526844 00000 n 0000482753 00000 n 0000111849 00000 n 0000113232 00000 n 0000526897 00000 n 0000526928 00000 n 0000482919 00000 n 0000113254 00000 n 0000115419 00000 n 0000526981 00000 n 0000527012 00000 n 0000483085 00000 n 0000115441 00000 n 0000117862 00000 n 0000527056 00000 n 0000527087 00000 n 0000483251 00000 n 0000117884 00000 n 0000119110 00000 n 0000527140 00000 n 0000527171 00000 n 0000483417 00000 n 0000119132 00000 n 0000120921 00000 n 0000527224 00000 n 0000527255 00000 n 0000483583 00000 n 0000120943 00000 n 0000122285 00000 n 0000527319 00000 n 0000527350 00000 n 0000483749 00000 n 0000122307 00000 n 0000123844 00000 n 0000527403 00000 n 0000527434 00000 n 0000483915 00000 n 0000123866 00000 n 0000125237 00000 n 0000527487 00000 n 0000527518 00000 n 0000484081 00000 n 0000125259 00000 n 0000127643 00000 n 0000527571 00000 n 0000527602 00000 n 0000484247 00000 n 0000127665 00000 n 0000129130 00000 n 0000527655 00000 n 0000527686 00000 n 0000484413 00000 n 0000129152 00000 n 0000131260 00000 n 0000527739 00000 n 0000527770 00000 n 0000484579 00000 n 0000131282 00000 n 0000132817 00000 n 0000527823 00000 n 0000527854 00000 n 0000484745 00000 n 0000132839 00000 n 0000134154 00000 n 0000527907 00000 n 0000527938 00000 n 0000484911 00000 n 0000134176 00000 n 0000136265 00000 n 0000527991 00000 n 0000528022 00000 n 0000485077 00000 n 0000136287 00000 n 0000138263 00000 n 0000528075 00000 n 0000528106 00000 n 0000485243 00000 n 0000138285 00000 n 0000140043 00000 n 0000528159 00000 n 0000528190 00000 n 0000485409 00000 n 0000140065 00000 n 0000141406 00000 n 0000528243 00000 n 0000528274 00000 n 0000485575 00000 n 0000141428 00000 n 0000143331 00000 n 0000528338 00000 n 0000528369 00000 n 0000485741 00000 n 0000143353 00000 n 0000145093 00000 n 0000528422 00000 n 0000528453 00000 n 0000485907 00000 n 0000145115 00000 n 0000146330 00000 n 0000528506 00000 n 0000528537 00000 n 0000486073 00000 n 0000146352 00000 n 0000148205 00000 n 0000528590 00000 n 0000528621 00000 n 0000486239 00000 n 0000148227 00000 n 0000150227 00000 n 0000528674 00000 n 0000528705 00000 n 0000486405 00000 n 0000150249 00000 n 0000152241 00000 n 0000528769 00000 n 0000528800 00000 n 0000486571 00000 n 0000152263 00000 n 0000154128 00000 n 0000528853 00000 n 0000528884 00000 n 0000486737 00000 n 0000154150 00000 n 0000156148 00000 n 0000528937 00000 n 0000528968 00000 n 0000486903 00000 n 0000156170 00000 n 0000157991 00000 n 0000529021 00000 n 0000529052 00000 n 0000487069 00000 n 0000158013 00000 n 0000159824 00000 n 0000529105 00000 n 0000529136 00000 n 0000487235 00000 n 0000159846 00000 n 0000162106 00000 n 0000529189 00000 n 0000529220 00000 n 0000487401 00000 n 0000162128 00000 n 0000163657 00000 n 0000529273 00000 n 0000529304 00000 n 0000487567 00000 n 0000163679 00000 n 0000164840 00000 n 0000529357 00000 n 0000529388 00000 n 0000487733 00000 n 0000164862 00000 n 0000165915 00000 n 0000529421 00000 n 0000529452 00000 n 0000487899 00000 n 0000165936 00000 n 0000167773 00000 n 0000529485 00000 n 0000529516 00000 n 0000488065 00000 n 0000167795 00000 n 0000168434 00000 n 0000529569 00000 n 0000529600 00000 n 0000488231 00000 n 0000168455 00000 n 0000169301 00000 n 0000529653 00000 n 0000529684 00000 n 0000488397 00000 n 0000169322 00000 n 0000170087 00000 n 0000529728 00000 n 0000529759 00000 n 0000488563 00000 n 0000170108 00000 n 0000172262 00000 n 0000529812 00000 n 0000529843 00000 n 0000488729 00000 n 0000172284 00000 n 0000173801 00000 n 0000529896 00000 n 0000529927 00000 n 0000488895 00000 n 0000173823 00000 n 0000176051 00000 n 0000529980 00000 n 0000530011 00000 n 0000489061 00000 n 0000176073 00000 n 0000176489 00000 n 0000530064 00000 n 0000530095 00000 n 0000489227 00000 n 0000176510 00000 n 0000177286 00000 n 0000530139 00000 n 0000530170 00000 n 0000489393 00000 n 0000177307 00000 n 0000178069 00000 n 0000530214 00000 n 0000530245 00000 n 0000489559 00000 n 0000178090 00000 n 0000180362 00000 n 0000530289 00000 n 0000530320 00000 n 0000489725 00000 n 0000180384 00000 n 0000182089 00000 n 0000530373 00000 n 0000530404 00000 n 0000489891 00000 n 0000182111 00000 n 0000184237 00000 n 0000530457 00000 n 0000530488 00000 n 0000490057 00000 n 0000184259 00000 n 0000186680 00000 n 0000530541 00000 n 0000530572 00000 n 0000490223 00000 n 0000186702 00000 n 0000187410 00000 n 0000530625 00000 n 0000530656 00000 n 0000490389 00000 n 0000187431 00000 n 0000188386 00000 n 0000530700 00000 n 0000530731 00000 n 0000490555 00000 n 0000188407 00000 n 0000189748 00000 n 0000530764 00000 n 0000530795 00000 n 0000490721 00000 n 0000189770 00000 n 0000192374 00000 n 0000530848 00000 n 0000530879 00000 n 0000490887 00000 n 0000192396 00000 n 0000194107 00000 n 0000530923 00000 n 0000530954 00000 n 0000491053 00000 n 0000194129 00000 n 0000195887 00000 n 0000531007 00000 n 0000531038 00000 n 0000491219 00000 n 0000195909 00000 n 0000197520 00000 n 0000531091 00000 n 0000531122 00000 n 0000491385 00000 n 0000197542 00000 n 0000199657 00000 n 0000531175 00000 n 0000531206 00000 n 0000491551 00000 n 0000199679 00000 n 0000201832 00000 n 0000531259 00000 n 0000531290 00000 n 0000491717 00000 n 0000201854 00000 n 0000203433 00000 n 0000531343 00000 n 0000531374 00000 n 0000491883 00000 n 0000203455 00000 n 0000204700 00000 n 0000531427 00000 n 0000531458 00000 n 0000492049 00000 n 0000204722 00000 n 0000205798 00000 n 0000531511 00000 n 0000531542 00000 n 0000492215 00000 n 0000205820 00000 n 0000206703 00000 n 0000531586 00000 n 0000531617 00000 n 0000492381 00000 n 0000206724 00000 n 0000207652 00000 n 0000531661 00000 n 0000531692 00000 n 0000492547 00000 n 0000207673 00000 n 0000209077 00000 n 0000531736 00000 n 0000531767 00000 n 0000492713 00000 n 0000209099 00000 n 0000210744 00000 n 0000531820 00000 n 0000531851 00000 n 0000492879 00000 n 0000210766 00000 n 0000212691 00000 n 0000531904 00000 n 0000531935 00000 n 0000493045 00000 n 0000212713 00000 n 0000214190 00000 n 0000531988 00000 n 0000532019 00000 n 0000493211 00000 n 0000214212 00000 n 0000215873 00000 n 0000532072 00000 n 0000532103 00000 n 0000493377 00000 n 0000215895 00000 n 0000218079 00000 n 0000532156 00000 n 0000532187 00000 n 0000493543 00000 n 0000218101 00000 n 0000220582 00000 n 0000532240 00000 n 0000532271 00000 n 0000493709 00000 n 0000220604 00000 n 0000222120 00000 n 0000532324 00000 n 0000532355 00000 n 0000493875 00000 n 0000222142 00000 n 0000224054 00000 n 0000532419 00000 n 0000532450 00000 n 0000494041 00000 n 0000224076 00000 n 0000226027 00000 n 0000532503 00000 n 0000532534 00000 n 0000494207 00000 n 0000226049 00000 n 0000227796 00000 n 0000532587 00000 n 0000532618 00000 n 0000494373 00000 n 0000227818 00000 n 0000229973 00000 n 0000532671 00000 n 0000532702 00000 n 0000494539 00000 n 0000229995 00000 n 0000232173 00000 n 0000532755 00000 n 0000532786 00000 n 0000494705 00000 n 0000232195 00000 n 0000233674 00000 n 0000532839 00000 n 0000532870 00000 n 0000494871 00000 n 0000233696 00000 n 0000234935 00000 n 0000532923 00000 n 0000532954 00000 n 0000495037 00000 n 0000234957 00000 n 0000236600 00000 n 0000533007 00000 n 0000533038 00000 n 0000495203 00000 n 0000236622 00000 n 0000238820 00000 n 0000533091 00000 n 0000533122 00000 n 0000495369 00000 n 0000238842 00000 n 0000240904 00000 n 0000533175 00000 n 0000533206 00000 n 0000495535 00000 n 0000240926 00000 n 0000242374 00000 n 0000533259 00000 n 0000533290 00000 n 0000495701 00000 n 0000242396 00000 n 0000244395 00000 n 0000533343 00000 n 0000533374 00000 n 0000495867 00000 n 0000244417 00000 n 0000246186 00000 n 0000533427 00000 n 0000533458 00000 n 0000496033 00000 n 0000246208 00000 n 0000247631 00000 n 0000533511 00000 n 0000533542 00000 n 0000496199 00000 n 0000247653 00000 n 0000249630 00000 n 0000533595 00000 n 0000533626 00000 n 0000496365 00000 n 0000249652 00000 n 0000251462 00000 n 0000533679 00000 n 0000533710 00000 n 0000496531 00000 n 0000251484 00000 n 0000252993 00000 n 0000533763 00000 n 0000533794 00000 n 0000496697 00000 n 0000253015 00000 n 0000255092 00000 n 0000533847 00000 n 0000533878 00000 n 0000496863 00000 n 0000255114 00000 n 0000256907 00000 n 0000533931 00000 n 0000533962 00000 n 0000497029 00000 n 0000256929 00000 n 0000258427 00000 n 0000534015 00000 n 0000534046 00000 n 0000497195 00000 n 0000258449 00000 n 0000260499 00000 n 0000534099 00000 n 0000534130 00000 n 0000497361 00000 n 0000260521 00000 n 0000262428 00000 n 0000534183 00000 n 0000534214 00000 n 0000497527 00000 n 0000262450 00000 n 0000264017 00000 n 0000534267 00000 n 0000534298 00000 n 0000497693 00000 n 0000264039 00000 n 0000266089 00000 n 0000534351 00000 n 0000534382 00000 n 0000497859 00000 n 0000266111 00000 n 0000267345 00000 n 0000534435 00000 n 0000534466 00000 n 0000498025 00000 n 0000267367 00000 n 0000268527 00000 n 0000534519 00000 n 0000534550 00000 n 0000498191 00000 n 0000268549 00000 n 0000269343 00000 n 0000534603 00000 n 0000534634 00000 n 0000498357 00000 n 0000269364 00000 n 0000270087 00000 n 0000534687 00000 n 0000534718 00000 n 0000498523 00000 n 0000270108 00000 n 0000271498 00000 n 0000534771 00000 n 0000534802 00000 n 0000498689 00000 n 0000271520 00000 n 0000272921 00000 n 0000534855 00000 n 0000534886 00000 n 0000498855 00000 n 0000272943 00000 n 0000274761 00000 n 0000534939 00000 n 0000534970 00000 n 0000499021 00000 n 0000274783 00000 n 0000277004 00000 n 0000535023 00000 n 0000535054 00000 n 0000499187 00000 n 0000277026 00000 n 0000278746 00000 n 0000535107 00000 n 0000535138 00000 n 0000499353 00000 n 0000278768 00000 n 0000279515 00000 n 0000535191 00000 n 0000535222 00000 n 0000499519 00000 n 0000279536 00000 n 0000280390 00000 n 0000535275 00000 n 0000535306 00000 n 0000499685 00000 n 0000280411 00000 n 0000281356 00000 n 0000535350 00000 n 0000535381 00000 n 0000499851 00000 n 0000281377 00000 n 0000281987 00000 n 0000535425 00000 n 0000535456 00000 n 0000500017 00000 n 0000282008 00000 n 0000283087 00000 n 0000535500 00000 n 0000535531 00000 n 0000500183 00000 n 0000283109 00000 n 0000285201 00000 n 0000535584 00000 n 0000535615 00000 n 0000500349 00000 n 0000285223 00000 n 0000287320 00000 n 0000535668 00000 n 0000535699 00000 n 0000500515 00000 n 0000287342 00000 n 0000289386 00000 n 0000535752 00000 n 0000535783 00000 n 0000500681 00000 n 0000289408 00000 n 0000291356 00000 n 0000535836 00000 n 0000535867 00000 n 0000500847 00000 n 0000291378 00000 n 0000293609 00000 n 0000535920 00000 n 0000535951 00000 n 0000501013 00000 n 0000293631 00000 n 0000294859 00000 n 0000536004 00000 n 0000536035 00000 n 0000501179 00000 n 0000294881 00000 n 0000295793 00000 n 0000536088 00000 n 0000536119 00000 n 0000501345 00000 n 0000295814 00000 n 0000298591 00000 n 0000536163 00000 n 0000536194 00000 n 0000501511 00000 n 0000298613 00000 n 0000301104 00000 n 0000536236 00000 n 0000536267 00000 n 0000501677 00000 n 0000301126 00000 n 0000303067 00000 n 0000536311 00000 n 0000536342 00000 n 0000501843 00000 n 0000303089 00000 n 0000305248 00000 n 0000536395 00000 n 0000536426 00000 n 0000502009 00000 n 0000305270 00000 n 0000307052 00000 n 0000536479 00000 n 0000536510 00000 n 0000502175 00000 n 0000307074 00000 n 0000307806 00000 n 0000536563 00000 n 0000536594 00000 n 0000502341 00000 n 0000307827 00000 n 0000309041 00000 n 0000536647 00000 n 0000536678 00000 n 0000502507 00000 n 0000309063 00000 n 0000309802 00000 n 0000536731 00000 n 0000536762 00000 n 0000502673 00000 n 0000309823 00000 n 0000310766 00000 n 0000536815 00000 n 0000536846 00000 n 0000502839 00000 n 0000310787 00000 n 0000312856 00000 n 0000536899 00000 n 0000536930 00000 n 0000503005 00000 n 0000312878 00000 n 0000314337 00000 n 0000536983 00000 n 0000537014 00000 n 0000503171 00000 n 0000314359 00000 n 0000316029 00000 n 0000537067 00000 n 0000537098 00000 n 0000503337 00000 n 0000316051 00000 n 0000318487 00000 n 0000537151 00000 n 0000537182 00000 n 0000503503 00000 n 0000318509 00000 n 0000320116 00000 n 0000537235 00000 n 0000537266 00000 n 0000503669 00000 n 0000320138 00000 n 0000322306 00000 n 0000537319 00000 n 0000537350 00000 n 0000503835 00000 n 0000322328 00000 n 0000324088 00000 n 0000537403 00000 n 0000537434 00000 n 0000504001 00000 n 0000324110 00000 n 0000326263 00000 n 0000537487 00000 n 0000537518 00000 n 0000504167 00000 n 0000326285 00000 n 0000328803 00000 n 0000537571 00000 n 0000537602 00000 n 0000504333 00000 n 0000328825 00000 n 0000330955 00000 n 0000537646 00000 n 0000537677 00000 n 0000504499 00000 n 0000330977 00000 n 0000332661 00000 n 0000537730 00000 n 0000537761 00000 n 0000504665 00000 n 0000332683 00000 n 0000334715 00000 n 0000537814 00000 n 0000537845 00000 n 0000504831 00000 n 0000334737 00000 n 0000336995 00000 n 0000537898 00000 n 0000537929 00000 n 0000504997 00000 n 0000337017 00000 n 0000338921 00000 n 0000537982 00000 n 0000538013 00000 n 0000505163 00000 n 0000338943 00000 n 0000340631 00000 n 0000538066 00000 n 0000538097 00000 n 0000505329 00000 n 0000340653 00000 n 0000342786 00000 n 0000538150 00000 n 0000538181 00000 n 0000505495 00000 n 0000342808 00000 n 0000344670 00000 n 0000538234 00000 n 0000538265 00000 n 0000505661 00000 n 0000344692 00000 n 0000346936 00000 n 0000538329 00000 n 0000538360 00000 n 0000505827 00000 n 0000346958 00000 n 0000348833 00000 n 0000538413 00000 n 0000538444 00000 n 0000505993 00000 n 0000348855 00000 n 0000351226 00000 n 0000538497 00000 n 0000538528 00000 n 0000506159 00000 n 0000351248 00000 n 0000352126 00000 n 0000538581 00000 n 0000538612 00000 n 0000506325 00000 n 0000352147 00000 n 0000353435 00000 n 0000538656 00000 n 0000538687 00000 n 0000506491 00000 n 0000353457 00000 n 0000355553 00000 n 0000538740 00000 n 0000538771 00000 n 0000506657 00000 n 0000355575 00000 n 0000357448 00000 n 0000538824 00000 n 0000538856 00000 n 0000506825 00000 n 0000357471 00000 n 0000359538 00000 n 0000538910 00000 n 0000538942 00000 n 0000506995 00000 n 0000359561 00000 n 0000361111 00000 n 0000538996 00000 n 0000539028 00000 n 0000507165 00000 n 0000361134 00000 n 0000362480 00000 n 0000539082 00000 n 0000539114 00000 n 0000507335 00000 n 0000362503 00000 n 0000364404 00000 n 0000539168 00000 n 0000539200 00000 n 0000507505 00000 n 0000364427 00000 n 0000366504 00000 n 0000539254 00000 n 0000539286 00000 n 0000507675 00000 n 0000366527 00000 n 0000368815 00000 n 0000539340 00000 n 0000539372 00000 n 0000507845 00000 n 0000368838 00000 n 0000369607 00000 n 0000539426 00000 n 0000539458 00000 n 0000508015 00000 n 0000369629 00000 n 0000370630 00000 n 0000539512 00000 n 0000539544 00000 n 0000508185 00000 n 0000370652 00000 n 0000372264 00000 n 0000539598 00000 n 0000539630 00000 n 0000508355 00000 n 0000372287 00000 n 0000373510 00000 n 0000539684 00000 n 0000539716 00000 n 0000508525 00000 n 0000373533 00000 n 0000375717 00000 n 0000539770 00000 n 0000539802 00000 n 0000508695 00000 n 0000375740 00000 n 0000377254 00000 n 0000539856 00000 n 0000539888 00000 n 0000508865 00000 n 0000377277 00000 n 0000378124 00000 n 0000539942 00000 n 0000539974 00000 n 0000509035 00000 n 0000378146 00000 n 0000378941 00000 n 0000540019 00000 n 0000540051 00000 n 0000509205 00000 n 0000378963 00000 n 0000381081 00000 n 0000540105 00000 n 0000540137 00000 n 0000509375 00000 n 0000381104 00000 n 0000382711 00000 n 0000540191 00000 n 0000540223 00000 n 0000509545 00000 n 0000382734 00000 n 0000385392 00000 n 0000540277 00000 n 0000540309 00000 n 0000509715 00000 n 0000385415 00000 n 0000386902 00000 n 0000540363 00000 n 0000540395 00000 n 0000509885 00000 n 0000386925 00000 n 0000389446 00000 n 0000540449 00000 n 0000540481 00000 n 0000510055 00000 n 0000389469 00000 n 0000390829 00000 n 0000540535 00000 n 0000540567 00000 n 0000510225 00000 n 0000390852 00000 n 0000392741 00000 n 0000540621 00000 n 0000540653 00000 n 0000510395 00000 n 0000392764 00000 n 0000393575 00000 n 0000540707 00000 n 0000540739 00000 n 0000510565 00000 n 0000393597 00000 n 0000394353 00000 n 0000540793 00000 n 0000540825 00000 n 0000510735 00000 n 0000394375 00000 n 0000395789 00000 n 0000540870 00000 n 0000540902 00000 n 0000510905 00000 n 0000395812 00000 n 0000397573 00000 n 0000540956 00000 n 0000540988 00000 n 0000511075 00000 n 0000397596 00000 n 0000399116 00000 n 0000541042 00000 n 0000541074 00000 n 0000511245 00000 n 0000399139 00000 n 0000400700 00000 n 0000541128 00000 n 0000541160 00000 n 0000511415 00000 n 0000400723 00000 n 0000401423 00000 n 0000541214 00000 n 0000541246 00000 n 0000511585 00000 n 0000401445 00000 n 0000402225 00000 n 0000541291 00000 n 0000541323 00000 n 0000511755 00000 n 0000402247 00000 n 0000403794 00000 n 0000541377 00000 n 0000541409 00000 n 0000511925 00000 n 0000403817 00000 n 0000405609 00000 n 0000541463 00000 n 0000541495 00000 n 0000512095 00000 n 0000405632 00000 n 0000407984 00000 n 0000541549 00000 n 0000541581 00000 n 0000512265 00000 n 0000408007 00000 n 0000410011 00000 n 0000541635 00000 n 0000541667 00000 n 0000512435 00000 n 0000410034 00000 n 0000411430 00000 n 0000541721 00000 n 0000541753 00000 n 0000512605 00000 n 0000411453 00000 n 0000412421 00000 n 0000541798 00000 n 0000541830 00000 n 0000512775 00000 n 0000412443 00000 n 0000413519 00000 n 0000541884 00000 n 0000541916 00000 n 0000512945 00000 n 0000413542 00000 n 0000415208 00000 n 0000541970 00000 n 0000542002 00000 n 0000513115 00000 n 0000415231 00000 n 0000417683 00000 n 0000542056 00000 n 0000542088 00000 n 0000513285 00000 n 0000417706 00000 n 0000419917 00000 n 0000542142 00000 n 0000542174 00000 n 0000513455 00000 n 0000419940 00000 n 0000422121 00000 n 0000542228 00000 n 0000542260 00000 n 0000513625 00000 n 0000422144 00000 n 0000423514 00000 n 0000542314 00000 n 0000542346 00000 n 0000513795 00000 n 0000423537 00000 n 0000425400 00000 n 0000542400 00000 n 0000542432 00000 n 0000513965 00000 n 0000425423 00000 n 0000426762 00000 n 0000542477 00000 n 0000542509 00000 n 0000514135 00000 n 0000426785 00000 n 0000428760 00000 n 0000542563 00000 n 0000542595 00000 n 0000514305 00000 n 0000428783 00000 n 0000429711 00000 n 0000542649 00000 n 0000542681 00000 n 0000514475 00000 n 0000429733 00000 n 0000431935 00000 n 0000542735 00000 n 0000542767 00000 n 0000514645 00000 n 0000431958 00000 n 0000433069 00000 n 0000542821 00000 n 0000542853 00000 n 0000514815 00000 n 0000433092 00000 n 0000434234 00000 n 0000542898 00000 n 0000542930 00000 n 0000514985 00000 n 0000434257 00000 n 0000436007 00000 n 0000542984 00000 n 0000543016 00000 n 0000515155 00000 n 0000436030 00000 n 0000437691 00000 n 0000543070 00000 n 0000543102 00000 n 0000515325 00000 n 0000437714 00000 n 0000438938 00000 n 0000543156 00000 n 0000543188 00000 n 0000515495 00000 n 0000438961 00000 n 0000440463 00000 n 0000543242 00000 n 0000543274 00000 n 0000515665 00000 n 0000440486 00000 n 0000441985 00000 n 0000543328 00000 n 0000543360 00000 n 0000515835 00000 n 0000442008 00000 n 0000444045 00000 n 0000543425 00000 n 0000543457 00000 n 0000516005 00000 n 0000444068 00000 n 0000446239 00000 n 0000543511 00000 n 0000543543 00000 n 0000516175 00000 n 0000446262 00000 n 0000447445 00000 n 0000543597 00000 n 0000543629 00000 n 0000516345 00000 n 0000447468 00000 n 0000449078 00000 n 0000543683 00000 n 0000543715 00000 n 0000516515 00000 n 0000449101 00000 n 0000450571 00000 n 0000543769 00000 n 0000543801 00000 n 0000516685 00000 n 0000450594 00000 n 0000452329 00000 n 0000543855 00000 n 0000543887 00000 n 0000516855 00000 n 0000452352 00000 n 0000454008 00000 n 0000543952 00000 n 0000543984 00000 n 0000517025 00000 n 0000454031 00000 n 0000454938 00000 n 0000544038 00000 n 0000544070 00000 n 0000517195 00000 n 0000454960 00000 n 0000455674 00000 n 0000544115 00000 n 0000544147 00000 n 0000517365 00000 n 0000455696 00000 n 0000455941 00000 n 0000544192 00000 n 0000544224 00000 n 0000517535 00000 n 0000455963 00000 n 0000457316 00000 n 0000544258 00000 n 0000544290 00000 n 0000517705 00000 n 0000457339 00000 n 0000458615 00000 n 0000544324 00000 n 0000544356 00000 n 0000517875 00000 n 0000458638 00000 n 0000459810 00000 n 0000544390 00000 n 0000544422 00000 n 0000518045 00000 n 0000459833 00000 n 0000461016 00000 n 0000544456 00000 n 0000544488 00000 n 0000518215 00000 n 0000461039 00000 n 0000462403 00000 n 0000544522 00000 n 0000544554 00000 n 0000518385 00000 n 0000462426 00000 n 0000463559 00000 n 0000544588 00000 n 0000544620 00000 n 0000518555 00000 n 0000463582 00000 n 0000465010 00000 n 0000544654 00000 n 0000544686 00000 n 0000518725 00000 n 0000465033 00000 n 0000466307 00000 n 0000544720 00000 n 0000544752 00000 n 0000518895 00000 n 0000466330 00000 n 0000467698 00000 n 0000544786 00000 n 0000544818 00000 n 0000519065 00000 n 0000467721 00000 n 0000469109 00000 n 0000544852 00000 n 0000544884 00000 n 0000519235 00000 n 0000469132 00000 n 0000470172 00000 n 0000544918 00000 n 0000544950 00000 n 0000519405 00000 n 0000470194 00000 n 0000471187 00000 n 0000544984 00000 n 0000545016 00000 n 0000519575 00000 n 0000471209 00000 n 0000472312 00000 n 0000545050 00000 n 0000545082 00000 n 0000519745 00000 n 0000472335 00000 n 0000472872 00000 n 0000545116 00000 n 0000545148 00000 n 0000519915 00000 n 0000472894 00000 n 0000474004 00000 n 0000545182 00000 n 0000545214 00000 n 0000548066 00000 n 0000555282 00000 n 0000564216 00000 n 0000569452 00000 n 0000545778 00000 n 0000546404 00000 n 0000576419 00000 n trailer << /Size 1400 /Root 1 0 R /Info 2 0 R /ID [] >> startxref 577998 %%EOF libdwarf-20210528/libdwarf/dwarf_macro5.c0000664000175000017500000014626214004647716015027 00000000000000/* Copyright (C) 2015-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_macro5.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 #define MC_SENTINAL 0xada #define CHECKNULLCONTEXT(m,d,e) \ if (!m || m->mc_sentinel != MC_SENTINAL) { \ if (m) { d = (m)->mc_dbg; } \ _dwarf_error_string(d, e, \ DW_DLE_BAD_MACRO_HEADER_POINTER, \ "DW_DLE_BAD_MACRO_HEADER_POINTER " \ " NULL header or corrupt header"); \ return DW_DLV_ERROR; \ } /* Section 6.3: Macro Information: Each macro unit ends with an entry containing an opcode of 0. */ static const Dwarf_Small dwarf_udata_string_form[] = {DW_FORM_udata,DW_FORM_string}; static const Dwarf_Small dwarf_udata_udata_form[] = {DW_FORM_udata,DW_FORM_udata}; static const Dwarf_Small dwarf_udata_strp_form[] = {DW_FORM_udata,DW_FORM_strp}; static const Dwarf_Small dwarf_udata_strp_sup_form[] = {DW_FORM_udata,DW_FORM_strp_sup}; static const Dwarf_Small dwarf_secoffset_form[] = {DW_FORM_sec_offset}; static const Dwarf_Small dwarf_udata_strx_form[] = {DW_FORM_udata,DW_FORM_strx}; struct Dwarf_Macro_Forms_s dw5formsarray[] = { {0,0,0}, {DW_MACRO_define,2,dwarf_udata_string_form}, {DW_MACRO_undef,2,dwarf_udata_string_form}, {DW_MACRO_start_file,2,dwarf_udata_udata_form}, {DW_MACRO_end_file,0,0}, {DW_MACRO_define_strp,2,dwarf_udata_strp_form}, {DW_MACRO_undef_strp,2,dwarf_udata_strp_form}, {DW_MACRO_import,1,dwarf_secoffset_form}, {DW_MACRO_define_sup,2,dwarf_udata_strp_sup_form}, {DW_MACRO_undef_sup,2,dwarf_udata_strp_sup_form}, {DW_MACRO_import_sup,1,dwarf_secoffset_form}, {DW_MACRO_define_strx,2,dwarf_udata_strx_form}, {DW_MACRO_undef_strx,2,dwarf_udata_strx_form}, }; /* Represents DWARF 5 macro info */ /* .debug_macro predefined, in order by value */ static const struct Dwarf_Macro_OperationsList_s dwarf_default_macro_opslist = { 13, dw5formsarray }; static int _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned *macro_ops_count_out, Dwarf_Unsigned *macro_ops_data_length, char **srcfiles, Dwarf_Signed srcfilescount, const char *comp_dir, const char *comp_name, Dwarf_CU_Context cu_context, Dwarf_Error * error); static int _dwarf_internal_macro_context(Dwarf_Die die, Dwarf_Bool offset_specified, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned *macro_unit_offset_out, Dwarf_Unsigned *macro_ops_count_out, Dwarf_Unsigned *macro_ops_data_length, Dwarf_Error * error); static int is_std_moperator(Dwarf_Small op) { if (op >= 1 && op <= DW_MACRO_undef_strx) { return TRUE; } return FALSE; } static int _dwarf_skim_forms(Dwarf_Debug dbg, Dwarf_Macro_Context mcontext, Dwarf_Small *mdata_start, unsigned formcount, const Dwarf_Small *forms, Dwarf_Small *section_end, Dwarf_Unsigned *forms_length, Dwarf_Error *error) { unsigned i = 0; Dwarf_Small curform = 0 ; Dwarf_Unsigned totallen = 0; Dwarf_Unsigned v = 0; Dwarf_Unsigned ret_value = 0; Dwarf_Unsigned length; Dwarf_Small *mdata = mdata_start; Dwarf_Unsigned leb128_length = 0; for ( ; i < formcount; ++i) { curform = forms[i]; if (mdata >= section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } switch(curform) { default: _dwarf_error(dbg,error, DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE); return DW_DLV_ERROR; case DW_FORM_block1: v = *(Dwarf_Small *) mdata; totallen += v+1; mdata += v+1; break; case DW_FORM_block2: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, mdata, DWARF_HALF_SIZE, error,section_end); v = ret_value + DWARF_HALF_SIZE; totallen += v; mdata += v; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, mdata, DWARF_32BIT_SIZE, error,section_end); v = ret_value + DWARF_32BIT_SIZE; totallen += v; mdata += v; break; case DW_FORM_data1: v = 1; totallen += v; mdata += v; break; case DW_FORM_data2: v = 2; totallen += v; mdata += v; break; case DW_FORM_data4: v = 4; totallen += v; mdata += v; break; case DW_FORM_data8: v = 8; totallen += v; mdata += v; break; case DW_FORM_data16: v = 8; totallen += v; mdata += v; break; case DW_FORM_string: { int res = _dwarf_check_string_valid(dbg, mdata,mdata, section_end, DW_DLE_MACRO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } v = strlen((char *) mdata) + 1; totallen += v; mdata += v; } break; case DW_FORM_block: DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); v = length + leb128_length; totallen += v; break; case DW_FORM_flag: v = 1; totallen += v; mdata += v; break; case DW_FORM_sec_offset: /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */ v = mcontext->mc_offset_size; totallen += v; mdata += v; break; case DW_FORM_sdata: /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += v; break; case DW_FORM_strx: DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += leb128_length;; break; case DW_FORM_strp: v = mcontext->mc_offset_size; mdata += v; totallen += v; break; case DW_FORM_udata: /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += leb128_length; break; } } if (mdata > section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } *forms_length = totallen; return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ static void dump_bytes(Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; unsigned pos = 0; printf("dump %ld bytes, start at 0x%lx\n", len,(unsigned long)start); printf("0x"); for (; cur < end;pos++, cur++) { if (!(pos %4)) { printf(" "); } printf("%02x",*cur); } printf("\n"); } Dwarf_Bool is_defundef(unsigned op) { switch(op){ case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: case DW_MACRO_undef_strp: case DW_MACRO_define_strx: case DW_MACRO_undef_strx: case DW_MACRO_define_sup: case DW_MACRO_undef_sup: return TRUE; } return FALSE; } #endif /* FOR DEBUGGING */ /* On first call (for this macro_context), build_ops_array is FALSE. On second, it is TRUE and we know the count so we allocate and fill in the ops array. */ static int _dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context, Dwarf_Bool build_ops_array, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; Dwarf_Small *section_end = 0; Dwarf_Small *section_base = 0; Dwarf_Unsigned opcount = 0; Dwarf_Unsigned known_ops_count = 0; struct Dwarf_Macro_Operator_s *opsarray = 0; struct Dwarf_Macro_Operator_s *curopsentry = 0; int res = 0; dbg = macro_context->mc_dbg; if (build_ops_array) { known_ops_count = macro_context->mc_macro_ops_count; opsarray = (struct Dwarf_Macro_Operator_s *) calloc(known_ops_count, sizeof(struct Dwarf_Macro_Operator_s)); if (!opsarray) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curopsentry = opsarray; macro_context->mc_ops = opsarray; } section_base = dbg->de_debug_macro.dss_data; section_end = section_base + dbg->de_debug_macro.dss_size; mdata = macro_context->mc_macro_ops; while (mdata < section_end) { Dwarf_Small op = 0; op = *mdata; ++opcount; ++mdata; if (!op) { Dwarf_Unsigned opslen = 0; /* End of ops, this is terminator, count the ending 0 as an operator so dwarfdump can print it. Normally we don't see this, the end operator signals end. */ opslen = mdata - macro_context->mc_macro_ops; macro_context->mc_macro_ops_count = opcount; macro_context->mc_ops_data_length = opslen; macro_context->mc_total_length = opslen + macro_context->mc_macro_header_length; if (build_ops_array) { curopsentry->mo_opcode = op; curopsentry->mo_form = 0; curopsentry->mo_data = 0; } return DW_DLV_OK; } if (is_std_moperator(op)) { struct Dwarf_Macro_Forms_s * ourform = dw5formsarray + op; /* ASSERT: op == ourform->mf_code */ unsigned formcount = ourform->mf_formcount; const Dwarf_Small *forms = ourform->mf_formbytes; Dwarf_Unsigned forms_length = 0; res = _dwarf_skim_forms(dbg,macro_context,mdata, formcount,forms, section_end, &forms_length,error); if ( res != DW_DLV_OK) { return res; } if (build_ops_array) { curopsentry->mo_opcode = op; curopsentry->mo_form = ourform; curopsentry->mo_data = mdata; } mdata += forms_length; } else { /* FIXME Add support for user defined ops. */ _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED); return DW_DLV_ERROR; } if (mdata > section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; } if (build_ops_array) { curopsentry++; } } _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; } int dwarf_get_macro_op(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * op_start_section_offset, Dwarf_Half * macro_operator, Dwarf_Half * forms_count, const Dwarf_Small ** formcode_array, Dwarf_Error *error) { struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Debug dbg = 0; Dwarf_Unsigned op_offset = 0; Dwarf_Half operator = 0; CHECKNULLCONTEXT(macro_context,dbg,error); dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; operator = curop->mo_opcode; if (!operator) { /* For the null byte at the end of an operator list. */ *op_start_section_offset = macro_context->mc_total_length+ macro_context->mc_section_offset -1; *macro_operator = operator; *forms_count = 0; *formcode_array = 0; return DW_DLV_OK; } op_offset = ((curop->mo_data -1) - macro_context->mc_macro_header) + macro_context->mc_section_offset; if (op_offset >= macro_context->mc_section_size) { dwarfstring m; char buf[50]; dwarfstring_constructor_static(&m,buf,sizeof(buf)); dwarfstring_append_printf_u(&m, "DW_DLE_MACRO_OFFSET_BAD: offset 0x%lx", op_offset); dwarfstring_append_printf_u(&m, " >= section size of 0x%lx", macro_context->mc_section_size); _dwarf_error_string(dbg,error,DW_DLE_MACRO_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } *op_start_section_offset = op_offset; *macro_operator = operator; if (curop->mo_form) { *forms_count = curop->mo_form->mf_formcount; *formcode_array = curop->mo_form->mf_formbytes; } else { /* ASSERT: macro_operator == 0 */ *forms_count = 0; *formcode_array = 0; } return DW_DLV_OK; } /* Here a DW_DLV_NO_ENTRY return means the macro operator is not a def/undef operator. */ int dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * index, Dwarf_Unsigned * offset, Dwarf_Half * forms_count, const char ** macro_string, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; int res = 0; Dwarf_Small *startptr = 0; Dwarf_Small *endptr = 0; Dwarf_Half lformscount = 0; struct Dwarf_Macro_Operator_s *curop = 0; unsigned macop = 0; CHECKNULLCONTEXT(macro_context,dbg,error); dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; mdata = curop->mo_data; lformscount = curop->mo_form->mf_formcount; if (lformscount != 2) { /*_dwarf_error(dbg, error,DW_DLE_MACRO_OPCODE_FORM_BAD);*/ return DW_DLV_NO_ENTRY; } switch(macop){ case DW_MACRO_define: case DW_MACRO_undef: { Dwarf_Unsigned linenum = 0; const char * content = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); content = (const char *)mdata; res = _dwarf_check_string_valid(dbg, startptr,mdata, endptr, DW_DLE_MACRO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } *line_number = linenum; *index = 0; *offset = 0; *forms_count = lformscount; *macro_string = content; } return DW_DLV_OK; case DW_MACRO_define_strp: case DW_MACRO_undef_strp: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned stringoffset = 0; Dwarf_Small form1 = curop->mo_form->mf_formbytes[1]; char * localstr = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); READ_UNALIGNED_CK(dbg,stringoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); res = _dwarf_extract_local_debug_str_string_given_offset(dbg, form1, stringoffset, &localstr, error); *index = 0; *line_number = linenum; *offset = stringoffset; *forms_count = lformscount; if (res == DW_DLV_ERROR) { *macro_string = ""; return res; } else if (res == DW_DLV_NO_ENTRY) { *macro_string = ""; } else { *macro_string = (const char *)localstr; } } return DW_DLV_OK; case DW_MACRO_define_strx: case DW_MACRO_undef_strx: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned stringindex = 0; Dwarf_Unsigned offsettostr= 0; int ress = 0; Dwarf_Byte_Ptr mdata_copy = 0; Dwarf_Small form1 = curop->mo_form->mf_formbytes[1]; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); *line_number = linenum; mdata_copy = mdata; DECODE_LEB128_UWORD_CK(mdata_copy,stringindex, dbg, error,endptr); /* mdata_copy is for call below */ *index = stringindex; *forms_count = lformscount; /* Redoes the index-getting. Gets offset. */ ress = _dwarf_extract_string_offset_via_str_offsets(dbg, mdata_copy, endptr, DW_AT_macros, /*arbitrary, unused by called routine. */ form1, macro_context->mc_cu_context, &offsettostr, error); if (ress == DW_DLV_ERROR) { return ress; } if (ress == DW_DLV_OK) { char *localstr = 0; *index = stringindex; *offset = offsettostr; ress = _dwarf_extract_local_debug_str_string_given_offset( dbg, form1, offsettostr, &localstr, error); if (ress == DW_DLV_ERROR) { return ress; } else if (ress == DW_DLV_NO_ENTRY){ *macro_string = "<:No string available>"; } else { *macro_string = (const char *)localstr; /* All is ok. */ } } else { *index = stringindex; *offset = 0; *macro_string = "<.debug_str_offsets not available>"; } } return DW_DLV_OK; case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned supoffset = 0; char *localstring = 0; int resup = 0; Dwarf_Error lerr = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); *line_number = linenum; *index = 0; *offset = supoffset; *forms_count = lformscount; resup = _dwarf_get_string_from_tied(dbg, supoffset, &localstring, &lerr); if (resup != DW_DLV_OK) { if (resup == DW_DLV_ERROR) { int myerrno = dwarf_errno(lerr); if (myerrno == DW_DLE_NO_TIED_FILE_AVAILABLE) { *macro_string = (char *)""; } else { _dwarf_error(dbg,error,myerrno); *macro_string = (char *)""; } dwarf_dealloc(dbg,lerr,DW_DLA_ERROR); } else { *macro_string = ""; } return resup; } *macro_string = (const char *)localstring; /* If NO ENTRY available, return DW_DLV_NO_ENTRY. We suspect this is better than DW_DLV_OK. */ return resup; } default: _dwarf_error(dbg,error,DW_DLE_MACRO_OP_UNHANDLED); return DW_DLV_ERROR; } return DW_DLV_NO_ENTRY; } /* ASSERT: we elsewhere guarantee room to copy into. If trimtarg ==1, trim trailing slash in targ. Caller should not pass in 'src' with leading / */ static void specialcat(char *targ,char *src,int trimtarg) { char *last = 0; while( *targ) { last = targ; targ++; } /* TARG now points at terminating NUL */ /* LAST points at final character in targ. */ if (trimtarg ) { if (last && *last == '/') { /* Truncate. */ *last = 0; targ = last; /* TARG again points at terminating NUL */ } } while (*src) { *targ = *src; targ++; src++; } *targ = 0; } /* If returns NULL caller must handle it. */ static const char * construct_from_dir_and_name(const char *dir, const char *name) { int truelen = 0; char *final = 0; /* Allow for NUL char and added / */ truelen = strlen(dir) + strlen(name) + 1 +1; final = (char *)malloc(truelen); if (!final) { return NULL; } final[0] = 0; specialcat(final,(char *)dir,1); strcat(final,"/"); specialcat(final,(char *)name,0); return final; } /* If returns NULL caller must handle it. */ static const char * construct_at_path_from_parts(Dwarf_Macro_Context mc) { if (mc->mc_file_path) { return mc->mc_file_path; } if (!mc->mc_at_comp_dir || !mc->mc_at_comp_dir[0]) { return mc->mc_at_name; } if (!mc->mc_at_name || !mc->mc_at_name[0]) { return NULL; } if (_dwarf_file_name_is_full_path( (Dwarf_Small *)mc->mc_at_name)) { return mc->mc_at_name; } /* Dwarf_Macro_Context destructor will free this. */ mc->mc_file_path = construct_from_dir_and_name( mc->mc_at_comp_dir,mc->mc_at_name); return mc->mc_file_path; } int dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * name_index_to_line_tab, const char ** src_file_name, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; unsigned macop = 0; struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; CHECKNULLCONTEXT(macro_context,dbg,error); dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; mdata = curop->mo_data; if (macop != DW_MACRO_start_file && macop != DW_MACRO_end_file) { return DW_DLV_NO_ENTRY; } if (macop == DW_MACRO_start_file) { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned srcindex = 0; Dwarf_Signed trueindex = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); DECODE_LEB128_UWORD_CK(mdata,srcindex, dbg, error,endptr); *line_number = linenum; *name_index_to_line_tab = srcindex; /* We deal with DWARF4 GNU extension with .debug_macro version number 4 and DWARF5 .debug_macro version number 5. */ if (macro_context->mc_version_number == DW_MACRO_VERSION5) { trueindex = srcindex; if (trueindex < 0) { *src_file_name = ""; return DW_DLV_OK; } if (trueindex < macro_context->mc_srcfiles_count) { *src_file_name = macro_context->mc_srcfiles[trueindex]; return DW_DLV_OK; } else { *src_file_name = ""; return DW_DLV_OK; } } else { /* All except DWARF5 */ /* Unsigned to signed here. */ trueindex = srcindex; /* Protects against crazy big srcindex, overflow territory. */ if (trueindex < 0 ) { /* Something insane here. */ *src_file_name = ""; return DW_DLV_OK; } /* Protects against crazy big srcindex, overflow territory. */ if (trueindex > (macro_context->mc_srcfiles_count+1)) { /* Something insane here. */ *src_file_name = ""; return DW_DLV_OK; } --trueindex; /* might now be -1 */ if (trueindex > macro_context->mc_srcfiles_count) { *src_file_name = ""; } if (srcindex > 0 && trueindex < macro_context->mc_srcfiles_count) { *src_file_name = macro_context->mc_srcfiles[trueindex]; } else { const char *mcatcomp = construct_at_path_from_parts(macro_context); if (mcatcomp) { *src_file_name = mcatcomp; } else { *src_file_name = ""; } } } } else { /* DW_MACRO_end_file. No operands. */ } return DW_DLV_OK; } /* Target_offset is the offset in a .debug_macro section, of a macro unit header. Returns DW_DLV_NO_ENTRY if the macro operator is not one of the import operators. */ int dwarf_get_macro_import(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * target_offset, Dwarf_Error *error) { Dwarf_Unsigned supoffset = 0; Dwarf_Debug dbg = 0; unsigned macop = 0; struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Small *mdata = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; CHECKNULLCONTEXT(macro_context,dbg,error); startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; mdata = curop->mo_data; if (macop != DW_MACRO_import && macop != DW_MACRO_import_sup) { return DW_DLV_NO_ENTRY; } READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); *target_offset = supoffset; return DW_DLV_OK; } /* */ static int valid_macro_form(Dwarf_Half form) { switch(form) { case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_data16: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_flag: case DW_FORM_sec_offset: case DW_FORM_string: case DW_FORM_strp: case DW_FORM_strx: return TRUE; } return FALSE; } static int validate_opcode(Dwarf_Debug dbg, struct Dwarf_Macro_Forms_s *curform, Dwarf_Error * error) { unsigned i = 0; struct Dwarf_Macro_Forms_s *stdfptr = 0; if (curform->mf_code >= DW_MACRO_lo_user) { /* Nothing to check. user level. */ return DW_DLV_OK; } if (curform->mf_code > DW_MACRO_undef_strx) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD); return DW_DLV_ERROR; } if (!curform->mf_code){ _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD); return DW_DLV_ERROR; } stdfptr = &dwarf_default_macro_opslist.mol_data[curform->mf_code]; if (curform->mf_formcount != stdfptr->mf_formcount) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD); return DW_DLV_ERROR; } for (i = 0; i < curform->mf_formcount; ++i) { if (curform->mf_formbytes[i] != stdfptr->mf_formbytes[1]) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD); return DW_DLV_ERROR; } } return DW_DLV_OK; } static int read_operands_table(Dwarf_Macro_Context macro_context, Dwarf_Small * macro_header, Dwarf_Small * macro_data, Dwarf_Small * section_base, Dwarf_Unsigned section_size, Dwarf_Unsigned *table_size_out, Dwarf_Error *error) { Dwarf_Small* table_data_start = macro_data; Dwarf_Unsigned local_size = 0; Dwarf_Unsigned cur_offset = 0; Dwarf_Small operand_table_count = 0; unsigned i = 0; struct Dwarf_Macro_Forms_s *curformentry = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; CHECKNULLCONTEXT(macro_context,dbg,error); dbg = macro_context->mc_dbg; cur_offset = (1+ macro_data) - macro_header; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; READ_UNALIGNED_CK(dbg,operand_table_count,Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,endptr); macro_data += sizeof(Dwarf_Small); /* Estimating minimum size */ local_size = operand_table_count * 4; cur_offset = (local_size+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } /* first, get size of table. */ table_data_start = macro_data; for (i = 0; i < operand_table_count; ++i) { /* Compiler warning about unused opcode_number variable should be ignored. */ UNUSEDARG Dwarf_Small opcode_number = 0; Dwarf_Unsigned formcount = 0; READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,endptr); macro_data += sizeof(Dwarf_Small); DECODE_LEB128_UWORD_CK(macro_data,formcount, dbg, error, endptr); cur_offset = (formcount+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } /* The 1 ubyte forms follow. Step past them. */ macro_data += formcount; } /* reset for reread. */ macro_data = table_data_start; /* allocate table */ macro_context->mc_opcode_forms = (struct Dwarf_Macro_Forms_s *) calloc(operand_table_count, sizeof(struct Dwarf_Macro_Forms_s)); macro_context->mc_opcode_count = operand_table_count; if (!macro_context->mc_opcode_forms) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curformentry = macro_context->mc_opcode_forms; for (i = 0; i < operand_table_count; ++i,++curformentry) { Dwarf_Small opcode_number = 0; Dwarf_Unsigned formcount = 0; int res = 0; cur_offset = (2 + macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small, macro_data,sizeof(Dwarf_Small), error,endptr); macro_data += sizeof(Dwarf_Small); DECODE_LEB128_UWORD_CK(macro_data,formcount, dbg, error, endptr); curformentry->mf_code = opcode_number; curformentry->mf_formcount = formcount; cur_offset = (formcount+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } curformentry->mf_formbytes = macro_data; macro_data += formcount; if (opcode_number > DW_MACRO_undef_strx ) { Dwarf_Half k = 0; for (k = 0; k < formcount; ++k) { if (!valid_macro_form( curformentry->mf_formbytes[k])) { _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED); return DW_DLV_ERROR; } } } res = validate_opcode(macro_context->mc_dbg, curformentry, error); if (res != DW_DLV_OK) { return res; } } *table_size_out = macro_data - table_data_start; return DW_DLV_OK; } /* This is not the normal srcfiles from dwarf_srcfiles. See translate translate_srcfiles_to_srcfiles2(). It is a list, but the contents were directly malloc, not _dwarf_get_alloc. */ static void dealloc_macro_srcfiles(char ** srcfiles, Dwarf_Signed srcfiles_count) { Dwarf_Signed i = 0; if (!srcfiles || !srcfiles_count) { return; } for (i = 0; i < srcfiles_count; ++i) { if (srcfiles[i]) { free(srcfiles[i]); srcfiles[i] = 0; } } free(srcfiles); } /* This makes the macro context safe from duplicate frees in case of error. */ static int translate_srcfiles_to_srcfiles2(char **srcfiles, Dwarf_Signed srcfiles_count, char **srcfiles2) { Dwarf_Signed i = 0; for (i = 0; i < srcfiles_count; ++i) { char * ostr = 0; char * newstr = 0; size_t slen = 0; ostr = srcfiles[i]; slen = strlen(ostr); newstr = calloc(1,slen+1); if (!newstr) { return DW_DLV_ERROR; } strcpy(newstr,ostr); srcfiles2[i] = newstr; } return DW_DLV_OK; } static void drop_srcfiles(Dwarf_Debug dbg,char ** srcfiles, Dwarf_Signed srcfiles_count) { Dwarf_Signed i = 0; for (i = 0; i < srcfiles_count; ++i) { if (srcfiles[i]) { dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); } static int _dwarf_internal_macro_context(Dwarf_Die die, Dwarf_Bool offset_specified, Dwarf_Unsigned offset_in, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; int res = DW_DLV_ERROR; Dwarf_Unsigned macro_offset = 0; Dwarf_Attribute macro_attr = 0; Dwarf_Signed srcfiles_count = 0; Dwarf_Signed srcfiles2_count = 0; char ** srcfiles = 0; /* srcfiles uses dwarf_get_alloc for strings so dealloc_macro_srcfiles() here will result in double-dealloc when dwarf_finish() happens to see the string deallocs before the macro context dealloc (the context dealloc will call dealloc_macro_srcfiles() !). Also see the comment at _dwarf_macro_destructor() here. */ char ** srcfiles2 = 0; const char *comp_dir = 0; const char *comp_name = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; /* Doing the load here results in duplication of the section-load call (in the by_offset interface below) but detects the missing section quickly. */ res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_macro.dss_size) { return DW_DLV_NO_ENTRY; } resattr = dwarf_attr(die, DW_AT_macros, ¯o_attr, error); if (resattr == DW_DLV_NO_ENTRY) { resattr = dwarf_attr(die, DW_AT_GNU_macros, ¯o_attr, error); } if (resattr != DW_DLV_OK) { return resattr; } if (!offset_specified) { lres = dwarf_global_formref(macro_attr, ¯o_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); return lres; } } else { macro_offset = offset_in; } /* If DWP cc_macro_base may be non-zero */ macro_offset += cu_context->cc_macro_base; lres = dwarf_srcfiles(die,&srcfiles,&srcfiles_count, error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); return lres; } lres = _dwarf_internal_get_die_comp_dir(die, &comp_dir, &comp_name,error); if (lres == DW_DLV_ERROR) { drop_srcfiles(dbg,srcfiles,srcfiles_count); srcfiles = 0; srcfiles_count = 0; dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); srcfiles = 0; return lres; } *macro_unit_offset_out = macro_offset; /* We cannot use space allocated by _dwarf_get_alloc() in the macro_context we will allocate shortly. So copy from what we have to a similar data set but malloc space directly. */ if (srcfiles_count > 0) { srcfiles2 = (char **) calloc(srcfiles_count, sizeof(char *)); if (!srcfiles2) { dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); drop_srcfiles(dbg,srcfiles,srcfiles_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } lres = translate_srcfiles_to_srcfiles2(srcfiles, srcfiles_count,srcfiles2); drop_srcfiles(dbg,srcfiles,srcfiles_count); srcfiles2_count = srcfiles_count; srcfiles = 0; srcfiles_count = 0; if (lres != DW_DLV_OK) { dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); dealloc_macro_srcfiles(srcfiles2, srcfiles2_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return lres; } } else { drop_srcfiles(dbg,srcfiles,srcfiles_count); srcfiles = 0; srcfiles_count = 0; } dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR); /* NO ENTRY or OK we accept, though NO ENTRY means there are no source files available. */ lres = _dwarf_internal_macro_context_by_offset(dbg, macro_offset,version_out,macro_context_out, macro_ops_count_out, macro_ops_data_length, srcfiles2,srcfiles2_count, comp_dir, comp_name, cu_context, error); /* In case of ERROR or NO_ENTRY srcfiles2 is already freed. */ return lres; } static int _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, char **srcfiles, Dwarf_Signed srcfilescount, const char *comp_dir, const char *comp_name, Dwarf_CU_Context cu_context, Dwarf_Error * error) { Dwarf_Unsigned line_table_offset = 0; Dwarf_Small * macro_header = 0; Dwarf_Small * macro_data = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned flags = 0; Dwarf_Small offset_size = 4; Dwarf_Unsigned cur_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_base = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned optablesize = 0; Dwarf_Unsigned macro_offset = offset; int res = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Bool build_ops_array = FALSE; res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error); if (res != DW_DLV_OK) { dealloc_macro_srcfiles(srcfiles,srcfilescount); return res; } if (!dbg->de_debug_macro.dss_size) { dealloc_macro_srcfiles(srcfiles,srcfilescount); return DW_DLV_NO_ENTRY; } section_base = dbg->de_debug_macro.dss_data; section_size = dbg->de_debug_macro.dss_size; /* The '3' ensures the header initial bytes present too. */ if ((3+macro_offset) >= section_size) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } macro_header = macro_offset + section_base; macro_data = macro_header; section_end = section_base +section_size; macro_context = (Dwarf_Macro_Context) _dwarf_get_alloc(dbg,DW_DLA_MACRO_CONTEXT,1); if (!macro_context) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if ((section_base + DWARF_HALF_SIZE + sizeof(Dwarf_Small)) > section_end ) { dealloc_macro_srcfiles(srcfiles,srcfilescount); dwarf_dealloc_macro_context(macro_context); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } /* Note here so if error return we get these freed eventually. */ macro_context->mc_srcfiles = srcfiles; macro_context->mc_srcfiles_count = srcfilescount; macro_context->mc_cu_context = cu_context; res = _dwarf_read_unaligned_ck_wrapper(dbg, &version,macro_data,DWARF_HALF_SIZE,section_end, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } if (version != DW_MACRO_VERSION4 && version != DW_MACRO_VERSION5) { dwarfstring ms; dwarfstring_constructor(&ms); dwarfstring_append_printf_u(&ms, "DW_DLE_MACRO_VERSION_ERROR: " "version 0x%x ",version); dwarfstring_append_printf_u(&ms, "at section offset " "0x%" DW_PR_XZEROS DW_PR_DUx " " "is incorrect, only 5 " "or the GNU extension value of 4 are valid. " "Corrupt dwarf.", macro_offset); _dwarf_error_string(dbg,error, DW_DLE_MACRO_VERSION_ERROR, dwarfstring_string(&ms)); dwarfstring_destructor(&ms); dwarf_dealloc_macro_context(macro_context); return DW_DLV_ERROR; } macro_data += DWARF_HALF_SIZE; res = _dwarf_read_unaligned_ck_wrapper(dbg, &flags,macro_data,sizeof(Dwarf_Small),section_end, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } macro_data += sizeof(Dwarf_Small); macro_context->mc_at_comp_dir = comp_dir; macro_context->mc_at_name = comp_name; macro_context->mc_macro_header = macro_header; macro_context->mc_section_offset = macro_offset; macro_context->mc_section_size = section_size; macro_context->mc_version_number = version; macro_context->mc_flags = flags; macro_context->mc_dbg = dbg; macro_context->mc_offset_size_flag = flags& MACRO_OFFSET_SIZE_FLAG?TRUE:FALSE; macro_context->mc_debug_line_offset_flag = flags& MACRO_LINE_OFFSET_FLAG?TRUE:FALSE; macro_context->mc_operands_table_flag = flags& MACRO_OP_TABLE_FLAG?TRUE:FALSE; offset_size = macro_context->mc_offset_size_flag?8:4; macro_context->mc_offset_size = offset_size; if (macro_context->mc_debug_line_offset_flag) { cur_offset = (offset_size+ macro_data) - section_base; if (cur_offset >= section_size) { dwarf_dealloc_macro_context(macro_context); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } res = _dwarf_read_unaligned_ck_wrapper(dbg, &line_table_offset,macro_data, offset_size,section_end, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } macro_data += offset_size; macro_context->mc_debug_line_offset = line_table_offset; } if (macro_context->mc_operands_table_flag) { res = read_operands_table(macro_context, macro_header, macro_data, section_base, section_size, &optablesize, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } } macro_data += optablesize; macro_context->mc_macro_ops = macro_data; macro_context->mc_macro_header_length =macro_data - macro_header; build_ops_array = FALSE; res = _dwarf_get_macro_ops_count_internal(macro_context, build_ops_array, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } build_ops_array = TRUE; res = _dwarf_get_macro_ops_count_internal(macro_context, build_ops_array, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } *macro_ops_count_out = macro_context->mc_macro_ops_count; *macro_ops_data_length = macro_context->mc_ops_data_length; *version_out = version; *macro_context_out = macro_context; return DW_DLV_OK; } int dwarf_macro_context_total_length(Dwarf_Macro_Context head, Dwarf_Unsigned * mac_total_len, Dwarf_Error *error) { Dwarf_Debug dbg = 0; if (head) { dbg = head->mc_dbg; } CHECKNULLCONTEXT(head,dbg,error); *mac_total_len = head->mc_total_length; return DW_DLV_OK; } int dwarf_macro_context_head(Dwarf_Macro_Context head, Dwarf_Half * version, Dwarf_Unsigned * mac_offset, Dwarf_Unsigned * mac_len, Dwarf_Unsigned * mac_header_len, unsigned * flags, Dwarf_Bool * has_line_offset, Dwarf_Unsigned * line_offset, Dwarf_Bool * has_offset_size_64, Dwarf_Bool * has_operands_table, Dwarf_Half * opcode_count, Dwarf_Error *error) { Dwarf_Debug dbg = 0; CHECKNULLCONTEXT(head,dbg,error); *version = head->mc_version_number; *mac_offset = head->mc_section_offset; *mac_len = head->mc_total_length; *mac_header_len = head->mc_macro_header_length; *flags = head->mc_flags; *line_offset = head->mc_debug_line_offset; *has_line_offset = head->mc_debug_line_offset_flag; *has_offset_size_64 = head->mc_offset_size_flag; *has_operands_table = head->mc_operands_table_flag; *opcode_count = head->mc_opcode_count; return DW_DLV_OK; } int dwarf_macro_operands_table(Dwarf_Macro_Context head, Dwarf_Half index, /* 0 to opcode_count -1 */ Dwarf_Half *opcode_number, Dwarf_Half *operand_count, const Dwarf_Small **operand_array, Dwarf_Error *error) { struct Dwarf_Macro_Forms_s * ops = 0; Dwarf_Debug dbg = 0; CHECKNULLCONTEXT(head,dbg,error); dbg = head->mc_dbg; if (index >= head->mc_opcode_count) { _dwarf_error(dbg, error, DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } ops = head->mc_opcode_forms + index; *opcode_number = ops->mf_code; *operand_count = ops->mf_formcount; *operand_array = ops->mf_formbytes; return DW_DLV_OK; } /* The base interface to the .debug_macro section data for a specific CU. The version number passed back by *version_out may be 4 (a gnu extension of DWARF) or 5. */ int dwarf_get_macro_context(Dwarf_Die cu_die, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { int res = 0; Dwarf_Bool offset_specified = FALSE; Dwarf_Unsigned offset = 0; res = _dwarf_internal_macro_context(cu_die, offset_specified, offset, version_out, macro_context, macro_unit_offset_out, macro_ops_count_out, macro_ops_data_length, error); return res; } /* Like dwarf_get_macro_context but here we use a specified offset instead of the offset in the cu_die. */ int dwarf_get_macro_context_by_offset(Dwarf_Die cu_die, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { int res = 0; Dwarf_Bool offset_specified = TRUE; Dwarf_Unsigned macro_unit_offset_out = 0; res = _dwarf_internal_macro_context(cu_die, offset_specified, offset, version_out, macro_context, ¯o_unit_offset_out, macro_ops_count_out, macro_ops_data_length, error); return res; } int dwarf_get_macro_section_name(Dwarf_Debug dbg, const char **sec_name_out, UNUSEDARG Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; sec = &dbg->de_debug_macro; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name_out = sec->dss_name; return DW_DLV_OK; } void dwarf_dealloc_macro_context(Dwarf_Macro_Context mc) { Dwarf_Debug dbg = 0; if (!mc) { return; } dbg = mc->mc_dbg; /* See _dwarf_macro_destructor() here */ dwarf_dealloc(dbg,mc,DW_DLA_MACRO_CONTEXT); } int _dwarf_macro_constructor(Dwarf_Debug dbg, void *m) { /* Nothing to do, the space is zeroed out */ Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m; /* Arbitrary sentinel. For debugging. */ mc->mc_sentinel = MC_SENTINAL; mc->mc_dbg = dbg; return DW_DLV_OK; } /* Here we free various fields of Dwarf_Macro_Context. The fields do not get dealloc'd. If we had a separate destructor for hand-calling (meaning when an error is detected during creation of a Dwarf_Macro_Context) and one for calling by dwarf_dealloc() then we could have the hand-calling dwarf_dealloc the fields and the one called on the dealloc of a Dwarf_Macro_Context could leave the _dwarf_get_alloc() fields for for normal dwarf_finish() cleanup. But for now we share this destructor for both purposes so no fields are _dwarf_get_alloc() and all are free-d here.. */ void _dwarf_macro_destructor(void *m) { Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m; dealloc_macro_srcfiles(mc->mc_srcfiles, mc->mc_srcfiles_count); mc->mc_srcfiles = 0; mc->mc_srcfiles_count = 0; free((void *)mc->mc_file_path); mc->mc_file_path = 0; free(mc->mc_ops); mc->mc_ops = 0; free(mc->mc_opcode_forms); mc->mc_opcode_forms = 0; memset(mc,0,sizeof(*mc)); /* Just a recognizable sentinel. For debugging. No real meaning . */ mc->mc_sentinel = 0xdeadbeef; } libdwarf-20210528/libdwarf/dwarf_generic_init.c0000664000175000017500000004023613764007262016270 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2011-2020 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Here is the deepest routes through dwarf_init_path_dl(), depending on arguments. It is called by dwarfdump to open an fd and return Dwarf_Debug. Much of this is to handle GNU debuglink. dwarf_init_path_dl(path true_path and globals, dbg1 dwarf_object_detector_path_dSYM (dsym only( if returns DW_DLV_OK itis dSYM dwarf_object_detector_path_b( &debuglink with global paths. dwarf_object_detector_path_b ftype check for dSYM if found it is the object to run on. dwarf_object_detector_fd (gets size ftype) return _dwarf_debuglink_finder_internal(TRUE passing in globals paths listr) new local dbg dwarf_init_path(path no dysm or debuglink no global paths) dwarf_object_detector_path_b( path no dsym or debuglink no global paths dwarf_object_detector (path dwarf_object_detector_fd (gets size ftype) for each global pathin list, add to dbg dwarf_gnu_debuglink(dbg for each global path in debuglink list _dwarf_debuglink_finder_internal(FALSE no global paths) if crc match return OK with pathname and fd returned else return NO_ENTRY */ #include "config.h" #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif #endif #include #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_object_detector.h" #include "dwarf_elf_access.h" /* Needed while libelf in use */ #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ /* This is the initialization set intended to handle multiple object formats. Created September 2018 The init functions here cannot process archives. For archives the libelf-only dwarf_elf_init*() functions are used if present, else archives cannot be read. */ #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* An original basic dwarf initializer function for consumers. Return a libdwarf error code on error, return DW_DLV_OK if this succeeds. dwarf_init_b() is a better choice where there are section groups in an object file. */ int dwarf_init(int fd, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) { return dwarf_init_b(fd,access, DW_GROUPNUMBER_ANY, errhand,errarg,ret_dbg,error); } static int open_a_file(const char * name) { /* Set to a file number that cannot be legal. */ int fd = -1; #if HAVE_ELF_OPEN /* It is not possible to share file handles between applications or DLLs. Each application has its own file-handle table. For two applications to use the same file using a DLL, they must both open the file individually. Let the 'libelf' dll open and close the file. */ fd = elf_open(name, O_RDONLY | O_BINARY); #else fd = open(name, O_RDONLY | O_BINARY); #endif return fd; } static int set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error) { int res = 0; res = dwarf_add_debuglink_global_path(dbg, "/usr/lib/debug",error); return res; } /* New in December 2018. */ int dwarf_init_path(const char *path, char * true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, const char * reserved1, Dwarf_Unsigned reserved2, Dwarf_Unsigned * reserved3, Dwarf_Error * error) { return dwarf_init_path_dl(path, true_path_out_buffer,true_path_bufferlen, access,groupnumber,errhand,errarg,ret_dbg, 0,0,0, reserved1,reserved2,reserved3,error); } static void final_common_settings(Dwarf_Debug dbg, const char *file_path, int fd, unsigned char lpath_source, unsigned char *path_source, Dwarf_Error *error) { int res = 0; dbg->de_path = strdup(file_path); dbg->de_fd = fd; dbg->de_owns_fd = TRUE; dbg->de_path_source = lpath_source; if (path_source) { *path_source = lpath_source; } dbg->de_owns_fd = TRUE; res = set_global_paths_init(dbg,error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } return; } /* New October 2020 Given true_path_out_buffer (and true_path_bufferlen) non-zero this finds a dSYM (if such exists) with the file name in true_path_out_buffer If not a dSYM it follows debuglink rules to try to find a file that matches requirements. If found returns DW_DLV_OK and copies the name to true_path_out_buffer; If none of the above found, it copies path into true_path and returns DW_DLV_OK, we know the name is good; The fd is owned by libdwarf and is in the created dbg->de_fd field. */ int dwarf_init_path_dl(const char *path, char * true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, char ** dl_path_array, unsigned int dl_path_count, unsigned char * path_source, UNUSEDARG const char * reserved1, UNUSEDARG Dwarf_Unsigned reserved2, UNUSEDARG Dwarf_Unsigned * reserved3, Dwarf_Error * error) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int res = DW_DLV_NO_ENTRY; int errcode = 0; int fd = -1; Dwarf_Debug dbg = 0; char *file_path = 0; unsigned char lpath_source = DW_PATHSOURCE_basic; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL, DW_DLV_ERROR); } if (!path) { /* Oops. Null path */ _dwarf_error_string(NULL, error,DW_DLE_STRING_PTR_NULL, "DW_DLE_STRING_PTR_NULL: Passing a" " null path argument to " "dwarf_init_path or dwarf_init_path_dl" " cannot work. Error."); return DW_DLV_ERROR; } /* a special dsym call so we only check once. */ if (true_path_out_buffer) { res = dwarf_object_detector_path_dSYM(path, true_path_out_buffer, true_path_bufferlen, dl_path_array,dl_path_count, &ftype,&endian,&offsetsize,&filesize, &lpath_source, &errcode); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { /* ignore error. Look further. */ errcode = 0; } } } else { } if (res != DW_DLV_OK) { res = dwarf_object_detector_path_b(path, true_path_out_buffer, true_path_bufferlen, dl_path_array,dl_path_count, &ftype,&endian,&offsetsize,&filesize, &lpath_source, &errcode); if (res != DW_DLV_OK ) { if (res == DW_DLV_ERROR) { errcode = 0; } } } if (res != DW_DLV_OK) { /* So as a last resurt in case of data corruption in the object. Lets try without investigating debuglink or dSYM. */ res = dwarf_object_detector_path_b(path, 0, 0, dl_path_array,dl_path_count, &ftype,&endian,&offsetsize,&filesize, &lpath_source, &errcode); if (res == DW_DLV_ERROR) { errcode = 0; } } if (res != DW_DLV_OK) { /* impossible. The last above *had* to work */ return res; } /* ASSERT: lpath_source != DW_PATHSOURCE_unspecified */ if (lpath_source != DW_PATHSOURCE_basic ) { /* MacOS dSYM or GNU debuglink */ file_path = true_path_out_buffer; fd = open_a_file(true_path_out_buffer); } else { /* ASSERT: pathlsource = DW_PATHSOURCE_basic */ file_path = (char *)path; fd = open_a_file(path); } if (fd == -1) { DWARF_DBG_ERROR(NULL, DW_DLE_FILE_UNAVAILABLE, DW_DLV_ERROR); } switch(ftype) { case DW_FTYPE_ELF: { res = _dwarf_elf_nlsetup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { close(fd); return res; } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); *ret_dbg = dbg; return res; } case DW_FTYPE_MACH_O: { res = _dwarf_macho_setup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { close(fd); return res; } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); *ret_dbg = dbg; return res; } case DW_FTYPE_PE: { res = _dwarf_pe_setup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { close(fd); return res; } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); *ret_dbg = dbg; return res; } default: close(fd); DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); } return DW_DLV_NO_ENTRY; } /* New March 2017, this provides for reading object files with multiple elf section groups. */ int dwarf_init_b(int fd, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int res = 0; int errcode = 0; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR); } res = dwarf_object_detector_fd(fd, &ftype, &endian,&offsetsize,&filesize,&errcode); if (res == DW_DLV_NO_ENTRY) { return res; } else if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); } switch(ftype) { case DW_FTYPE_ELF: { int res2 = 0; res2 = _dwarf_elf_nlsetup(fd,"", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (res2 != DW_DLV_OK) { return res2; } set_global_paths_init(*ret_dbg,error); return res2; } case DW_FTYPE_MACH_O: { int resm = 0; resm = _dwarf_macho_setup(fd,"", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (resm != DW_DLV_OK) { return resm; } set_global_paths_init(*ret_dbg,error); return resm; } case DW_FTYPE_PE: { int resp = 0; resp = _dwarf_pe_setup(fd, "", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (resp != DW_DLV_OK) { return resp; } set_global_paths_init(*ret_dbg,error); return resp; } } DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); return res; } /* Frees all memory that was not previously freed by dwarf_dealloc. Aside from certain categories. Applicable when dwarf_init() or dwarf_elf_init() or the -b() form was used to init 'dbg'. */ int dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) { if (!dbg) { return DW_DLV_OK; } if (dbg->de_obj_file) { /* The initial character of a valid dbg->de_obj_file->object struct is a letter: E, F, M, or P */ char otype = *(char *)(dbg->de_obj_file->object); switch(otype) { case 'E': #ifdef DWARF_WITH_LIBELF dwarf_elf_object_access_finish(dbg->de_obj_file); #endif /* DWARF_WITH_LIBELF */ break; case 'F': /* Non-libelf elf access */ _dwarf_destruct_elf_nlaccess(dbg->de_obj_file); break; case 'M': _dwarf_destruct_macho_access(dbg->de_obj_file); break; case 'P': _dwarf_destruct_pe_access(dbg->de_obj_file); break; default: /* Do nothing. A serious internal error */ break; } } if (dbg->de_owns_fd) { close(dbg->de_fd); dbg->de_owns_fd = FALSE; } free((void *)dbg->de_path); dbg->de_path = 0; /* dwarf_object_finish() also frees de_path, but that is safe because we set it to zero here so no duplicate free will occur. It never returns DW_DLV_ERROR. Not all code uses libdwarf exactly as we do hence the free() there. */ return dwarf_object_finish(dbg, error); } /* tieddbg should be the executable or .o that has the .debug_addr section that the base dbg refers to. See Split Objects in DWARF5. Allows setting to NULL (NULL is the default of de_tied_data.td_tied_object). New September 2015. */ int dwarf_set_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug tieddbg, Dwarf_Error*error) { if (!dbg) { DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); } dbg->de_tied_data.td_tied_object = tieddbg; if (tieddbg) { tieddbg->de_tied_data.td_is_tied_object = TRUE; } return DW_DLV_OK; } /* Unsure of the use-case of this. New September 2015. */ int dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, UNUSEDARG Dwarf_Error*error) { *tieddbg_out = dbg->de_tied_data.td_tied_object; return DW_DLV_OK; } libdwarf-20210528/libdwarf/ChangeLog0000664000175000017500000002171614054251052014045 000000000000002021-05-28 David Anderson * libdwarf_version.h: Updated version string. * dwarf_names.h,dwarf_names_enum.h,dwarf_names_new.h, dwarf_names.c: Regenerated. 2021-05-25 David Anderson * dwarf_crc32.c: Added a comment for the Windows case in case it will help someone. I have no way to really test the alternative #include . 2021-05-25 David Anderson * dwarf.h,dwarf_errmsg_list.h,dwarf_line.h, dwarf_line_table_reader_common.h: Removed trailing whitespace, fixed indents. * dwarf_leb.c,dwarf_leb_test.c,dwarf_line.c,dwarf_query.c: Fixed indents and removed trailing whitespace. Fixed one too-long line by splitting to 2 lines. 2021-05-20 David Anderson * dwarf_line.h: Modified libdwarf-internal functions for LNCT handlng. Added a couple new functions for that as well. Added new fields for reporting the DW_LNCT extensions beyond DWARF5. * dwarf_line.c: New helper functions to report properly on errors in DW_LNCT forms. Completed handling of DWARF5 DW_LNCT and its FORMs. * dwarf_line_table_reader_common.h: Modified calls of the LNCT reading/checking for completeness. Moved some array/member refs to make the calls to _dwarf_decode_line_udata_form etc (all to do with DW_LNCT values). * dwarf_print_lines.c: Now prints the DW_LNCT extensions. 2021-05-18 David Anderson * dwarf_errmsg_list.h, libdwarf.h.in: Add error DW_DLE_NEGATIVE_SIZE. generated_libdwarf.h.in: Regenerated. * dwarf_form.c: Properly set secend in _dwarf_extract_local_debug_str_string_given_offset for DW_FORM_line_strp. * dwarf_query.c: In _dwarf_die_attr_unsigned_constant() allow DW_FORM_implicit_const and add some comments on small functions. Return error and DW_DLE_NEGATIVE_SIZE in case the form is a negative implicit const. 2021-05-18 David Anderson * pdfbld.sh: Comment out the build of the rearranged (placing the table of contents at the front) libdwarf2.1.pdf as that version is 20MiB! * CMakeLists.txt: Moved the install of libdwarf stuff here from ../CMakeLists.txt so it works for cmake before and after cmake 3.13. Repair an old ommission in an install that modern cmake seemingly did not care if repaired or not. 2021-05-15 David Anderson * libdwarf2.1.mm: Added additional explanation of an example call to the library in the Dwarf_Error section. Now rev 3.27. * libdwarf2.1.pdf: Regenerated. Version 3.27. 2021-05-13 David Anderson * test_dwarfstring.c,test_headersok.c,test_linkedtopath.c: Changes made to avoid compiler warnings. 2021-05-11 David Anderson * libdwarf2.1.mm: Corrected errors in the formatting of a couple input lines to get consistency. the output in the pdf doex not change. Ver 3.26 * libdwarf2.1.pdf: Regenerated as 3.26 2021-04-20 David Anderson * dwarf_leb.c: Now reads uleb/sleb allowing zeroes padding at the end. * dwarf_leb_test.c: Additional tests added with constructed examples with zeroes padding and comments explaining how it all works. See tests v5, v6, and v7. 2021-04-20 David Anderson * libdwarf2.1.pdf: Regenerated, no change intended. * pdfbld.sh: Now build the consumer both in standard and bloated form (we only ship the standard form). 2021-03-07 David Anderson * pdfbld.sh: Abandon the rearrangement of the pdf, it bloated the pdf from 600KB to over 14MB. and would double the size of a release. * libdwarf2.1.pdf: Regenerated. 2021-03-05 David Anderson * libdwarf_version.h: Updated version string. * dwarf_names.h,dwarf_names_enum.h,dwarf_names_new.h, dwarf_names.c: Regenerated. 2021-02-24 David Anderson * dwarf.h: Now with the properly spelled _ghs_ names. * dwarf_names.c,dwarf_names_enum.h: Regenerated with the properly spelled _ghs_ names. 2021-02-19 David Anderson * dwarf.h: Many DWARF-extension name/value pairs were made available to me, so those are now in dwarf.h. * dwarf_abbrev.c: An error issue with a corrupted object lead to an errormessage that read very confusingly. I've updated the message to be a bit clearer. * dwarf_names.c,dwarf_names_enum.h: Regenerated. * dwarf_query.c(dw_get_special_offset): Updated so we get some additional form classes report d correctly on certain DW_AT extensions to the standard.. * gennames.c: More names, so a constant used to generate .c and .h files needed to go 300->350. The array is only used to build C source code and does not appear in libdwarf or dwarfdump. 2021-02-16 David Anderson * dwarf_query.c: Removed a () that was accidental. * dwarf_form_class_names.c: Removed a trailing space. 2021-02-15 David Anderson * libdwarf_version.h: Updated version string. * dwarf_names.h,dwarf_names_enum.h,dwarf_names_new.h, dwarf_names.c: Regenerated. 2021-02-14 David Anderson * dwarf_form_class_names: Fixed whitespace issue. * libdwarf.h.in: Revised the Form_Class enum for better readability. * generated_libdwarf.h.in: Regenerated. 2021-02-13 David Anderson * dwarf_die_deliv.c: Fixing indents and trailing whitespace. Removed a couple blank lines. * dwarf_find_sigref.c,dwarf_line.c: Fixing indents and trailing whitespace. 2021-02-12 David Anderson * dwarf_find_sigref.c: Deleted two pointless blank lines. * libdwarf.h.in: The dwarf_find_die_given_sig8 prototype showed actual argument names. Now those names hidden in comments. * generates_libdwarf.h.in: Regenerated. 2021-02-06 David Anderson * CMakeLists.txt: Adding dwarf_find_sigref.c which follows DW_FORM_ref_sig8 to report targets. * Makefile.am: Adding dwarf_find_sigref.c which follows DW_FORM_ref_sig8 to report targets. * Makefile.in: Regenerated. * dwarf_abbrev.c: Deleted a blank line. * dwarf_die_deliv.c: Additional minor refactoring for clarity and reuse. * dwarf_find_sigref.c: Now correctly finds the ref_sig8 targets. Does not yet reference any tied-file. * dwarf_line.c: Minor refactoring to focus on the code flow, but also allowing (and reporting) when a compiler erroneously used DW_FORM_addr on DW_AT_stmt_list. * dwarf_opaque.h: refactored new CU context functions now availablt to dwarf_find_sigref.c. * libdwarf.h.in: New function dwarf_find_die_given_sig8() lets callers follow the references. Not yet documented in libdwarf2.1.mm. * generated_libdwarf.h.in: Regenerated. 2021-02-04 David Anderson * dwarf_die_deliv.c: Refactored the code creating CU_Context records, removing duplicated code to three new small functions: calculate_next_cu_context_offset(), create_a_new_cu_context_record_on_list() and load_die_containing_section(). Much easier to understand the flow now. * dwarf_form.c: Clarified a comment. * dwarf_opaque.h: Corrected a comment about cc_unit_type field. * dwarf_tied.c: Corrected commentary about reading CUs. 2021-02-02 David Anderson * libdwarf2.1.mm: Rev 3.25. Documents dwarf_get_FORM_CLASS_name(). * libdwarf2.1.pdf: Rev 3.25. Regenerated 2021-02-02 David Anderson * dwarf_form_class_names.c: new. Lets library clients print the name of any enum Dwarf_Form_Class variable by calling dwarf_get_FORM_CLASS name(). * CMakeLists.txt,Makefile.am: Now builds dwarf_form_class_names.c. * Makefile.in:Regenerated. * libdwarf.h.in: Adds prototype for dwarf_get_FORM_CLASS name(). * generated_libdwarf.h.in: Regenerated. 2021-01-31 David Anderson * dwarf_form.c(dwarf_addr_form_is_indexed): For better readability a chain of if-statements is now a switch/case. 2021-01-28 David Anderson * checkexamples.c,crc32.c,dwarf_alloc.c,dwarf_arange.c, dwarf_debuglink.c,dwarf_die_deli,.c,dwarf_elf_access.c, dwarf_elf_load_headers.c,dwarf_elfread.c,dwarf_form.c, dwarf_frame.c,dwarf_frame2.c,dwarf_global.c,dwarf_gnu_index.c, dwarf_init_finish.c,dwarf_line.c,dwarf_loc.c, dwarf_locationop_read.c,dwarf_macro5.c,dwarf_object_detector.c, dwarf_query.c,dwarf_ranges.c,dwarf_stringsection.c, dwarf_tied_test.c,dwarf_tsearchhash.c,dwarf_util.c, dwarf_xu_index.c,dwarfstring.c,dwgetopt.c,pro_die.c, pro_expr.c,pro_forms.c,pro_frame.c,pro_funcs.c,pro_init.c, pro_log_extra_flag_strings.c,test_linkedtopath.c: Fix indents. 2021-01-28 David Anderson * libdwarf2p.1.mm: Rev 1.53. Added a few words about relocating DW_OP_addr data: Such relocation generation only works right if the DW_OP_addr is the very first DW_OP in the expression. * libdwarf2p.1.pdf: Rev 1.53. Regenerated. * libdwarf2.1.mm: Rev 3.24. A font-marker was missing a \ so from page 252 the fonts were mixed up. * libdwarf2.1.pdf: Rev 3.24. Regenerated libdwarf-20210528/libdwarf/dwarf_stringsection.c0000664000175000017500000000512514004647512016516 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_util.h" int dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed * returned_str_len, Dwarf_Error * error) { int res = DW_DLV_ERROR; void *secptr = 0; void *begin = 0; void *end = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (offset == dbg->de_debug_str.dss_size) { /* Normal (if we've iterated thru the set of strings using dwarf_get_str and are at the end). */ return DW_DLV_NO_ENTRY; } if (offset > dbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD); return DW_DLV_ERROR; } if (string == NULL) { _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_str.dss_size) { return DW_DLV_NO_ENTRY; } secptr =dbg->de_debug_str.dss_data; begin = (char *)secptr + offset; end = (char *)secptr + dbg->de_debug_str.dss_size; res = _dwarf_check_string_valid(dbg,secptr,begin,end, DW_DLE_DEBUG_STR_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } *string = (char *) begin; *returned_str_len = strlen(*string); return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_section.h0000644000175000017500000000762713771421504015001 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions (C) 2016 David Anderson . All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* relocation section names */ extern const char *_dwarf_rel_section_names[]; /* section names */ extern const char *_dwarf_sectnames[]; /* struct to hold relocation entries. It is maintained as a linked list of relocation structs, and will then be written at as a whole into the relocation section. Whether its 32 bit or 64 bit will be obtained from Dwarf_Debug pointer. */ /* struct stores a chunk of data pertaining to a section */ struct Dwarf_P_Section_Data_s { int ds_elf_sect_no; /* elf section number */ char *ds_data; /* data contained in section */ unsigned long ds_nbytes; /* bytes of data used so far */ unsigned long ds_orig_alloc; /* bytes allocated originally */ Dwarf_P_Section_Data ds_next; /* next on the list */ }; /* Used to allow a dummy initial struct (which we drop before it gets used This must not match any legitimate 'section' number. */ #define MAGIC_SECT_NO -3 /* Size of chunk of data allocated in one alloc Not clear if this is the best size. Used to be just 4096 for user data, the section data struct was a separate malloc. */ #define CHUNK_SIZE (4096 - sizeof (struct Dwarf_P_Section_Data_s)) /* chunk alloc routine - if chunk->ds_data is nil, it will alloc CHUNK_SIZE bytes, and return pointer to the beginning. If chunk is not nil, it will see if there's enoungh space for nbytes in current chunk, if not, add new chunk to linked list, and return a char * pointer to it. Return null if unsuccessful. */ Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, unsigned long nbytes); /* GET_CHUNK_ERROR is new Sept 2016 to use DW_DLV_ERROR. */ #define GET_CHUNK_ERR(dbg,sectno,ptr,nbytes,error) \ { \ (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ if ((ptr) == NULL) { \ DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,DW_DLV_ERROR); \ } \ } #define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \ { \ (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ if ((ptr) == NULL) { \ DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1); \ } \ } int _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); /* These are for creating ELF section type codes. We are not trying to match any particulare ABI's settings for section type. In the producer, see de_callback_func() calls. If SHT_MIPS_DWARF was defined sometimes that was the value taken: 0x7000001e If it's important to someone then passing in a string like SHT=0x7000001e to the 'extra' argument of dwarf_producer_init() would work nicely (leading/trailing spaces are allowed, as is a NULL pointer instead of a string). One is a convenient default for testing purposes. */ #define SECTION_TYPE 1 /* SHT_PROGBITS in Elf. */ libdwarf-20210528/libdwarf/dwarf_harmless.h0000644000175000017500000000227413743575426015463 00000000000000/* Copyright (C) 2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size); void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp); libdwarf-20210528/libdwarf/dwarf_names.h0000664000175000017500000000704314054205616014734 00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #ifndef DWARF_NAMES_H #define DWARF_NAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIVIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIKIND_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_NAMES_H */ /* END FILE */ libdwarf-20210528/libdwarf/pro_init.c0000664000175000017500000003522614004646600014265 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2017 David Anderson, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_line.h" #include "memcpy_swap.h" #include "pro_section.h" /* for MAGIC_SECT_NO */ #include "pro_reloc_symbolic.h" #include "pro_reloc_stream.h" #include "dwarf_tsearch.h" #include "dwarfstring.h" #define IS_64BITPTR(dbg) ((dbg)->de_flags & DW_DLC_POINTER64 ? 1 : 0) #define ISA_IA64(dbg) ((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0) struct isa_relocs_s { const char *name_; int reloc32_; int reloc64_; int segrel_; /* only used if IRIX */ }; #ifndef TRUE #define TRUE 1 #endif /*TRUE*/ #ifndef FALSE #define FALSE 0 #endif /*FALSE*/ /* Some of these may be the wrong relocation for DWARF relocations. FIXME. Most will be unusable without additional effort as they have not been tested. */ #define R_MIPS_32 2 #define R_MIPS_64 18 #define R_MIPS_SCN_DISP 32 #define R_386_32 1 #define R_386_64 0 /* impossible */ #define R_X86_64_32 10 #define R_X86_64_64 1 #define R_SPARC_UA32 23 #define R_SPARC_UA64 54 #define R_ARM_ABS32 2 #define R_ARM_ABS64 0 /* impossible */ #define R_AARCH64_ABS32 258 #define R_AARCH64_ABS64 257 #define R_IA64_DIR32LSB 0x25 #define R_IA64_DIR64LSB 0x27 #define R_PPC_REL32 26 #define R_PPC_REL64 44 #define R_PPC64_REL32 R_PPC_REL32 #define R_PPC64_REL64 44 static struct isa_relocs_s isa_relocs[] = { {"irix", R_MIPS_32,R_MIPS_64,R_MIPS_SCN_DISP}, {"mips", R_MIPS_32,R_MIPS_64,0}, {"x86", R_386_32, R_386_64,0}, {"x86_64",R_X86_64_32,R_X86_64_64,0}, {"ia64", R_IA64_DIR32LSB,R_IA64_DIR64LSB,0}, {"arm64", R_AARCH64_ABS32,R_AARCH64_ABS64,0}, {"arm", R_ARM_ABS32,R_ARM_ABS64,0}, {"ppc", R_PPC_REL32,R_PPC_REL64,0}, {"ppc64", R_PPC64_REL32,R_PPC64_REL64,0}, {"sparc", R_SPARC_UA32,R_SPARC_UA64,0}, /* The last entry MUST be all zeros. */ {0,0,0,0} }; static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, const char *extrainfo, int *error_ret); /* This function sets up a new dwarf producing region. flags: Indicates type of access method, one of DW_DLC* macros func(): Used to create a new object file, a call back function errhand(): Error Handler provided by user errarg: Argument to errhand() error: returned error value */ /* We want the following to have an elf section number that matches 'nothing' */ static struct Dwarf_P_Section_Data_s init_sect = { MAGIC_SECT_NO, 0, 0, 0, 0 }; static struct Dwarf_P_Section_Data_s init_sect_debug_str = { MAGIC_SECT_NO, 0, 0, 0, 0 }; static struct Dwarf_P_Section_Data_s init_sect_debug_line_str = { MAGIC_SECT_NO, 0, 0, 0, 0 }; /* New April 2014. Replaces all previous producer init functions. It adds a string to select the relevant ABI/ISA and a string defining the selected DWARF version to output. There are some overlaps between the flags and the ISA/ABI string choices. ( it is neither strictly ABI nor strictly ISA name, but a useful name for both.) Generally, the function inteprets these in a tolerant fashion, so inconsistencies in the selections are not noticed...but they may have a surprising effect. The extra string is a way to allow new options without changing the interface. The idea is the caller might supply a list of such things as one string, comma-separated. The interface is not intended to allow spaces or tabs in the names, so don't do that :-) If no extra strings are needed (none are defined initially) then pass a NULL pointer or an empty string as the 'extra' parameter. */ int dwarf_producer_init(Dwarf_Unsigned flags, Dwarf_Callback_Func func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void * user_data, const char *isa_name, /* See isa_reloc_s. */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *dbg_returned, Dwarf_Error * error) { Dwarf_P_Debug dbg = 0; int res = 0; int err_ret = 0; dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Debug_s)); if (dbg == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); /* For the time being */ if (func == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, DW_DLV_ERROR); } dbg->de_callback_func = func; dbg->de_errhand = errhand; dbg->de_errarg = errarg; dbg->de_user_data = user_data; res = common_init(dbg, flags,isa_name,dwarf_version, extra,&err_ret); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, err_ret, DW_DLV_ERROR); } *dbg_returned = dbg; return DW_DLV_OK; } int dwarf_pro_set_default_string_form(Dwarf_P_Debug dbg, int form, UNUSEDARG Dwarf_Error * error) { if (form != DW_FORM_string && form != DW_FORM_strp) { _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); return DW_DLV_ERROR; } dbg->de_debug_default_str_form = form; return DW_DLV_OK; } static int set_reloc_numbers(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Unsigned flags, const char *abiname) { struct isa_relocs_s *isap = 0; if (!abiname) { return DW_DLV_NO_ENTRY; } for (isap = &isa_relocs[0]; ;isap++) { if (!isap->name_) { /* No more names known. Never found the one we wanted. */ return DW_DLV_NO_ENTRY; } if (!strcmp(abiname,isap->name_)) { if (dbg->de_pointer_size == 4) { dbg->de_ptr_reloc = isap->reloc32_; } else { dbg->de_ptr_reloc = isap->reloc64_; } if (dbg->de_dwarf_offset_size == 4) { dbg->de_offset_reloc = isap->reloc32_; } else { dbg->de_offset_reloc = isap->reloc64_; } /* segrel only meaningful for IRIX, otherwise harmless, unused. */ dbg->de_exc_reloc = isap->segrel_; return DW_DLV_OK; } } /* UNREACHED */ } /* This is the Daniel J Bernstein hash function originally posted to Usenet news. http://en.wikipedia.org/wiki/List_of_hash_functions or http://stackoverflow.com/questions/\ 10696223/reason-for-5381-number-in-djb-hash-function). See Also DWARF5 Section 7.33 */ static DW_TSHASHTYPE _dwarf_string_hashfunc(const char *str) { DW_TSHASHTYPE up = 0; DW_TSHASHTYPE hash = 5381; int c = 0; /* Extra parens suppress warning about assign in test. */ while ((c = *str++)) { hash = hash * 33 + c ; } up = hash; return up; } static DW_TSHASHTYPE key_simple_string_hashfunc(const void *keyp) { struct Dwarf_P_debug_str_entry_s* mt = (struct Dwarf_P_debug_str_entry_s*) keyp; const char *str = 0; if (mt->dse_has_table_offset) { /* ASSERT: mt->dse_dbg->de_debug_str->ds_data not zero. */ str = (const char *)mt->dse_dbg->de_debug_str->ds_data + mt->dse_table_offset; } else { /* ASSERT: dse_name != 0 */ str = (const char *)mt->dse_name; } return _dwarf_string_hashfunc(str); } static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, const char *extra, int *err_ret) { unsigned int k = 0; int res = 0; dbg->de_version_magic_number = PRO_VERSION_MAGIC; dbg->de_n_debug_sect = 0; dbg->de_debug_sects = &init_sect; dbg->de_debug_str = &init_sect_debug_str; dbg->de_debug_line_str = &init_sect_debug_line_str; dbg->de_current_active_section = &init_sect; dbg->de_flags = flags; /* DW_DLC_POINTER32 assumed. */ dbg->de_pointer_size = 4; /* Standard DWARF 64bit offset, length field 12 bytes */ dbg->de_dwarf_offset_size = 4; dbg->de_elf_offset_size = 4; dbg->de_64bit_extension = 0; dbg->de_big_endian = (dbg->de_flags&DW_DLC_TARGET_BIGENDIAN)? TRUE:FALSE; /* DW_DLC_POINTER64 is identical to DW_DLC_SIZE_64 */ if (dbg->de_flags & DW_DLC_POINTER64) { dbg->de_pointer_size = 8; } if (dbg->de_flags & DW_DLC_OFFSET64) { dbg->de_pointer_size = 8; dbg->de_dwarf_offset_size = 4; dbg->de_64bit_extension = 0; /* When dwarf_offset_size == 8 then for standard dwarf set de_64bit_extension to 1. */ dbg->de_elf_offset_size = 8; } else { if (dbg->de_flags & DW_DLC_IRIX_OFFSET64) { dbg->de_pointer_size = 8; dbg->de_big_endian = TRUE; dbg->de_dwarf_offset_size = 8; dbg->de_64bit_extension = 0; dbg->de_elf_offset_size = 8; } } if (abiname && (!strcmp(abiname,"irix"))) { dbg->de_irix_exc_augmentation = 1; } else { dbg->de_irix_exc_augmentation = 0; } /* We must set reloc numbers even if doing symbolic relocations because we use the numbers up until we are generating debug. A zero is interpreted as no relocations. So ensure we have real relocations. */ res = set_reloc_numbers(dbg,flags,abiname); if (res != DW_DLV_OK) { *err_ret = DW_DLE_BAD_ABINAME; return DW_DLV_ERROR; } dbg->de_output_version = 2; if (dwarf_version) { if (!strcmp(dwarf_version,"V2")) { dbg->de_output_version = 2; } else if (!strcmp(dwarf_version,"V3")) { dbg->de_output_version = 3; } else if (!strcmp(dwarf_version,"V4")) { dbg->de_output_version = 4; } else if (!strcmp(dwarf_version,"V5")) { dbg->de_output_version = 5; } else { *err_ret = DW_DLE_VERSION_STAMP_ERROR; return DW_DLV_ERROR; } } _dwarf_init_default_line_header_vals(dbg); res = _dwarf_log_extra_flagstrings(dbg,extra,err_ret); if (res == DW_DLV_ERROR) { return res; } if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { dbg->de_relocation_record_size = sizeof(struct Dwarf_Relocation_Data_s); } else { /* This is only going to work when the HOST == TARGET, surely? */ #ifdef DWARF_WITH_LIBELF #if HAVE_ELF64_GETEHDR dbg->de_relocation_record_size = ((dbg->de_pointer_size == 8)? sizeof(REL64) : sizeof(REL32)); #else dbg->de_relocation_record_size = sizeof(REL32); #endif #else /* DWARF_WITH_LIBELF */ *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; return DW_DLV_ERROR; #endif /* DWARF_WITH_LIBELF */ } /* For .debug_str creation. */ dwarf_initialize_search_hash(&dbg->de_debug_str_hashtab, key_simple_string_hashfunc,0); dbg->de_debug_default_str_form = DW_FORM_string; dwarf_initialize_search_hash(&dbg->de_debug_line_str_hashtab, key_simple_string_hashfunc,0); if (dbg->de_dwarf_offset_size == 8) { if (dbg->de_output_version <= 3) { dbg->de_ar_data_attribute_form = DW_FORM_data8; } else { dbg->de_ar_data_attribute_form = DW_FORM_sec_offset; } dbg->de_ar_ref_attr_form = DW_FORM_ref8; } else { if (dbg->de_output_version <= 3) { dbg->de_ar_data_attribute_form = DW_FORM_data4; } else { dbg->de_ar_data_attribute_form = DW_FORM_sec_offset; } dbg->de_ar_ref_attr_form = DW_FORM_ref4; } if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_symbolic; dbg->de_relocate_pair_by_symbol = _dwarf_pro_reloc_length_symbolic; dbg->de_transform_relocs_to_disk = _dwarf_symbolic_relocs_to_disk; } else { #ifdef DWARF_WITH_LIBELF if (IS_64BITPTR(dbg)) { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_stream64; } else { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_stream32; } dbg->de_relocate_pair_by_symbol = 0; dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; #else /* DWARF_WITH_LIBELF */ *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; return DW_DLV_ERROR; #endif /* DWARF_WITH_LIBELF */ } for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; } /* First assume host, target same endianness FIXME */ dbg->de_same_endian = 1; dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; #ifdef WORDS_BIGENDIAN /* host is big endian, so what endian is target? */ if (flags & DW_DLC_TARGET_LITTLEENDIAN) { dbg->de_same_endian = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #else /* little endian */ /* host is little endian, so what endian is target? */ if (flags & DW_DLC_TARGET_BIGENDIAN) { dbg->de_same_endian = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_die.c0000664000175000017500000006316114004646617014072 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_util.h" #include "pro_alloc.h" #include "pro_die.h" #include "pro_section.h" #include "dwarf_tsearch.h" #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #define TRUE 1 #define FALSE 0 /* This function creates a new die. tag: tag of the new die to be created parent,child,left,right: specify neighbors of the new die. Only one of these may be non-null */ Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { Dwarf_P_Die created = 0; int res = 0; res = dwarf_new_die_a(dbg,tag,parent,child, left,right,&created,error); if (res != DW_DLV_OK) { return (Dwarf_P_Die)DW_DLV_BADADDR; } return created; } /* New September 2016. Preferred as error checking is easier, no need for ugly cast. */ int dwarf_new_die_a(Dwarf_P_Debug dbg, Dwarf_Tag tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_P_Die *die_out, Dwarf_Error *error) { Dwarf_P_Die ret_die = 0; int res = 0; ret_die = (Dwarf_P_Die) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s)); if (ret_die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC, DW_DLV_ERROR); } ret_die->di_parent = NULL; ret_die->di_left = NULL; ret_die->di_right = NULL; ret_die->di_child = NULL; ret_die->di_last_child = NULL; ret_die->di_tag = tag; ret_die->di_dbg = dbg; ret_die->di_marker = 0; res = dwarf_die_link_a(ret_die, parent, child, left, right, error); if (res != DW_DLV_OK) { _dwarf_p_dealloc(dbg,(Dwarf_Small *)ret_die); ret_die = 0; } else { *die_out = ret_die; } return res; } /* This function links up a die to specified neighbors parent,child,left,right: specify neighbors of the new die. Only one of these may be non-null This is the original version. Use dwarf_die_link_a() instead as that function is easier to use (in checking for error). */ Dwarf_P_Die dwarf_die_link(Dwarf_P_Die new_die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { int res = 0; res = dwarf_die_link_a(new_die,parent,child,left,right,error); if (res != DW_DLV_OK) { return (Dwarf_P_Die)DW_DLV_BADADDR; } return new_die; } /* New September 2016. Error return easier to deal with than dwarf_die_link(). */ int dwarf_die_link_a(Dwarf_P_Die new_die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { /* Count the # of non null neighbors. */ int n_nulls = 0; if (parent != NULL) { n_nulls++; if (new_die->di_parent != NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP, DW_DLV_ERROR); } new_die->di_parent = parent; if (parent->di_child) { /* di_last_child identifies the last sibling, the die we want to attach new_die to. */ /* ASSERT: if di_child is set so is di_last_child. */ Dwarf_P_Die former_lastchild = parent->di_last_child; parent->di_last_child = new_die; /* Attach to the new die to end of the sibling list. */ former_lastchild->di_right = new_die; new_die->di_left = former_lastchild; } else { parent->di_child = new_die; parent->di_last_child = new_die; } } if (child != NULL) { n_nulls++; new_die->di_child = child; new_die->di_last_child = child; if (child->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { child->di_parent = new_die; } } if (left != NULL) { n_nulls++; new_die->di_left = left; if (left->di_right) { /* There's already a right sibling of left, insert the new die in the list. */ new_die->di_right = left->di_right; left->di_right->di_left = new_die; } left->di_right = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { new_die->di_parent = left->di_parent; } } if (right != NULL) { n_nulls++; new_die->di_right = right; if (right->di_left) { /* There is already a left sibling of the right die, insert the new die in the list. */ new_die->di_left = right->di_left; right->di_left->di_right = new_die; } right->di_left = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { new_die->di_parent = right->di_parent; } } if (n_nulls > 1) { /* Multiple neighbors! error! */ DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS, DW_DLV_ERROR); } return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_die_marker(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); } die->di_marker = marker; return 0; } int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } die->di_marker = marker; return DW_DLV_OK; } Dwarf_Unsigned dwarf_get_die_marker(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned * marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); } *marker = die->di_marker; return 0; } int dwarf_get_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned * marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } *marker = die->di_marker; return DW_DLV_ERROR; } /*--------------------------------------------------------- This function adds a die to dbg struct. It should be called using the root of all the dies. ---------------------------------------------------------*/ /* Original form of this call.. dwarf_add_die_to_debug_a() is preferred now. */ Dwarf_Unsigned dwarf_add_die_to_debug(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { int res = dwarf_add_die_to_debug_a(dbg,first_die,error); if (res == DW_DLV_ERROR) { return DW_DLV_NOCOUNT; } return 0; } /* New September 2016. The new and preferred form. */ int dwarf_add_die_to_debug_a(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { if (first_die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } if (first_die->di_tag != DW_TAG_compile_unit) { DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_ERROR); } dbg->de_dies = first_die; return DW_DLV_OK; } int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; /* Add AT_stmt_list attribute */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } new_attr->ar_attribute = DW_AT_stmt_list; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = 0; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(first_die, new_attr); return DW_DLV_OK; } static int _dwarf_debug_str_compare_func(const void *l,const void *r) { const struct Dwarf_P_debug_str_entry_s*el = l; const struct Dwarf_P_debug_str_entry_s*er = r; char *lname = 0; char *rname = 0; int ir = 0; if (el->dse_has_table_offset) { /* When set the name is in the debug_str table. */ /* ASSERT: dse_dbg->de_debug_str->ds_data is non-zero. ASSERT: dse_name NULL. */ lname = el->dse_dbg->de_debug_str->ds_data + el->dse_table_offset; } else { /* ASSERT: dse_name non-null */ lname = el->dse_name; } if (er->dse_has_table_offset) { /* When set the name is in the debug_str table. */ /* ASSERT: dse_dbg->de_debug_str->ds_data is non-zero. ASSERT: dse_name NULL. */ rname = er->dse_dbg->de_debug_str->ds_data + er->dse_table_offset; } else { /* ASSERT: dse_name non-null */ rname = er->dse_name; } ir = strcmp(lname,rname); return ir; } static void debug_str_entry_free_func(void *m) { free(m); } static int make_debug_str_entry(Dwarf_P_Debug dbg, struct Dwarf_P_debug_str_entry_s **mt_out, char *name, unsigned slen, unsigned char has_offset, Dwarf_Unsigned offset_in_table, Dwarf_Error *error) { struct Dwarf_P_debug_str_entry_s *mt = (struct Dwarf_P_debug_str_entry_s *)calloc( sizeof(struct Dwarf_P_debug_str_entry_s),1); if (!mt) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } mt->dse_slen = slen; mt->dse_table_offset = 0; mt->dse_dbg = dbg; if (has_offset) { mt->dse_has_table_offset = TRUE; mt->dse_table_offset = offset_in_table; mt->dse_name = 0; } else { /* ASSERT: name != NULL */ mt->dse_has_table_offset = FALSE; /* We just set dse_table_offset so it has a known value, though nothing should refer to dse_table_offset because dse_has_table_offset is FALSE.*/ mt->dse_table_offset = 0; mt->dse_name = name; } *mt_out = mt; return DW_DLV_OK; } #define STRTAB_BASE_ALLOC_SIZE 2048 static int insert_debug_str_data_string(Dwarf_P_Debug dbg, char *name, unsigned slen, Dwarf_P_Section_Data sd, Dwarf_Unsigned*adding_at_offset, Dwarf_Error * error) { Dwarf_Unsigned current_offset = 0; if (!sd->ds_data) { Dwarf_Unsigned initial_alloc = STRTAB_BASE_ALLOC_SIZE; Dwarf_Unsigned base_insert_offset = 0; /* Inserting our first string. The GNU linker refuses to commonize strings if the section starts with a NUL byte, so start with real string, using a base_insert_offset of 0. */ if ( (slen + base_insert_offset) >= STRTAB_BASE_ALLOC_SIZE) { initial_alloc = slen *2+ base_insert_offset; } if (initial_alloc < slen) { _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); return DW_DLV_ERROR; } sd->ds_data = calloc(1,initial_alloc); if (!sd->ds_data) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } sd->ds_orig_alloc = initial_alloc; *adding_at_offset = base_insert_offset; sd->ds_nbytes = slen + base_insert_offset; strcpy(sd->ds_data+base_insert_offset,name); return DW_DLV_OK; } current_offset = sd->ds_nbytes; if ( (current_offset + slen) >= sd->ds_orig_alloc) { unsigned updated_length = sd->ds_orig_alloc; char *newbuf = 0; if (slen > updated_length) { /* Very long string passed in. */ updated_length = slen *2; } else { updated_length = updated_length *2; } if (updated_length < sd->ds_orig_alloc) { _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); return DW_DLV_ERROR; } newbuf = calloc(1,updated_length); if (!newbuf) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(newbuf,sd->ds_data,sd->ds_nbytes); free(sd->ds_data); sd->ds_data = newbuf; sd->ds_orig_alloc = updated_length; newbuf = 0; } strcpy(sd->ds_data + current_offset,name); sd->ds_nbytes += slen; *adding_at_offset = current_offset; return DW_DLV_OK; } /* Find the string offset using the hash table, and if not known, insert the new string. */ int _dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, char *name, enum dwarf_which_hash whash, unsigned slen, /* includes space for trailing NUL */ Dwarf_Unsigned *offset_in_debug_str, Dwarf_Error *error) { struct Dwarf_P_debug_str_entry_s *mt = 0; struct Dwarf_P_debug_str_entry_s *mt2 = 0; struct Dwarf_P_debug_str_entry_s *retval = 0; struct Dwarf_P_debug_str_entry_s *re = 0; int res = 0; Dwarf_Unsigned adding_at_offset = 0; void **hashtab = 0; Dwarf_P_Section_Data sd = 0; struct Dwarf_P_Str_stats_s * stats = 0; switch (whash) { case _dwarf_hash_debug_str: hashtab = &dbg->de_debug_str_hashtab; sd = dbg->de_debug_str; stats = &dbg->de_stats.ps_strp; break; case _dwarf_hash_debug_line_str: hashtab = &dbg->de_debug_line_str_hashtab; sd = dbg->de_debug_line_str; stats = &dbg->de_stats.ps_line_strp; break; case _dwarf_hash_debug_str_sup: default: /* Not supported or unknown. */ _dwarf_p_error(dbg, error, DW_DLE_STRING_HASHTAB_IDENTITY_ERROR); return DW_DLV_ERROR; } res = make_debug_str_entry(dbg,&mt,name, slen,FALSE, 0, error); if (res != DW_DLV_OK) { return res; } /* We do a find as we do not want the string pointer passed in to be in the hash table, we want a pointer into the debug_str table in the hash table. */ retval = dwarf_tfind(mt,(void *const*)hashtab, _dwarf_debug_str_compare_func); if (retval) { stats->ps_strp_reused_count++; stats->ps_strp_reused_len += slen; re = *(struct Dwarf_P_debug_str_entry_s **)retval; *offset_in_debug_str = re->dse_table_offset; debug_str_entry_free_func(mt); return DW_DLV_OK; } /* We know the string is not in .debug_str data yet. Insert it into the big string table and get that offset. */ debug_str_entry_free_func(mt); mt = 0; res = insert_debug_str_data_string(dbg,name,slen,sd, &adding_at_offset, error); if (res != DW_DLV_OK) { return res; } /* The name is in the string table itself, so use that pointer and offset for the string. */ res = make_debug_str_entry(dbg,&mt2, 0, slen,TRUE,adding_at_offset,error); if (res != DW_DLV_OK) { return res; } retval = dwarf_tsearch(mt2, (void *)hashtab, _dwarf_debug_str_compare_func); if (!retval) { debug_str_entry_free_func(mt2); _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* This indirection is one of the surprises in using tsearch... */ re = *(struct Dwarf_P_debug_str_entry_s **)retval; if (re != mt2) { debug_str_entry_free_func(mt2); /* Found it in hash tab: illogical as the tsearch_find should have found it. */ _dwarf_p_error(dbg, error, DW_DLE_ILLOGICAL_TSEARCH); return DW_DLV_ERROR; } stats->ps_strp_count_debug_str++; stats->ps_strp_len_debug_str += slen; /* we added it to hash, do not free mt2 (which == re). */ *offset_in_debug_str = re->dse_table_offset; return DW_DLV_OK; } /* Returns DW_DLV_OK or DW_DLV_ERROR. */ int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, Dwarf_P_Debug dbg, char *name, Dwarf_Error *error) { int form = dbg->de_debug_default_str_form; unsigned slen = strlen(name)+1; if (form == DW_FORM_string || slen <= dbg->de_dwarf_offset_size) { new_attr->ar_nbytes = slen; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, slen); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dbg->de_stats.ps_str_count++; dbg->de_stats.ps_str_total_length += slen; strcpy(new_attr->ar_data, name); new_attr->ar_attribute_form = DW_FORM_string; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ return DW_DLV_OK; } if (form == DW_FORM_strp) { int uwordb_size = dbg->de_dwarf_offset_size; Dwarf_Unsigned offset_in_debug_str = 0; int res = 0; res = _dwarf_insert_or_find_in_debug_str(dbg,name, _dwarf_hash_debug_str,slen, &offset_in_debug_str,error); if (res != DW_DLV_OK) { return res; } new_attr->ar_attribute_form = form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; /* During transform to disk a symbol index will be applied. */ new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } { Dwarf_Unsigned du = offset_in_debug_str; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } return DW_DLV_OK; } _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); return DW_DLV_ERROR; } /*------------------------------------------------------------------ Add AT_name attribute to die --------------------------------------------------------------------*/ /* Original function. dwarf_add_AT_name_a() is the suggested alternative. */ Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_name_a(die, name, &a, error); if (res == DW_DLV_ERROR) { return (Dwarf_P_Attribute)(DW_DLV_BADADDR); } return a; } /* New December 2018. */ int dwarf_add_AT_name_a(Dwarf_P_Die die, char *name, Dwarf_P_Attribute *newattr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_name; res = _dwarf_pro_set_string_attr(new_attr,die->di_dbg,name,error); if (res != DW_DLV_OK) { return DW_DLV_ERROR; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(die, new_attr); *newattr_out = new_attr; return DW_DLV_OK; } /*-------------------------------------------------------------------- Add AT_comp_dir attribute to die --------------------------------------------------------------------*/ Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_comp_dir_a(ownerdie, current_working_directory, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)(DW_DLV_BADADDR); } return a; } int dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (ownerdie == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_comp_dir; res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, current_working_directory,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_MIPS_fde; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(die, new_attr); return DW_DLV_OK; } /* Sept 2016: returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_macro_info; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(die, new_attr); return DW_DLV_OK; } /* Updates the list of attributes on this Dwarf_P_Die */ void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr) { if (die->di_last_attr) { /* Inserts new attr at the end */ die->di_last_attr->ar_next = attr; die->di_last_attr = attr; die->di_n_attr++; } else { die->di_n_attr = 1; die->di_attrs = die->di_last_attr = attr; } } libdwarf-20210528/libdwarf/dwarf_locationop_read.c0000664000175000017500000006303014051761236016766 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include /* for debugging only. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_loc.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 /* Richard Henderson, on DW_OP_GNU_encoded_addr: The operand is an absolute address. The first byte of the value is an encoding length: 0 2 4 or 8. If zero it means the following is address-size. The address then follows immediately for that number of bytes. */ static int read_encoded_addr(Dwarf_Small *loc_ptr, Dwarf_Debug dbg, Dwarf_Small *section_end_ptr, Dwarf_Half address_size, Dwarf_Unsigned * val_out, int * len_out, Dwarf_Error *error) { int len = 0; Dwarf_Small op = *loc_ptr; Dwarf_Unsigned operand = 0; len++; if (!op) { op = address_size; } switch (op) { case 1: *val_out = *loc_ptr; len++; break; case 2: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 2, error,section_end_ptr); *val_out = operand; len +=2; break; case 4: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 4, error,section_end_ptr); *val_out = operand; len +=4; break; case 8: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 8, error,section_end_ptr); *val_out = operand; len +=8; break; default: /* We do not know how much to read. */ _dwarf_error(dbg, error, DW_DLE_GNU_OPCODE_ERROR); return DW_DLV_ERROR; }; *len_out = len; return DW_DLV_OK; } /* Return DW_DLV_NO_ENTRY when at the end of the ops for this block (a single Dwarf_Loccesc and multiple Dwarf_Locs will eventually result from calling this till DW_DLV_NO_ENTRY). All op reader code should call this to extract operator fields. For any DWARF version. */ int _dwarf_read_loc_expr_op(Dwarf_Debug dbg, Dwarf_Block_c * loc_block, /* Caller: Start numbering at 0. */ Dwarf_Signed opnumber, /* 2 for DWARF 2 etc. */ Dwarf_Half version_stamp, Dwarf_Half offset_size, /* 4 or 8 */ Dwarf_Half address_size, /* 2,4, 8 */ Dwarf_Signed startoffset_in, /* offset in block, not section offset */ Dwarf_Small *section_end, /* nextoffset_out so caller knows next entry startoffset */ Dwarf_Unsigned *nextoffset_out, /* The values picked up. */ Dwarf_Loc_Expr_Op curr_loc, Dwarf_Error * error) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Unsigned offset = startoffset_in; Dwarf_Unsigned operand1 = 0; Dwarf_Unsigned operand2 = 0; Dwarf_Unsigned operand3 = 0; Dwarf_Small atom = 0; Dwarf_Unsigned leb128_length = 0; if (offset > loc_block->bl_len) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } loc_len = loc_block->bl_len; if (offset == loc_len) { return DW_DLV_NO_ENTRY; } loc_ptr = (Dwarf_Small*)loc_block->bl_data + offset; if ((loc_ptr+1) > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } memset(curr_loc,0,sizeof(*curr_loc)); curr_loc->lr_opnumber = opnumber; curr_loc->lr_offset = offset; /* loc_ptr is ok to deref, see loc_ptr+1 test just above. */ atom = *(Dwarf_Small *) loc_ptr; loc_ptr++; offset++; curr_loc->lr_atom = atom; switch (atom) { case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: break; case DW_OP_regx: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: operand1 = atom - DW_OP_lit0; break; case DW_OP_addr: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, address_size, error,section_end); loc_ptr += address_size; offset += address_size; break; case DW_OP_const1u: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_const1s: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Sbyte *) loc_ptr; SIGN_EXTEND(operand1,1); loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_const2u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_const2s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error, section_end); SIGN_EXTEND(operand1,2); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_const4u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error, section_end); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_const4s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error, section_end); SIGN_EXTEND(operand1,4); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_const8u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8, error, section_end); loc_ptr = loc_ptr + 8; offset = offset + 8; break; case DW_OP_const8s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8, error, section_end); loc_ptr = loc_ptr + 8; offset = offset + 8; break; case DW_OP_constu: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_consts: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_fbreg: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_bregx: /* uleb reg num followed by sleb offset */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_dup: case DW_OP_drop: break; case DW_OP_pick: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_over: case DW_OP_swap: case DW_OP_rot: case DW_OP_deref: break; case DW_OP_deref_size: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_xderef: break; case DW_OP_xderef_type: /* DWARF5 */ if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_xderef_size: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_abs: case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_neg: case DW_OP_not: case DW_OP_or: case DW_OP_plus: break; case DW_OP_plus_uconst: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: break; case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: break; case DW_OP_skip: case DW_OP_bra: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); SIGN_EXTEND(operand1,2); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_piece: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_nop: break; case DW_OP_push_object_address: /* DWARF3 */ break; case DW_OP_call2: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_call4: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error,section_end); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_call_ref: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, offset_size, error,section_end); loc_ptr = loc_ptr + offset_size; offset = offset + offset_size; break; case DW_OP_form_tls_address: /* DWARF3f */ break; case DW_OP_call_frame_cfa: /* DWARF3f */ break; case DW_OP_bit_piece: /* DWARF3f */ /* uleb size in bits followed by uleb offset in bits */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; /* The operator means: push the currently computed (by the operations encountered so far in this expression) onto the expression stack as the offset in thread-local-storage of the variable. */ case DW_OP_GNU_push_tls_address: /* 0xe0 */ /* Believed to have no operands. */ /* Unimplemented in gdb 7.5.1 ? */ break; case DW_OP_deref_type: /* DWARF5 */ case DW_OP_GNU_deref_type: /* 0xf6 */ if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; /* die offset (uleb128). */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_implicit_value: /* DWARF4 0xa0 */ /* uleb length of value bytes followed by that number of bytes of the value. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Second operand is block of 'operand1' bytes of stuff. */ /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } break; case DW_OP_stack_value: /* DWARF4 */ break; case DW_OP_GNU_uninit: /* 0xf0 */ /* Unimplemented in gdb 7.5.1 */ /* Carolyn Tice: Follows a DW_OP_reg or DW_OP_regx and marks the reg as being uninitialized. */ break; case DW_OP_GNU_encoded_addr: { /* 0xf1 */ /* Richard Henderson: The operand is an absolute address. The first byte of the value is an encoding length: 0 2 4 or 8. If zero it means the following is address-size. The address then follows immediately for that number of bytes. */ int length = 0; int reares = read_encoded_addr(loc_ptr,dbg, section_end, address_size, &operand1, &length,error); if (reares != DW_DLV_OK) { return reares; } loc_ptr += length; if (loc_ptr > section_end) { _dwarf_error(dbg,error, DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset += length; } break; case DW_OP_implicit_pointer: /* DWARF5 */ case DW_OP_GNU_implicit_pointer:{ /* 0xf2 */ /* Jakub Jelinek: The value is an optimized-out pointer value. Represented as an offset_size DIE offset (a simple unsigned integer) in DWARF3,4 followed by a signed leb128 offset. For DWARF2, it is actually pointer size (address size). The offset is global a section offset, not cu-relative. Relocation to a different object file is up to the user, per DWARF5 Page 41. http://www.dwarfstd.org/ShowIssue.php?issue=100831.1 */ Dwarf_Small iplen = offset_size; if (version_stamp == DW_CU_VERSION2 /* 2 */ ) { iplen = address_size; } READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, iplen,error,section_end); loc_ptr = loc_ptr + iplen; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + iplen; DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; } break; case DW_OP_entry_value: /* DWARF5 */ case DW_OP_GNU_entry_value: /* 0xf3 */ /* Jakub Jelinek: A register reused really soon, but the value is unchanged. So to represent that value we have a uleb128 size followed by a DWARF expression block that size. http://www.dwarfstd.org/ShowIssue.php?issue=100909.1 */ /* uleb length of value bytes followed by that number of bytes of the value. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Second operand is block of 'operand1' bytes of stuff. */ /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } break; case DW_OP_const_type: /* DWARF5 */ case DW_OP_GNU_const_type: /* 0xf4 */ { /* die offset as uleb. cu-relative */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Next byte is size of following data block. */ operand2 = *loc_ptr; loc_ptr = loc_ptr + 1; offset = offset + 1; /* Operand 3 points to a value in the block of size just gotten as operand2. It must fit in a Dwarf_Unsigned. Get the type from the die at operand1 (a CU relative offset). */ /* FIXME: We should do something very different than what we do here! */ operand3 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; loc_ptr = loc_ptr + operand2; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + operand2; } break; case DW_OP_regval_type: /* DWARF5 */ case DW_OP_GNU_regval_type: /* 0xf5 */ /* reg num uleb*/ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* cu die off uleb*/ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_convert: /* DWARF5 */ case DW_OP_GNU_convert: /* 0xf7 */ case DW_OP_reinterpret: /* DWARF5 */ case DW_OP_GNU_reinterpret: /* 0xf9 */ /* die offset or zero */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_GNU_parameter_ref : /* 0xfa */ /* 4 byte unsigned int */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error,section_end);; loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_addrx : /* DWARF5 */ case DW_OP_GNU_addr_index : /* 0xfb DebugFission */ /* Index into .debug_addr. The value in .debug_addr is an address. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_constx : /* DWARF5 */ case DW_OP_GNU_const_index : /* 0xfc DebugFission */ /* Index into .debug_addr. The value in .debug_addr is a constant that fits in an address. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_GNU_variable_value: { /* 0xfd, 2017 By J Jelinek */ /* https://gcc.gnu.org/legacy-ml/gcc-patches/2017-02/ msg01499.html */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, offset_size,error,section_end); loc_ptr = loc_ptr + offset_size; if (loc_ptr > section_end) { _dwarf_error_string(dbg,error, DW_DLE_LOCEXPR_OFF_SECTION_END, "DW_DLE_LOCEXPR_OFF_SECTION_END: Error reading " "DW_OP_GNU_variable_value."); return DW_DLV_ERROR; } break; } default: { dwarfstring m; const char *atomname = 0; /* This can happen if the offset_size or address_size in the OP stream was incorrect for the object file.*/ dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "ERROR: DW_DLE_LOC_EXPR_BAD as DW_OP atom " "0x%x ",atom); dwarfstring_append(&m, "("); dwarf_get_OP_name(atom,&atomname); dwarfstring_append(&m,(char *)(atomname? atomname:"")); dwarfstring_append(&m, ")"); dwarfstring_append(&m,"is unknown."); _dwarf_error_string(dbg, error, DW_DLE_LOC_EXPR_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } /* If offset == loc_len this would be normal end-of-expression. */ if (offset > loc_len) { /* We stepped past the end of the expression. This has to be a compiler bug. Operators missing their values cannot be detected as such except at the end of an expression (like this). The results would be wrong if returned. */ _dwarf_error(dbg, error, DW_DLE_LOC_BAD_TERMINATION); return DW_DLV_ERROR; } curr_loc->lr_atom = atom; curr_loc->lr_raw1 = operand1; curr_loc->lr_number = operand1; curr_loc->lr_raw2 = operand2; curr_loc->lr_number2 = operand2; /* lr_number 3 is a pointer to a value iff DW_OP_const or DW_OP_GNU_const_type */ curr_loc->lr_raw3 = operand3; curr_loc->lr_number3 = operand3; *nextoffset_out = offset; return DW_DLV_OK; } libdwarf-20210528/libdwarf/CODINGSTYLE0000664000175000017500000000533013644370703014005 00000000000000This document is a brief description of the main coding style conventions in libdwarf. Many of them will be obvious from the code, but over time some accidental diffences crept in. Code should be indented in multiples of 4 spaces, and tabs should not be used to indent the source code. Use the dicheck program to check indenting. dwarf.h and libdwarf.h must have all arguments commented out as these are public headers. Because a prototype like int dwarf_example_prototype(Dwarf_Debug foo); would be made unusable by a legitimate preprocessor definition such as #define foo + The struct naming convention is 'struct Camel_Caps_s' for the struct and 'Camel_Caps' for any typedef for the struct. Admittedly having both camel caps and an underbar is an unusual convention, but it is the way the coding was begun in the early 1990's and we should remain consistent now. All user-referenceable data and functions and user_visible types should begin with DW_ or dwarf_. Non-static libdwarf global data and functions should begin with _dwarf (a somewhat questionable approach, but workable). Function names should be all lower case with underbars for readability. There should never be static data in any function. Nor should there ever be static data outside of libdwarf functions. libdwarf can be called from multiple threads (but only from one thread per Dwarf_Debug) and multiple Dwarf_Debug objects can be open at one time. Instead place such data per-dbg into the Dwarf_Debug structure in dwarf_opaque.h. Similarly for the producer code. Function-local variables should be lower-case with underbars for readability. It's ok for a small loop with counters to use single letter names like i or k or m. structure members should have a struct-specific 2-character prefix to the name (followed by an underbar). That makes it much easier to grep for uses of members. Try to keep lines under 80 characters in length. Ensure every if() has {} to enclose the actions. There is a slight preference for if( over if(. Similarly with for (, while (, and switch (. Not obsessing about these space-issues... Use libdwarf.h types for all the data objects you define, though sometimes an 'unsigned' or 'int' or 'size_t' is ok in restricted circumstances. Dwarf_Unsigned Dwarf_Signed are the preferred integer types for general use. No .c file should ever have an 'extern *' to access some external. Instead, such external references should be defined in a header file and every .c with a reference to the external should #include the relevant header. Being obsessive about this ensures that when the definition changes it will match the function declaration. There are a couple violations of this as of 2012, and those should be fixed! ------------ libdwarf-20210528/libdwarf/pro_encode_nm.c0000664000175000017500000000620713764007262015255 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_encode_nm.h" #define MORE_BYTES 0x80 #define DATA_MASK 0x7f #define DIGIT_WIDTH 7 #define SIGN_BIT 0x40 /* Encode val as a leb128. This encodes it as an unsigned number. */ /* Return DW_DLV_ERROR or DW_DLV_OK. space to write leb number is provided by caller, with caller passing length. number of bytes used returned thru nbytes arg */ int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, char *space, int splen) { char *a; char *end = space + splen; a = space; do { unsigned char uc; if (a >= end) { return DW_DLV_ERROR; } uc = val & DATA_MASK; val >>= DIGIT_WIDTH; if (val != 0) { uc |= MORE_BYTES; } *a = uc; a++; } while (val); *nbytes = (int)(a - space); return DW_DLV_OK; } /* return DW_DLV_ERROR or DW_DLV_OK. ** space to write leb number is provided by caller, with caller ** passing length. ** number of bytes used returned thru nbytes arg ** encodes a signed number. */ int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, char *space, int splen) { char *str; Dwarf_Signed sign = -(value < 0); int more = 1; char *end = space + splen; str = space; do { unsigned char byte = value & DATA_MASK; value >>= DIGIT_WIDTH; if (str >= end) { return DW_DLV_ERROR; } /* Remaining chunks would just contain the sign bit, and this chunk has already captured at least one sign bit. */ if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) { more = 0; } else { byte |= MORE_BYTES; } *str = byte; str++; } while (more); *nbytes = (int)(str - space); return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_expr.c0000664000175000017500000004542214004647037014304 00000000000000/* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_expr.h" #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 /* These two function creates a new expression struct that can be used to build up a location expression. Neither ever returns DW_DLV_NO_ENTRY */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Expr e = 0; int res = dwarf_new_expr_a(dbg,&e,error); if (res != DW_DLV_OK) { return NULL; } return e; } /* New January 2021. Was accidentally forgotten when doing the addition of producer functions returning DW_DLV_OK etc in place of pointers. */ int dwarf_new_expr_a(Dwarf_P_Debug dbg, Dwarf_P_Expr *newexpr, Dwarf_Error *error) { Dwarf_P_Expr ret_expr; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } ret_expr = (Dwarf_P_Expr) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); if (ret_expr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_expr->ex_dbg = dbg; *newexpr = ret_expr; return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_Unsigned len = 0; int res = 0; res = dwarf_add_expr_gen_a(expr,opcode, val1,val2,&len,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return len; } int dwarf_add_expr_gen_a(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Unsigned *stream_length_out, Dwarf_Error * error) { /* 2* since used to concatenate 2 leb's below */ char encode_buffer[2 * ENCODE_SPACE_NEEDED]; char encode_buffer2[ENCODE_SPACE_NEEDED]; int res = 0; Dwarf_P_Debug dbg = 0; /* Give the buffer where the operands are first going to be assembled the largest alignment. */ Dwarf_Unsigned operand_buffer[10]; /* Size of the byte stream buffer that needs to be memcpy-ed. */ int operand_size = 0; /* Points to the byte stream for the first operand, and finally to the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ Dwarf_Small *operand = 0; /* Size of the byte stream for second operand. */ int operand2_size = 0; int address_size = 0; /* int offset_size = 0; */ /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ Dwarf_Small *next_byte_ptr = 0; /* Offset past the last byte written into Dwarf_P_Expr_s. */ int next_byte_offset = 0; /* ***** BEGIN CODE ***** */ if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } dbg = expr->ex_dbg; if (!dbg) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } address_size =dbg->de_pointer_size; /* offset_size =dbg->de_dwarf_offset_size; */ operand = NULL; operand_size = 0; switch (opcode) { case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_regx: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: break; case DW_OP_addr: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1,sizeof(val1), address_size); operand_size = address_size; break; case DW_OP_const1u: case DW_OP_const1s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_const2u: case DW_OP_const2s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); operand_size = 2; break; case DW_OP_const4u: case DW_OP_const4s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); operand_size = SIZEOFT32; break; case DW_OP_const8u: case DW_OP_const8s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); operand_size = 8; break; case DW_OP_constu: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_consts: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_fbreg: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_bregx: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* Put this one directly into 'operand' at tail of prev value */ res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, ((char *) operand) + operand_size, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand_size += operand2_size; case DW_OP_dup: case DW_OP_drop: break; case DW_OP_pick: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, (const void *) &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_over: case DW_OP_swap: case DW_OP_rot: case DW_OP_deref: case DW_OP_xderef: break; case DW_OP_deref_size: case DW_OP_xderef_size: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, (const void *) &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_abs: case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_neg: case DW_OP_not: case DW_OP_or: case DW_OP_plus: break; case DW_OP_plus_uconst: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: break; case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: break; case DW_OP_skip: case DW_OP_bra: /* The operand is 16bit, signed. */ WRITE_UNALIGNED(dbg, encode_buffer, &val1,\ sizeof(val1), SIZEOFT16); operand_size = SIZEOFT16; operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_piece: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_nop: break; case DW_OP_push_object_address: /* DWARF3 */ break; case DW_OP_call2: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16); operand_size = SIZEOFT16; break; case DW_OP_call4: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); operand_size = SIZEOFT32; break; case DW_OP_call_ref: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), dbg->de_dwarf_offset_size); operand_size = dbg->de_dwarf_offset_size; break; case DW_OP_form_tls_address: /* DWARF3f */ break; case DW_OP_call_frame_cfa: /* DWARF3f */ break; case DW_OP_bit_piece: /* DWARF3f */ res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* Put this one directly into 'operand' at tail of prev value */ res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size, ((char *) operand) + operand_size, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand_size += operand2_size; break; default: _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); return DW_DLV_ERROR; } next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; *next_byte_ptr = opcode; next_byte_ptr++; if (operand) { memcpy(next_byte_ptr, operand, operand_size); } expr->ex_next_byte_offset = next_byte_offset; *stream_length_out = next_byte_offset; return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int res = 0; res = dwarf_add_expr_addr_c(expr,addr,sym_index, &length,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return length; } int dwarf_add_expr_addr_c(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Unsigned sym_index, Dwarf_Unsigned *stream_length_out, Dwarf_Error * error) { Dwarf_P_Debug dbg; Dwarf_Small *next_byte_ptr; Dwarf_Unsigned next_byte_offset; int upointer_size; if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } dbg = expr->ex_dbg; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } upointer_size = dbg->de_pointer_size; next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; *next_byte_ptr = DW_OP_addr; next_byte_ptr++; WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, sizeof(addr), upointer_size); if (expr->ex_reloc_offset != 0) { _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); return DW_DLV_ERROR; } expr->ex_reloc_sym_index = sym_index; expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; expr->ex_next_byte_offset = next_byte_offset; *stream_length_out = next_byte_offset; return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Signed sym_index, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int res = 0; Dwarf_P_Debug dbg = 0; if (sym_index < 0) { _dwarf_p_error(dbg, error, DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD); return DW_DLV_NOCOUNT; } res = dwarf_add_expr_addr_c(expr, (Dwarf_Unsigned)addr, (Dwarf_Unsigned)sym_index, &length,error); if (res != DW_DLV_OK) { return (Dwarf_Unsigned)DW_DLV_NOCOUNT; } return length; } Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) { Dwarf_Unsigned l = 0; int res = 0; res = dwarf_expr_current_offset_a(expr,&l,error); if (res != DW_DLV_OK) { return (DW_DLV_NOCOUNT); } return l; } int dwarf_expr_current_offset_a(Dwarf_P_Expr expr, Dwarf_Unsigned * stream_length_out, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } *stream_length_out = expr->ex_next_byte_offset; return DW_DLV_OK; } void dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return; } expr->ex_next_byte_offset=0; } Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Unsigned * length, Dwarf_Error * error) { Dwarf_Small *addr = 0; int res = 0; res = dwarf_expr_into_block_a(expr,length,&addr,error); if (res != DW_DLV_OK) { return (DW_DLV_BADADDR); } return (Dwarf_Addr)(uintptr_t)addr; } int dwarf_expr_into_block_a(Dwarf_P_Expr expr, Dwarf_Unsigned * length, Dwarf_Small ** address, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (length != NULL) *length = expr->ex_next_byte_offset; *address = &(expr->ex_byte_stream[0]); return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_pe_descr.h0000664000175000017500000001764213763277530015435 00000000000000#ifndef DWARF_PE_DESCR_H #define DWARF_PE_DESCR_H /* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define IMAGE_DOS_SIGNATURE_dw 0x5a4d /* le on disk 'M' 'Z' */ #define IMAGE_DOS_REVSIGNATURE_dw 0x4d5a /* be on disk */ #define IMAGE_NT_SIGNATURE_dw 0x00004550 #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ /* Data types see https://msdn.microsoft.com/en-us/library/\ windows/desktop/aa383751(v=vs.85).aspx */ /*#define FIELD_OFFSET(type,field) \ ((LONG)(LONG_PTR)&(((type *)0)->field))*/ #define IMAGE_SIZEOF_SYMBOL 18 struct dos_header_dw { TYP(dh_mz,2); TYP(dh_dos_data,58); TYP(dh_image_offset,4); }; /* IMAGE_FILE_HEADER_dw see https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680313(v=vs.85).aspx */ typedef struct { TYP(Machine,2); TYP(NumberOfSections,2); TYP(TimeDateStamp,4); TYP(PointerToSymbolTable,4); TYP(NumberOfSymbols,4); TYP(SizeOfOptionalHeader,2); TYP(Characteristics,2); } IMAGE_FILE_HEADER_dw; /* IMAGE_DATA_DIRECTORY_dw see https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680305(v=vs.85).aspx */ typedef struct { TYP(VirtualAddress,4); TYP(Size,4); } IMAGE_DATA_DIRECTORY_dw; /* IMAGE_OPTIONAL_HEADER see https://msdn.microsoft.com/en-us/library/\ windows/desktop/ms680339(v=vs.85).aspx */ #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 typedef struct { TYP(Magic,2); unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; TYP(SizeOfCode,4); TYP(SizeOfInitializedData,4); TYP(SizeOfUninitializedData,4); TYP(AddressOfEntryPoint,4); TYP(BaseOfCode,4); TYP(BaseOfData,4); TYP(ImageBase,4); TYP(SectionAlignment,4); TYP(FileAlignment,4); TYP(MajorOperatingSystemVersion,2); TYP(MinorOperatingSystemVersion,2); TYP(MajorImageVersion,2); TYP(MinorImageVersion,2); TYP(MajorSubsystemVersion,2); TYP(MinorSubsystemVersion,2); TYP(Win32VersionValue,4); TYP(SizeOfImage,4); TYP(SizeOfHeaders,4); TYP(CheckSum,4); TYP(Subsystem,2); TYP(DllCharacteristics,2); TYP(SizeOfStackReserve,4); TYP(SizeOfStackCommit,4); TYP(SizeOfHeapReserve,4); TYP(SizeOfHeapCommit,4); TYP(LoaderFlags,4); TYP(NumberOfRvaAndSizes,4); IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32_dw; typedef struct { TYP(Magic,2); unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; TYP(SizeOfCode,4); TYP(SizeOfInitializedData,4); TYP(SizeOfUninitializedData,4); TYP(AddressOfEntryPoint,4); TYP(BaseOfCode,4); TYP(ImageBase,8); TYP(SectionAlignment,4); TYP(FileAlignment,4); TYP(MajorOperatingSystemVersion,2); TYP(MinorOperatingSystemVersion,2); TYP(MajorImageVersion,2); TYP(MinorImageVersion,2); TYP(MajorSubsystemVersion,2); TYP(MinorSubsystemVersion,2); TYP(Win32VersionValue,4); TYP(SizeOfImage,4); TYP(SizeOfHeaders,4); TYP(CheckSum,4); TYP(Subsystem,2); TYP(DllCharacteristics,2); TYP(SizeOfStackReserve,8); TYP(SizeOfStackCommit,8); TYP(SizeOfHeapReserve,8); TYP(SizeOfHeapCommit,8); TYP(LoaderFlags,4); TYP(NumberOfRvaAndSizes,4); IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64_dw; /* IMAGE_NT_HEADERS see https://msdn.microsoft.com/fr-fr/library/\ windows/desktop/ms680336(v=vs.85).aspx */ #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 typedef struct { TYP(Signature,4); IMAGE_FILE_HEADER_dw FileHeader; IMAGE_OPTIONAL_HEADER64_dw OptionalHeader; } IMAGE_NT_HEADERS64_dw, *PIMAGE_NT_HEADERS64_dw; typedef struct { TYP(Signature,4); IMAGE_FILE_HEADER_dw FileHeader; IMAGE_OPTIONAL_HEADER32_dw OptionalHeader; } IMAGE_NT_HEADERS32_dw, *PIMAGE_NT_HEADERS32_dw; /* IMAGE_SECTION_HEADER_dw see: https://msdn.microsoft.com/en-us/library/windows/\ desktop/ms680341(v=vs.85).aspx and, for details on VirtualSize and SizeOfRawData: https://docs.microsoft.com/en-us/windows/desktop/\ api/winnt/ns-winnt-_image_section_header */ #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct { char Name[IMAGE_SIZEOF_SHORT_NAME]; union { TYP(PhysicalAddress,4); TYP(VirtualSize,4); } Misc; TYP(VirtualAddress,4); TYP(SizeOfRawData,4); TYP(PointerToRawData,4); TYP(PointerToRelocations,4); TYP(PointerToLinenumbers,4); TYP(NumberOfRelocations,2); TYP(NumberOfLinenumbers,2); TYP(Characteristics,4); } IMAGE_SECTION_HEADER_dw, *PIMAGE_SECTION_HEADER_dw; #define IMAGE_SCN_SCALE_INDEX 0x00000001 #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 #define IMAGE_SCN_LNK_OTHER 0x00000100 #define IMAGE_SCN_LNK_INFO 0x00000200 #define IMAGE_SCN_LNK_REMOVE 0x00000800 #define IMAGE_SCN_LNK_COMDAT 0x00001000 #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 #define IMAGE_SCN_MEM_FARDATA 0x00008000 #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 #define IMAGE_SCN_MEM_LOCKED 0x00040000 #define IMAGE_SCN_MEM_PRELOAD 0x00080000 #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 #define IMAGE_SCN_ALIGN_MASK 0x00F00000 #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 #define IMAGE_SCN_MEM_SHARED 0x10000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 #define IMAGE_SCN_MEM_WRITE 0x80000000 #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_PE_DESCR_H */ libdwarf-20210528/libdwarf/pro_weaks.c0000664000175000017500000000425513764007262014441 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif /* HAVE_ELFACCESS_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" /* This function adds another weak name to the list of weak names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_weakname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, weak_name, dwarf_snk_weakname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_weakname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, weak_name, dwarf_snk_weakname, error); return res; } libdwarf-20210528/libdwarf/test_linkedtopath.c0000664000175000017500000003250614047263150016167 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #endif /* HAVE_UNISTD_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #include /* for open() */ #include /* for open() */ #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_debuglink.h" static int errcount = 0; char * getcwd(UNUSEDARG char *buf, UNUSEDARG size_t size) { if (size >= 12) { strcpy(buf,"/exam/ple"); return buf; } /* This should not happen, if it does this test is coded wrong. */ return "/exam/ple"; } /* dummy func we do not need real one */ int _dwarf_load_section(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { return DW_DLV_OK; } /* A horrible fake version for these tests */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval) { static struct Dwarf_Error_s stuff; stuff.er_errval = errval; *error = &stuff; } /* literal copy from dwarf_error.c */ Dwarf_Unsigned dwarf_errno(Dwarf_Error error) { if (!error) { return (0); } return (error->er_errval); } /* A literal copy from dwarf_util.c */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *strptr, void *areaendptr, int suggested_error, Dwarf_Error*error) { Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; if (p < start) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (p >= end) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (dbg->de_assume_string_in_bounds) { /* This NOT the default. But folks can choose to live dangerously and just assume strings ok. */ return DW_DLV_OK; } while (p < end) { if (*p == 0) { return DW_DLV_OK; } ++p; } _dwarf_error(dbg,error,DW_DLE_STRING_NOT_TERMINATED); return DW_DLV_ERROR; } static void check_svalid(int expret,int gotret,int experr,int goterr,int line, char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (experr != goterr) { errcount++; printf("ERROR expected errcode %d, got %d line %d %s\n", experr,goterr,line,filename_in); } } static void test1(Dwarf_Debug dbg) { char testbuffer[1000]; char *area = testbuffer; char * str = testbuffer; const char *msg = "This is a simple string for testing."; int res = 0; char *end = testbuffer +100; Dwarf_Error error = 0; testbuffer[0] = 0; strcpy(testbuffer,msg); /* The error value is arbitrary, not realistic. */ res = _dwarf_check_string_valid(dbg, area,str, end,DW_DLE_CORRUPT_GNU_DEBUGID_STRING, &error); check_svalid(DW_DLV_OK,res, 0,dwarf_errno(error), __LINE__,__FILE__); end = testbuffer +10; res = _dwarf_check_string_valid(dbg, area,str, end,DW_DLE_STRING_NOT_TERMINATED, &error); check_svalid(DW_DLV_ERROR, res, DW_DLE_STRING_NOT_TERMINATED, dwarf_errno(error), __LINE__,__FILE__); end = testbuffer +10; area = end +2; res = _dwarf_check_string_valid(dbg,area,str, end,DW_DLE_CORRUPT_GNU_DEBUGID_STRING, &error); check_svalid(DW_DLV_ERROR,res, DW_DLE_CORRUPT_GNU_DEBUGID_STRING, dwarf_errno(error), __LINE__,__FILE__); } static void checkjoin(int expret,int gotret,char*expstr,char*gotstr, int line, const char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (strcmp(expstr,gotstr)) { errcount++; printf("ERROR expected string \"%s\", got \"%s\" " "line %d %s\n", expstr,gotstr,line,filename_in); } } static void test2(Dwarf_Debug dbg) { dwarfstring targ; dwarfstring inp; int res = 0; dwarfstring_constructor(&targ); dwarfstring_constructor(&inp); dwarfstring_append(&targ,"/a/b"); dwarfstring_append(&inp,"foo"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/a/b/foo", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_append(&targ,"gef"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/foo", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef/"); dwarfstring_append(&inp,"/jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef/"); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef"); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&inp,"/jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/jkl/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"jkl/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"jkl"); dwarfstring_append(&inp,"pqr/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"jkl/pqr/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"/"); dwarfstring_append(&inp,"/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_destructor(&targ); dwarfstring_destructor(&inp); } static void checklinkedto(int expret,int gotret, int expcount,int gotcount,int line, char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (expcount != gotcount) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expcount,gotcount,line,filename_in); } } static void printpaths(unsigned count,char **array,dwarfstring *fullpath) { unsigned i = 0; printf("linkstring full path: %s\n", dwarfstring_string(fullpath)); printf("\n"); printf(" Paths:\n"); for (i = 0 ; i < count ; ++i) { char *s = array[i]; printf(" [%2d] \"%s\"\n",i,s); } printf("\n"); } static unsigned char buildid[20] = { 0x11,0x22,0x33, 0x44, 0x21,0x22,0x23, 0x44, 0xa1,0xa2,0xa3, 0xa4, 0xb1,0xb2,0xb3, 0xb4, 0xc1,0xc2,0xc3, 0xc4 }; /* Since we don't find the files here this is not a good test. However, the program is used by rundebuglink.sh */ static void test3(Dwarf_Debug dbg) { char * executablepath = "/a/b"; char * linkstring = "de"; dwarfstring result; char ** global_prefix = 0; unsigned char crc[4]; unsigned buildid_length = 20; char **paths_returned = 0; unsigned paths_returned_count = 0; int errcode = 0; Dwarf_Error error = 0; int res = 0; dwarfstring linkstring_fullpath; unsigned i = 0; crc[0] = 0x12; crc[1] = 0x34; crc[2] = 0x56; crc[3] = 0xab; res = dwarf_add_debuglink_global_path(dbg, "/usr/lib/debug",&error); printf("Adding global path /usr/lib/debug\n"); if (res != DW_DLV_OK){ ++errcount; printf("Adding debuglink global path failed line %d %s\n", __LINE__,__FILE__); exit(1); } res = dwarf_add_debuglink_global_path(dbg, "/fake/lib/debug",&error); printf("Adding global path /fake/lib/debug\n"); if (res != DW_DLV_OK){ ++errcount; printf("Adding debuglink global path failed line %d %s\n", __LINE__,__FILE__); exit(1); } /* The test will not be repeatable in general unless we give executablepath a starting / so getcwd() will not be called. */ printf("executable path %s\n",executablepath); printf("linkstring %s\n",linkstring); dbg->de_path = executablepath; dwarfstring_constructor(&result); dwarfstring_constructor(&linkstring_fullpath); res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath, linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned, &linkstring_fullpath); free(paths_returned); paths_returned = 0; paths_returned_count = 0; errcode = 0; dwarfstring_reset(&linkstring_fullpath); dwarfstring_reset(&result); executablepath = "/foo/ge"; printf("executable path %s\n",executablepath); linkstring = "h/i"; printf("linkstring %s\n",linkstring); res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath,linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned, &linkstring_fullpath); free(paths_returned); paths_returned = 0; paths_returned_count = 0; errcode = 0; dwarfstring_reset(&result); dwarfstring_reset(&linkstring_fullpath); executablepath = "a/b/ge"; linkstring = "i.debug"; printf("executable path %s\n",executablepath); printf("linkstring %s\n",linkstring); res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath,linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned, &linkstring_fullpath); free(paths_returned); free(global_prefix); paths_returned = 0; paths_returned_count = 0; for (i = 0; i < dbg->de_gnu_global_path_count; ++i) { free((char *) dbg->de_gnu_global_paths[i]); dbg->de_gnu_global_paths[i] = 0; } free(dbg->de_gnu_global_paths); dbg->de_gnu_global_paths = 0; errcode = 0; dwarfstring_destructor(&result); dwarfstring_destructor(&linkstring_fullpath); } int main() { Dwarf_Debug dbg = 0; struct Dwarf_Debug_s db; dbg = &db; memset(dbg,0,sizeof(db)); test1(dbg); test2(dbg); test3(dbg); if (errcount) { return 1; } return 0; } libdwarf-20210528/libdwarf/pro_line.h0000664000175000017500000000772614012266121014255 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2017 David Anderson All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define DW_LINE_VERSION2 2 #define DW_LINE_VERSION3 3 #define DW_LINE_VERSION4 4 #if defined(__i386) || defined(__x86_64) #define MIN_INST_LENGTH 1 #elif defined(__s390__) || defined(__s390x__) /* Correct value unknown. This is temporary as we need a better way to set this (in dwarfgen). This at least works for dwarfgen testing at this point, avoids an error. */ #define MIN_INST_LENGTH 1 #else /* 1 is not necessarily the most efficient (space-wise) for various architectures, but will allow line tables to be generated without error if the input expects the min length to be 1. When using dwarfgen the setting should be that of the output arch, not the host (unless the two essentially match). */ #define MIN_INST_LENGTH 4 #endif #define DEFAULT_IS_STMT false /* line base and range are temporarily defines. They need to be calculated later. */ #define LINE_BASE -1 #define LINE_RANGE 4 #define OPCODE_BASE 10 /* DWARF2. 13 in DWARF3, 4, 5 */ #define MAX_OPCODE 255 /* This struct holds file or include_dir entries for the statement prologue. Defined in pro_line.h */ struct Dwarf_P_F_Entry_s { char *dfe_name; Dwarf_P_F_Entry dfe_next; /* DWARF 2,3,4, files only not inc dirs */ char *dfe_args; /* has dir index, time of modification, length in bytes. Encodes as leb128 */ int dfe_nbytes; /* number of bytes in args */ /* Dwarf5 Use or not depends on file_name_entry_format actually used. */ unsigned dfe_index; Dwarf_Unsigned dfe_timestamp; unsigned dfe_size; unsigned char dfe_md5[16]; }; /* Struct holding line number information for each of the producer line entries */ struct Dwarf_P_Line_s { /* code address */ Dwarf_Addr dpl_address; /* file index, index into file entry */ Dwarf_Unsigned dpl_file; /* line number */ Dwarf_Unsigned dpl_line; /* column number */ Dwarf_Unsigned dpl_column; /* whether its a beginning of a stmt */ Dwarf_Ubyte dpl_is_stmt; /* whether its a beginning of basic blk */ Dwarf_Ubyte dpl_basic_block; /* used to store opcodes set_address, and end_seq */ Dwarf_Ubyte dpl_opc; /* Used only for relocations. Has index of symbol relative to which relocation has to be done (the S part in S + A) */ Dwarf_Unsigned dpl_r_symidx; Dwarf_P_Line dpl_next; Dwarf_Ubyte dpl_prologue_end; /* DWARF3 */ Dwarf_Ubyte dpl_epilogue_begin; /* DWARF3 */ Dwarf_Unsigned dpl_isa; /* DWARF3 */ Dwarf_Unsigned dpl_discriminator; /* DWARF4 */ }; /* to initialize state machine registers, definition in pro_line.c */ void _dwarf_pro_reg_init(Dwarf_P_Debug dbg,Dwarf_P_Line); void _dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg); libdwarf-20210528/libdwarf/ChangeLog20170000664000175000017500000004407713644370703014375 00000000000000 2017-12-01 David Anderson * gennames.c: Update version string. 2017-12-01 David Anderson * dwarf_frame2.c: dwarf_get_fde_augmentation_data() could return data that would result in segfaulting in a caller. Now the length is checked and if in error then DW_DLE_AUG_DATA_LENGTH_BAD is set as the error. 2017-11-08 David Anderson * dwarf_die_deliv.c(_dwarf_die_next_info_ptr): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_frame.c(_dwarf_get_return_address_reg): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_frame2.c(dwarf_create_cie_from_after_start): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_line_table_reader_common.c(_dwarf_read_line_table_header): DW201711-002 fix. Dereferencing pointers not fully checked could lead to segv in libdwarf. * dwarf_query.c(_dwarf_die_attr_unsigned_constant): Dereferencing a pointer not fully checked could lead to segv in libdwarf. 2017-11-01 David Anderson * dwarf_frame.c(_dwarf_exec_frame_instr): An invalid frame section with a DW_CFA_advance_loc1 could result in dereferencing an invalid pointer. Now fixed. 2017-10-29 David Anderson * dwarf.h: There was a typo in DW_FORM_strx4. 2017-10-20 David Anderson * dwarf_form.c: New function: dwarf_formdata16() reads DW_FORM_data16. * dwarf_query.c,dwarf_util.c: Added support for DW_FORM_data16. * libdwarf.h.in: Declarations for new functions dwarf_add_AT_data16() and dwarf_formdata16() and new datatype Dwarf_Form_Data16 (since there is no numerical type we can use at present). 2017-10-15 David Anderson * dwgetopt.c: Removing unused local variable 'found'. 2017-10-15 David Anderson * dwgetopt.c,dwgetopt.h: Now handles simple long argument names cases. 2017-10-05 David Anderson * gennames.c: Update version string. 2017-10-13 David Anderson * dwarf.h,libdwarf/dwarf_loc.c: Corrected spelling to match its use in DWARF5: DW_SECT_LOC -> DW_SECT_LOCLISTS 2017-10-05 David Anderson * tag_attr.list,dwarf.h,dwarf_die_deliv.c, dwarf_opaque.h, dwarf_query.c,libdwarf.h.in: Changed DW_AT_ranges_base spelling to DW_AT_rnglists_base to match the final DWARF5 standard. 2017-09-26 David Anderson * gennames.c: Update version string. * dwarf_abbrev.c: See DW201709-001. A carefully constructed invalid abbrev section could result in a caller getting an invalid memory reference. So an addtional 'if' statement catches the error now. 2017-08-22 David Anderson * gennames.c: Update version string. 2017-08-21 David Anderson * Makefile.in: Now 'make test', not 'make tests'. So consistent test name with dwarfdump. * configure.cmake: Improving the handling of libelf (mainly for Windows) and simplifying this file. * dwarf_init_finish.c: Fixed indentation errors. * gennames.c: Update version string. 2017-07-27 David Anderson * dwarf_init_finish.c(_dwarf_setup): Removed some dead code and that simplified the the logic. Comments fixed as some in this area were not correct (stale comments). 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Renamed LOCATION_OF_LIBELFHEADER to HAVE_LOCATION_OF_LIBELFHEADER for consistency with config.h.in generally. * configure: Regenerated 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Consistent use of LOCATION_OF_LIBELFHEADER so Windows can build libdwarf with configure or cmake. * configure: Regenerated 2017-07-08 David Anderson * gennames.c: Update version string. 2017-07-06 David Anderson * dwarf_query.c(_dwarf_get_value_ptr): Did an add that could overflow and segv given certain fuzzing and a certain run time data layout. Fixed so the bad data is detected now and libdwarf returns an error code. A place in _dwarf_extract_address_from_debug_addr() that an overflow might possibly occur fixed too. 2017-06-29 David Anderson * dwarf_elf_access.c: Added R_SPARC_TLS_DTPOFF32 for the EM_SPARC32PLUS. 2017-06-03 David Anderson * dwarf_form.c,dwarf_frame2.c: Now use _dwarf_decode_s_leb128_chk(), the checked form. * dwarf_leb.c: Deleted _dwarf_decode_u_leb128() and _dwarf_decode_s_leb128(), they are no longer used. * dwarf_reloc_386.h: Removed some trailing whitespace. * dwarf_util.h: Removed READ_UNALIGNED macro. Removed declarations of the deleted two functions _dwarf_decode_u_leb128() and _dwarf_decode_s_leb128() 2017-05-30 David Anderson * dwarf_die_deliv.c: Added commentary about the DW_AT_dwo_id found only in experimental DWARF4. * libdwarf.h.in: Added commentary about Dwarf_Sig8 struct. 2017-05-28 David Anderson * gennames.c: Update version string. 2017-05-25 David Anderson * gennames.c: Update version string. * dwarf_reloc_386.h: Added so dwarfdump can print i386 relocations sensibly. * dwarf_elf_access.c: For WIN32 added dwarf_reloc_386.h include. 2017-05-18 David Anderson * dwarf_elf_access.c: Added R_X86_64_PC32 to the list of relocations we can expect to see. 2017-05-18 David Anderson * dwarf_opaque.h: Now names _dwarf_destroy_group_map so the group map destructor can be called when cleaning up a Dwarf_Debug. * dwarf_alloc.c: Call _dwarf_destroy_group_map(). * dwarf_groups.c: Implemented _dwarf_destroy_group_map() to clean up the map. 2017-05-18 David Anderson * dwarf_init_finish.c: One argument was unused in is_a_special_section_semi_dwarf() so removed that argument. Function is local (static) so safe to change it. Avoids a compiler warning. 2017-05-18 David Anderson * libdwarf2.1.mm: Filling in documentation of the new sections. Rev 2.58. There is more on this to do. * libdwarf2.1.pdf: Regenerated. * dwarf_groups.c: Inserted a space so things lined up, one place. 2017-05-18 David Anderson * libdwarf2.1.mm: Documenting new functions including .debug_names access and group operations. Rev 2.57. There is more on this to do. * libdwarf2.1.pdf: Regenerated. 2017-05-18 David Anderson * libdwarf2.1.mm: Documenting new functions including .debug_names access and group operations. Rev 2.56. 2017-05-14 David Anderson * libdwarf2.1.mm: Added a comment about a special case of dwarf_get_section_count(). Rev 2.55 now. * CMakeLists.txt, Makefile.in: Add dwarf_groups.c(.o), a new source file. * dwarf_elf_access.c: Added trailing _doas to a local variable so related uses easily found with grep. Added some sections to the relocatables sections list. * dwarf_errmsg_list.c: Added six new error codes related to groups. * dwarf_groups.c: New file to deal with both split-dwarf and comdat groups. Added section name to the struct for improved reporting from dwarfdump. Much easier to understand groups this way. Added array of dwo section names so those group 2 names get the right group (and obviously get it right). * dwarf_init_finish.c: most of the new code for groups is in this file. Now accomodates non-dwarf SHT_GROUP sections by figuring out they should be ignored. Fixed some indentation issues. Added critical commentary to make it easier to follow the handling of groups. * dwarf_die_deliv.c: Named a local for a call so the call would not have an unadorned 0. * dwarf_opaque.h: New fields for comdat groups. A new small struct, Dwarf_Group_Data_s has the data so it's all in one place. * dwarf_query.c: Trailing blank lines deleted. Added a few lines of #if 0 code, for debugging. * libdwarf.h.in: New error codes and new functions for section groups. 2017-04-29 David Anderson * pro_arange.c,pro_init.c, pro_opaque.h, pro_section.c, pro_types.c: Renamed de_reloc_name function pointer as de_relocate_by_name_symbol. Most relocation points use a single section-name elf symbol as the relocation reference. Renamed de_reloc_pair function pointer as de_relocate_pair_by_symbol. dump_bytes() debug code is now #if 0. Deleted set but not used local variable in _dwarf_pro_generate_debuginfo(). 2017-04-21 David Anderson * pro_section.c: Improved commentary on the abbrev section offset and on the backpatch of overall CU length once CU generated. 2017-04-20 David Anderson * dwarf_die_deliv.c: declaration of local separated from definition for easier insertion of debug stuff. Nothing substantive done. * dwarf_errmsg_list.c,libdwarf.h.in: Added DW_DLE_UNIT_TYPE_NOT_HANDLED. * dwarf_util.c: Fixed setup of debug_info header field reader. output code. 2017-04-20 David Anderson * pro_section.c: A harmless(!) comment-within-comment removed. 2017-04-20 David Anderson * gennames.c: Update version string. 2017-04-20 David Anderson * configure.in: Added additional gcc -W to --enable-wall. * configure: Regenerated. * dwarf_errmsg_list.c: Added new error codes in new DWARF5 support. * dwarf_line_table_reader_common.c: Improved comments and added specific code for DWARF5 (just clarity here, no real change). * dwarf_opaque.h: Removed unused declaration of cc_at_comp_dir. * dwarf_print_lines.c: Update copyright year. * libdwarf.h.in: Added new DW_DLE codes. * pro_alloc.c: Added tdestroy for the de_debug_line_str_hashtab to support a .debug_line_str section. * pro_arange.c: Renamed local variables for greater clarity and fixed an improper length write to be offset_size. * pro_die.c: Generalized _dwarf_insert_or_find_in_debug_str() so it can apply to the debug_str or debug_line_str sections. * pro_finish.c: We have new statistics arrangement to aid in getting statistics on debug_str and debug_line_str independently. So a little change needed to get things to compile. * pro_frame.c: Now sets cie_version properly for all DWARF versions. * pro_frame.h: cie_version field changed to proper size (Dwarf_Half). * pro_init.c: Support for .debug_line_str strings added. Corrected ancient serious botch in setting up 64bit output. Tweaked the version setup a little (no real change). Moved _dwarf_init_default_line_header_vals() call to where it actually works right for getting version number. * pro_line.c: Unified handling of include directories and files so that we can reuse code readily. Eliminating one internal struct declaration. * pro_line.h: Added new fields for DWARF5 data. Deleted struct Dwarf_P_Inc_Dir_s. * pro_opaque.h: Rearranged section codes and strings and added in DWARF5 sections. Added fields to Dwarf_P_Line_Inits_s for DWARF5 support. Revised struct Dwarf_P_Stats_s and Dwarf_P_Debug_s for DWARF5 support. * pro_section.c: Added DWARF5 sections to tables and began the addition to generation of these sections. Refactored debug_line header output for clarity, DWARF5 support, and to avoid code duplication. 2017-04-19 David Anderson * dwarf_opaque.h: Deleted the unused field cc_at_comp_dir. 2017-04-17 David Anderson * pro_init.c(common_init): Handling of 64bit offsets was coded wrong, the length field would be emitted incorrectly (confusing standard 64bit offset dwarf with non-standard IRIX 64bit offset dwarf). 2017-04-17 David Anderson * gennames.c: Update version string. * dwarf_dnames.c: Fixed indentation of a few lines. * dwarf_frame2.c: Deleted the argument fde_eh_encoding_out from the local function get_gcc_eh_augmentation() as is not needed and got an annoying compiler warning. * dwarf_print_lines.c: Removed trailing whitespace. 2017-04-16 David Anderson * CMakeLists.txt: Added in the new files dwarf_dnames.c, .h 2017-04-16 David Anderson * README: A common build problem and the fix are mentioned. * configure.in: Added more checking messages and results so easier diagnose problems. * config.h.in,configure: Regenerated with GNU Autoconf 2.69 2017-04-15 David Anderson * dwarf_print_lines.c: Added a comment , a reminder that _dwarf_print_line_context_record() was never implemented. * libdwarf.h.in: Deleted mistaken declarations dwarf_srcfiles_b(), dwarf_get_macro(), and dwarf_get_all_defined_macros(). No such functions were ever defined. 2017-04-12 David Anderson * gennames.c: Update version string. 2017-04-12 David Anderson * dwarf_alloc.c: Renamed function as _dwarf_debugnames_destructor(). * dwarf_dnames.c: Implemented a suite of new functions to allow reading .debug_names. dwarf_debugnames_header() is the entry point to get .debug_names information. * dwarf_dnames.h: new structs and fields to complete getting access to .debug_names section data. * dwarf_form.c: Refactored so dwarf_dnames.c has access to getting form data. * dwarf_opaque.h: Declare new internal .debug_names access functions. * libdwarf.h.in: Declare new .debug_names functions and new error codes. * pro_section.c: Partial outline for generation of DWARF5 .debug_names added. 2017-04-02 David Anderson * dwarf.h: Corrected comment about DW_IDX_type_unit. * dwarf_alloc.c, dwarf_alloc.h: Added support for .debug_names and Dwarf_Dnames_Head. * dwarf_dnames.c,dwarf_dnames.h: Skeleton implemenatation of .debug_denames section reader. * dwarf_errmsg_list.c: Added new *DEBUG_NAMES* error codes. * libdwarf.h.in: New *DEBUG_NAMES* and new Dwarf_Dnames_Head type. * pro_opaque.h: Now defines DEBUG_NAMES * pro_section.c: Now defines _dwarf_pro_generate_debug_names, and _dwarf_pro_generate_debug_names. A skeleton implementation. 2017-04-02 David Anderson * checkexamples.c: Slight change in a comment. * libdwarf.h.in: Added commentary. * libdwarf2.1.mm: Document dwarf_init_b(), dwarf_elf_init_b() and dwarf_object_init_b(). * libdwarf2.1.pdf: Regenerate. Version 2.54 2017-04-02 David Anderson * gennames.c: Update version string. 2017-04-02 David Anderson * dwarf_init_finish.c(determine_target_group): Correct the default group number code so the if() tests work properly. 2017-03-30 David Anderson * gennames.c: Update version string. 2017-03-30 David Anderson * dwarf_arange.c: Now uses DW_DLE_ADDRESS_SIZE_ZERO to be more precise about the error found in the object. * dwarf_die_deliv.c: Adding DWARF5 cu header reading. Adding support to more fully support split dwarf. Fixed some potential leaks (in case of erroneous DWARF). New functions that add functionality where needed to deal with reading split dwarf DWARF5. * dwarf_errmsg_list.c: Clarified DW_DLE_ADDRESS_SIZE_ERROR string and added DW_DLE_IMPROPER_DWO_ID DW_DLE_GROUPNUMBER_ERROR and DW_DLE_ADDRESS_SIZE_ZERO. * dwarf_form.c,dwarf_loc.c: Fixed trailing whitespace. * dwarf_init_finish.c: Added support so split dwarf can be read properly. New function dwarf_object_init_b() is part of that support. * dwarf_opaque.c: Added de_groupnumber. Clarified some fields with commentary. * dwarf_original_elf_init.c: New functions dwarf_init_b() dwarf_elf_init_b() for groupnumber support. * dwarf_query.c: Removed trailing whitespace. * dwarf_xu_index.c: Moved static declaration so it is useful in more places in this source. * libdwarf.h.in: Added DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, DW_GROUPNUMBER_DWO as part of giving better split dwarf support. Declared the new global functions mentioned just above. 2017-03-23 David Anderson * dwarf_query.c(dwarf_dietype_offset): dwarf_dietype_offset() leaked a Dwarf_Attribute. The one line fix removes the leak. 2017-03-23 David Anderson * gennames.c: Update version string. 2017-03-21 David Anderson * dwarf_form.c: Vulnerability DW201703-006 and DW201703-001 fixed. Some types of form were not checked as being in bounds. * dwarf_leb.c: Vulnerability DW201703-002 fixed. A check for out of bounds was done after the relevant dereference. Fixed. * dwarf_loc.c: Vulnerability DW201703-005 fixed. _dwarf_read_loc_expr_op() was failing to check for a bounds violation. * dwarf_query.c: Vulnerability DW201703-006. A call to _dwarf_reference_outside_section() did not pass a sufficiently careful argument list, so a bounds violation was missed. 2017-03-21 David Anderson * checkexamples.c: Updated dwarf_discr_list example with a cast to match function declaration. * libdwarf2.1.mm: Updated dwarf_discr_list example with a cast to match function declaration. * libdwarf2.1.pdf: Regenerated. Version 2.53 2017-03-04 David Anderson * dwarf_loc2.c(_dwarf_get_locdesc_c): Renamed to _dwarf_get_locdesc_op_c and corrected the handling so offsets properly dealt with and so a final empty operator is synthesized properly into an end operator like DWARF5. 2017-01-30 David Anderson * dwarf_die_deliv.c(_dwarf_make_CU_Context): Recent change in dwarf.h for DWARF5 package files required a small change here. * dwarf_xu_index.c(dwarf_get_xu_section_names): Recent change in dwarf.h for DWARF5 package files required a small change here and in dwp_secnames[]. * dwarf.h: Now matches final DWARF5. 2017-01-23 David Anderson * config.h.in.cmake,configure,configure.cmake,configure.in, CMakeLists.txt,Makefile.in: Add checks for sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h so relocations noticed for Solaris. Better diagostic about not-building archive or shared library. * configure: Regenerated * dwarf_elf_access.c: Ifdef added for sys/elf_386.h,sys/elf_amd64.h, sys/elf_SPARC.h so Solaris relocations are found. * Makefile.in 2017-01-02 David Anderson * dwarf.h: DWARF5 added new DW_UT codes compared to earlier DWARF5 drafts. libdwarf-20210528/libdwarf/dwarf_frame.h0000664000175000017500000003741114012266121014715 00000000000000/* Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The dwarf 2.0 standard dictates that only the following fields can be read when an unexpected augmentation string (in the cie) is encountered: CIE length, CIE_id, version and augmentation; FDE: length, CIE pointer, initial location and address range. Unfortunately, with the above restrictions, it is impossible to read the instruction table from a CIE or a FDE when a new augmentation string is encountered. To fix this problem, the following layout is used, if the augmentation string starts with the string "z". CIE FDE length length CIE_id CIE_pointer version initial_location augmentation address_range - length_of_augmented_fields (*NEW*) code_alignment_factor Any new fields as necessary data_alignment_factor instruction_table return_address length_of_augmented fields Any new fields as necessary initial_instructions The type of all the old data items are the same as what is described in dwarf 2.0 standard. The length_of_augmented_fields is an LEB128 data item that denotes the size (in bytes) of the augmented fields (not including the size of "length_of_augmented_fields" itself). Handling of cie augmentation strings is necessarly a heuristic. See dwarf_frame.c for the currently known augmentation strings. ---START SGI-ONLY COMMENT: SGI-IRIX versions of cie or fde were intended to use "z1", "z2" as the augmenter strings if required for new augmentation. However, that never happened (as of March 2005). The fde's augmented by the string "z" have a new field (signed constant, 4 byte field) called offset_into_exception_tables, following the length_of_augmented field. This field contains an offset into the "_MIPS_eh_region", which describes the IRIX CC exception handling tables. ---END SGI-ONLY COMMENT GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4) The similarity to IRIX 'z' (and proposed but never implemented IRIX z1, z2 etc) was confusing things. If the section is .eh_frame then 'z' means GNU exception information 'Augmentation Data' not IRIX 'z'. See The Linux Standard Base Core Specification version 3.0 */ #define DW_DEBUG_FRAME_VERSION 1 /* DWARF2 */ #define DW_DEBUG_FRAME_VERSION3 3 /* DWARF3 */ #define DW_DEBUG_FRAME_VERSION4 4 /* DWARF4 */ /* The following is SGI/IRIX specific, and probably no longer in use anywhere. */ #define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1" /* The value of the offset field for Cie's. */ #define DW_CIE_OFFSET ~(0x0) /* The augmentation string may be NULL. */ #define DW_EMPTY_STRING "" #define DW_FRAME_INSTR_OPCODE_SHIFT 6 #define DW_FRAME_INSTR_OFFSET_MASK 0x3f /* This struct denotes the rule for a register in a row of the frame table. In other words, it is one element of the table. */ struct Dwarf_Reg_Rule_s { /* Is a flag indicating whether the rule includes the offset field, ie whether the ru_offset field is valid or not. Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. It is important, since reg+offset (offset of 0) is different from just 'register' since the former means 'read memory at address given by the sum of register contents plus offset to get the value'. whereas the latter means 'the value is in the register'. The 'register' numbers are either real registers (ie, table columns defined as real registers) or defined entries that are not really hardware registers, such as DW_FRAME_SAME_VAL or DW_FRAME_CFA_COL. */ Dwarf_Sbyte ru_is_off; /* DW_EXPR_OFFSET (0, DWARF2) DW_EXPR_VAL_OFFSET 1 (dwarf2/3) DW_EXPR_EXPRESSION 2 (dwarf2/3) DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) See dwarf_frame.h. */ Dwarf_Sbyte ru_value_type; /* Register involved in this rule. */ Dwarf_Half ru_register; /* Offset to add to register, if indicated by ru_is_offset and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION this is DW_FORM_block block-length, not offset. */ Dwarf_Unsigned ru_offset_or_block_len; /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set, else 0. */ Dwarf_Small *ru_block; }; typedef struct Dwarf_Frame_s *Dwarf_Frame; /* This structure represents a row of the frame table. Fr_loc is the pc value for this row, and Fr_reg contains the rule for each column. Entry DW_FRAME_CFA_COL of fr_reg was the traditional MIPS way of setting CFA. cfa_rule is the new one. */ struct Dwarf_Frame_s { /* Pc value corresponding to this row of the frame table. */ Dwarf_Addr fr_loc; /* Rules for all the registers in this row. */ struct Dwarf_Reg_Rule_s fr_cfa_rule; /* fr_reg_count is the the number of entries of the fr_reg array. */ unsigned long fr_reg_count; struct Dwarf_Reg_Rule_s *fr_reg; Dwarf_Frame fr_next; }; typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List; /* This is used to chain together Dwarf_Frame_Op structures. */ struct Dwarf_Frame_Op_List_s { Dwarf_Frame_Op *fl_frame_instr; Dwarf_Frame_Op_List fl_next; }; /* See dwarf_frame.c for the heuristics used to set the Dwarf_Cie ci_augmentation_type. This succinctly helps interpret the size and meaning of .debug_frame and (for gcc) .eh_frame. In the case of gcc .eh_frame (gcc 3.3, 3.4) z may be followed by one or more of L R P. */ enum Dwarf_augmentation_type { aug_empty_string, /* Default empty augmentation string. */ aug_irix_exception_table, /* IRIX plain "z", for exception handling, IRIX CC compiler. Proposed z1 z2 ... never implemented. */ aug_gcc_eh_z, /* gcc z augmentation, (including L R P variations). gcc 3.3 3.4 exception handling in eh_frame. */ aug_irix_mti_v1, /* IRIX "mti v1" augmentation string. Probably never in any released SGI-IRIX compiler. */ aug_eh, /* For gcc .eh_frame, "eh" is the string., gcc 1,2, egcs. Older values. */ aug_armcc, /* "armcc+" meaning the cfa calculation is corrected to be standard (output by Arm C RVCT 3.0 SP1 and later). See http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html for details. */ aug_unknown, /* Unknown augmentation, we cannot do much. */ /* HC, From http://sourceforge.net/p/elftoolchain/tickets/397/ */ aug_metaware, aug_past_last }; /* This structure contains all the pertinent info for a Cie. Most of the fields are taken straight from the definition of a Cie. Ci_cie_start points to the address (in .debug_frame) where this Cie begins. Ci_cie_instr_start points to the first byte of the frame instructions for this Cie. Ci_dbg points to the associated Dwarf_Debug structure. Ci_initial_table is a pointer to the table row generated by the instructions for this Cie. */ struct Dwarf_Cie_s { Dwarf_Unsigned ci_length; char *ci_augmentation; Dwarf_Small ci_code_alignment_factor; Dwarf_Sbyte ci_data_alignment_factor; Dwarf_Small ci_return_address_register; Dwarf_Small *ci_cie_start; Dwarf_Small *ci_cie_instr_start; Dwarf_Small *ci_cie_end; Dwarf_Debug ci_dbg; Dwarf_Frame ci_initial_table; Dwarf_Cie ci_next; Dwarf_Small ci_length_size; Dwarf_Small ci_extension_size; Dwarf_Half ci_cie_version_number; enum Dwarf_augmentation_type ci_augmentation_type; /* The following 2 for GNU .eh_frame exception handling Augmentation Data. Set if ci_augmentation_type is aug_gcc_eh_z. Zero if unused. */ Dwarf_Unsigned ci_gnu_eh_augmentation_len; Dwarf_Ptr ci_gnu_eh_augmentation_bytes; /* These are extracted from the gnu eh_frame augmentation if the augmentation begins with 'z'. See Linux LSB documents. Otherwize these are zero. */ unsigned char ci_gnu_personality_handler_encoding; unsigned char ci_gnu_lsda_encoding; unsigned char ci_gnu_fde_begin_encoding; /* If 'P' augmentation present, is handler addr. Else is zero. */ Dwarf_Addr ci_gnu_personality_handler_addr; /* In creating list of cie's (which will become an array) record the position so fde can get it on fde creation. */ Dwarf_Unsigned ci_index; Dwarf_Small * ci_section_ptr; Dwarf_Unsigned ci_section_length; Dwarf_Small * ci_section_end; /* DWARF4 adds address size and segment size to the CIE: the .debug_info section may not always be present to allow libdwarf to find address_size from the compilation-unit. */ Dwarf_Half ci_address_size; Dwarf_Half ci_segment_size; }; /* This structure contains all the pertinent info for a Fde. Most of the fields are taken straight from the definition. fd_cie_index is the index of the Cie associated with this Fde in the list of Cie's for this debug_frame. Fd_cie points to the corresponding Dwarf_Cie structure. Fd_fde_start points to the start address of the Fde. Fd_fde_instr_start points to the start of the instructions for this Fde. Fd_dbg points to the associated Dwarf_Debug structure. */ struct Dwarf_Fde_s { Dwarf_Unsigned fd_length; Dwarf_Addr fd_cie_offset; Dwarf_Unsigned fd_cie_index; Dwarf_Cie fd_cie; Dwarf_Addr fd_initial_location; Dwarf_Small *fd_initial_loc_pos; Dwarf_Addr fd_address_range; Dwarf_Small *fd_fde_start; Dwarf_Small *fd_fde_instr_start; Dwarf_Small *fd_fde_end; Dwarf_Debug fd_dbg; /* fd_offset_into_exception_tables is SGI/IRIX exception table offset. Unused and zero if not IRIX .debug_frame. */ Dwarf_Signed fd_offset_into_exception_tables; Dwarf_Fde fd_next; Dwarf_Small fd_length_size; Dwarf_Small fd_extension_size; /* So we know from an fde which 'count' of fde-s in Dwarf_Debug applies: eh or standard. */ Dwarf_Small fd_is_eh; /* The following 2 for GNU .eh_frame exception handling Augmentation Data. Set if CIE ci_augmentation_type is aug_gcc_eh_z. Zero if unused. */ Dwarf_Unsigned fd_gnu_eh_augmentation_len; Dwarf_Bool fd_gnu_eh_aug_present; Dwarf_Ptr fd_gnu_eh_augmentation_bytes; Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter present: is address of the Language Specific Data Area (LSDA). If not 'L" is zero. */ /* The following 3 are about the Elf section the FDEs come from.*/ Dwarf_Small * fd_section_ptr; Dwarf_Unsigned fd_section_length; Dwarf_Unsigned fd_section_index; Dwarf_Small * fd_section_end; /* If fd_eh_table_value_set is true, then fd_eh_table_value is meaningful. Never meaningful for .debug_frame, is part of .eh_frame. */ Dwarf_Unsigned fd_eh_table_value; Dwarf_Bool fd_eh_table_value_set; /* The following are memoization to save recalculation. */ struct Dwarf_Frame_s fd_fde_table; Dwarf_Addr fd_fde_pc_requested; Dwarf_Bool fd_have_fde_tab; }; int _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, Dwarf_Off ** offsetlist, Dwarf_Signed * returncount, Dwarf_Error * err); int _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, /* If non-zero, this is gcc eh_frame. */ Dwarf_Error * error); enum Dwarf_augmentation_type _dwarf_get_augmentation_type(Dwarf_Debug dbg, Dwarf_Small *augmentation_string, int is_gcc_eh_frame); int _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, int version, Dwarf_Debug dbg, Dwarf_Byte_Ptr section_end, unsigned long *size, Dwarf_Unsigned *return_address_register, Dwarf_Error *error); /* Temporary recording of crucial cie/fde prefix data. Vastly simplifies some argument lists. */ struct cie_fde_prefix_s { /* cf_start_addr is a pointer to the first byte of this fde/cie (meaning the length field itself) */ Dwarf_Small * cf_start_addr; /* cf_addr_after_prefix is a pointer to the first byte of this fde/cie we are reading now, immediately following the length field read by READ_AREA_LENGTH. */ Dwarf_Small * cf_addr_after_prefix; /* cf_length is the length field value from the cie/fde header. */ Dwarf_Unsigned cf_length; int cf_local_length_size; int cf_local_extension_size; Dwarf_Unsigned cf_cie_id; Dwarf_Small * cf_cie_id_addr; /*used for eh_frame calculations.*/ /* Simplifies passing around these values to create fde having these here. */ /* cf_section_ptr is a pointer to the first byte of the object section the prefix is read from. */ Dwarf_Small * cf_section_ptr; Dwarf_Unsigned cf_section_index; Dwarf_Unsigned cf_section_length; }; int _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Frame_Op ** ret_frame_instr, Dwarf_Bool search_pc, Dwarf_Addr search_pc_val, Dwarf_Addr initial_loc, Dwarf_Small * start_instr_ptr, Dwarf_Small * final_instr_ptr, Dwarf_Frame table, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error); int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, Dwarf_Small *frame_ptr_in, Dwarf_Small *section_ptr_in, Dwarf_Unsigned section_index_in, Dwarf_Unsigned section_length_in, struct cie_fde_prefix_s *prefix_out, Dwarf_Error *error); int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s * prefix, Dwarf_Small *section_pointer, Dwarf_Small *frame_ptr, Dwarf_Small *section_ptr_end, int use_gnu_cie_calc, Dwarf_Cie cie_ptr_in, Dwarf_Fde *fde_ptr_out, Dwarf_Error *error); int dwarf_create_cie_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small* section_pointer, Dwarf_Small* frame_ptr, Dwarf_Small *section_ptr_end, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie *cie_ptr_out, Dwarf_Error *error); int _dwarf_frame_constructor(Dwarf_Debug dbg,void * ); void _dwarf_frame_destructor (void *); void _dwarf_fde_destructor (void *); libdwarf-20210528/libdwarf/dwarf_base_types.h0000664000175000017500000001056414012266121015761 00000000000000/* Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define true 1 #define false 0 /* .debug_addr new in DWARF5 */ #define DW_ADDR_VERSION5 5 /* To identify a cie. That is, for .debug_frame */ #define DW_CIE_ID ~(0x0) #define DW_CIE_VERSION 1 /* DWARF2 */ #define DW_CIE_VERSION3 3 /* DWARF3 */ #define DW_CIE_VERSION4 4 /* DWARF4 */ #define DW_CIE_VERSION5 5 /* DWARF5 */ /* For .debug_info DWARF2,3,4,5. .debug_types in DWARF4 only, and gets DW_CU_VERSION4. */ #define DW_CU_VERSION2 2 #define DW_CU_VERSION3 3 #define DW_CU_VERSION4 4 #define DW_CU_VERSION5 5 /* For .debug_macro: DWARF 4 (extension) or DWARF5 */ #define DW_MACRO_VERSION4 4 #define DW_MACRO_VERSION5 5 /* DWARF2,3, 4 and 5.*/ #define DW_ARANGES_VERSION2 2 #define DW_LINE_VERSION2 2 #define DW_LINE_VERSION3 3 #define DW_LINE_VERSION4 4 #define DW_LINE_VERSION5 5 /* .debug_line_str (and .dwo) new in DWARF5. */ #define DW_LINE_STR_VERSION5 5 #define EXPERIMENTAL_LINE_TABLES_VERSION 0xf006\ /* Experimental two-level line tables */ /* .debug_loc (and .dwo) First header version number is DWARF5. */ #define DW_LOC_VERSION5 5 /* .debug_names new in DWARF5. */ #define DW_NAMES_VERSION5 5 /* .debug_pubnames in DWARF2,3,4. */ #define DW_PUBNAMES_VERSION2 2 /* .debug_pubnames in DWARF3,4. */ #define DW_PUBTYPES_VERSION2 2 /* .debug_ranges gets a version number in header in DWARF5. */ #define DW_RANGES_VERSION5 5 /* .debug_str_offsets (and .dwo) new in DWARF5. */ #define DW_STR_OFFSETS_VERSION5 5 #define DW_STR_OFFSETS_VERSION4 4 /* GNU extension in DW4 */ /* .debug_sup new in DWARF5. */ #define DW_SUP_VERSION5 5 /* .debug_cu_index new in DWARF5. */ #define DW_CU_INDEX_VERSION5 5 /* .debug_tu_index new in DWARF5. */ #define DW_TU_INDEX_VERSION5 5 /* These are allocation type codes for structs that are internal to the Libdwarf Consumer library. */ #define DW_DLA_ABBREV_LIST 0x1e #define DW_DLA_CHAIN 0x1f #define DW_DLA_CU_CONTEXT 0x20 #define DW_DLA_FRAME 0x21 #define DW_DLA_GLOBAL_CONTEXT 0x22 #define DW_DLA_FILE_ENTRY 0x23 #define DW_DLA_LINE_CONTEXT 0x24 #define DW_DLA_LOC_CHAIN 0x25 #define DW_DLA_HASH_TABLE 0x26 #define DW_DLA_FUNC_CONTEXT 0x27 #define DW_DLA_TYPENAME_CONTEXT 0x28 #define DW_DLA_VAR_CONTEXT 0x29 #define DW_DLA_WEAK_CONTEXT 0x2a #define DW_DLA_PUBTYPES_CONTEXT 0x2b /* DWARF3 */ #define DW_DLA_HASH_TABLE_ENTRY 0x2c #define DW_DLA_FISSION_PERCU 0x2d #define DW_DLA_CHAIN_2 0x3d /* Thru 0x36 reserved for internal future use. */ /* Maximum number of allocation types for allocation routines. Only used with malloc_check.c and that is basically obsolete. */ #define MAX_DW_DLA 0x3a typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; typedef Dwarf_Small *Dwarf_Byte_Ptr; #define DWARF_HALF_SIZE 2 #define DWARF_32BIT_SIZE 4 #define DWARF_64BIT_SIZE 8 typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List; typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry; typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context; typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table; typedef struct Dwarf_Hash_Table_Entry_s *Dwarf_Hash_Table_Entry; typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr; libdwarf-20210528/libdwarf/dwarf_debuglink.h0000664000175000017500000000403614012266121015564 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_DEBUGLINK_H #define DWARF_DEBUGLINK_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input); int _dwarf_construct_linkedto_path( char **global_prefixes_in, unsigned length_global_prefixes_in, char *pathname_in, char *link_string_in, /* from debug link */ dwarfstring *link_string_fullpath, unsigned char *crc_in, /* from debug_link, 4 bytes */ unsigned char *buildid, /* from gnu buildid */ unsigned buildid_length, /* from gnu buildid */ char ***paths_out, unsigned *paths_out_length, int *errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_DEBUGLINK_H */ libdwarf-20210528/libdwarf/dwarf_arange.h0000644000175000017500000000372113743575426015100 00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This structure is used to read an arange into. */ struct Dwarf_Arange_s { /* The segment selector. Only non-zero if Dwarf4, only meaningful if ar_segment_selector_size non-zero */ Dwarf_Unsigned ar_segment_selector; /* Starting address of the arange, ie low-pc. */ Dwarf_Addr ar_address; /* Length of the arange. */ Dwarf_Unsigned ar_length; /* Offset into .debug_info of the start of the compilation-unit containing this set of aranges. Applies only to .debug_info, not .debug_types. */ Dwarf_Off ar_info_offset; /* Corresponding Dwarf_Debug. */ Dwarf_Debug ar_dbg; Dwarf_Half ar_segment_selector_size; }; int _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrs, Dwarf_Off ** offsets, Dwarf_Signed * count, Dwarf_Error * error); libdwarf-20210528/libdwarf/dwarf_funcs.c0000664000175000017500000000666213764007262014754 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_funcs.h" #include "dwarf_global.h" int dwarf_get_funcs(Dwarf_Debug dbg, Dwarf_Func ** funcs, Dwarf_Signed * ret_func_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_funcnames, error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_funcnames.dss_size) { return DW_DLV_NO_ENTRY; } return _dwarf_internal_get_pubnames_like_data(dbg, ".debug_funcnames", dbg->de_debug_funcnames.dss_data, dbg->de_debug_funcnames.dss_size, /* Type punning for sections with identical format. */ (Dwarf_Global **) funcs, ret_func_count, error, DW_DLA_FUNC_CONTEXT, DW_DLA_FUNC, DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD, DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_funcs_dealloc(Dwarf_Debug dbg, Dwarf_Func * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count); return; } int dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; if (func == NULL) { _dwarf_error(NULL, error, DW_DLE_FUNC_NULL); return DW_DLV_ERROR; } *ret_name = (char *) (func->gl_name); return DW_DLV_OK; } int dwarf_func_die_offset(Dwarf_Func func_in, Dwarf_Off * return_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_die_offset(func, return_offset, error); } int dwarf_func_cu_offset(Dwarf_Func func_in, Dwarf_Off * return_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_cu_offset(func, return_offset, error); } int dwarf_func_name_offsets(Dwarf_Func func_in, char **ret_func_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_name_offsets(func, ret_func_name, die_offset, cu_die_offset, error); } libdwarf-20210528/libdwarf/Makefile.am0000664000175000017500000001323714012266121014323 00000000000000###Copyright (C) 2018 Vincent Torri #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif /* HAVE_ELFACCESS_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_section.h" /* This function adds another function name to the list of function names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_funcname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *function_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, function_name, dwarf_snk_funcname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_funcname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *function_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, function_name, dwarf_snk_funcname, error); return res; } libdwarf-20210528/libdwarf/dwarf_die_deliv.c0000664000175000017500000030512214012616041015537 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_str_offsets.h" #include "dwarfstring.h" #include "dwarf_die_deliv.h" #define FALSE 0 #define TRUE 1 /* These are sanity checks, not 'rules'. */ #define MINIMUM_ADDRESS_SIZE 2 #define MAXIMUM_ADDRESS_SIZE 8 static void assign_correct_unit_type(Dwarf_CU_Context cu_context); static int find_cu_die_base_fields(Dwarf_Debug dbg, Dwarf_CU_Context cucon, Dwarf_Die cudie, Dwarf_Error* error); static int _dwarf_siblingof_internal(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_CU_Context context, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error); /* see cuandunit.txt for an overview of the DWARF5 split dwarf sections and values and the DWARF4 GNU cc version of a draft version of DWARF5 (quite different from the final DWARF5). */ static struct Dwarf_Sig8_s dwarfsig8zero; #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif /* New October 2011. Enables client code to know if it is a debug_info or debug_types context. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die die) { return die->di_is_info; } /* For a given Dwarf_Debug dbg, this function checks if a CU that includes the given offset has been read or not. If yes, it returns the Dwarf_CU_Context for the CU. Otherwise it returns NULL. Being an internal routine, it is assumed that a valid dbg is passed. **This is a sequential search. May be too slow. If debug_info and debug_abbrev not loaded, this will wind up returning NULL. So no need to load before calling this. */ static Dwarf_CU_Context _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; if (offset >= dis->de_last_offset){ return NULL; } if (dis->de_cu_context != NULL && dis->de_cu_context->cc_next != NULL && dis->de_cu_context->cc_next->cc_debug_offset == offset) { return dis->de_cu_context->cc_next; } if (dis->de_cu_context != NULL && dis->de_cu_context->cc_debug_offset <= offset) { for (cu_context = dis->de_cu_context; cu_context != NULL; cu_context = cu_context->cc_next) { if (offset >= cu_context->cc_debug_offset && offset < cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { return cu_context; } } } for (cu_context = dis->de_cu_context_list; cu_context != NULL; cu_context = cu_context->cc_next) { if (offset >= cu_context->cc_debug_offset && offset < cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { return cu_context; } } return NULL; } int dwarf_get_debugfission_for_die(Dwarf_Die die, struct Dwarf_Debug_Fission_Per_CU_s *fission_out, Dwarf_Error *error) { Dwarf_CU_Context context = 0; Dwarf_Debug dbg = 0; struct Dwarf_Debug_Fission_Per_CU_s * percu = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; if (!_dwarf_file_has_debug_fission_index(dbg)) { return DW_DLV_NO_ENTRY; } /* Logic should work for DW4 and DW5. */ if (context->cc_unit_type == DW_UT_type|| context->cc_unit_type == DW_UT_split_type ) { if (!_dwarf_file_has_debug_fission_tu_index(dbg)) { return DW_DLV_NO_ENTRY; } } else if (context->cc_unit_type == DW_UT_split_compile) { if (!_dwarf_file_has_debug_fission_cu_index(dbg)) { return DW_DLV_NO_ENTRY; } } percu = &context->cc_dwp_offsets; if (!percu->pcu_type) { return DW_DLV_NO_ENTRY; } *fission_out = *percu; return DW_DLV_OK; } static Dwarf_Bool is_unknown_UT_value(int ut) { switch(ut) { case DW_UT_compile: case DW_UT_type: case DW_UT_partial: return FALSE; case DW_UT_skeleton: case DW_UT_split_compile: case DW_UT_split_type: return FALSE; } return TRUE; } /* ASSERT: whichone is a DW_SECT* macro value. */ Dwarf_Unsigned _dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s* dwp, unsigned whichone, Dwarf_Unsigned * size) { Dwarf_Unsigned sectoff = 0; if (!dwp->pcu_type) { return 0; } sectoff = dwp->pcu_offset[whichone]; *size = dwp->pcu_size[whichone]; return sectoff; } /* _dwarf_get_fission_addition_die returns DW_DLV_OK etc. */ int _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index, Dwarf_Unsigned *offset, Dwarf_Unsigned *size, Dwarf_Error *error) { /* We do not yet know the DIE hash, so we cannot use it to identify the offset. */ Dwarf_CU_Context context = 0; Dwarf_Unsigned dwpadd = 0; Dwarf_Unsigned dwpsize = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dwpadd = _dwarf_get_dwp_extra_offset( &context->cc_dwp_offsets, dw_sect_index,&dwpsize); *offset = dwpadd; *size = dwpsize; return DW_DLV_OK; } /* Not sure if this is the only way to be sure early on in reading a compile unit. */ static int section_name_ends_with_dwo(const char *name) { int lenstr = 0; int dotpos = 0; if (!name) { return FALSE; } lenstr = strlen(name); if (lenstr < 5) { return FALSE; } dotpos = lenstr - 4; if (strcmp(name+dotpos,".dwo")) { return FALSE; } return TRUE; } void _dwarf_create_address_size_dwarf_error(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned addrsize, int errcode,const char *errname) { dwarfstring m; const char *bites = "bytes"; if (addrsize == 1) { bites = "byte"; } dwarfstring_constructor(&m); dwarfstring_append(&m,(char *)errname); dwarfstring_append_printf_u(&m, ": Address size of %u ", addrsize); dwarfstring_append_printf_s(&m, "%s is not supported. Corrupt DWARF.", (char *)bites); _dwarf_error_string(dbg,error,errcode, dwarfstring_string(&m)); dwarfstring_destructor(&m); } /* New January 2017 */ static int _dwarf_read_cu_version_and_abbrev_offset(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Bool is_info, UNUSEDARG unsigned group_number, unsigned offset_size, /* 4 or 8 */ Dwarf_CU_Context cu_context, /* end_data used for sanity checking */ Dwarf_Small * end_data, Dwarf_Unsigned * bytes_read_out, Dwarf_Error * error) { Dwarf_Small * data_start = data; Dwarf_Small * dataptr = data; int unit_type = 0; Dwarf_Ubyte addrsize = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version = 0; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, dataptr,DWARF_HALF_SIZE,error,end_data); dataptr += DWARF_HALF_SIZE; if (version == DW_CU_VERSION5) { Dwarf_Ubyte unit_typeb = 0; READ_UNALIGNED_CK(dbg, unit_typeb, Dwarf_Ubyte, dataptr, sizeof(unit_typeb),error,end_data); dataptr += sizeof(unit_typeb); unit_type = unit_typeb; /* We do not need is_info flag in DWARF5 */ if (is_unknown_UT_value(unit_type)) { /* DWARF5 object file is corrupt. Invalid value */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_CU_UT_TYPE_ERROR: we do not know " " the CU header unit_type 0x%x",unit_type); dwarfstring_append_printf_u(&m," (%u) so cannot" "process this compilation_unit. A valid type ", unit_type); dwarfstring_append(&m,"would be DW_UT_compile" ", for example"); _dwarf_error_string(dbg, error, DW_DLE_CU_UT_TYPE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, addrsize, unsigned char, dataptr, sizeof(addrsize),error,end_data); dataptr += sizeof(char); READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, dataptr, offset_size,error,end_data); dataptr += offset_size; } else if (version == DW_CU_VERSION2 || version == DW_CU_VERSION3 || version == DW_CU_VERSION4) { /* DWARF2,3,4 */ READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, dataptr, offset_size,error,end_data); dataptr += offset_size; READ_UNALIGNED_CK(dbg, addrsize, Dwarf_Ubyte, dataptr, sizeof(addrsize),error,end_data); dataptr += sizeof(addrsize); /* This is an initial approximation of unit_type. For DW4 we will refine this after we have built the CU header (by reading CU_die) */ unit_type = is_info?DW_UT_compile:DW_UT_type; } else { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } cu_context->cc_version_stamp = version; cu_context->cc_unit_type = unit_type; cu_context->cc_address_size = addrsize; cu_context->cc_abbrev_offset = abbrev_offset; if (!addrsize) { _dwarf_error(dbg,error,DW_DLE_ADDRESS_SIZE_ZERO); return DW_DLV_ERROR; } if (addrsize < MINIMUM_ADDRESS_SIZE || addrsize > MAXIMUM_ADDRESS_SIZE ) { _dwarf_create_address_size_dwarf_error(dbg,error,addrsize, DW_DLE_ADDRESS_SIZE_ERROR, "DW_DLE_ADDRESS_SIZE_ERROR::"); return DW_DLV_ERROR; } if (addrsize > sizeof(Dwarf_Addr)) { _dwarf_create_address_size_dwarf_error(dbg,error,addrsize, DW_DLE_ADDRESS_SIZE_ERROR, "DW_DLE_ADDRESS_SIZE_ERROR: not representable" " in Dwarf_Addr field."); return DW_DLV_ERROR; } /* We are ignoring this. Can get it from DWARF5. */ cu_context->cc_segment_selector_size = 0; *bytes_read_out = (dataptr - data_start); return DW_DLV_OK; } /* .debug_info[.dwo] .debug_types[.dwo] the latter only DWARF4. */ static int read_info_area_length_and_check(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned offset, Dwarf_Byte_Ptr *cu_ptr_io, Dwarf_Unsigned section_size, Dwarf_Byte_Ptr section_end_ptr, Dwarf_Unsigned *max_cu_global_offset_out, Dwarf_Error *error) { Dwarf_Byte_Ptr cu_ptr = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Unsigned max_cu_global_offset = 0; Dwarf_Unsigned length = 0; cu_ptr = *cu_ptr_io; /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, cu_ptr, local_length_size, local_extension_size, error,section_size,section_end_ptr); if (!length) { return DW_DLV_NO_ENTRY; } cu_context->cc_length_size = local_length_size; cu_context->cc_extension_size = local_extension_size; cu_context->cc_length = length; /* This is a bare minimum, not the real max offset. A preliminary sanity check. */ max_cu_global_offset = offset + length + local_extension_size + local_length_size; if (length > section_size) { _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } if (max_cu_global_offset > section_size) { _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } *cu_ptr_io = cu_ptr; *max_cu_global_offset_out = max_cu_global_offset; return DW_DLV_OK; } /* In DWARF4 GNU dwp there is a problem. We cannot read the CU die and it's DW_AT_GNU_dwo_id until we know the section offsets from the index files. Hence we do not know how to search the index files by key. So search by offset. There is no such problem in DWARF5. We have not yet corrected the unit_type so, for DWARF4, we check for simpler unit types. */ static int fill_in_dwp_offsets_if_present(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Sig8 * signaturedata, Dwarf_Off offset, Dwarf_Error *error) { Dwarf_Half unit_type = cu_context->cc_unit_type; const char * typename = 0; Dwarf_Half ver = cu_context->cc_version_stamp; if (unit_type == DW_UT_split_type || (ver == DW_CU_VERSION4 && unit_type == DW_UT_type)){ typename = "tu"; if (!_dwarf_file_has_debug_fission_tu_index(dbg) ){ /* nothing to do. */ return DW_DLV_OK; } } else if (unit_type == DW_UT_split_compile || (ver == DW_CU_VERSION4 && unit_type == DW_UT_compile)){ typename = "cu"; if (!_dwarf_file_has_debug_fission_cu_index(dbg) ){ /* nothing to do. */ return DW_DLV_OK; } } else { /* nothing to do. */ return DW_DLV_OK; } if (cu_context->cc_signature_present) { int resdf = 0; resdf = dwarf_get_debugfission_for_key(dbg, signaturedata, typename, &cu_context->cc_dwp_offsets, error); if (resdf == DW_DLV_ERROR) { return resdf; } else if (resdf == DW_DLV_NO_ENTRY) { _dwarf_error_string(dbg, error, DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH, "DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH: " " dwarf_get_debugfission_for_key returned" " DW_DLV_NO_ENTRY, something is wrong"); return DW_DLV_ERROR; } } else { int resdf = 0; resdf = _dwarf_get_debugfission_for_offset(dbg, offset, typename, &cu_context->cc_dwp_offsets, error); if (resdf == DW_DLV_ERROR) { return resdf; } else if (resdf == DW_DLV_NO_ENTRY) { _dwarf_error_string(dbg, error, DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH, "DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH: " " dwarf_get_debugfission_for_offset returned" " DW_DLV_NO_ENTRY, something is wrong"); return DW_DLV_ERROR; } cu_context->cc_signature = cu_context->cc_dwp_offsets.pcu_hash; cu_context->cc_signature_present = TRUE; } return DW_DLV_OK; } static int finish_cu_context_via_cudie_inner( Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Error *error) { { /* DW4: Look for DW_AT_dwo_id and DW_AT_low_pc and more. if there is one pick up the hash DW5: hash in skeleton CU die Also pick up cc_str_offset_base and any other base values. */ Dwarf_Die cudie = 0; int resdwo = 0; /* Must call the internal siblingof so we do not depend on the dbg...de_cu_context used by and for dwarf_cu_header_* calls. */ resdwo = _dwarf_siblingof_internal(dbg,NULL, cu_context, cu_context->cc_is_info, &cudie, error); if (resdwo == DW_DLV_OK) { Dwarf_Half cutag = 0; int resdwob = 0; resdwob = find_cu_die_base_fields(dbg, cu_context, cudie, error); if (resdwob == DW_DLV_NO_ENTRY) { /* The CU die has no children */ dwarf_dealloc(dbg,cudie,DW_DLA_DIE); cudie = 0; cu_context->cc_cu_die_has_children = FALSE; return DW_DLV_OK; } else if (resdwob == DW_DLV_ERROR) { /* Not applicable or an error */ dwarf_dealloc(dbg,cudie,DW_DLA_DIE); cudie = 0; return resdwob; } resdwob = dwarf_tag(cudie,&cutag,error); if (resdwob == DW_DLV_OK) { cu_context->cc_cu_die_tag = cutag; } dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return resdwob; } else if (resdwo == DW_DLV_NO_ENTRY) { /* no cudie. Empty CU. */ return DW_DLV_OK; } else { /* no cudie. Error.*/ return resdwo; } } return DW_DLV_OK; } static void local_dealloc_cu_context(Dwarf_Debug dbg, Dwarf_CU_Context context) { Dwarf_Hash_Table hash_table = 0; if (!context) { return; } hash_table = context->cc_abbrev_hash_table; if (hash_table) { _dwarf_free_abbrev_hash_table_contents(dbg,hash_table); hash_table->tb_entries = 0; dwarf_dealloc(dbg,hash_table, DW_DLA_HASH_TABLE); context->cc_abbrev_hash_table = 0; } dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); } static void report_local_unit_type_error(Dwarf_Debug dbg, int unit_type, const char *msg, Dwarf_Error *err) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_CU_UT_TYPE_VALUE: %s ",(char *)msg); dwarfstring_append_printf_u(&m, "the compilation unit unit_type is 0x%x," " which is unknown to libdwarf. Corrupt DWARF.", unit_type); _dwarf_error_string(dbg,err,DW_DLE_CU_UT_TYPE_VALUE, dwarfstring_string(&m)); dwarfstring_destructor(&m); } /* This function is used to create a CU Context for a compilation-unit that begins at offset in .debug_info. The CU Context is attached to the list of CU Contexts for this dbg. It is assumed that the CU at offset has not been read before, and so do not call this routine before making sure of this with _dwarf_find_CU_Context(). Returns NULL on error. As always, being an internal routine, assumes a good dbg. The offset argument is global offset, the offset in the section, irrespective of CUs. The offset has the DWP Package File offset built in as it comes from the actual section. max_cu_local_offset is a local offset in this CU. So zero of this field is immediately following the length field of the CU header. so max_cu_local_offset is identical to the CU length field. max_cu_global_offset is the offset one-past the end of this entire CU. */ static int _dwarf_make_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,Dwarf_Bool is_info, Dwarf_CU_Context * context_out,Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned typeoffset = 0; Dwarf_Sig8 signaturedata; Dwarf_Unsigned types_extra_len = 0; Dwarf_Unsigned max_cu_local_offset = 0; Dwarf_Unsigned max_cu_global_offset = 0; Dwarf_Byte_Ptr cu_ptr = 0; Dwarf_Byte_Ptr section_end_ptr = 0; int local_length_size = 0; Dwarf_Unsigned bytes_read = 0; const char * secname = 0; Dwarf_Debug_InfoTypes dis = 0; struct Dwarf_Section_s * secdp = 0; Dwarf_Unsigned section_size = 0; int unit_type = 0; int version = 0; Dwarf_Small * dataptr = 0; int res = 0; if (is_info) { secname = dbg->de_debug_info.dss_name; dis = &dbg->de_info_reading; secdp = &dbg->de_debug_info; } else { secname = dbg->de_debug_types.dss_name; dis = &dbg->de_types_reading; secdp = &dbg->de_debug_types; } section_size = secdp->dss_size; signaturedata = dwarfsig8zero; cu_context = (Dwarf_CU_Context)_dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1); if (!cu_context) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } cu_context->cc_dbg = dbg; cu_context->cc_is_info = is_info; dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; /* Preliminary sanity checking. */ if (!dataptr) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } if (offset >= section_size) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } if ((offset+4) > section_size) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } section_end_ptr = dataptr+section_size; cu_ptr = (Dwarf_Byte_Ptr) (dataptr+offset); if (section_name_ends_with_dwo(secname)) { cu_context->cc_is_dwo = TRUE; } res = read_info_area_length_and_check(dbg, cu_context, offset, &cu_ptr, section_size, section_end_ptr, &max_cu_global_offset, error); if (res != DW_DLV_OK) { local_dealloc_cu_context(dbg,cu_context); return res; } local_length_size = cu_context->cc_length_size; length = cu_context->cc_length; max_cu_local_offset = length; res = _dwarf_read_cu_version_and_abbrev_offset(dbg, cu_ptr, is_info, dbg->de_groupnumber, local_length_size, cu_context, section_end_ptr, &bytes_read,error); if (res != DW_DLV_OK) { local_dealloc_cu_context(dbg,cu_context); return res; } version = cu_context->cc_version_stamp; cu_ptr += bytes_read; unit_type = cu_context->cc_unit_type; if (cu_ptr > section_end_ptr) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } /* In a dwp context, the abbrev_offset is still incomplete. We need to add in the base from the .debug_cu_index or .debug_tu_index . Done below */ /* At this point, for DW4, the unit_type is not fully correct as we don't know if it is a skeleton or a split_compile or split_type */ if (version == DW_CU_VERSION5 || version == DW_CU_VERSION4) { /* DW4/DW5 header fields, depending on UT type. See DW5 section 7.5.1.x, DW4 data is a GNU extension of DW4. */ switch(unit_type) { case DW_UT_split_type: case DW_UT_type: { types_extra_len = sizeof(Dwarf_Sig8) /* 8 */ + local_length_size /*type_offset size*/; break; } case DW_UT_skeleton: case DW_UT_split_compile: { types_extra_len = sizeof(Dwarf_Sig8) /* 8 */; break; } case DW_UT_compile: /* No additional fields */ case DW_UT_partial: /* No additional fields */ break; default: /* Data corruption in libdwarf? */ report_local_unit_type_error(dbg, unit_type, "(DW4 or DW5)",error); local_dealloc_cu_context(dbg,cu_context); return DW_DLV_ERROR; } } /* Compare the space following the length field to the bytes in the CU header. */ if (length < (CU_VERSION_STAMP_SIZE /* is 2 */ + local_length_size /*for debug_abbrev offset */ + CU_ADDRESS_SIZE_SIZE /* is 1 */ + /* and finally size of the rest of the header: */ types_extra_len)) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } /* Now we can read the fields with some confidence, we know the fields of the header are inside the section. */ cu_context->cc_unit_type = unit_type; switch(unit_type) { case DW_UT_split_type: case DW_UT_type: { int tres = 0; /* ASSERT: DW_CU_VERSION4 or DW_CU_VERSION5, determined by logic above. Now read the debug_types extra header fields of the signature (8 bytes) and the typeoffset. This can be in executable, ordinary object (as in Type Unit), there was no dwo in DWARF4 */ memcpy(&signaturedata,cu_ptr,sizeof(signaturedata)); cu_ptr += sizeof(signaturedata); tres = _dwarf_read_unaligned_ck_wrapper(dbg, &typeoffset,cu_ptr,local_length_size, section_end_ptr,error); if (tres != DW_DLV_OK ) { local_dealloc_cu_context(dbg,cu_context); return tres; } cu_context->cc_signature = signaturedata; cu_context->cc_signature_present = TRUE; cu_context->cc_signature_offset = typeoffset; if (typeoffset >= max_cu_local_offset) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD); return DW_DLV_ERROR; } } break; case DW_UT_skeleton: case DW_UT_split_compile: { /* These unit types make a pair and paired units have identical signature.*/ memcpy(&signaturedata,cu_ptr,sizeof(signaturedata)); cu_context->cc_signature = signaturedata; cu_context->cc_signature_present = TRUE; break; } /* The following with no additional fields */ case DW_UT_compile: case DW_UT_partial: break; default: { /* Data corruption in libdwarf? */ report_local_unit_type_error(dbg, unit_type, "",error); local_dealloc_cu_context(dbg,cu_context); return DW_DLV_ERROR; } } cu_context->cc_abbrev_hash_table = (Dwarf_Hash_Table) _dwarf_get_alloc(dbg,DW_DLA_HASH_TABLE, 1); if (cu_context->cc_abbrev_hash_table == NULL) { local_dealloc_cu_context(dbg,cu_context); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } cu_context->cc_debug_offset = offset; /* This is recording an overall section value for later sanity checking. */ dis->de_last_offset = max_cu_global_offset; *context_out = cu_context; return DW_DLV_OK; } static int reloc_incomplete(int res,Dwarf_Error err) { int e = 0; if (res == DW_DLV_OK) { return FALSE; } if (res == DW_DLV_NO_ENTRY) { return FALSE; } e = dwarf_errno(err); switch(e) { case DW_DLE_RELOC_MISMATCH_INDEX: case DW_DLE_RELOC_MISMATCH_RELOC_INDEX: case DW_DLE_RELOC_MISMATCH_STRTAB_INDEX: case DW_DLE_RELOC_SECTION_MISMATCH: case DW_DLE_RELOC_SECTION_MISSING_INDEX: case DW_DLE_RELOC_SECTION_LENGTH_ODD: case DW_DLE_RELOC_SECTION_PTR_NULL: case DW_DLE_RELOC_SECTION_MALLOC_FAIL: case DW_DLE_SEEK_OFF_END: case DW_DLE_RELOC_INVALID: case DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD: return TRUE; } return FALSE; } /* Returns offset of next compilation-unit thru next_cu_offset pointer. It sequentially moves from one cu to the next. The current cu is recorded internally by libdwarf. The _b form is new for DWARF4 adding new returned fields. */ int dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Unsigned * next_cu_offset, Dwarf_Error * error) { Dwarf_Bool is_info = true; Dwarf_Half header_type = 0; return _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, 0,0,0,0,0, next_cu_offset, &header_type, error); } int dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Half * offset_size, Dwarf_Half * extension_size, Dwarf_Unsigned * next_cu_offset, Dwarf_Error * error) { Dwarf_Bool is_info = true; Dwarf_Half header_type = 0; return _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, offset_size,extension_size, 0,0,0, next_cu_offset, &header_type, error); } int dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Half * offset_size, Dwarf_Half * extension_size, Dwarf_Sig8 * signature, Dwarf_Unsigned * typeoffset, Dwarf_Unsigned * next_cu_offset, Dwarf_Error * error) { Dwarf_Half header_type = 0; int res =_dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, offset_size, extension_size, signature, 0, typeoffset, next_cu_offset, &header_type, error); return res; } int dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Half * offset_size, Dwarf_Half * extension_size, Dwarf_Sig8 * signature, Dwarf_Unsigned * typeoffset, Dwarf_Unsigned * next_cu_offset, Dwarf_Half * header_cu_type, Dwarf_Error * error) { /* Faking has_signature to do nothing. */ Dwarf_Bool* has_signature = 0; int res = 0; res = _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, offset_size, extension_size, signature, has_signature, typeoffset, next_cu_offset, header_cu_type, error); return res; } static void local_attrlist_dealloc(Dwarf_Debug dbg, Dwarf_Signed atcount, Dwarf_Attribute *alist) { Dwarf_Signed i = 0; for ( ; i < atcount; ++i) { dwarf_dealloc(dbg,alist[i],DW_DLA_ATTR); } dwarf_dealloc(dbg,alist,DW_DLA_LIST); } /* For a DWP/DWO the base fields of a CU are inherited from the skeleton. DWARF5 section 3.1.3 "Split Full Compilation Unit Entries". */ static int find_cu_die_base_fields(Dwarf_Debug dbg, Dwarf_CU_Context cucon, Dwarf_Die cudie, Dwarf_Error* error) { Dwarf_CU_Context cu_context = 0; Dwarf_Attribute * alist = 0; Dwarf_Signed atcount = 0; unsigned version_stamp = 2; int alres = 0; Dwarf_Signed i = 0; Dwarf_Signed low_pc_attrnum = -1; Dwarf_Signed at_addr_base_attrnum = -1; cu_context = cudie->di_cu_context; version_stamp = cu_context->cc_version_stamp; alres = dwarf_attrlist(cudie, &alist, &atcount,error); if (alres != DW_DLV_OK) { /* Something is badly wrong. No attrlist! */ return alres; } /* DW_AT_dwo_id and/or DW_AT_GNU_dwo_id are only found in some experimental DWARF4. Even DWARF3,4 use DW_AT_low_pc as base address DWARF5 changed CU header contents to make this attribute unnecessary. DW_AT_GNU_odr_signature is the same format, but is in a different namespace so not appropriate here.. */ for (i = 0; i < atcount; ++i) { Dwarf_Half attrnum = 0; Dwarf_Half form = 0; int ares = 0; int ares2 = 0; Dwarf_Attribute attr = alist[i]; ares = dwarf_whatattr(attr,&attrnum,error); if (ares == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } ares2 = dwarf_whatform(attr,&form,error); if (ares2 == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } /* We are not returning on DW_DLV_NO_ENTRY or DW_DLV_ERROR here. Such will be caught later. Lets finish a CU die scan and finish the cu_context */ if (ares == DW_DLV_OK && ares2 == DW_DLV_OK) { switch(form) { case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: cucon->cc_at_strx_present = TRUE; } switch(attrnum) { case DW_AT_dwo_id: case DW_AT_GNU_dwo_id: { Dwarf_Sig8 signature; /* This is for DWARF4 with an early non-standard version of split dwarf. Not DWARF5. */ int sres = 0; if (version_stamp != DW_CU_VERSION4 ) { /* Not supposed to happen. */ local_attrlist_dealloc(dbg,atcount,alist); _dwarf_error(dbg,error, DW_DLE_IMPROPER_DWO_ID); return DW_DLV_ERROR; } signature = dwarfsig8zero; sres = dwarf_formsig8_const(attr, &signature,error); if (sres == DW_DLV_OK) { if (!cucon->cc_signature_present) { cucon->cc_signature = signature; cucon->cc_signature_present = TRUE; } else { /* Something wrong. Two styles of sig? Can happen with DWARF4 debug-fission extension DWO_id. */ if (memcmp(&signature,&cucon->cc_signature, sizeof(signature))) { /* The two sigs do not match! */ const char *m="DW_DLE_SIGNATURE_MISMATCH" "DWARF4 extension fission signature" " and DW_AT_GNU_dwo_id do not match" " ignoring DW_AT[_GNU]_dwo_id"; dwarf_insert_harmless_error(dbg, (char*)m); } } } else { /* Something is badly wrong. */ local_attrlist_dealloc(dbg,atcount,alist); return sres; } /* Something is badly wrong. */ break; } /* If, in .debug_rnglists for a CU the applicable range has no base address this attribute provides a base address. If this is indexed doing this now would lead to an infinite recursion. So wait till all the other fields seen. */ case DW_AT_low_pc: { low_pc_attrnum = i; break; } /* The offset is of the first offset in .debug_str_offsets that is the string table for this CU. */ case DW_AT_str_offsets_base:{ int udres = 0; udres = dwarf_global_formref(attr, &cucon->cc_str_offsets_base, error); if (udres == DW_DLV_OK) { cucon->cc_str_offsets_base_present = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ return udres; } break; } /* offset in .debug_loclists of the offsets table applicable to this CU. */ case DW_AT_loclists_base: { int udres = 0; udres = dwarf_global_formref(attr, &cucon->cc_loclists_base, error); if (udres == DW_DLV_OK) { cucon->cc_loclists_base_present = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ return udres; } break; } /* Base offset in .debug_addr of the addr table for this CU. DWARF5 (and possibly GNU DWARF4) */ case DW_AT_addr_base: case DW_AT_GNU_addr_base: { int udres = 0; at_addr_base_attrnum = i; udres = dwarf_global_formref(attr, &cucon->cc_addr_base, error); if (udres == DW_DLV_OK) { cucon->cc_addr_base_present = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ return udres; } break; } case DW_AT_GNU_ranges_base: { /* The DW4 ranges base was never used in GNU but did get emitted in skeletons. http://llvm.1065342.n5.nabble.com/ DebugInfo-DW-AT-GNU-ranges-base-in- non-fission-td64194.html But we accept it anyway. */ /* offset in .debug_rnglists of the offsets table applicable to this CU. Note that this base applies when referencing from the dwp, but NOT when referencing from the a.out */ int udres = 0; udres = dwarf_global_formref(attr, &cucon->cc_ranges_base, error); if (udres == DW_DLV_OK) { cucon->cc_ranges_base_present = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ return udres; } break; } case DW_AT_rnglists_base: { int udres = 0; udres = dwarf_global_formref(attr, &cucon->cc_rnglists_base, error); if (udres == DW_DLV_OK) { cucon->cc_rnglists_base_present = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ return udres; } break; } /* A signature, found in a DWARF5 skeleton compilation unit. */ case DW_AT_GNU_dwo_name: case DW_AT_dwo_name: { int dnres = 0; dnres = dwarf_formstring(attr, &cucon->cc_dwo_name,error); if (dnres != DW_DLV_OK) { local_attrlist_dealloc(dbg,atcount,alist); return dnres; } cucon->cc_dwo_name_present = TRUE; break; } default: /* do nothing, not an attribute we need to deal with here. */ break; } } } if (low_pc_attrnum >= 0 ){ int lres = 0; Dwarf_Attribute attr = alist[low_pc_attrnum]; Dwarf_Half form = 0; /* If the form is indexed, we better have seen DW_AT_addr_base.! */ lres = dwarf_whatform(attr,&form,error); if (lres != DW_DLV_OK) { local_attrlist_dealloc(dbg,atcount,alist); return lres; } if (dwarf_addr_form_is_indexed(form)) { if (at_addr_base_attrnum < 0) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_ATTR_NO_CU_CONTEXT: " "The DW_AT_low_pc CU_DIE uses " "an indexed attribute yet " "DW_AT_addr_base is not in the CU DIE."); _dwarf_error_string(dbg,error, DW_DLE_ATTR_NO_CU_CONTEXT, dwarfstring_string(&m)); dwarfstring_destructor(&m); local_attrlist_dealloc(dbg,atcount,alist); return DW_DLV_ERROR; } } lres = dwarf_formaddr(attr, &cucon->cc_low_pc,error); if (lres == DW_DLV_OK) { cucon->cc_low_pc_present = TRUE; } else { /* Something is badly wrong. */ local_attrlist_dealloc(dbg,atcount,alist); return lres; } } local_attrlist_dealloc(dbg,atcount,alist); alist = 0; atcount = 0; { int chres = 0; Dwarf_Half flag = 0; /* always winds up with cc_cu_die_has_children set intentionally...to something. */ cucon->cc_cu_die_has_children = TRUE; chres = dwarf_die_abbrev_children_flag(cudie,&flag); /* If chres is not DW_DLV_OK the assumption of children remains true. */ if (chres == DW_DLV_OK) { cucon->cc_cu_die_has_children = flag; } } return DW_DLV_OK; } /* Called only for DWARF4 */ static void assign_correct_unit_type(Dwarf_CU_Context cu_context) { Dwarf_Half tag = cu_context->cc_cu_die_tag; if (!cu_context->cc_cu_die_has_children) { if (cu_context->cc_signature_present) { if (tag == DW_TAG_compile_unit || tag == DW_TAG_type_unit ) { cu_context->cc_unit_type = DW_UT_skeleton; } } } else { if (cu_context->cc_signature_present) { if (tag == DW_TAG_compile_unit) { cu_context->cc_unit_type = DW_UT_split_compile; } else if (tag == DW_TAG_type_unit) { cu_context->cc_unit_type = DW_UT_split_type; } } } } static int finish_up_cu_context_from_cudie(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_CU_Context cu_context, Dwarf_Error *error) { int version = cu_context->cc_version_stamp; Dwarf_Sig8 signaturedata; int res = 0; signaturedata = dwarfsig8zero; signaturedata = cu_context->cc_signature; /* Loads and initializes the dwarf .debug_cu_index and .debug_tu_index split dwarf package file sections */ res = fill_in_dwp_offsets_if_present(dbg, cu_context, &signaturedata, offset, error); if (res == DW_DLV_ERROR) { return res; } if (res != DW_DLV_OK) { return res; } if (cu_context->cc_dwp_offsets.pcu_type) { Dwarf_Unsigned absize = 0; Dwarf_Unsigned aboff = 0; aboff = _dwarf_get_dwp_extra_offset( &cu_context->cc_dwp_offsets, DW_SECT_ABBREV, &absize); cu_context->cc_abbrev_offset += aboff; } if (cu_context->cc_abbrev_offset >= dbg->de_debug_abbrev.dss_size) { _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR); return DW_DLV_ERROR; } /* Now we can read the CU die and determine the correct DW_UT_ type for DWARF4 and some offset base fields for DW4-fission and DW5, and even DW3 and DW4 and some non-std DW2 */ { res = finish_cu_context_via_cudie_inner(dbg, cu_context, error); if (res == DW_DLV_ERROR) { return res; } if (res != DW_DLV_OK) { return res; } if (version == DW_CU_VERSION4) { assign_correct_unit_type(cu_context); } if (cu_context->cc_signature_present) { /* Initially just for DW_SECT_STR_OFFSETS, finds the section offset of the contribution which is not the same as the table offset. */ res = _dwarf_find_all_offsets_via_fission(dbg, cu_context,error); if (res == DW_DLV_ERROR) { /* something seriously wrong. */ return res; } } } return DW_DLV_OK; } /* CU_Contexts do not overlap. cu_context we see here is not in the list we are updating. See _dwarf_find_CU_Context() Invariant: cc_debug_offset in strictly ascending order in the list. */ static void insert_into_cu_context_list(Dwarf_Debug_InfoTypes dis, Dwarf_CU_Context icu_context) { Dwarf_Unsigned ioffset = icu_context->cc_debug_offset; Dwarf_Unsigned eoffset = 0; Dwarf_Unsigned hoffset = 0; Dwarf_Unsigned coffset = 0; Dwarf_CU_Context next = 0; Dwarf_CU_Context past = 0; Dwarf_CU_Context cur = 0; /* Add the context into the section context list. This is the one and only place where it is saved for re-use and eventual dealloc. */ if (!dis->de_cu_context_list) { /* First cu encountered. */ dis->de_cu_context_list = icu_context; dis->de_cu_context_list_end = icu_context; return; } eoffset = dis->de_cu_context_list_end->cc_debug_offset; if (eoffset < ioffset) { /* Normal case, add at end. */ dis->de_cu_context_list_end->cc_next = icu_context; dis->de_cu_context_list_end = icu_context; return; } hoffset = dis->de_cu_context_list->cc_debug_offset; if (hoffset > ioffset) { /* insert as new head. Unusual. */ next = dis->de_cu_context_list; dis->de_cu_context_list = icu_context; dis->de_cu_context_list->cc_next = next; /* No need to touch de_cu_context_list_end */ return; } cur = dis->de_cu_context_list; past = 0; /* Insert in middle somewhere. Neither at start nor end. ASSERT: cur non-null ASSERT: past non-null */ past = cur; cur = cur->cc_next; for ( ; cur ; cur = next) { next = cur->cc_next; coffset = cur->cc_debug_offset; if (coffset > ioffset) { /* Insert before cur, using past. ASSERT: past non-null */ past->cc_next = icu_context; icu_context->cc_next = cur; return; } past = cur; } /* Impossible, for end, coffset (ie, eoffset) > ioffset */ /* NOTREACHED */ return; } Dwarf_Unsigned _dwarf_calculate_next_cu_context_offset(Dwarf_CU_Context cu_context) { Dwarf_Unsigned next_cu_offset = 0; next_cu_offset = cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; return next_cu_offset; } int _dwarf_create_a_new_cu_context_record_on_list( Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis, Dwarf_Bool is_info, Dwarf_Unsigned section_size, Dwarf_Unsigned new_cu_offset, Dwarf_CU_Context *context_out, Dwarf_Error *error) { int res = 0; Dwarf_CU_Context cu_context = 0; if ((new_cu_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >= section_size) { _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD); return DW_DLV_ERROR; } res = _dwarf_make_CU_Context(dbg, new_cu_offset,is_info, &cu_context,error); if (res != DW_DLV_OK) { return res; } /* The called func does not dealloc cu_context in case of error, so we do it here. */ res = finish_up_cu_context_from_cudie(dbg,new_cu_offset, cu_context,error); if (res == DW_DLV_ERROR) { local_dealloc_cu_context(dbg,cu_context); return res; } if (res == DW_DLV_NO_ENTRY) { local_dealloc_cu_context(dbg,cu_context); return res; } /* Add the new cu_context to a list of contexts */ insert_into_cu_context_list(dis,cu_context); *context_out = cu_context; return DW_DLV_OK; } int _dwarf_load_die_containing_section(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Error *error) { Dwarf_Error err2 = 0; int resd = is_info? _dwarf_load_debug_info(dbg, &err2): _dwarf_load_debug_types(dbg,&err2); if (resd == DW_DLV_ERROR) { if (reloc_incomplete(resd,err2)) { /* We will assume all is ok, though it is not. Relocation errors need not be fatal. */ char msg_buf[300]; char *dwerrmsg = 0; char *msgprefix = "Relocations did not complete successfully, " "but we are " " ignoring error: "; size_t totallen = 0; size_t prefixlen = 0; dwerrmsg = dwarf_errmsg(err2); prefixlen = strlen(msgprefix); totallen = prefixlen + strlen(dwerrmsg); if ( totallen >= sizeof(msg_buf)) { /* Impossible unless something corrupted. Provide a shorter dwerrmsg*/ strcpy(msg_buf, "Error:corrupted dwarf message table!"); } else { strcpy(msg_buf,msgprefix); strcpy(msg_buf+prefixlen,dwerrmsg); } dwarf_insert_harmless_error(dbg,msg_buf); /* Fall thru to use the newly loaded section. even though it might not be adequately relocated. */ dwarf_dealloc_error(dbg,err2); if (error) { *error = 0; } return DW_DLV_OK; } if (error) { *error = err2; } else { dwarf_dealloc_error(dbg,err2); } return DW_DLV_ERROR; } return resd; } int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Half * offset_size, Dwarf_Half * extension_size, Dwarf_Sig8 * signature_out, Dwarf_Bool * has_signature, Dwarf_Unsigned *typeoffset, Dwarf_Unsigned * next_cu_offset, /* header_type: DW_UT_compile, DW_UT_partial, DW_UT_type, returned through the pointer. A new item in DWARF5, synthesized for earlier DWARF CUs (& TUs). */ Dwarf_Half * header_type, Dwarf_Error * error) { /* Offset for current and new CU. */ Dwarf_Unsigned new_offset = 0; /* CU Context for current CU. */ Dwarf_CU_Context cu_context = 0; Dwarf_Debug_InfoTypes dis = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *dataptr = 0; struct Dwarf_Section_s *secdp = 0; int res = 0; /* ***** BEGIN CODE ***** */ if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (is_info) { dis =&dbg->de_info_reading; dataptr = dbg->de_debug_info.dss_data; secdp = &dbg->de_debug_info; } else { dis =&dbg->de_types_reading; dataptr = dbg->de_debug_types.dss_data; secdp = &dbg->de_debug_types; } if (!dataptr) { res = _dwarf_load_die_containing_section(dbg, is_info, error); if (res != DW_DLV_OK) { return res; } } #if 0 /* Get offset into .debug_info of next CU. If dbg has no context, this has to be the first one. */ if (!dis->de_cu_context) { Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; new_offset = 0; if (!dataptr) { Dwarf_Error err2= 0; int resd = is_info? _dwarf_load_debug_info(dbg, &err2): _dwarf_load_debug_types(dbg,&err2); if (resd != DW_DLV_OK) { if (reloc_incomplete(resd,err2)) { /* We will assume all is ok, though it is not. Relocation errors need not be fatal. */ char msg_buf[300]; char *dwerrmsg = 0; char *msgprefix = "Relocations did not complete successfully, " "but we are " " ignoring error: "; size_t totallen = 0; size_t prefixlen = 0; dwerrmsg = dwarf_errmsg(err2); prefixlen = strlen(msgprefix); totallen = prefixlen + strlen(dwerrmsg); if ( totallen >= sizeof(msg_buf)) { /* Impossible unless something corrupted. Provide a shorter dwerrmsg*/ strcpy(msg_buf, "Error:corrupted dwarf message table!"); } else { strcpy(msg_buf,msgprefix); strcpy(msg_buf+prefixlen,dwerrmsg); } dwarf_insert_harmless_error(dbg,msg_buf); /* Fall thru to use the newly loaded section. even though it might not be adequately relocated. */ if (resd == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,err2); err2 = 0; } } else { if (error) { *error = err2; err2 = 0; } /* There is nothing here, or what is here is damaged. */ return resd; } } } } #endif /* 0 */ if (!dis->de_cu_context) { /* We are leaving new_offset zero. We are at the start of a section. */ new_offset = 0; } else { new_offset = _dwarf_calculate_next_cu_context_offset( dis->de_cu_context); } /* Check that there is room in .debug_info beyond the new offset for at least a new cu header. If not, return -1 (DW_DLV_NO_ENTRY) to indicate end of debug_info section, and reset de_cu_debug_info_offset to enable looping back through the cu's. */ section_size = secdp->dss_size; if ((new_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >= section_size) { dis->de_cu_context = NULL; return DW_DLV_NO_ENTRY; } /* Check if this CU has been read before. */ cu_context = _dwarf_find_CU_Context(dbg, new_offset,is_info); /* If not, make CU Context for it. */ if (!cu_context) { res = _dwarf_create_a_new_cu_context_record_on_list( dbg,dis,is_info,section_size,new_offset, &cu_context,error); if (res != DW_DLV_OK) { return res; } } /* Next assignment is what makes _dwarf_next_cu_header*() with no offset presented work to march through all the CUs in order. Other places creating a cu_context do not set de_cu_context. */ dis->de_cu_context = cu_context; if (cu_header_length) { *cu_header_length = cu_context->cc_length; } if (version_stamp) { *version_stamp = cu_context->cc_version_stamp; } if (abbrev_offset) { *abbrev_offset = cu_context->cc_abbrev_offset; } if (address_size) { *address_size = cu_context->cc_address_size; } if (offset_size) { *offset_size = cu_context->cc_length_size; } if (extension_size) { *extension_size = cu_context->cc_extension_size; } if (header_type) { *header_type = cu_context->cc_unit_type; } if (typeoffset) { *typeoffset = cu_context->cc_signature_offset; } if (signature_out) { *signature_out = cu_context->cc_signature; } if (has_signature) { *has_signature = cu_context->cc_signature_present; } /* Determine the offset of the next CU. */ new_offset = new_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; /* Allowing null argument starting 22 April 2019. */ if (next_cu_offset) { *next_cu_offset = new_offset; } { Dwarf_Debug tieddbg = 0; int tres = 0; tieddbg = dbg->de_tied_data.td_tied_object; if (tieddbg) { tres = _dwarf_merge_all_base_attrs_of_cu_die( dbg, cu_context, tieddbg, 0, error); } if (tres == DW_DLV_ERROR) { /* We'll assume any errors will be discovered later. Lets get our CU_context finished. */ dwarf_dealloc_error(dbg,*error); *error = 0; } } return DW_DLV_OK; } /* This involves data in a split dwarf or package file. Given hash signature, return the CU_die of the applicable CU. The hash is assumed to be from 'somewhere'. For DWARF 4: From a skeleton DIE DW_AT_GNU_dwo_id ("cu" case) or From a DW_FORM_ref_sig8 ("tu" case). For DWARF5: From dwo_id in a skeleton CU header (DW_UT_skeleton). From a DW_FORM_ref_sig8 ("tu" case). If "tu" request, the CU_die of of the type unit. Works on either a dwp package file or a dwo object. If "cu" request, the CU_die of the compilation unit. Works on either a dwp package file or a dwo object. If the hash passed is not present, returns DW_DLV_NO_ENTRY (but read the next two paragraphs for more detail). If a dwp package file with the hash signature is present in the applicable index but no matching compilation unit can be found, it returns DW_DLV_ERROR. If a .dwo object there is no index and we look at the compilation units (possibly all of them). If not present then we return DW_DLV_NO_ENTRY. The returned_die is a CU DIE if the sig_type is "cu". The returned_die is a type DIE if the sig_type is "tu". Perhaps both should return CU die. New 27 April, 2015 */ int dwarf_die_from_hash_signature(Dwarf_Debug dbg, Dwarf_Sig8 * hash_sig, const char * sig_type /* "tu" or "cu"*/, Dwarf_Die * returned_die, Dwarf_Error* error) { Dwarf_Bool is_type_unit = FALSE; int sres = 0; sres = _dwarf_load_debug_info(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } sres = _dwarf_load_debug_types(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } if (!strcmp(sig_type,"tu")) { is_type_unit = TRUE; } else if (!strcmp(sig_type,"cu")) { is_type_unit = FALSE; } else { _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING); return DW_DLV_ERROR; } if (_dwarf_file_has_debug_fission_index(dbg)) { /* This is a dwp package file. */ int fisres = 0; Dwarf_Bool is_info2 = 0; Dwarf_Off cu_header_off = 0; Dwarf_Off cu_size = 0; Dwarf_Off cu_die_off = 0; Dwarf_Off typeoffset = 0; Dwarf_Die cudie = 0; Dwarf_Die typedie = 0; Dwarf_CU_Context context = 0; Dwarf_Debug_Fission_Per_CU fiss; memset(&fiss,0,sizeof(fiss)); fisres = dwarf_get_debugfission_for_key(dbg,hash_sig, sig_type,&fiss,error); if (fisres != DW_DLV_OK) { return fisres; } /* Found it */ if (is_type_unit) { /* DW4 has debug_types, so look in .debug_types Else look in .debug_info. */ is_info2 = dbg->de_debug_types.dss_size?FALSE:TRUE; } else { is_info2 = TRUE; } cu_header_off = _dwarf_get_dwp_extra_offset(&fiss, is_info2?DW_SECT_INFO:DW_SECT_TYPES, &cu_size); fisres = dwarf_get_cu_die_offset_given_cu_header_offset_b( dbg,cu_header_off, is_info2, &cu_die_off,error); if (fisres != DW_DLV_OK) { return fisres; } fisres = dwarf_offdie_b(dbg,cu_die_off,is_info2, &cudie,error); if (fisres != DW_DLV_OK) { return fisres; } if (!is_type_unit) { *returned_die = cudie; return DW_DLV_OK; } context = cudie->di_cu_context; typeoffset = context->cc_signature_offset; typeoffset += cu_header_off; fisres = dwarf_offdie_b(dbg,typeoffset,is_info2, &typedie,error); if (fisres != DW_DLV_OK) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return fisres; } *returned_die = typedie; dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return DW_DLV_OK; } /* Look thru all the CUs, there is no DWP tu/cu index. There will be COMDAT sections for the type TUs (DW_UT_type). A single non-comdat for the DW_UT_compile. */ /* FIXME: DW_DLE_DEBUG_FISSION_INCOMPLETE */ _dwarf_error(dbg,error,DW_DLE_DEBUG_FISSION_INCOMPLETE); return DW_DLV_ERROR; } static int dwarf_ptr_CU_offset(Dwarf_CU_Context cu_context, Dwarf_Byte_Ptr di_ptr, Dwarf_Bool is_info, Dwarf_Off * cu_off) { Dwarf_Debug dbg = cu_context->cc_dbg; Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *cu_off = (di_ptr - dataptr); return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ /* Just for debug purposes */ void print_sib_offset(Dwarf_Die sibling) { Dwarf_Off sib_off; Dwarf_Error error; dwarf_dieoffset(sibling,&sib_off,&error); fprintf(stderr," SIB OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,sib_off); } void print_ptr_offset(Dwarf_CU_Context cu_context, Dwarf_Byte_Ptr di_ptr) { Dwarf_Off ptr_off; dwarf_ptr_CU_offset(cu_context,di_ptr,&ptr_off); fprintf(stderr," PTR OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,ptr_off); } #endif /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child() called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset It is essentially guaranteed that dbg->de_last_die is a stale DIE pointer of a deallocated DIE when we get here. It must not be used as a DIE pointer here, just as a sort of anonymous pointer that we just check against NULL. There is a (subtle?) dependence on the fact that when we call this the last dwarf_child() call would have been for this sibling. Meaning that this works in a depth-first traversal even though there is no stack of 'de_last_die' values. The check for dbg->de_last_die just ensures sanity. If one is switching between normal debug_frame and eh_frame (traversing them in tandem, let us say) in a single Dwarf_Debug this validator makes no sense. It works if one processes a .debug_frame (entirely) and then an eh_frame (or vice versa) though. Use caution. */ int dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset) { Dwarf_Debug dbg = 0; Dwarf_Error *error = 0; Dwarf_Debug_InfoTypes dis = 0; CHECK_DIE(sibling, DW_DLV_ERROR); dbg = sibling->di_cu_context->cc_dbg; dis = sibling->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading; *offset = 0; if (dis->de_last_die && dis->de_last_di_ptr) { if (sibling->di_debug_ptr == dis->de_last_di_ptr) { return DW_DLV_OK; } } /* Calculate global offset used for error reporting */ dwarf_ptr_CU_offset(sibling->di_cu_context, dis->de_last_di_ptr,sibling->di_is_info,offset); return DW_DLV_ERROR; } /* This function does two slightly different things depending on the input flag want_AT_sibling. If this flag is true, it checks if the input die has a DW_AT_sibling attribute. If it does it returns a pointer to the start of the sibling die in the .debug_info section. Otherwise it behaves the same as the want_AT_sibling false case. If the want_AT_sibling flag is false, it returns a pointer to the immediately adjacent die in the .debug_info section. Die_info_end points to the end of the .debug_info portion for the cu the die belongs to. It is used to check that the search for the next die does not cross the end of the current cu. Cu_info_start points to the start of the .debug_info portion for the current cu, and is used to add to the offset for DW_AT_sibling attributes. Finally, has_die_child is a pointer to a Dwarf_Bool that is set true if the present die has children, false otherwise. However, in case want_AT_child is true and the die has a DW_AT_sibling attribute *has_die_child is set false to indicate that the children are being skipped. die_info_end points to the last byte+1 of the cu. */ static int _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, Dwarf_CU_Context cu_context, Dwarf_Byte_Ptr die_info_end, Dwarf_Byte_Ptr cu_info_start, Dwarf_Bool want_AT_sibling, Dwarf_Bool * has_die_child, Dwarf_Byte_Ptr *next_die_ptr_out, Dwarf_Error *error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Abbrev_List abbrev_list = 0; Dwarf_Half attr = 0; Dwarf_Half attr_form = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned utmp = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr abbrev_end = 0; int lres = 0; Dwarf_Unsigned highest_code = 0; dbg = cu_context->cc_dbg; info_ptr = die_info_ptr; DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end); abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Should never happen. Tested before we got here. */ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); return DW_DLV_ERROR; } lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code, &abbrev_list,&highest_code,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, " DW_DLE_NEXT_DIE_NO_ABBREV_LIST " "There is no abbrev present for code %u" " in this compilation unit. ", abbrev_code); dwarfstring_append_printf_u(&m, "The highest known code in any " "compilation unit is %u.", highest_code); _dwarf_error_string(dbg, error, DW_DLE_NEXT_DIE_NO_ABBREV_LIST, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } dbg = cu_context->cc_dbg; *has_die_child = abbrev_list->abl_has_child; abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(cu_context); do { Dwarf_Unsigned utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error, abbrev_end); if (utmp2 > DW_AT_hi_user) { _dwarf_error(dbg, error, DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } attr = (Dwarf_Half) utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error, abbrev_end); if (!_dwarf_valid_form_we_know(utmp2,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } attr_form = (Dwarf_Half) utmp2; if (attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; /* DECODE_LEB128_UWORD updates info_ptr */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error, die_info_end); attr_form = (Dwarf_Half) utmp6; } if (attr_form == DW_FORM_implicit_const) { UNUSEDARG Dwarf_Signed cval = 0; DECODE_LEB128_SWORD_CK(abbrev_ptr, cval,dbg,error, abbrev_end); } if (want_AT_sibling && attr == DW_AT_sibling) { switch (attr_form) { case DW_FORM_ref1: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Small), error,die_info_end); break; case DW_FORM_ref2: /* READ_UNALIGNED does not update info_ptr */ READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr,DWARF_HALF_SIZE, error,die_info_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, DWARF_32BIT_SIZE, error,die_info_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, DWARF_64BIT_SIZE, error,die_info_end); break; case DW_FORM_ref_udata: DECODE_LEB128_UWORD_CK(info_ptr, offset, dbg,error,die_info_end); break; case DW_FORM_ref_addr: /* Very unusual. The FORM is intended to refer to a different CU, but a different CU cannot be a sibling, can it? We could ignore this and treat as if no DW_AT_sibling present. Or derive the offset from it and if it is in the same CU use it directly. The offset here is *supposed* to be a global offset, so adding cu_info_start is wrong to any offset we find here unless cu_info_start is zero! Lets pretend there is no DW_AT_sibling attribute. */ goto no_sibling_attr; default: _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_WRONG_FORM); return DW_DLV_ERROR; } /* Reset *has_die_child to indicate children skipped. */ *has_die_child = false; /* A value beyond die_info_end indicates an error. Exactly at die_info_end means 1-past-cu-end and simply means we are at the end, do not return error. Higher level will detect that we are at the end. */ { /* Care required here. Offset can be garbage. */ Dwarf_Unsigned plen = 0; /* ptrdiff_t is generated but not named */ plen = (die_info_end >= cu_info_start)? (die_info_end - cu_info_start):0; if (offset > plen) { /* Error case, bad DWARF. */ _dwarf_error(dbg, error, DW_DLE_SIBLING_OFFSET_WRONG); return DW_DLV_ERROR; } } /* At or before end-of-cu */ *next_die_ptr_out = cu_info_start + offset; return DW_DLV_OK; } no_sibling_attr: if (attr_form != 0 && attr_form != DW_FORM_implicit_const) { int res = 0; Dwarf_Unsigned sizeofval = 0; Dwarf_Unsigned ssize = 0; res = _dwarf_get_size_of_val(cu_context->cc_dbg, attr_form, cu_context->cc_version_stamp, cu_context->cc_address_size, info_ptr, cu_context->cc_length_size, &sizeofval, die_info_end, error); if (res != DW_DLV_OK) { return res; } /* It is ok for info_ptr == die_info_end, as we will test later before using a too-large info_ptr */ /* ptrdiff_t is generated but not named */ ssize = (die_info_end >= info_ptr)? (die_info_end - info_ptr): 0; if (sizeofval > ssize) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_NEXT_DIE_PAST_END:" " the DIE value just checked is %u" " bytes long, and that would extend" " past the end of the section.", sizeofval); _dwarf_error_string(dbg, error, DW_DLE_NEXT_DIE_PAST_END, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } info_ptr += sizeofval; if (info_ptr > die_info_end) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_NEXT_DIE_PAST_END:" " the DIE value just checked is %u" " bytes long, and puts us past" " the end of the section", sizeofval); dwarfstring_append_printf_u(&m, " which is 0x%x", (Dwarf_Unsigned)(uintptr_t)die_info_end); _dwarf_error_string(dbg, error, DW_DLE_NEXT_DIE_PAST_END, dwarfstring_string(&m)); dwarfstring_destructor(&m); /* More than one-past-end indicates a bug somewhere, likely bad dwarf generation. */ return DW_DLV_ERROR; } } } while (attr != 0 || attr_form != 0); *next_die_ptr_out = info_ptr; return DW_DLV_OK; } /* Multiple TAGs are in fact compile units. Allow them all. Return non-zero if a CU tag. Else return 0. */ static int is_cu_tag(int t) { if (t == DW_TAG_compile_unit || t == DW_TAG_partial_unit || t == DW_TAG_skeleton_unit || t == DW_TAG_type_unit) { return 1; } return 0; } /* Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns a Dwarf_Die for the sibling of die. In case die is NULL, it returns (thru ptr) a Dwarf_Die for the first die in the current cu in dbg. Returns DW_DLV_ERROR on error. It is assumed that every sibling chain including those with only one element is terminated with a NULL die, except a chain with only a NULL die. The algorithm moves from one die to the adjacent one. It returns when the depth of children it sees equals the number of sibling chain terminations. A single count, child_depth is used to track the depth of children and sibling terminations encountered. Child_depth is incremented when a die has the Has-Child flag set unless the child happens to be a NULL die. Child_depth is decremented when a die has Has-Child false, and the adjacent die is NULL. Algorithm returns when child_depth is 0. **NOTE: Do not modify input die, since it is used at the end. */ int dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { int res = 0; Dwarf_Bool is_info = TRUE; Dwarf_Debug_InfoTypes dis = 0; dis = &dbg->de_info_reading; res = _dwarf_siblingof_internal(dbg,die, die?die->di_cu_context:dis->de_cu_context, is_info,caller_ret_die,error); return res; } /* This is the new form, October 2011. On calling with 'die' NULL, we cannot tell if this is debug_info or debug_types, so we must be informed!. */ int dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { int res; Dwarf_Debug_InfoTypes dis = 0; dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; res = _dwarf_siblingof_internal(dbg,die, die?die->di_cu_context:dis->de_cu_context, is_info,caller_ret_die,error); return res; } static int _dwarf_siblingof_internal(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_CU_Context context, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { Dwarf_Die ret_die = 0; Dwarf_Byte_Ptr die_info_ptr = 0; Dwarf_Byte_Ptr cu_info_start = 0; /* die_info_end points 1-past end of die (once set) */ Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; Dwarf_Unsigned highest_code = 0; int lres = 0; int dieres = 0; /* Since die may be NULL, we rely on the input argument. */ Dwarf_Small *dataptr = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; if (die == NULL) { /* Find root die of cu */ /* die_info_end is untouched here, need not be set in this branch. */ Dwarf_Off off2 = 0; Dwarf_Unsigned headerlen = 0; int cres = 0; /* If we've not loaded debug_info context will be NULL. */ if (!context) { local_dealloc_cu_context(dbg,context); return DW_DLV_ERROR; } off2 = context->cc_debug_offset; cu_info_start = dataptr + off2; cres = _dwarf_length_of_cu_header(dbg, off2,is_info, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } die_info_ptr = cu_info_start + headerlen; die_info_end = _dwarf_calculate_info_section_end_ptr(context); /* Recording the CU die pointer so we can later access for special FORMs relating to .debug_str_offsets and .debug_addr */ context->cc_cu_die_offset_present = TRUE; context->cc_cu_die_global_sec_offset = off2 + headerlen; } else { /* Find sibling die. */ Dwarf_Bool has_child = false; Dwarf_Signed child_depth = 0; /* We cannot have a legal die unless debug_info was loaded, so no need to load debug_info here. */ CHECK_DIE(die, DW_DLV_ERROR); die_info_ptr = die->di_debug_ptr; if (*die_info_ptr == 0) { return DW_DLV_NO_ENTRY; } context = die->di_cu_context; cu_info_start = dataptr+ context->cc_debug_offset; die_info_end = _dwarf_calculate_info_section_end_ptr(context); if ((*die_info_ptr) == 0) { return DW_DLV_NO_ENTRY; } child_depth = 0; do { int res2 = 0; Dwarf_Byte_Ptr die_info_ptr2 = 0; res2 = _dwarf_next_die_info_ptr(die_info_ptr, context, die_info_end, cu_info_start, true, &has_child, &die_info_ptr2, error); if (res2 != DW_DLV_OK) { return res2; } if (die_info_ptr2 < die_info_ptr) { /* There is something very wrong, our die value decreased. Bad DWARF. */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_NEXT_DIE_LOW_ERROR: " "Somehow the next die pointer 0x%x", (Dwarf_Unsigned)(uintptr_t)die_info_ptr2); dwarfstring_append_printf_u(&m, " points before the current die " "pointer 0x%x so an " "overflow of some sort happened", (Dwarf_Unsigned)(uintptr_t)die_info_ptr); _dwarf_error_string(dbg, error, DW_DLE_NEXT_DIE_LOW_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (die_info_ptr2 > die_info_end) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_NEXT_DIE_PAST_END: " "the next DIE at 0x%x", (Dwarf_Unsigned)(uintptr_t)die_info_ptr2); dwarfstring_append_printf_u(&m, " would be past " " the end of the section (0x%x)," " which is an error.", (Dwarf_Unsigned)(uintptr_t)die_info_end); _dwarf_error_string(dbg, error, DW_DLE_NEXT_DIE_PAST_END, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } die_info_ptr = die_info_ptr2; /* die_info_end is one past end. Do not read it! A test for '!= die_info_end' would work as well, but perhaps < reads more like the meaning. */ if (die_info_ptr < die_info_end) { if ((*die_info_ptr) == 0 && has_child) { die_info_ptr++; has_child = false; } } /* die_info_ptr can be one-past-end. */ if ((die_info_ptr == die_info_end) || ((*die_info_ptr) == 0)) { /* We are at the end of a sibling list. get back to the next containing sibling list (looking for a libling list with more on it). */ for (;;) { if (child_depth == 0) { /* Meaning there is no outer list, so stop. */ break; } if (die_info_ptr == die_info_end) { /* September 2016: do not deref if we are past end. If we are at end at this point it means the sibling list inside this CU is not properly terminated. August 2019: We used to declare an error, DW_DLE_SIBLING_LIST_IMPROPER but now we just silently declare this is the end of the list. Each level of a sibling nest should have a single NUL byte, but here things are wrong, the DWARF is corrupt. */ return DW_DLV_NO_ENTRY; } if (*die_info_ptr) { /* We have a real sibling. */ break; } /* Move out one DIE level. Move past NUL byte marking end of this sibling list. */ child_depth--; die_info_ptr++; } } else { child_depth = has_child ? child_depth + 1 : child_depth; } } while (child_depth != 0); } /* die_info_ptr > die_info_end is really a bug (possibly in dwarf generation)(but we are past end, no more DIEs here), whereas die_info_ptr == die_info_end means 'one past end, no more DIEs here'. */ if (die_info_ptr >= die_info_end) { return DW_DLV_NO_ENTRY; } if ((*die_info_ptr) == 0) { return DW_DLV_NO_ENTRY; } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (ret_die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_die->di_is_info = is_info; ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die == NULL ? context : die->di_cu_context; dieres = _dwarf_leb128_uword_wrapper(dbg, &die_info_ptr,die_info_end,&utmp,error); if (dieres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return dieres; } if (die_info_ptr > die_info_end) { /* We managed to go past the end of the CU!. Something is badly wrong. */ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return DW_DLV_ERROR; } abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Zero means a null DIE */ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return DW_DLV_NO_ENTRY; } ret_die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code, &ret_die->di_abbrev_list, &highest_code,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DIE_ABBREV_LIST_NULL: " "There is no abbrev present for code %u" " in this compilation unit. ", abbrev_code); dwarfstring_append_printf_u(&m, "The highest known code" " in any compilation unit is %u .", highest_code); _dwarf_error_string(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL,dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (die == NULL && !is_cu_tag(ret_die->di_abbrev_list->abl_tag)) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU); return DW_DLV_ERROR; } *caller_ret_die = ret_die; return DW_DLV_OK; } int dwarf_child(Dwarf_Die die, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { Dwarf_Byte_Ptr die_info_ptr = 0; Dwarf_Byte_Ptr die_info_ptr2 = 0; /* die_info_end points one-past-end of die area. */ Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Die ret_die = 0; Dwarf_Bool has_die_child = 0; Dwarf_Debug dbg; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; Dwarf_Debug_InfoTypes dis = 0; int res = 0; Dwarf_CU_Context context = 0; int lres = 0; Dwarf_Unsigned highest_code = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dis = die->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading; die_info_ptr = die->di_debug_ptr; /* We are saving a DIE pointer here, but the pointer will not be presumed live later, when it is tested. */ dis->de_last_die = die; dis->de_last_di_ptr = die_info_ptr; /* NULL die has no child. */ if ((*die_info_ptr) == 0) { return DW_DLV_NO_ENTRY; } context = die->di_cu_context; die_info_end = _dwarf_calculate_info_section_end_ptr(context); res = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, die_info_end, NULL, false, &has_die_child, &die_info_ptr2, error); if (res != DW_DLV_OK) { return res; } if (die_info_ptr == die_info_end) { return DW_DLV_NO_ENTRY; } die_info_ptr = die_info_ptr2; dis->de_last_di_ptr = die_info_ptr; if (!has_die_child) { /* Look for end of sibling chain. */ while (dis->de_last_di_ptr < die_info_end) { if (*dis->de_last_di_ptr) { break; } ++dis->de_last_di_ptr; } return DW_DLV_NO_ENTRY; } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (ret_die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die->di_cu_context; ret_die->di_is_info = die->di_is_info; DECODE_LEB128_UWORD_CK(die_info_ptr, utmp, dbg,error,die_info_end); abbrev_code = (Dwarf_Unsigned) utmp; dis->de_last_di_ptr = die_info_ptr; if (abbrev_code == 0) { /* Look for end of sibling chain */ while (dis->de_last_di_ptr < die_info_end) { if (*dis->de_last_di_ptr) { break; } ++dis->de_last_di_ptr; } /* We have arrived at a null DIE, at the end of a CU or the end of a list of siblings. */ *caller_ret_die = 0; dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); ret_die = 0; return DW_DLV_NO_ENTRY; } ret_die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code, &ret_die->di_abbrev_list, &highest_code,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); ret_die = 0; return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarfstring_constructor(&m); dwarf_dealloc_die(ret_die); ret_die = 0; dwarfstring_append_printf_u(&m, "DW_DLE_ABBREV_MISSING: the abbrev code not found " " in dwarf_child() is %u. ",abbrev_code); dwarfstring_append_printf_u(&m, "The highest known code" " in any compilation unit is %u.", highest_code); _dwarf_error_string(dbg, error, DW_DLE_ABBREV_MISSING, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } *caller_ret_die = ret_die; return DW_DLV_OK; } /* Given a (global, not cu_relative) die offset, this returns a pointer to a DIE thru *new_die. It is up to the caller to do a dwarf_dealloc(dbg,*new_die,DW_DLE_DIE); The old form only works with debug_info. The new _b form works with debug_info or debug_types. */ int dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error) { Dwarf_Bool is_info = true; return dwarf_offdie_b(dbg,offset,is_info,new_die,error); } int dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Die * new_die, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Small *dataptr = 0; Dwarf_Off new_cu_offset = 0; Dwarf_Die die = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; int lres = 0; Dwarf_Debug_InfoTypes dis = 0; Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Unsigned highest_code = 0; struct Dwarf_Section_s * secdp = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (is_info) { dis =&dbg->de_info_reading; secdp = &dbg->de_debug_info; dataptr = dbg->de_debug_info.dss_data; } else { dis =&dbg->de_types_reading; secdp = &dbg->de_debug_types; dataptr = dbg->de_debug_types.dss_data; } if (!dataptr) { lres = _dwarf_load_die_containing_section(dbg, is_info, error); if (lres != DW_DLV_OK) { return lres; } } cu_context = _dwarf_find_CU_Context(dbg, offset,is_info); if (cu_context == NULL) { Dwarf_Unsigned section_size = 0; if (dis->de_cu_context_list_end != NULL) { new_cu_offset = _dwarf_calculate_next_cu_context_offset( dis->de_cu_context_list_end); }/* Else new_cu_offset remains 0, no CUs on list, a fresh section setup. */ section_size = secdp->dss_size; do { lres = _dwarf_create_a_new_cu_context_record_on_list( dbg, dis,is_info,section_size,new_cu_offset, &cu_context,error); if (lres != DW_DLV_OK) { return lres; } new_cu_offset = _dwarf_calculate_next_cu_context_offset( cu_context); /* Not setting dis->de_cu_context, leave that unchanged. */ } while (offset >= new_cu_offset); } /* We have a cu_context for this offset. */ die_info_end = _dwarf_calculate_info_section_end_ptr(cu_context); die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (!die) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } die->di_cu_context = cu_context; die->di_is_info = is_info; /* dataptr above might be stale if we loaded a section above. So access dss_data here. */ if (is_info) { info_ptr = offset + dbg->de_debug_info.dss_data; } else { info_ptr = offset + dbg->de_debug_types.dss_data; } die->di_debug_ptr = info_ptr; lres = _dwarf_leb128_uword_wrapper(dbg,&info_ptr,die_info_end, &utmp,error); if (lres != DW_DLV_OK) { dwarf_dealloc_die(die); return lres; } abbrev_code = utmp; if (abbrev_code == 0) { /* we are at a null DIE (or there is a bug). */ dwarf_dealloc_die(die); die = 0; return DW_DLV_NO_ENTRY; } die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code, &die->di_abbrev_list, &highest_code,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc_die(die); die = 0; return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarfstring m; dwarf_dealloc_die(die); die = 0; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DIE_ABBREV_LIST_NULL: " "There is no abbrev present for code %u" " in this compilation unit" " when calling dwarf_offdie_b(). ", abbrev_code); dwarfstring_append_printf_u(&m, "The highest known code " "in any compilation unit is %u .", highest_code); _dwarf_error_string(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } *new_die = die; return DW_DLV_OK; } /* New March 2016. Lets one cross check the abbreviations section and the DIE information presented by dwarfdump -i -G -v. */ int dwarf_die_abbrev_global_offset(Dwarf_Die die, Dwarf_Off * abbrev_goffset, Dwarf_Unsigned * abbrev_count, Dwarf_Error* error) { Dwarf_Abbrev_List dal = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dal = die->di_abbrev_list; if (!dal) { _dwarf_error(dbg,error,DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *abbrev_goffset = dal->abl_goffset; *abbrev_count = dal->abl_count; return DW_DLV_OK; } /* New August 2018. Because some real compressed sections have .zdebug instead of .debug as the leading characters. actual_sec_name_out points to a static string so so not free it. */ int dwarf_get_real_section_name(Dwarf_Debug dbg, const char *std_section_name, const char **actual_sec_name_out, Dwarf_Small *marked_zcompressed, /* zdebug */ Dwarf_Small *marked_zlib_compressed, /* ZLIB string */ Dwarf_Small *marked_shf_compressed, /* SHF_COMPRESSED */ Dwarf_Unsigned *compressed_length, Dwarf_Unsigned *uncompressed_length, Dwarf_Error *error) { unsigned i = 0; char tbuf[50]; unsigned std_sec_name_len = strlen(std_section_name); tbuf[0] = 0; /* std_section_name never has the .dwo on the end, so allow for that and allow one (arbitrarily) more. */ if ((std_sec_name_len + 5) < sizeof(tbuf)) { strcpy(tbuf,std_section_name); strcpy(tbuf+std_sec_name_len,".dwo"); } if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } for (i=0; i < dbg->de_debug_sections_total_entries; i++) { struct Dwarf_dbg_sect_s *sdata = &dbg->de_debug_sections[i]; struct Dwarf_Section_s *section = sdata->ds_secdata; const char *std = section->dss_standard_name; if (!strcmp(std,std_section_name) || !strcmp(std,tbuf)) { const char *used = section->dss_name; *actual_sec_name_out = used; if (sdata->ds_have_zdebug) { *marked_zcompressed = TRUE; } if (section->dss_ZLIB_compressed) { *marked_zlib_compressed = TRUE; if (uncompressed_length) { *uncompressed_length = section->dss_uncompressed_length; } if (compressed_length) { *compressed_length = section->dss_compressed_length; } } if (section->dss_shf_compressed) { *marked_shf_compressed = TRUE; if (uncompressed_length) { *uncompressed_length = section->dss_uncompressed_length; } if (compressed_length) { *compressed_length = section->dss_compressed_length; } } return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* This is useful when printing DIE data. The string pointer returned must not be freed. With non-elf objects it is possible the string returned might be empty or NULL, so callers should be prepared for that kind of return. */ int dwarf_get_die_section_name(Dwarf_Debug dbg, Dwarf_Bool is_info, const char ** sec_name, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (is_info) { sec = &dbg->de_debug_info; } else { sec = &dbg->de_debug_types; } if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } /* This one assumes is_info not known to caller but a DIE is known. */ int dwarf_get_die_section_name_b(Dwarf_Die die, const char ** sec_name, Dwarf_Error * error) { Dwarf_CU_Context context = 0; Dwarf_Bool is_info = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; is_info = context->cc_is_info; return dwarf_get_die_section_name(dbg,is_info,sec_name,error); } libdwarf-20210528/libdwarf/dwarf_dsc.h0000644000175000017500000000407313743575426014415 00000000000000/* Copyright (C) 2016-2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dsc_type: if 0, then dsc_low is a single discriminant value and dsc_high is zero.. If 1, then dsc_low, dsc_high are a discriminant range All the messy complexity here is so we can have both a set of values read as uleb and as sleb. We make our own copy of the block for the same reason. */ struct Dwarf_Dsc_Entry_s { /* Type is a 1 byte leb that reads the same as sleb or uleb because its value can only be zero or one. */ Dwarf_Half dsc_type; Dwarf_Unsigned dsc_low_u; Dwarf_Unsigned dsc_high_u; Dwarf_Signed dsc_low_s; Dwarf_Signed dsc_high_s; }; struct Dwarf_Dsc_Head_s { Dwarf_Debug dsh_debug; Dwarf_Unsigned dsh_count; Dwarf_Small *dsh_block; Dwarf_Unsigned dsh_block_len; /* Following two are flags to tell us whether lebs already read in a given signedness. */ Dwarf_Bool dsh_set_unsigned; Dwarf_Bool dsh_set_signed; struct Dwarf_Dsc_Entry_s *dsh_array; }; void _dwarf_dsc_destructor(void *m); libdwarf-20210528/libdwarf/pro_forms.c0000664000175000017500000015706114004647024014453 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2007-2020 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_die.h" #include "pro_expr.h" #define TRUE 1 #define FALSE 0 #define DW_CU_VERSION5 5 #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif /* Indicates no relocation needed. */ #define NO_ELF_SYM_INDEX 0 #ifdef WORDS_BIGENDIAN #define ASNAR(t,s,l) \ do { \ unsigned tbyte = sizeof(t) - l; \ t = 0; \ dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(t,s,l) \ do { \ t = 0; \ dbg->de_copy_word(&t,&s[0],l); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ memcpy(t,(const void *)p,l); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ #ifdef WORDS_BIGENDIAN #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + \ sizeof(dest) - length) < 0) { \ memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ sizeof(dest) - length); \ } \ } while (0) #else /* LITTLE ENDIAN */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \ memcpy((char *)&dest+length, \ "\xff\xff\xff\xff\xff\xff\xff\xff", \ sizeof(dest) - length); \ } \ } while (0) #endif /* ! LITTLE_ENDIAN */ /* This function adds an attribute whose value is a target address to the given die. The attribute is given the name provided by attr. The address is given in pc_value. */ static int local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error); /* old interface */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; if (sym_index < 0) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } res = dwarf_add_AT_targ_address_c(dbg, ownerdie, attr, pc_value, (Dwarf_Unsigned) sym_index, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } /* New interface, replacing dwarf_add_AT_targ_address. Essentially just makes sym_index a Dwarf_Unsigned so for symbolic relocations it can be a full address. */ Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_targ_address_c(dbg, ownerdie,attr,pc_value,sym_index, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; switch (attr) { case DW_AT_low_pc: case DW_AT_high_pc: /* added to support location lists */ /* no way to check that this is a loclist-style address though */ case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_frame_base: case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: case DW_AT_vtable_elem_location: case DW_AT_const_value: /* Gcc can generate this as address. */ case DW_AT_entry_pc: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_addr, pc_value, sym_index,attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_ref_address_a(dbg,ownerdie, attr,pc_value,sym_index,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; switch (attr) { case DW_AT_type: case DW_AT_import: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* FIXME: For DWARF3 and later this call is problematic as DW_FORM_ref_addr is really an offset in .debug_info , not an address. */ res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_ref_addr, pc_value, sym_index,attr_out, error); return res; } /* Make sure attribute types are checked before entering here. */ static int local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int upointer_size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } upointer_size = dbg->de_pointer_size; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } /* attribute types have already been checked */ /* switch (attr) { ... } */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = form; new_attr->ar_nbytes = upointer_size; new_attr->ar_rel_symidx = sym_index; new_attr->ar_reloc_len = upointer_size; new_attr->ar_next = 0; if (sym_index != NO_ELF_SYM_INDEX) { new_attr->ar_rel_type = dbg->de_ptr_reloc; } else { new_attr->ar_rel_type = R_MIPS_NONE; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, upointer_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &pc_value, sizeof(pc_value), upointer_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* Pass in array (ie a pointer to) of Dwarf_Signed with input_array_length elements. A block of bytes is created with the sleb data in it. A pointer to the glob of bytes is returned through the output_block pointer and its length through output_block_len pointer. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug dbg, Dwarf_Unsigned input_array_length, Dwarf_Signed * input_array, Dwarf_Unsigned *output_block_len, void ** output_block_returned, Dwarf_Error* error ) { Dwarf_Unsigned output_length_in_bytes = 0; char * output_block = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; unsigned u = 0; char * ptr = 0; int remain = 0; int result = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } /* First compress everything to find the total size. */ output_length_in_bytes = 0; for (u=0; ude_ar_data_attribute_form is data4 or data8 and dwarf4 changes the definition for such on DW_AT_high_pc. DWARF 3: the FORM here has no defined meaning for dwarf3. DWARF 4: the FORM here means that for DW_AT_high_pc the value is not a high address but is instead an offset from a (separate) DW_AT_low_pc. The intent for DWARF4 is that this is not a relocated address at all. Instead a simple offset. But this should NOT be called for a simple non-relocated offset. So do not call this with an attr of DW_AT_high_pc. Use dwarf_add_AT_unsigned_const() (for example) instead of dwarf_add_AT_dataref when the value is a simple offset . */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; /* TODO: Add checking here */ res = local_add_AT_address_a(dbg, ownerdie, attr, dbg->de_ar_data_attribute_form, pc_value, sym_index, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; /* TODO: Add checking here */ res = local_add_AT_address_a(dbg, ownerdie, attr, dbg->de_ar_data_attribute_form, pc_value, sym_index, &a, error); if (res != DW_DLV_OK) { return((Dwarf_P_Attribute)DW_DLV_BADADDR); } return a; } Dwarf_P_Attribute dwarf_add_AT_block( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_Error *error) { int res = 0; Dwarf_P_Attribute new_attr = 0; res = dwarf_add_AT_block_a(dbg,ownerdie,attr, block_data,block_size,&new_attr,error); if (res != DW_DLV_OK) { return((Dwarf_P_Attribute)DW_DLV_BADADDR); } return new_attr; } /* For DW_FORM_block* or DW_FORM_exprloc */ int dwarf_add_AT_block_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_P_Attribute* attr_out, Dwarf_Error *error) { Dwarf_P_Attribute new_attr = 0; int result = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int len_size = 0; char * attrdata = 0; Dwarf_Bool is_exprloc_related = FALSE; Dwarf_Half out_version = dbg->de_output_version; switch (attr) { case DW_AT_location: case DW_AT_use_location: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_static_link: case DW_AT_vtable_elem_location: case DW_AT_lower_bound: case DW_AT_upper_bound: case DW_AT_data_location: is_exprloc_related = TRUE; } if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } /* I don't mess with block1, block2, block4, not worth the effort, and block would be wrong to use block for DW_FORM_exprloc */ /* So, encode the length into LEB128 */ result = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer,sizeof(encode_buffer)); if (result != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Allocate the new attribute */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Fill in the attribute */ new_attr->ar_attribute = attr; if (is_exprloc_related && out_version == 5) { new_attr->ar_attribute_form = DW_FORM_exprloc; } else { new_attr->ar_attribute_form = DW_FORM_block; } new_attr->ar_nbytes = len_size + block_size; new_attr->ar_next = 0; new_attr->ar_data = attrdata = (char *) _dwarf_p_get_alloc(dbg, len_size + block_size); if (new_attr->ar_data == NULL) { /* free the block we got earlier */ _dwarf_p_dealloc(dbg, (unsigned char *) new_attr); _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* write length and data to attribute data buffer */ memcpy(attrdata, encode_buffer, len_size); attrdata += len_size; memcpy(attrdata, block_data, block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is an unsigned constant. It determines the size of the value field from the value of the constant. */ Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_unsigned_const_a(dbg, ownerdie,attr,value, &a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; Dwarf_Small size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_ordering: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_inline: case DW_AT_language: case DW_AT_visibility: case DW_AT_virtuality: case DW_AT_accessibility: case DW_AT_address_class: case DW_AT_calling_convention: case DW_AT_encoding: case DW_AT_identifier_case: case DW_AT_MIPS_loop_unroll_factor: case DW_AT_MIPS_software_pipeline_depth: break; case DW_AT_decl_column: case DW_AT_decl_file: case DW_AT_decl_line: case DW_AT_const_value: case DW_AT_start_scope: case DW_AT_stride_size: /* DW_AT_bit_stride is DWARF3 name */ case DW_AT_count: case DW_AT_high_pc: /* DWARF5: allowing const udata high_pc */ case DW_AT_associated: case DW_AT_allocated: case DW_AT_upper_bound: case DW_AT_lower_bound: case DW_AT_call_file: case DW_AT_call_line: case DW_AT_data_member_location: case DW_AT_trampoline: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. */ if (value <= UCHAR_MAX) { attr_form = DW_FORM_data1; size = 1; } else if (value <= USHRT_MAX) { attr_form = DW_FORM_data2; size = 2; } else if (value <= UINT_MAX) { attr_form = DW_FORM_data4; size = 4; } else { attr_form = DW_FORM_data8; size = 8; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_rel_type = R_MIPS_NONE; /* irrelevant: unused with R_MIPS_NONE */ new_attr->ar_reloc_len = 0; new_attr->ar_nbytes = size; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is an signed constant. It determines the size of the value field from the value of the constant. */ Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_signed_const_a(dbg, ownerdie,attr,value,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; Dwarf_Small size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_lower_bound: case DW_AT_upper_bound: case DW_AT_const_value: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_byte_size: case DW_AT_count: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_allocated: case DW_AT_associated: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. */ if (value >= SCHAR_MIN && value <= SCHAR_MAX) { attr_form = DW_FORM_data1; size = 1; } else if (value >= SHRT_MIN && value <= SHRT_MAX) { attr_form = DW_FORM_data2; size = 2; } else if (value >= INT_MIN && value <= INT_MAX) { attr_form = DW_FORM_data4; size = 4; } else { attr_form = DW_FORM_data8; size = 8; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_rel_type = R_MIPS_NONE; /* irrelevant: unused with R_MIPS_NONE */ new_attr->ar_reloc_len = 0; new_attr->ar_nbytes = size; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is a location expression. */ Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error * error) { int res = 0; Dwarf_P_Attribute a = 0; res = dwarf_add_AT_location_expr_a(dbg,ownerdie,attr, loc_expr,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } /* Preferred interface as of December 2018 */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; char *len_str = 0; int len_size = 0; Dwarf_Unsigned block_size = 0; char *block_dest_ptr = 0; int do_len_as_int = 0; int dwarf_version = dbg->de_output_version; Dwarf_Bool is_exprloc_related = FALSE; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } if (loc_expr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (loc_expr->ex_dbg != dbg) { _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); return DW_DLV_ERROR; } block_size = loc_expr->ex_next_byte_offset; switch (attr) { case DW_AT_location: case DW_AT_use_location: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_static_link: case DW_AT_vtable_elem_location: case DW_AT_lower_bound: case DW_AT_upper_bound: case DW_AT_data_location: is_exprloc_related = TRUE; break; case DW_AT_string_length: case DW_AT_const_value: case DW_AT_count: case DW_AT_associated: case DW_AT_allocated: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_byte_size: case DW_AT_bit_size: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. This is a bit fake in that the size will never be particularly large and always < UINT_MAX. */ if (is_exprloc_related && dwarf_version == DW_CU_VERSION5) { attr_form = DW_FORM_exprloc; res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } len_str = (char *) encode_buffer; } else if (block_size <= UCHAR_MAX) { attr_form = DW_FORM_block1; len_size = 1; do_len_as_int = 1; } else if (block_size <= USHRT_MAX) { attr_form = DW_FORM_block2; len_size = 2; do_len_as_int = 1; } else if (block_size <= UINT_MAX) { attr_form = DW_FORM_block4; len_size = 4; do_len_as_int = 1; } else { attr_form = DW_FORM_block; res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } len_str = (char *) encode_buffer; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_reloc_len = dbg->de_pointer_size; if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { new_attr->ar_rel_type = dbg->de_ptr_reloc; } else { new_attr->ar_rel_type = R_MIPS_NONE; } new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; /* If there is a relocation the code assumes that relocation on a DW_OP_addr and the addr is the initial expression in the block */ new_attr->ar_rel_offset = loc_expr->ex_reloc_offset + len_size; new_attr->ar_nbytes = block_size + len_size; new_attr->ar_next = 0; new_attr->ar_data = block_dest_ptr = (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (do_len_as_int) { WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size, sizeof(block_size), len_size); } else { /* Is uleb number form, DW_FORM_block or DW_FORM_exprloc. See above. */ memcpy(block_dest_ptr, len_str, len_size); } block_dest_ptr += len_size; if (block_size > sizeof(loc_expr->ex_byte_stream)) { /* ex_byte_stream has a fixed max value. */ _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } #if 0 /* New for DWARF5 DW_FORM_exprloc */ int dwarf_add_AT_exprloc(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Block *b, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; Dwarf_P_Attribute new_attr = 0; char *len_str = 0; int len_size = 0; Dwarf_Unsigned block_size = 0; char *block_dest_ptr = 0; Dwarf_Half attr_form = DW_FORM_exprloc; #if 0 if (attr_form != DW_FORM_exprloc) { /* This is just for a single FORM! */ _dwarf_p_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return DW_DLV_ERROR; } #endif block_size = b.dl_len; res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } len_str = (char *) encode_buffer; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_reloc_len = dbg->de_pointer_size; if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { new_attr->ar_rel_type = dbg->de_ptr_reloc; } else { new_attr->ar_rel_type = R_MIPS_NONE; } new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; /* If there is a relocation the code assumes that relocation on a DW_OP_addr and the addr is the initial expression in the block */ new_attr->ar_nbytes = block_size + len_size; new_attr->ar_next = 0; new_attr->ar_data = block_dest_ptr = (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Is uleb number form */ memcpy(block_dest_ptr, len_str, len_size); block_dest_ptr += len_size; if (block_size > sizeof(loc_expr->ex_byte_stream)) { /* ex_byte_stream has a fixed max value. */ _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } #endif /* 0 */ /* This function adds attributes of reference class. The references here are local CU references, not DW_FORM_ref_addr. The offset field is 4 bytes for 32-bit objects, and 8-bytes for 64-bit objects. Otherdie is the that is referenced by ownerdie. For reference attributes, the ar_data and ar_nbytes are not needed. Instead, the ar_ref_die points to the other die, and its di_offset value is used as the reference value. */ static int _dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, int check_otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } if (check_otherdie && (otherdie == NULL)) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_count: case DW_AT_sibling: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_discr: case DW_AT_import: case DW_AT_common_reference: case DW_AT_containing_type: case DW_AT_default_value: case DW_AT_lower_bound: case DW_AT_bit_stride: /* Early name is DW_AT_stride_size */ case DW_AT_upper_bound: case DW_AT_abstract_origin: case DW_AT_base_types: case DW_AT_friend: case DW_AT_namelist_item: case DW_AT_priority: case DW_AT_specification: case DW_AT_type: case DW_AT_allocated: case DW_AT_associated: case DW_AT_byte_stride: case DW_AT_extension: case DW_AT_trampoline: case DW_AT_small: case DW_AT_object_pointer: case DW_AT_signature: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; new_attr->ar_nbytes = dbg->de_dwarf_offset_size; new_attr->ar_reloc_len = dbg->de_dwarf_offset_size; new_attr->ar_ref_die = otherdie; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_next = 0; /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* Allowing the target die to be identified later. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 0, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 1, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } /* Allowing the target die to be identified later. */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 0, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } int dwarf_fixup_AT_reference_die(Dwarf_P_Debug dbg, Dwarf_Half attrnum, Dwarf_P_Die sourcedie, Dwarf_P_Die targetdie, Dwarf_Error *error) { Dwarf_P_Attribute a = 0; Dwarf_P_Attribute cur = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } for (cur = sourcedie->di_attrs; cur; cur = cur->ar_next) { if (attrnum == cur->ar_attribute) { a = cur; break; } } if (!a) { _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_NULL); return DW_DLV_ERROR; } if (a->ar_ref_die) { _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_DUP); return DW_DLV_ERROR; } a->ar_ref_die = targetdie; return DW_DLV_OK; } /* This function adds attributes of the flag class. */ Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_flag_a(dbg,ownerdie,attr,flag, &a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_flag_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = DW_FORM_flag; new_attr->ar_nbytes = 1; new_attr->ar_reloc_len = 0; /* not used */ new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, 1); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, &flag, 1); /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds values of attributes belonging to the string class. */ Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_string_a(dbg, ownerdie,attr,string,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_string_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } switch (attr) { /* See also: pro_section.c for same strings attribute list. */ case DW_AT_comp_dir: case DW_AT_const_value: /* DWARF5, but ok for any version really.*/ case DW_AT_linkage_name: case DW_AT_MIPS_abstract_name: case DW_AT_MIPS_linkage_name: case DW_AT_name: case DW_AT_producer: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } new_attr->ar_attribute = attr; res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, string,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, char *string_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_const_value_string_a(ownerdie, string_value,&a,error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute) DW_DLV_BADADDR; } return a; } int dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie, char *string_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_const_value; res = _dwarf_pro_set_string_attr(new_attr,dbg, string_value,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_with_ref_sig8_a(ownerdie, attrnum,sig8_in,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_ref_sig8; new_attr->ar_nbytes = sizeof (Dwarf_Sig8); new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, sizeof(Dwarf_Sig8)); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data,sig8_in,sizeof(Dwarf_Sig8)); new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_producer_a(ownerdie, producer_string,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute)DW_DLV_BADADDR); } return a; } int dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_producer; res = _dwarf_pro_set_string_attr(new_attr,dbg, producer_string,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; res = dwarf_add_AT_any_value_sleb_a( ownerdie,DW_AT_const_value, signed_value, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_any_value_sleb_a( ownerdie,DW_AT_const_value, signed_value, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } int dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *outattr, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_implicit_const; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; /* The value will go in the abbrev section. Not the DIE. Encoding done with abbrev generation. */ new_attr->ar_data = 0; new_attr->ar_nbytes = 0; new_attr->ar_implicit_const = signed_value; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *outattr = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_Error * error) { int res = 0; Dwarf_P_Attribute a = 0; res = dwarf_add_AT_any_value_sleb_a(ownerdie, attrnum, signed_value, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int leb_size = 0; Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_sdata; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* AT_const_value, uleb */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) { Dwarf_P_Attribute a =0; int res = 0; res = dwarf_add_AT_any_value_uleb_a( ownerdie,DW_AT_const_value, unsigned_value, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { return dwarf_add_AT_any_value_uleb_a( ownerdie,DW_AT_const_value, unsigned_value, attr_out, error); } int dwarf_add_AT_data16(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Form_Data16 * ptr_to_val, Dwarf_P_Attribute * attr_return, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int val_size = sizeof(Dwarf_Form_Data16); Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_data16; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, val_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, ptr_to_val->fd_data, val_size); new_attr->ar_nbytes = val_size; _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_return = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_any_value_uleb_a(ownerdie, attrnum,unsigned_value,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int leb_size; Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_udata; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_tied.c0000664000175000017500000001757714012266121014556 00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #ifdef HAVE_STDLIB_H #include /* for free(). */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include /* For debugging. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" #define TRUE 1 #define FALSE 0 void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) { const char *sigv = 0; unsigned u = 0; printf("%s 0x",msg); sigv = &sig->signature[0]; for (u = 0; u < 8; u++) { printf("%02x",0xff&sigv[u]); } printf(" line %d\n",lineno); } void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) { struct Dwarf_Tied_Entry_s *e = 0; e = calloc(1,sizeof(struct Dwarf_Tied_Entry_s)); if (e) { e->dt_key = *key; e->dt_context = val; } return e; } /* Tied data Key is Dwarf_Sig8. A hash needed because we are using a hash search here. Would not be needed for the other tree searchs like balanced trees.. */ DW_TSHASHTYPE _dwarf_tied_data_hashfunc(const void *keyp) { const struct Dwarf_Tied_Entry_s * enp = keyp; DW_TSHASHTYPE hashv = 0; /* Just take some of the 8 bytes of the signature. */ memcpy(&hashv,enp->dt_key.signature,sizeof(hashv)); return hashv; } int _dwarf_tied_compare_function(const void *l, const void *r) { const struct Dwarf_Tied_Entry_s * lp = l; const struct Dwarf_Tied_Entry_s * rp = r; const char *lcp = (const char *)&lp->dt_key.signature; const char *rcp = (const char *)&rp->dt_key.signature; const char *lcpend = lcp + sizeof(Dwarf_Sig8); for ( ;lcp < lcpend; ++lcp,++rcp) { if (*lcp < *rcp) { return -1; } else if (*lcp > *rcp) { return 1; } } /* match. */ return 0; } void _dwarf_tied_destroy_free_node(void*nodep) { struct Dwarf_Tied_Entry_s * enp = nodep; free(enp); return; } /* This presumes only we are reading the debug_info CUs from tieddbg. That is a reasonable requirement, one hopes. Currently it reads all the tied CUs at once up to the point of finding a match unless there is an error.. This the only way we call _dwarf_next_cu_header*( ) on the tied file, so safe. */ static int _dwarf_loop_reading_debug_info_for_cu( Dwarf_Debug tieddbg, Dwarf_Error *error) { unsigned loop_count = 0; /* We will not find tied signatures for .debug_addr (or line tables) in .debug_types. it seems. Those signatures point from 'normal' to 'dwo/dwp' (DWARF4) */ int is_info = TRUE; Dwarf_CU_Context startingcontext = 0; Dwarf_Unsigned next_cu_offset = 0; startingcontext = tieddbg->de_info_reading.de_cu_context; if (startingcontext) { next_cu_offset = startingcontext->cc_debug_offset + startingcontext->cc_length + startingcontext->cc_length_size + startingcontext->cc_extension_size; } for (;;++loop_count) { int sres = DW_DLV_OK; Dwarf_Half cu_type = 0; Dwarf_CU_Context latestcontext = 0; Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Half extension_size = 0; Dwarf_Half length_size = 0; Dwarf_Sig8 signature; Dwarf_Bool has_signature = FALSE; Dwarf_Unsigned typeoffset = 0; memset(&signature,0,sizeof(signature)); sres = _dwarf_next_cu_header_internal(tieddbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &length_size,&extension_size, &signature, &has_signature, &typeoffset, &next_cu_offset, &cu_type, error); if (sres == DW_DLV_NO_ENTRY) { break; } latestcontext = tieddbg->de_info_reading.de_cu_context; if (has_signature) { void *retval = 0; Dwarf_Sig8 consign = latestcontext->cc_signature; void *entry = _dwarf_tied_make_entry(&consign,latestcontext); if (!entry) { return DW_DLV_NO_ENTRY; } /* Insert this signature and context. */ retval = dwarf_tsearch(entry, &tieddbg->de_tied_data.td_tied_search, _dwarf_tied_compare_function); if (!retval) { free(entry); /* FAILED might be out of memory.*/ return DW_DLV_NO_ENTRY; } else { struct Dwarf_Tied_Data_s * retent = *(struct Dwarf_Tied_Data_s**) retval; if (retent == entry) { /* we added a record. */ return DW_DLV_OK; } else { /* found existing, no add */ free(entry); return DW_DLV_OK; } } } } /* Apparently we never found the sig we are looking for. Pretend ok. Caller will check for success. */ return DW_DLV_OK; } /* If out of memory just return DW_DLV_NO_ENTRY. */ int _dwarf_search_for_signature(Dwarf_Debug tieddbg, Dwarf_Sig8 sig, Dwarf_CU_Context *context_out, Dwarf_Error *error) { void *entry2 = 0; struct Dwarf_Tied_Entry_s entry; struct Dwarf_Tied_Data_s * tied = &tieddbg->de_tied_data; int res = 0; if (!tied->td_tied_search) { dwarf_initialize_search_hash(&tied->td_tied_search, _dwarf_tied_data_hashfunc,0); if (!tied->td_tied_search) { return DW_DLV_NO_ENTRY; } } entry.dt_key = sig; entry.dt_context = 0; entry2 = dwarf_tfind(&entry, &tied->td_tied_search, _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; *context_out = e2->dt_context; return DW_DLV_OK; } /* We now ensure all tieddbg CUs signatures are in the td_tied_search, The caller is NOT doing info section read operations on the tieddbg in this (tied)dbg, so it cannot goof up their _dwarf_next_cu_header*(). */ res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,error); if (res == DW_DLV_ERROR) { return res; } entry2 = dwarf_tfind(&entry, &tied->td_tied_search, _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; *context_out = e2->dt_context; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } libdwarf-20210528/libdwarf/dwarf_elf_reloc_x86_64.h0000664000175000017500000000713313644370703016605 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_x86_64(unsigned long); #ifndef R_X86_64_NONE #define R_X86_64_NONE 0 #endif /* R_X86_64_NONE */ #ifndef R_X86_64_64 #define R_X86_64_64 1 #endif /* R_X86_64_64 */ #ifndef R_X86_64_PC32 #define R_X86_64_PC32 2 #endif /* R_X86_64_PC32 */ #ifndef R_X86_64_GOT32 #define R_X86_64_GOT32 3 #endif /* R_X86_64_GOT32 */ #ifndef R_X86_64_PLT32 #define R_X86_64_PLT32 4 #endif /* R_X86_64_PLT32 */ #ifndef R_X86_64_COPY #define R_X86_64_COPY 5 #endif /* R_X86_64_COPY */ #ifndef R_X86_64_GLOB_DAT #define R_X86_64_GLOB_DAT 6 #endif /* R_X86_64_GLOB_DAT */ #ifndef R_X86_64_JUMP_SLOT #define R_X86_64_JUMP_SLOT 7 #endif /* R_X86_64_JUMP_SLOT */ #ifndef R_X86_64_RELATIVE #define R_X86_64_RELATIVE 8 #endif /* R_X86_64_RELATIVE */ #ifndef R_X86_64_GOTPCREL #define R_X86_64_GOTPCREL 9 #endif /* R_X86_64_GOTPCREL */ #ifndef R_X86_64_32 #define R_X86_64_32 10 #endif /* R_X86_64_32 */ #ifndef R_X86_64_32S #define R_X86_64_32S 11 #endif /* R_X86_64_32S */ #ifndef R_X86_64_16 #define R_X86_64_16 12 #endif /* R_X86_64_16 */ #ifndef R_X86_64_PC16 #define R_X86_64_PC16 13 #endif /* R_X86_64_PC16 */ #ifndef R_X86_64_8 #define R_X86_64_8 14 #endif /* R_X86_64_8 */ #ifndef R_X86_64_PC8 #define R_X86_64_PC8 15 #endif /* R_X86_64_PC8 */ #ifndef R_X86_64_DTPMOD64 #define R_X86_64_DTPMOD64 16 #endif /* R_X86_64_DTPMOD64 */ #ifndef R_X86_64_DTPOFF64 #define R_X86_64_DTPOFF64 17 #endif /* R_X86_64_DTPOFF64 */ #ifndef R_X86_64_TPOFF64 #define R_X86_64_TPOFF64 18 #endif /* R_X86_64_TPOFF64 */ #ifndef R_X86_64_TLSGD #define R_X86_64_TLSGD 19 #endif /* R_X86_64_TLSGD */ #ifndef R_X86_64_TLSLD #define R_X86_64_TLSLD 20 #endif /* R_X86_64_TLSLD */ #ifndef R_X86_64_DTPOFF32 #define R_X86_64_DTPOFF32 21 #endif /* R_X86_64_DTPOFF32 */ #ifndef R_X86_64_GOTTPOFF #define R_X86_64_GOTTPOFF 22 #endif /* R_X86_64_GOTTPOFF */ #ifndef R_X86_64_TPOFF32 #define R_X86_64_TPOFF32 23 #endif /* R_X86_64_TPOFF32 */ #ifndef R_X86_64_PC64 #define R_X86_64_PC64 24 #endif /* R_X86_64_PC64 */ #ifndef R_X86_64_GOTOFF64 #define R_X86_64_GOTOFF64 25 #endif /* R_X86_64_GOTOFF64 */ #ifndef R_X86_64_GOTPC32 #define R_X86_64_GOTPC32 26 #endif /* R_X86_64_GOTPC32 */ #ifndef R_X86_64_GOT64 #define R_X86_64_GOT64 27 #endif /* R_X86_64_GOT64 */ #ifndef R_X86_64_GOTPCREL64 #define R_X86_64_GOTPCREL64 28 #endif /* R_X86_64_GOTPCREL64 */ #ifndef R_X86_64_GOTPC64 #define R_X86_64_GOTPC64 29 #endif /* R_X86_64_GOTPC64 */ #ifndef R_X86_64_GOTPLT64 #define R_X86_64_GOTPLT64 30 #endif /* R_X86_64_GOTPLT64 */ #ifndef R_X86_64_PLTOFF64 #define R_X86_64_PLTOFF64 31 #endif /* R_X86_64_PLTOFF64 */ #ifndef R_X86_64_SIZE32 #define R_X86_64_SIZE32 32 #endif /* R_X86_64_SIZE32 */ #ifndef R_X86_64_SIZE64 #define R_X86_64_SIZE64 33 #endif /* R_X86_64_SIZE64 */ #ifndef R_X86_64_GOTPC32_TLSDESC #define R_X86_64_GOTPC32_TLSDESC 34 #endif /* R_X86_64_GOTPC32_TLSDESC */ #ifndef R_X86_64_TLSDESC_CALL #define R_X86_64_TLSDESC_CALL 35 #endif /* R_X86_64_TLSDESC_CALL */ #ifndef R_X86_64_TLSDESC #define R_X86_64_TLSDESC 36 #endif /* R_X86_64_TLSDESC */ #ifndef R_X86_64_IRELATIVE #define R_X86_64_IRELATIVE 37 #endif /* R_X86_64_IRELATIVE */ #ifndef R_X86_64_RELATIVE64 #define R_X86_64_RELATIVE64 38 #endif /* R_X86_64_RELATIVE64 */ #ifndef R_X86_64_GOTPCRELX #define R_X86_64_GOTPCRELX 41 #endif /* R_X86_64_GOTPCRELX */ #ifndef R_X86_64_REX_GOTPCRELX #define R_X86_64_REX_GOTPCRELX 42 #endif /* R_X86_64_REX_GOTPCRELX */ libdwarf-20210528/libdwarf/dwgetopt.h0000664000175000017500000000631313763273117014311 00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with * the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwopterr; extern int dwoptind; extern int dwoptopt; extern int dwoptreset; extern char *dwoptarg; int dwgetopt(int nargc, char * const nargv[], const char *ostr); /* As of October 2017 it seems adviseable to allow long option names. So based on a reading of 'man 3 getopt' we reimplement a portion of GNU getopt_long(). It's a wonderfully sensible design and all the credit should go to the original designers. We are not implementing all the features of GNU/Linux getopt_long(), just the features we wish to use. Specifically, we require val be 0 and flag be NULL and ignore those fields. We do not implement GNU digit_optind at all. Within these restrictions the interface behaves the same as GNU getopt_long() (or so it appears from the getopt documentation: release 4.04 of the Linux man-pages project, GETOPT(3), http://www.kernel.org/doc/man-pages/). */ struct dwoption { const char *name; int has_arg; int *flag; int val; }; #define dwno_argument 0 #define dwrequired_argument 1 #define dwoptional_argument 2 int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex); #ifdef __cplusplus } #endif /* __cplusplus */ libdwarf-20210528/libdwarf/gennames.c0000664000175000017500000005072514015304156014237 00000000000000/* Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2009-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include /* For errno declaration. */ #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include "dwgetopt.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ /* gennames.c Prints routines to return constant name for the associated value (such as the TAG name string for a particular tag). The input is dwarf.h For each set of names with a common prefix, we create a routine to return the name given the value. Also print header file that gives prototypes of routines. To handle cases where there are multiple names for a single value (DW_AT_* has some due to ambiguities in the DWARF2 spec) we take the first of a given value as the definitive name. TAGs, Attributes, etc are given distinct checks. There are multiple output files as some people find one form more pleasant than the other. The doprinting argument is so that when used by tag_tree.c, and tag_attr.c that we don't get irritating messages on stderr when those dwarfdump built-time applications are run. Some compilers generate better code for switch statements than others, so the -s and -t options let the user decide which is better for their compiler (when building dwarfdump): a simple switch or code doing binary search. This choice affects the runtime speed of dwarfdump. */ #define TRUE 1 #define FALSE 0 #define FAILED 1 static void OpenAllFiles(void); static void WriteFileTrailers(void); static void CloseAllFiles(void); static void GenerateInitialFileLines(void); static void GenerateOneSet(void); #ifdef TRACE_ARRAY static void PrintArray(void); #endif /* TRACE_ARRAY */ static int is_skippable_line(char *pLine); static void ParseDefinitionsAndWriteOutput(void); /* We don't need really long lines: the input file is simple. */ #define MAX_LINE_SIZE 1000 /* We don't need a variable array size, it just has to be big enough. */ #define ARRAY_SIZE 350 #define MAX_NAME_LEN 64 /* To store entries from dwarf.h */ typedef struct { char name[MAX_NAME_LEN]; /* short name */ unsigned value; /* value */ /* Original spot in array. Lets us guarantee a stable sort. */ unsigned original_position; } array_data; /* A group_array is a grouping from dwarf.h. All the TAGs are one group, all the FORMs are another group, and so on. */ static array_data group_array[ARRAY_SIZE]; static unsigned array_count = 0; typedef int (*compfn)(const void *,const void *); static int Compare(array_data *,array_data *); static const char *prefix_root = "DW_"; static const unsigned prefix_root_len = 3; /* f_dwarf_in is the input dwarf.h. The others are output files. */ static FILE *f_dwarf_in; static FILE *f_names_h; static FILE *f_names_c; static FILE *f_names_enum_h; static FILE *f_names_new_h; /* Size unchecked, but large enough. */ static char prefix[200] = ""; static const char *usage[] = { "Usage: gennames ", " -i input-table-path", " -o output-table-path", " -s use 'switch' in generation", " -t use 'tables' in generation", "", }; static void print_args(int argc, char *argv[]) { int index; printf("Arguments: "); for (index = 1; index < argc; ++index) { printf("%s ",argv[index]); } printf("\n"); } char *program_name = 0; static char *input_name = 0; static char *output_name = 0; static int use_switch = TRUE; static int use_tables = FALSE; static void print_version(const char * name) { #ifdef _DEBUG const char *acType = "Debug"; #else const char *acType = "Release"; #endif /* _DEBUG */ printf("%s [%s %s]\n",name,DW_VERSION_DATE_STR,acType); } static void print_usage_message(const char *options[]) { int index; for (index = 0; *options[index]; ++index) { printf("%s\n",options[index]); } } /* process arguments */ static void process_args(int argc, char *argv[]) { int c = 0; int usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:st")) != EOF) { switch (c) { case 'i': input_name = dwoptarg; break; case 'o': output_name = dwoptarg; break; case 's': use_switch = TRUE; use_tables = FALSE; break; case 't': use_switch = FALSE; use_tables = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(usage); exit(FAILED); } } int main(int argc,char **argv) { print_version(argv[0]); print_args(argc,argv); process_args(argc,argv); OpenAllFiles(); GenerateInitialFileLines(); ParseDefinitionsAndWriteOutput(); WriteFileTrailers(); CloseAllFiles(); return 0; } /* Print the array used to hold the tags, attributes values */ #ifdef TRACE_ARRAY static void PrintArray(void) { int i; for (i = 0; i < array_count; ++i) { printf("%d: Name %s_%s, Value 0x%04x\n", i,prefix, array[i].name, array[i].value); } } #endif /* TRACE_ARRAY */ /* By including original position we force a stable sort */ static int Compare(array_data *elem1,array_data *elem2) { if (elem1->value < elem2->value) { return -1; } if (elem1->value > elem2->value) { return 1; } if (elem1->original_position < elem2->original_position) { return -1; } if (elem1->original_position > elem2->original_position) { return 1; } return 0; } static FILE * open_path(const char *base, const char *file, const char *direction) { FILE *f = 0; /* POSIX PATH_MAX would suffice, normally stdio BUFSIZ is larger than PATH_MAX */ static char path_name[BUFSIZ]; /* 2 == space for / and NUL */ size_t netlen = strlen(file) +strlen(base) + 2; if (netlen >= BUFSIZ) { printf("Error opening '%s/%s', name too long\n",base,file); exit(1); } strcpy(path_name,base); strcat(path_name,"/"); strcat(path_name,file); f = fopen(path_name,direction); if (!f) { printf("Error opening '%s'\n",path_name); exit(1); } return f; } /* Open files and write the basic headers */ static void OpenAllFiles(void) { const char *dwarf_h = "dwarf.h"; const char *names_h = "dwarf_names.h"; const char *names_c = "dwarf_names.c"; const char *names_enum_h = "dwarf_names_enum.h"; const char *names_new_h = "dwarf_names_new.h"; f_dwarf_in = open_path(input_name,dwarf_h,"r"); f_names_enum_h = open_path(output_name,names_enum_h,"w"); f_names_new_h = open_path(output_name,names_new_h,"w"); f_names_h = open_path(output_name,names_h,"w"); f_names_c = open_path(output_name,names_c,"w"); } static void GenerateInitialFileLines(void) { /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h, "/* Automatically generated, do not edit. */\n"); fprintf(f_names_enum_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_enum_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_enum_h,"#ifndef __DWARF_NAMES_ENUM_H__\n"); fprintf(f_names_enum_h,"#define __DWARF_NAMES_ENUM_H__\n"); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h, "/* Automatically generated, do not edit. */\n"); fprintf(f_names_new_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_new_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_new_h,"/* define DWARF_PRINT_PREFIX " "before this\n"); fprintf(f_names_new_h," point if you wish to. */\n"); fprintf(f_names_new_h,"#ifndef DWARF_PRINT_PREFIX\n"); fprintf(f_names_new_h,"#define DWARF_PRINT_PREFIX dwarf_\n"); fprintf(f_names_new_h,"#endif\n"); fprintf(f_names_new_h,"#define dw_glue(x,y) x##y\n"); fprintf(f_names_new_h,"#define dw_glue2(x,y) dw_glue(x,y)\n"); fprintf(f_names_new_h,"#define DWPREFIX(x) " "dw_glue2(DWARF_PRINT_PREFIX,x)\n"); /* Generate entries for 'dwarf_names.h' */ fprintf(f_names_h,"/* Generated routines, do not edit. */\n"); fprintf(f_names_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_h,"#ifndef DWARF_NAMES_H\n"); fprintf(f_names_h,"#define DWARF_NAMES_H\n\n"); fprintf(f_names_h,"#ifdef __cplusplus\n"); fprintf(f_names_h,"extern \"C\" {\n"); fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); /* Generate entries for 'dwarf_names.c' */ fprintf(f_names_c,"/* Generated routines, do not edit. */\n"); fprintf(f_names_c,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_c,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_c,"#include \"dwarf.h\"\n\n"); fprintf(f_names_c,"#include \"libdwarf.h\"\n\n"); if (use_tables) { fprintf(f_names_c,"typedef struct Names_Data {\n"); fprintf(f_names_c," const char *l_name; \n"); fprintf(f_names_c," unsigned value; \n"); fprintf(f_names_c,"} Names_Data;\n\n"); /* Generate code to find an entry */ fprintf(f_names_c, "/* Use standard binary search to get entry */\n"); fprintf(f_names_c,"static int\nfind_entry(Names_Data *table," "const int last,unsigned value, const char **s_out)\n"); fprintf(f_names_c,"{\n"); fprintf(f_names_c," int low = 0;\n"); fprintf(f_names_c," int high = last;\n"); fprintf(f_names_c," int mid;\n"); fprintf(f_names_c," unsigned maxval = " "table[last-1].value;\n"); fprintf(f_names_c,"\n"); fprintf(f_names_c," if (value > maxval) {\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," while (low < high) {\n"); fprintf(f_names_c," mid = low + ((high - low) " "/ 2);\n"); fprintf(f_names_c," if (mid == last) {\n"); fprintf(f_names_c," break;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," if (table[mid].value " "< value) {\n"); fprintf(f_names_c," low = mid + 1;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," else {\n"); fprintf(f_names_c," high = mid;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c,"\n"); fprintf(f_names_c," if (low < last && table[low]." "value == value) {\n"); fprintf(f_names_c," /* Found: low is the entry */\n"); fprintf(f_names_c," *s_out = table[low].l_name;\n"); fprintf(f_names_c," return DW_DLV_OK;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c,"}\n"); fprintf(f_names_c,"\n"); } } /* Close files and write basic trailers */ static void WriteFileTrailers(void) { /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"#endif /* __DWARF_NAMES_ENUM_H__ */\n"); fprintf(f_names_enum_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names.h' */ fprintf(f_names_h,"\n#ifdef __cplusplus\n"); fprintf(f_names_h,"}\n"); fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); fprintf(f_names_h,"#endif /* DWARF_NAMES_H */\n"); fprintf(f_names_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names.c' */ fprintf(f_names_c,"\n/* END FILE */\n"); } static void CloseAllFiles(void) { fclose(f_dwarf_in); fclose(f_names_enum_h); fclose(f_names_new_h); fclose(f_names_h); fclose(f_names_c); } /* Write the table and code for a common set of names */ static void GenerateOneSet(void) { unsigned u; unsigned prev_value = 0; size_t len; char *prefix_id = prefix + prefix_root_len; unsigned actual_array_count = 0; #ifdef TRACE_ARRAY printf("List before sorting:\n"); PrintArray(); #endif /* TRACE_ARRAY */ /* Sort the array, because the values in 'libdwarf.h' are not in ascending order; if we use '-t' we must be sure the values are sorted, for the binary search to work properly. We want a stable sort, hence mergesort. */ qsort((void *)&group_array,array_count, sizeof(array_data),(compfn)Compare); #ifdef TRACE_ARRAY printf("\nList after sorting:\n"); PrintArray(); #endif /* TRACE_ARRAY */ /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"\nenum Dwarf_%s_e {\n",prefix_id); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h,"int DWPREFIX(get_%s_name) " "(unsigned int, const char **);\n",prefix_id); /* Generate entries for 'dwarf_names.h' and libdwarf.h */ fprintf(f_names_h,"extern int dwarf_get_%s_name" "(unsigned int /*val_in*/,\n",prefix_id); fprintf(f_names_h," const char ** /*s_out */);\n"); /* Generate code for 'dwarf_names.c' */ fprintf(f_names_c,"/* ARGSUSED */\n"); fprintf(f_names_c,"int\n"); fprintf(f_names_c,"dwarf_get_%s_name (unsigned int val,\n", prefix_id); fprintf(f_names_c," const char ** s_out)\n"); fprintf(f_names_c,"{\n"); if (use_tables) { fprintf(f_names_c," static Names_Data Dwarf_%s_n[] = {\n", prefix_id); } else { fprintf(f_names_c," switch (val) {\n"); } for (u = 0; u < array_count; ++u) { /* Check if value already dumped */ if (u > 0 && group_array[u].value == prev_value) { fprintf(f_names_c, " /* Skipping alternate spelling of value\n"); fprintf(f_names_c, " 0x%x. %s_%s */\n", (unsigned)prev_value, prefix, group_array[u].name); continue; } prev_value = group_array[u].value; /* Generate entries for 'dwarf_names_enum.h'. The 39 just makes nice formatting in the output. */ len = 39 - strlen(prefix); fprintf(f_names_enum_h," %s_%-*s = 0x%04x", prefix,(int)len,group_array[u].name,group_array[u].value); fprintf(f_names_enum_h,(u + 1 < array_count) ? ",\n" : "\n"); /* Generate entries for 'dwarf_names.c' */ if (use_tables) { fprintf(f_names_c," {/* %3u */ \"%s_%s\", ", actual_array_count,prefix,group_array[u].name); fprintf(f_names_c," %s_%s}", prefix,group_array[u].name); fprintf(f_names_c,(u + 1 < array_count) ? ",\n" : "\n"); } else { fprintf(f_names_c," case %s_%s:\n", prefix,group_array[u].name); fprintf(f_names_c," *s_out = \"%s_%s\";\n", prefix,group_array[u].name); fprintf(f_names_c," return DW_DLV_OK;\n"); } ++actual_array_count; } /* Closing entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"};\n"); if (use_tables) { /* Closing entries for 'dwarf_names.c' */ fprintf(f_names_c," };\n\n"); /* Closing code for 'dwarf_names.c' */ fprintf(f_names_c," const int last_entry = %d;\n", actual_array_count); fprintf(f_names_c," /* find the entry */\n"); fprintf(f_names_c, " int r = find_entry(Dwarf_%s_n," "last_entry,val,s_out);\n",prefix_id); fprintf(f_names_c," return r;\n"); fprintf(f_names_c,"}\n"); } else { fprintf(f_names_c," }\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c,"}\n"); } /* Mark the group_array as empty */ array_count = 0; } /* Detect empty lines (and other lines we do not want to read) */ static int is_skippable_line(char *pLine) { int empty = TRUE; for (; *pLine && empty; ++pLine) { empty = isspace(*pLine); } return empty; } static void safe_strncpy(char *out, unsigned out_len, char *in,unsigned in_len) { if (in_len >= out_len) { fprintf(stderr,"Impossible input line from dwarf.h. " "Giving up. \n"); fprintf(stderr,"Length %u is too large, limited to %u.\n", in_len,out_len); exit(1); } strncpy(out,in,in_len); } /* Parse the 'dwarf.h' file and generate the tables */ static void ParseDefinitionsAndWriteOutput(void) { char new_prefix[64]; char *second_underscore = NULL; char type[1000]; char name[1000]; char value[1000]; char extra[1000]; char line_in[MAX_LINE_SIZE]; int pending = FALSE; int prefix_len = 0; /* Process each line from 'dwarf.h' */ while (!feof(f_dwarf_in)) { /* errno is cleared here so printing errno after the fgets is showing errno as set by fgets. */ char *fgbad = 0; errno = 0; fgbad = fgets(line_in,sizeof(line_in),f_dwarf_in); if (!fgbad) { if (feof(f_dwarf_in)) { break; } /* Is error. errno must be set. */ fprintf(stderr,"Error reading dwarf.h!. Errno %d\n", errno); exit(1); } if (is_skippable_line(line_in)) { continue; } sscanf(line_in,"%s %s %s %s",type,name,value,extra); if (strcmp(type,"#define") || strncmp(name,prefix_root,prefix_root_len)) { continue; } second_underscore = strchr(name + prefix_root_len,'_'); prefix_len = (int)(second_underscore - name); safe_strncpy(new_prefix,sizeof(new_prefix),name,prefix_len); new_prefix[prefix_len] = 0; /* Check for new prefix set */ if (strcmp(prefix,new_prefix)) { if (pending) { /* Generate current prefix set */ GenerateOneSet(); } pending = TRUE; strcpy(prefix,new_prefix); } /* Be sure we have a valid entry */ if (array_count >= ARRAY_SIZE) { printf("Too many entries for current " "group_array size of %d",ARRAY_SIZE); exit(1); } /* Move past the second underscore */ ++second_underscore; { unsigned long v = strtoul(value,NULL,16); /* Some values are duplicated, that is ok. After the sort we will weed out the duplicate values, see GenerateOneSet(). */ /* Record current entry */ if (strlen(second_underscore) >= MAX_NAME_LEN) { printf("Too long a name %s for max len %d\n", second_underscore,MAX_NAME_LEN); exit(1); } strcpy(group_array[array_count].name,second_underscore); group_array[array_count].value = v; group_array[array_count].original_position = array_count; ++array_count; } } if (pending) { /* Generate final prefix set */ GenerateOneSet(); } } libdwarf-20210528/libdwarf/dwarf_incl.h0000644000175000017500000000336713743575426014576 00000000000000/* Copyright (C) 2000, 2002, 2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2008-2010 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_INCL_H #define DWARF_INCL_H #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) /* At a certain point libelf.h requires _GNU_SOURCE. here we assume the criteria in configure determined that usefully. */ #define _GNU_SOURCE 1 #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" #include /* strcpy() strlen() */ #include #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #endif /* DWARF_INCL_H */ libdwarf-20210528/libdwarf/dwarf_tsearch.h0000664000175000017500000001044714012266121015254 00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ /* configure/cmake ensure uintptr_t defined, but if not, possibly "-Duintptr_t=unsigned long" might help */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, dwarf_postorder, dwarf_endorder, dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. */ /* We rename these so there is no conflict with another version of the tsearch sources, such as is used in dwarfdump. */ #define dwarf_tsearch _dwarf_tsearch #define dwarf_tfind _dwarf_tfind #define dwarf_tdelete _dwarf_tdelete #define dwarf_twalk _dwarf_twalk #define dwarf_tdestroy _dwarf_tdestroy #define dwarf_tdump _dwarf_tdump #define dwarf_initialize_search_hash _dwarf_initialize_search_hash void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ libdwarf-20210528/libdwarf/baseline.ltp0000644000175000017500000000232513743575426014611 00000000000000Adding global path /usr/lib/debug Adding global path /fake/lib/debug executable path /a/b linkstring de linkstring full path: /a/de Paths: [ 0] "/usr/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/a/de" [ 3] "/a/.debug/de" [ 4] "/usr/lib/debug/a/de" [ 5] "/fake/lib/debug/a/de" executable path /foo/ge linkstring h/i linkstring full path: /foo/h/i Paths: [ 0] "/usr/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/foo/h/i" [ 3] "/foo/.debug/h/i" [ 4] "/usr/lib/debug/foo/h/i" [ 5] "/fake/lib/debug/foo/h/i" executable path a/b/ge linkstring i.debug linkstring full path: /exam/ple/a/b/i.debug Paths: [ 0] "/usr/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/.build-id/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/exam/ple/a/b/i.debug" [ 3] "/exam/ple/a/b/.debug/i.debug" [ 4] "/usr/lib/debug/exam/ple/a/b/i.debug" [ 5] "/fake/lib/debug/exam/ple/a/b/i.debug" libdwarf-20210528/libdwarf/dwarf_form.c0000664000175000017500000017543514051567524014610 00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarfstring.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_die_deliv.h" #include "dwarf_str_offsets.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 /* It is necessary at times to cause errors of this sort in determining what we really have. So best to avoid too much malloc and free, hence the static constructor dwarfstring will use malloc if we guess too-small for the size of mbuf. */ static void generate_form_error(Dwarf_Debug dbg, Dwarf_Error *error, unsigned form, int err_code, const char *errname, const char *funcname) { dwarfstring m; char mbuf[DWARFSTRING_ALLOC_SIZE]; const char * defaultname = ""; dwarfstring_constructor_static(&m,mbuf, sizeof(mbuf)); dwarfstring_append(&m,(char *)errname); dwarfstring_append(&m,": In function "); dwarfstring_append(&m,(char *)funcname); dwarfstring_append_printf_u(&m, " on seeing form 0x%x ",form); dwarf_get_FORM_name(form,&defaultname); dwarfstring_append_printf_s(&m, " (%s)",(char *)defaultname); _dwarf_error_string(dbg,error,err_code, dwarfstring_string(&m)); dwarfstring_destructor(&m); } /* This code was repeated many times, now it is all in one place. */ static int get_attr_dbg(Dwarf_Debug *dbg, Dwarf_CU_Context * cu_context, Dwarf_Attribute attr, Dwarf_Error *error) { Dwarf_CU_Context cup; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } cup = attr->ar_cu_context; if (cup == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return DW_DLV_ERROR; } if (cup->cc_dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return DW_DLV_ERROR; } *cu_context = cup; *dbg = cup->cc_dbg; return DW_DLV_OK; } int dwarf_hasform(Dwarf_Attribute attr, Dwarf_Half form, Dwarf_Bool * return_bool, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_bool = (attr->ar_attribute_form == form); return DW_DLV_OK; } /* Not often called, we do not worry about efficiency here. The dwarf_whatform() call does the sanity checks for us. */ int dwarf_whatform_direct(Dwarf_Attribute attr, Dwarf_Half * return_form, Dwarf_Error * error) { int res = dwarf_whatform(attr, return_form, error); if (res != DW_DLV_OK) { return res; } *return_form = attr->ar_attribute_form_direct; return DW_DLV_OK; } /* Pass in the content of a block and the length of that content. On success return DW_DLV_OK and set *value_count to the size of the array returned through value_array. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug dbg, Dwarf_Unsigned input_length_in_bytes, void * input_block, Dwarf_Unsigned * value_count, Dwarf_Signed ** value_array, Dwarf_Error * error) { Dwarf_Unsigned output_length_in_units = 0; Dwarf_Signed * output_block = 0; unsigned i = 0; char * ptr = 0; int remain = 0; Dwarf_Signed * array = 0; Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ input_length_in_bytes; output_length_in_units = 0; remain = input_length_in_bytes; ptr = input_block; while (remain > 0) { Dwarf_Unsigned len = 0; Dwarf_Signed value = 0; int rres = 0; rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &value,endptr); if (rres != DW_DLV_OK) { _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); return DW_DLV_ERROR; } ptr += len; remain -= len; output_length_in_units++; } if (remain != 0) { _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } output_block = (Dwarf_Signed*) _dwarf_get_alloc(dbg, DW_DLA_STRING, output_length_in_units * sizeof(Dwarf_Signed)); if (!output_block) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } array = output_block; remain = input_length_in_bytes; ptr = input_block; for (i=0; i0; i++) { Dwarf_Signed num; Dwarf_Unsigned len; int sres = 0; sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &num,endptr); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg,output_block,DW_DLA_STRING); _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); return DW_DLV_ERROR; } ptr += len; remain -= len; array[i] = num; } if (remain != 0) { dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } *value_count = output_length_in_units; *value_array = output_block; return DW_DLV_OK; } /* This code was contributed around 2007 and the return value is in the wrong form. See dwarf_uncompress_integer_block_a() above. As of 2019 it is not clear that Sun Sparc compilers are in current use, nor whether there is a reason to make reads of this data format safe from corrupted object files. */ void * dwarf_uncompress_integer_block( Dwarf_Debug dbg, Dwarf_Bool unit_is_signed, Dwarf_Small unit_length_in_bits, void* input_block, Dwarf_Unsigned input_length_in_bytes, Dwarf_Unsigned* output_length_in_units_ptr, Dwarf_Error* error ) { Dwarf_Unsigned output_length_in_units = 0; void * output_block = 0; unsigned i = 0; char * ptr = 0; int remain = 0; /* This only applies to Sun and there an unsigned is 4 bytes so this works. As with most linux. */ unsigned * array = 0; Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ input_length_in_bytes; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return((void *)DW_DLV_BADADDR); } if (unit_is_signed == false || unit_length_in_bits != 32 || input_block == NULL || input_length_in_bytes == 0 || output_length_in_units_ptr == NULL) { _dwarf_error(NULL, error, DW_DLE_BADBITC); return ((void *) DW_DLV_BADADDR); } /* At this point we assume the format is: signed 32 bit */ /* first uncompress everything to find the total size. */ output_length_in_units = 0; remain = input_length_in_bytes; ptr = input_block; while (remain > 0) { Dwarf_Unsigned len = 0; Dwarf_Signed value = 0; int rres = 0; rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &value,endptr); if (rres != DW_DLV_OK) { return ((void *)DW_DLV_BADADDR); } ptr += len; remain -= len; output_length_in_units++; } if (remain != 0) { _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); return((void *)DW_DLV_BADADDR); } /* then alloc */ output_block = (void *) _dwarf_get_alloc(dbg, DW_DLA_STRING, output_length_in_units * (unit_length_in_bits / 8)); if (output_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return((void*)DW_DLV_BADADDR); } /* then uncompress again and copy into new buffer */ array = (unsigned *) output_block; remain = input_length_in_bytes; ptr = input_block; for (i=0; i0; i++) { Dwarf_Signed num; Dwarf_Unsigned len; int sres = 0; sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &num,endptr); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg,output_block,DW_DLA_STRING); return ((void *) DW_DLV_BADADDR); } ptr += len; remain -= len; array[i] = num; } if (remain != 0) { dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return((Dwarf_P_Attribute)DW_DLV_BADADDR); } *output_length_in_units_ptr = output_length_in_units; return output_block; } void dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space) { dwarf_dealloc(dbg, space, DW_DLA_STRING); } int dwarf_whatform(Dwarf_Attribute attr, Dwarf_Half * return_form, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_form = attr->ar_attribute_form; return DW_DLV_OK; } /* This function is analogous to dwarf_whatform. It returns the attribute in attr instead of the form. */ int dwarf_whatattr(Dwarf_Attribute attr, Dwarf_Half * return_attr, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_attr = (attr->ar_attribute); return DW_DLV_OK; } /* Convert an offset within the local CU into a section-relative debug_info (or debug_types) offset. See dwarf_global_formref() and dwarf_formref() for additional information on conversion rules. */ int dwarf_convert_to_global_offset(Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } switch (attr->ar_attribute_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: /* It is a cu-local offset. Convert to section-global. */ /* It would be nice to put some code to check legality of the offset */ /* cc_debug_offset always has any DWP Package File offset included (when the cu_context created) so there is no extra work for DWP. Globalize the offset */ offset += cu_context->cc_debug_offset; break; case DW_FORM_ref_addr: /* This offset is defined to be debug_info global already, so use this value unaltered. Since a DWP package file is not relocated there is no way that this reference offset to an address in any other CU can be correct for a DWP Package File offset */ break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_BAD_REF_FORM. The form " "code is 0x%x which cannot be converted to a global " " offset by " "dwarf_convert_to_global_offset()", attr->ar_attribute_form); _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } *ret_offset = (offset); return DW_DLV_OK; } /* A global offset cannot be returned by this interface: see dwarf_global_formref(). DW_FORM_ref_addr is considered an incorrect form for this call because DW_FORM_ref_addr is a global-offset into the debug_info section. For the same reason DW_FORM_data4/data8 are not returned from this function. For the same reason DW_FORM_sec_offset is not returned from this function, DW_FORM_sec_offset is a global offset (to various sections, not a CU relative offset. DW_FORM_ref_addr has a value which was documented in DWARF2 as address-size but which was always an offset so should have always been offset size (wording corrected in DWARF3). The dwarfstd.org FAQ "How big is a DW_FORM_ref_addr?" suggested all should use offset-size, but that suggestion seems to have been ignored in favor of doing what the DWARF2 and 3 standards actually say. November, 2010: *ret_offset is always set now. Even in case of error. Set to zero for most errors, but for DW_DLE_ATTR_FORM_OFFSET_BAD *ret_offset is set to the bad offset. DW_FORM_addrx DW_FORM_strx DW_FORM_rnglistx DW_FORM_GNU_addr_index DW_FORM_GNU_str_index are not references to .debug_info/.debug_types, so they are not allowed here. */ int dwarf_formref(Dwarf_Attribute attr, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned maximumoffset = 0; int res = DW_DLV_ERROR; Dwarf_Byte_Ptr section_end = 0; *ret_offset = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch (attr->ar_attribute_form) { case DW_FORM_ref1: offset = *(Dwarf_Small *) attr->ar_debug_ptr; break; case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); break; case DW_FORM_ref_udata: { Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr; Dwarf_Unsigned localoffset = 0; DECODE_LEB128_UWORD_CK(ptr,localoffset, dbg,error,section_end); offset = localoffset; break; } case DW_FORM_ref_sig8: /* We cannot handle this here. The reference is to .debug_types not a .debug_info CU local offset. */ _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED); return DW_DLV_ERROR; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_BAD_REF_FORM. The form " "code is 0x%x which does not have an offset " " for " "dwarf_formref() to return.", attr->ar_attribute_form); _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } /* Check that offset is within current cu portion of .debug_info. */ maximumoffset = cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; if (offset >= maximumoffset) { /* For the DW_TAG_compile_unit is legal to have the DW_AT_sibling attribute outside the current cu portion of .debug_info. In other words, sibling points to the end of the CU. It is used for precompiled headers. The valid condition will be: 'offset == maximumoffset'. */ Dwarf_Half tag = 0; int tres = dwarf_tag(attr->ar_die,&tag,error); if (tres != DW_DLV_OK) { if (tres == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_NO_TAG_FOR_DIE); return DW_DLV_ERROR; } return DW_DLV_ERROR; } if (DW_TAG_compile_unit != tag && DW_AT_sibling != attr->ar_attribute && offset > maximumoffset) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); /* Return the incorrect offset for better error reporting */ *ret_offset = (offset); return DW_DLV_ERROR; } } *ret_offset = (offset); return DW_DLV_OK; } static int _dwarf_formsig8_internal(Dwarf_Attribute attr, int formexpected, int formerrnum, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr field_end = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (attr->ar_attribute_form != formexpected ) { _dwarf_error(dbg, error, formerrnum); return DW_DLV_ERROR; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); field_end = attr->ar_debug_ptr + sizeof(Dwarf_Sig8); if (field_end > section_end) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); return DW_DLV_ERROR; } memcpy(returned_sig_bytes, attr->ar_debug_ptr, sizeof(Dwarf_Sig8)); return DW_DLV_OK; } int dwarf_formsig8_const(Dwarf_Attribute attr, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { int res =_dwarf_formsig8_internal(attr, DW_FORM_data8, DW_DLE_ATTR_FORM_NOT_DATA8, returned_sig_bytes,error); return res; } /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes directly to the caller). Not a string, an 8 byte MD5 hash or a signature. This function is new in DWARF4 libdwarf and used in more places in DWARF5. */ int dwarf_formsig8(Dwarf_Attribute attr, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { int res = _dwarf_formsig8_internal(attr, DW_FORM_ref_sig8, DW_DLE_BAD_REF_SIG8_FORM, returned_sig_bytes,error); return res; } /* Since this returns section-relative debug_info offsets, this can represent all REFERENCE forms correctly and allows all applicable forms. DW_FORM_ref_addr has a value which was documented in DWARF2 as address-size but which was always an offset so should have always been offset size (wording corrected in DWARF3). gcc and Go and libdwarf producer code define the length of the value of DW_FORM_ref_addr per the version. So for V2 it is address-size and V3 and later it is offset-size. See the DWARF4 document for the 3 cases fitting reference forms. The caller must determine which section the reference 'points' to. The function added in November 2009, dwarf_get_form_class(), helps in this regard. unlike dwarf_formref(), this allows references to sections other than just .debug_info/.debug_types. See case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: 2013 GNU extension case DW_FORM_GNU_strp_alt: 2013 GNU extension case DW_FORM_strp_sup: DWARF5, sup string section case DW_FORM_line_strp: DWARF5, .debug_line_str section */ int dwarf_global_formref(Dwarf_Attribute attr, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Half context_version = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); context_version = cu_context->cc_version_stamp; switch (attr->ar_attribute_form) { case DW_FORM_ref1: offset = *(Dwarf_Small *) attr->ar_debug_ptr; goto fixoffset; case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref_udata: { Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr; Dwarf_Unsigned localoffset = 0; DECODE_LEB128_UWORD_CK(ptr,localoffset, dbg,error,section_end); offset = localoffset; fixoffset: /* we have a local offset, make it global */ /* check legality of offset */ if (offset >= cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); return DW_DLV_ERROR; } /* globalize the offset */ offset += cu_context->cc_debug_offset; } break; /* The DWARF2 document did not make clear that DW_FORM_data4( and 8) were references with global offsets to some section. That was first clearly documented in DWARF3. In DWARF4 these two forms are no longer references. */ case DW_FORM_data4: if (context_version >= DW_CU_VERSION4) { _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error, section_end); /* The offset is global. */ break; case DW_FORM_data8: if (context_version >= DW_CU_VERSION4) { _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); /* The offset is global. */ break; case DW_FORM_ref_addr: { /* In Dwarf V2 DW_FORM_ref_addr was defined as address-size even though it is a .debug_info offset. Fixed in Dwarf V3 to be offset-size. */ unsigned length_size = 0; if (context_version == 2) { length_size = cu_context->cc_address_size; } else { length_size = cu_context->cc_length_size; } if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); return DW_DLV_ERROR; } } break; /* Index into .debug_rnglists/.debug_loclists section. Return the index itself. */ case DW_FORM_loclistx: case DW_FORM_rnglistx: { unsigned length_size = cu_context->cc_length_size; READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, length_size, error,section_end); } break; case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: /* 2013 GNU extension */ case DW_FORM_GNU_strp_alt: /* 2013 GNU extension */ case DW_FORM_strp_sup: /* DWARF5, sup string section */ case DW_FORM_line_strp: /* DWARF5, .debug_line_str section */ { /* DW_FORM_sec_offset first exists in DWARF4.*/ /* It is up to the caller to know what the offset of DW_FORM_sec_offset, DW_FORM_strp_sup or DW_FORM_GNU_strp_alt etc refer to, the offset is not going to refer to .debug_info! */ unsigned length_size = cu_context->cc_length_size; if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); return DW_DLV_ERROR; } } break; case DW_FORM_ref_sig8: /* FIXME */ /* We cannot handle this yet. The reference could be to .debug_types, and this function only returns an offset in .debug_info at this point. */ _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED); return DW_DLV_ERROR; default: { dwarfstring m; int formcode = attr->ar_attribute_form; int fcres = 0; const char *name = 0; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_BAD_REF_FORM: The form code is 0x%x ", formcode); fcres = dwarf_get_FORM_name (formcode,&name); if (fcres != DW_DLV_OK) { name=""; } dwarfstring_append_printf_s(&m, " %s.",(char *)name); _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } /* We do not know what section the offset refers to, so we have no way to check it for correctness. */ *ret_offset = offset; return DW_DLV_OK; } /* Part of DebugFission. So a consumer can get the index when the object with the actual debug_addr is elsewhere. New May 2014*/ int _dwarf_get_addr_index_itself(int theform, Dwarf_Small *info_ptr, Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned *val_out, Dwarf_Error * error) { Dwarf_Unsigned index = 0; Dwarf_Byte_Ptr section_end = 0; section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch(theform){ case DW_FORM_GNU_addr_index: case DW_FORM_addrx: DECODE_LEB128_UWORD_CK(info_ptr,index, dbg,error,section_end); break; case DW_FORM_addrx1: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 1, error,section_end); break; case DW_FORM_addrx2: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 2, error,section_end); break; case DW_FORM_addrx3: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 3, error,section_end); break; case DW_FORM_addrx4: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 4, error,section_end); break; default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); return DW_DLV_ERROR; } *val_out = index; return DW_DLV_OK; } int dwarf_get_debug_addr_index(Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error * error) { int theform = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } theform = attr->ar_attribute_form; if (dwarf_addr_form_is_indexed(theform)) { Dwarf_Unsigned index = 0; res = _dwarf_get_addr_index_itself(theform, attr->ar_debug_ptr,dbg,cu_context,&index,error); *return_index = index; return res; } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); return DW_DLV_ERROR; } static int dw_read_index_val_itself(Dwarf_Debug dbg, unsigned theform, Dwarf_Small *info_ptr, Dwarf_Small *section_end, Dwarf_Unsigned *return_index, Dwarf_Error *error) { Dwarf_Unsigned index = 0; switch(theform) { case DW_FORM_strx: case DW_FORM_GNU_str_index: DECODE_LEB128_UWORD_CK(info_ptr,index, dbg,error,section_end); break; case DW_FORM_strx1: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 1, error,section_end); break; case DW_FORM_strx2: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 2, error,section_end); break; case DW_FORM_strx3: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 3, error,section_end); break; case DW_FORM_strx4: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 4, error,section_end); break; default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_STR_INDEX); return DW_DLV_ERROR; } *return_index = index; return DW_DLV_OK; } /* Part of DebugFission. So a dwarf dumper application can get the index and print it for the user. A convenience function. New May 2014 Also used with DWARF5 forms. */ int dwarf_get_debug_str_index(Dwarf_Attribute attr, Dwarf_Unsigned *return_index, Dwarf_Error *error) { int theform = attr->ar_attribute_form; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Unsigned index = 0; Dwarf_Small *info_ptr = 0; int indxres = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); info_ptr = attr->ar_debug_ptr; indxres = dw_read_index_val_itself(dbg, theform, info_ptr, section_end, &index,error); if (indxres == DW_DLV_OK) { *return_index = index; return indxres; } return indxres; } int _dwarf_extract_data16(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Small *section_start, Dwarf_Small *section_end, Dwarf_Form_Data16 * returned_val, Dwarf_Error *error) { Dwarf_Small *data16end = 0; data16end = data + sizeof(Dwarf_Form_Data16); if (data < section_start || section_end < data16end) { _dwarf_error(dbg, error,DW_DLE_DATA16_OUTSIDE_SECTION); return DW_DLV_ERROR; } memcpy(returned_val, data, sizeof(Dwarf_Form_Data16)); return DW_DLV_OK; } int dwarf_formdata16(Dwarf_Attribute attr, Dwarf_Form_Data16 * returned_val, Dwarf_Error* error) { Dwarf_Half attrform = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned section_length = 0; Dwarf_Small *section_start = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } if (returned_val == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } attrform = attr->ar_attribute_form; if (attrform != DW_FORM_data16) { generate_form_error(dbg,error,attrform, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "dwarf_formdata16"); return DW_DLV_ERROR; } res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_start = _dwarf_calculate_info_section_start_ptr( cu_context,§ion_length); section_end = section_start + section_length; res = _dwarf_extract_data16(dbg, attr->ar_debug_ptr, section_start, section_end, returned_val, error); return res; } /* The *addrx are DWARF5 standard. The GNU form is non-standard gcc DWARF4 */ Dwarf_Bool dwarf_addr_form_is_indexed(int form) { switch(form) { case DW_FORM_addrx: case DW_FORM_addrx1: case DW_FORM_addrx2: case DW_FORM_addrx3: case DW_FORM_addrx4: case DW_FORM_GNU_addr_index: return TRUE; } return FALSE; } int dwarf_formaddr(Dwarf_Attribute attr, Dwarf_Addr * return_addr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Addr ret_addr = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Half attrform = 0; int res = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } attrform = attr->ar_attribute_form; if (dwarf_addr_form_is_indexed(attrform)) { res = _dwarf_look_in_local_and_tied( attrform, cu_context, attr->ar_debug_ptr, return_addr, error); return res; } if (attrform == DW_FORM_addr /* || attrform == DW_FORM_ref_addr Allowance of DW_FORM_ref_addr was a mistake. The value returned in that case is NOT an address it is a global debug_info offset (ie, not CU-relative offset within the CU in debug_info). The DWARF2 document refers to it as an address (misleadingly) in sec 6.5.4 where it describes the reference form. It is address-sized so that the linker can easily update it, but it is a reference inside the debug_info section. No longer allowed. */ ) { Dwarf_Small *section_end = _dwarf_calculate_info_section_end_ptr(cu_context); READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr, attr->ar_debug_ptr, cu_context->cc_address_size, error,section_end); *return_addr = ret_addr; return DW_DLV_OK; } generate_form_error(dbg,error,attrform, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "dwarf_formaddr"); return DW_DLV_ERROR; } int dwarf_formflag(Dwarf_Attribute attr, Dwarf_Bool * ret_bool, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } cu_context = attr->ar_cu_context; if (cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return DW_DLV_ERROR; } dbg = cu_context->cc_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return DW_DLV_ERROR; } if (attr->ar_attribute_form == DW_FORM_flag_present) { /* Implicit means we don't read any data at all. Just the existence of the Form does it. DWARF4. */ *ret_bool = 1; return DW_DLV_OK; } if (attr->ar_attribute_form == DW_FORM_flag) { *ret_bool = *(Dwarf_Small *)(attr->ar_debug_ptr); return DW_DLV_OK; } generate_form_error(dbg,error,attr->ar_attribute_form, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "dwarf_formflat"); return DW_DLV_ERROR; } Dwarf_Bool _dwarf_allow_formudata(unsigned form) { switch(form) { case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_udata: case DW_FORM_loclistx: case DW_FORM_rnglistx: return TRUE; } return FALSE; } /* If the form is DW_FORM_constx and the .debug_addr section is missing, this returns DW_DLV_ERROR and the error number in the Dwarf_Error is DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION. When that arises, a consumer should call dwarf_get_debug_addr_index() and use that on the appropriate .debug_addr section in the executable or another object. */ int _dwarf_formudata_internal(Dwarf_Debug dbg, unsigned form, Dwarf_Byte_Ptr data, Dwarf_Byte_Ptr section_end, Dwarf_Unsigned *return_uval, Dwarf_Unsigned *bytes_read, Dwarf_Error *error) { Dwarf_Unsigned ret_value = 0; switch (form) { case DW_FORM_data1: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, sizeof(Dwarf_Small), error,section_end); *return_uval = ret_value; *bytes_read = 1; return DW_DLV_OK; /* READ_UNALIGNED does the right thing as it reads the right number bits and generates host order. So we can just assign to *return_uval. */ case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_HALF_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = 2; return DW_DLV_OK; } case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = DWARF_32BIT_SIZE;; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_64BIT_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = DWARF_64BIT_SIZE; return DW_DLV_OK; } break; /* real udata */ case DW_FORM_loclistx: case DW_FORM_rnglistx: case DW_FORM_udata: { Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(data, ret_value,leblen, dbg,error,section_end); *return_uval = ret_value; *bytes_read = leblen; return DW_DLV_OK; } /* IRIX bug 583450. We do not allow reading sdata from a udata value. Caller can retry, calling sdata */ default: break; } generate_form_error(dbg,error,form, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "formudata (internal function)"); return DW_DLV_ERROR; } int dwarf_formudata(Dwarf_Attribute attr, Dwarf_Unsigned * return_uval, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Unsigned bytes_read = 0; Dwarf_Byte_Ptr data = attr->ar_debug_ptr; unsigned form = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); form = attr->ar_attribute_form; res = _dwarf_formudata_internal(dbg, form, data, section_end, return_uval, &bytes_read, error); return res; } int dwarf_formsdata(Dwarf_Attribute attr, Dwarf_Signed * return_sval, Dwarf_Error * error) { Dwarf_Signed ret_value = 0; Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch (attr->ar_attribute_form) { case DW_FORM_data1: if ( attr->ar_debug_ptr >= section_end) { _dwarf_error(dbg, error, DW_DLE_DIE_BAD); return DW_DLV_ERROR; } *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_ptr); return DW_DLV_OK; /* READ_UNALIGNED does not sign extend. So we have to use a cast to get the value sign extended in the right way for each case. */ case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); *return_sval = (Dwarf_Shalf) ret_value; return DW_DLV_OK; } case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); SIGN_EXTEND(ret_value,DWARF_32BIT_SIZE); *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); /* No SIGN_EXTEND needed, we are filling all bytes already.*/ *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } /* DW_FORM_implicit_const is a value in the abbreviations, not in the DIEs. */ case DW_FORM_implicit_const: *return_sval = attr->ar_implicit_const; return DW_DLV_OK; case DW_FORM_sdata: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; DECODE_LEB128_SWORD_CK(tmp, ret_value, dbg,error,section_end); *return_sval = ret_value; return DW_DLV_OK; } /* IRIX bug 583450. We do not allow reading sdata from a udata value. Caller can retry, calling udata */ default: break; } generate_form_error(dbg,error,attr->ar_attribute_form, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "dwarf_formsdata"); return DW_DLV_ERROR; } int _dwarf_formblock_internal(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_CU_Context cu_context, Dwarf_Block * return_block, Dwarf_Error * error) { Dwarf_Small *section_start = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned section_length = 0; Dwarf_Unsigned length = 0; Dwarf_Small *data = 0; section_end = _dwarf_calculate_info_section_end_ptr(cu_context); section_start = _dwarf_calculate_info_section_start_ptr(cu_context, §ion_length); switch (attr->ar_attribute_form) { case DW_FORM_block1: length = *(Dwarf_Small *) attr->ar_debug_ptr; data = attr->ar_debug_ptr + sizeof(Dwarf_Small); break; case DW_FORM_block2: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); data = attr->ar_debug_ptr + DWARF_HALF_SIZE; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); data = attr->ar_debug_ptr + DWARF_32BIT_SIZE; break; case DW_FORM_exprloc: case DW_FORM_block: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(tmp, length, leblen, dbg,error,section_end); data = attr->ar_debug_ptr + leblen; break; } default: generate_form_error(dbg,error,attr->ar_attribute_form, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "dwarf_formblock"); return DW_DLV_ERROR; } /* We have the data. Check for errors. */ if (length >= section_length) { /* Sanity test looking for wraparound: when length actually added in it would not be caught. Test could be just >, but >= ok here too.*/ _dwarf_error_string(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: " "The length of the block is greater " "than the section length! Corrupt Dwarf."); return DW_DLV_ERROR; } if ((attr->ar_debug_ptr + length) > section_end) { _dwarf_error_string(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: " "The block length means the block " "runs off the end of the section length!" " Corrupt Dwarf."); return DW_DLV_ERROR; } if (data > section_end) { _dwarf_error_string(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: " "The block content is " "past the end of the section!" " Corrupt Dwarf."); _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return DW_DLV_ERROR; } if ((data + length) > section_end) { _dwarf_error_string(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR, "DW_DLE_FORM_BLOCK_LENGTH_ERROR: " "The end of the block content is " "past the end of the section!" " Corrupt Dwarf."); return DW_DLV_ERROR; } return_block->bl_len = length; return_block->bl_data = data; /* This struct is public so use the old name instead of what we now would call it: bl_kind */ return_block->bl_from_loclist = DW_LKIND_expression; return_block->bl_section_offset = data - section_start; return DW_DLV_OK; } int dwarf_formblock(Dwarf_Attribute attr, Dwarf_Block ** return_block, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; Dwarf_Block local_block; Dwarf_Block *out_block = 0; int res = 0; memset(&local_block,0,sizeof(local_block)); res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_formblock_internal(dbg,attr, cu_context, &local_block, error); if (res != DW_DLV_OK) { return res; } out_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); if (out_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } *out_block = local_block; *return_block = out_block; return DW_DLV_OK; } int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *data_ptr, Dwarf_Small *end_data_ptr, UNUSEDARG Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, Dwarf_Unsigned *str_sect_offset_out, Dwarf_Error *error) { Dwarf_Unsigned index_to_offset_entry = 0; Dwarf_Unsigned offsetintable = 0; Dwarf_Unsigned end_offsetintable = 0; Dwarf_Unsigned indexoffset = 0; Dwarf_Unsigned baseoffset = 0; int res = 0; int idxres = 0; Dwarf_Small *sof_start = 0; Dwarf_Unsigned sof_len = 0; Dwarf_Small *sof_end = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } /* If this is a dwp we look there, but I suppose we could also look for the section in the tied file it is not here. */ sof_start = dbg->de_debug_str_offsets.dss_data; sof_len = dbg->de_debug_str_offsets.dss_size; sof_end = sof_start+sof_len; idxres = dw_read_index_val_itself(dbg, attrform,data_ptr,end_data_ptr,&index_to_offset_entry,error); if ( idxres != DW_DLV_OK) { return idxres; } if (cu_context->cc_str_offsets_base_present) { baseoffset = cu_context->cc_str_offsets_base; } indexoffset = index_to_offset_entry* cu_context->cc_length_size; baseoffset = cu_context->cc_str_offsets_base; if (!baseoffset) { if (cu_context->cc_version_stamp == DW_CU_VERSION5 ) { /* A base offset of 0 isnormally never correct for DWARF5. but some early GNU compilers emitted DWARF4 .debug_str_offsets, so lets check the first table. */ Dwarf_Small * ststart = dbg->de_debug_str_offsets.dss_data; Dwarf_Small * stend = 0; Dwarf_Unsigned stsize = dbg->de_debug_str_offsets.dss_size; Dwarf_Unsigned length = 0; Dwarf_Half local_offset_size = 0; Dwarf_Half local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; stend = ststart + stsize; res = _dwarf_trial_read_dwarf_five_hdr(dbg, ststart,stsize,stend, &length, &local_offset_size, &local_extension_size, &version, &padding, error); if (res == DW_DLV_OK) { baseoffset = local_extension_size + local_offset_size + 2*DWARF_HALF_SIZE; } else { if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } } } } offsetintable = baseoffset +indexoffset; end_offsetintable = offsetintable + cu_context->cc_str_offsets_offset_size; /* The offsets table is a series of offset-size entries. The == case in the test applies when we are at the last table entry, so == is not an error, hence only test > */ if (end_offsetintable > dbg->de_debug_str_offsets.dss_size ) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ATTR_FORM_SIZE_BAD: The end offset of " "a .debug_str_offsets table is 0x%x ", end_offsetintable); dwarfstring_append_printf_u(&m, "but the object section is just 0x%x " "bytes long", dbg->de_debug_str_offsets.dss_size); _dwarf_error_string(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } { Dwarf_Unsigned offsettostr = baseoffset+offsetintable; /* Now read the string offset from the offset table. */ READ_UNALIGNED_CK(dbg,offsettostr,Dwarf_Unsigned, sof_start+ offsetintable, cu_context->cc_length_size,error,sof_end); *str_sect_offset_out = offsettostr; } return DW_DLV_OK; } int _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, unsigned attrform, Dwarf_Unsigned offset, char ** return_str, Dwarf_Error * error) { if (attrform == DW_FORM_strp || attrform == DW_FORM_line_strp || attrform == DW_FORM_GNU_str_index || attrform == DW_FORM_strx1 || attrform == DW_FORM_strx2 || attrform == DW_FORM_strx3 || attrform == DW_FORM_strx4 || attrform == DW_FORM_strx) { /* The 'offset' into .debug_str or .debug_line_str is given, here we turn that into a pointer. */ Dwarf_Small *secend = 0; Dwarf_Small *secbegin = 0; Dwarf_Small *strbegin = 0; Dwarf_Unsigned secsize = 0; int errcode = 0; const char *errname = 0; int res = 0; if (attrform == DW_FORM_line_strp) { res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error); if (res != DW_DLV_OK) { return res; } errcode = DW_DLE_STRP_OFFSET_BAD; errname = "DW_DLE_STRP_OFFSET_BAD"; secsize = dbg->de_debug_line_str.dss_size; secbegin = dbg->de_debug_line_str.dss_data; strbegin= dbg->de_debug_line_str.dss_data + offset; secend = dbg->de_debug_line_str.dss_data + secsize; } else { /* DW_FORM_strp etc */ res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } errcode = DW_DLE_STRING_OFFSET_BAD; errname = "DW_DLE_STRING_OFFSET_BAD"; secsize = dbg->de_debug_str.dss_size; secbegin = dbg->de_debug_str.dss_data; strbegin= dbg->de_debug_str.dss_data + offset; secend = dbg->de_debug_str.dss_data + secsize; } if (offset >= secsize) { dwarfstring m; const char *name = ""; dwarf_get_FORM_name(attrform,&name); dwarfstring_constructor(&m); dwarfstring_append(&m,(char *)errname); dwarfstring_append_printf_s(&m, " Form %s ",(char *)name); dwarfstring_append_printf_u(&m, "string offset of 0x%" DW_PR_DUx " ", offset); dwarfstring_append_printf_u(&m, "is larger than the string section " "size of 0x%" DW_PR_DUx, secsize); _dwarf_error_string(dbg, error, errcode, dwarfstring_string(&m)); dwarfstring_destructor(&m); /* Badly damaged DWARF here. */ return DW_DLV_ERROR; } res= _dwarf_check_string_valid(dbg,secbegin,strbegin, secend, errcode,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *)strbegin; return DW_DLV_OK; } generate_form_error(dbg,error,attrform, DW_DLE_ATTR_FORM_BAD, "DW_DLE_ATTR_FORM_BAD", "extract debug_str string"); return DW_DLV_ERROR; } /* Contrary to pre-2005 documentation, The string pointer returned thru return_str must never have dwarf_dealloc() applied to it. Documentation fixed July 2005. */ int dwarf_formstring(Dwarf_Attribute attr, char **return_str, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; int res = DW_DLV_ERROR; Dwarf_Small *secdataptr = 0; Dwarf_Small *secend = 0; Dwarf_Unsigned secdatalen = 0; Dwarf_Small *infoptr = attr->ar_debug_ptr; Dwarf_Small *contextend = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (cu_context->cc_is_info) { secdataptr = (Dwarf_Small *)dbg->de_debug_info.dss_data; secdatalen = dbg->de_debug_info.dss_size; } else { secdataptr = (Dwarf_Small *)dbg->de_debug_types.dss_data; secdatalen = dbg->de_debug_types.dss_size; } contextend = secdataptr + cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; secend = secdataptr + secdatalen; if (contextend < secend) { secend = contextend; } switch(attr->ar_attribute_form) { case DW_FORM_string: { Dwarf_Small *begin = attr->ar_debug_ptr; res= _dwarf_check_string_valid(dbg,secdataptr,begin, secend, DW_DLE_FORM_STRING_BAD_STRING,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *) (begin); return DW_DLV_OK; } case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: { Dwarf_Error alterr = 0; /* See dwarfstd.org issue 120604.1 This is the offset in the .debug_str section of another object file. The 'tied' file notion should apply. It is not clear whether both a supplementary and a split object might be needed at the same time (hence two 'tied' files simultaneously). */ Dwarf_Off soffset = 0; res = dwarf_global_formref(attr, &soffset,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_string_from_tied(dbg, soffset, return_str, &alterr); if (res == DW_DLV_ERROR) { if (dwarf_errno(alterr) == DW_DLE_NO_TIED_FILE_AVAILABLE) { dwarf_dealloc(dbg,alterr,DW_DLA_ERROR); if ( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) { *return_str = (char *)""; } else { *return_str = (char *)""; } return DW_DLV_OK; } if (error) { *error = alterr; } return res; } if (res == DW_DLV_NO_ENTRY) { if ( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) { *return_str = (char *)""; }else { *return_str = (char *)""; } } return res; } case DW_FORM_GNU_str_index: case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: { Dwarf_Unsigned offsettostr= 0; res = _dwarf_extract_string_offset_via_str_offsets(dbg, infoptr, secend, attr->ar_attribute, attr->ar_attribute_form, cu_context, &offsettostr, error); if (res != DW_DLV_OK) { return res; } offset = offsettostr; break; } case DW_FORM_strp: case DW_FORM_line_strp:{ READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, infoptr, cu_context->cc_length_size,error,secend); break; } default: _dwarf_error(dbg, error, DW_DLE_STRING_FORM_IMPROPER); return DW_DLV_ERROR; } /* Now we have offset so read the string from debug_str or debug_line_str. */ res = _dwarf_extract_local_debug_str_string_given_offset(dbg, attr->ar_attribute_form, offset, return_str, error); return res; } int _dwarf_get_string_from_tied(Dwarf_Debug dbg, Dwarf_Unsigned offset, char **return_str, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; Dwarf_Small *secend = 0; Dwarf_Small *secbegin = 0; Dwarf_Small *strbegin = 0; int res = DW_DLV_ERROR; Dwarf_Error localerror = 0; /* Attach errors to dbg, not tieddbg. */ tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE); return DW_DLV_ERROR; } /* The 'offset' into .debug_str is set. */ res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str, &localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } if (offset >= tieddbg->de_debug_str.dss_size) { /* Badly damaged DWARF here. */ _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return DW_DLV_ERROR; } secbegin = tieddbg->de_debug_str.dss_data; strbegin= tieddbg->de_debug_str.dss_data + offset; secend = tieddbg->de_debug_str.dss_data + tieddbg->de_debug_str.dss_size; /* Ensure the offset lies within the .debug_str */ if (offset >= tieddbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return DW_DLV_ERROR; } res= _dwarf_check_string_valid(tieddbg,secbegin,strbegin, secend, DW_DLE_NO_TIED_STRING_AVAILABLE, &localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } *return_str = (char *) (tieddbg->de_debug_str.dss_data + offset); return DW_DLV_OK; } int dwarf_formexprloc(Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return DW_DLV_ERROR; } if (attr->ar_attribute_form == DW_FORM_exprloc ) { Dwarf_Die die = 0; Dwarf_Unsigned leb_len = 0; Dwarf_Byte_Ptr section_start = 0; Dwarf_Unsigned section_len = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Unsigned exprlen = 0; Dwarf_Small * addr = attr->ar_debug_ptr; info_ptr = addr; section_start = _dwarf_calculate_info_section_start_ptr(cu_context, §ion_len); section_end = section_start + section_len; DECODE_LEB128_UWORD_LEN_CK(info_ptr, exprlen, leb_len, dbg,error,section_end); if (exprlen > section_len) { /* Corrupted dwarf! */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ATTR_OUTSIDE_SECTION: " "The expression length is %u,",exprlen); dwarfstring_append_printf_u(&m, " but the section length is just %u. " "Corrupt Dwarf.",section_len); _dwarf_error_string(dbg, error, DW_DLE_ATTR_OUTSIDE_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } die = attr->ar_die; /* Is the block entirely in the section, or is there bug somewhere? Here the final addr may be 1 past end of section. */ if (_dwarf_reference_outside_section(die, (Dwarf_Small *)addr, ((Dwarf_Small *)addr)+exprlen +leb_len)) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_ATTR_OUTSIDE_SECTION: " "The expression length %u,",exprlen); dwarfstring_append_printf_u(&m, " plus the leb value length of " "%u ",leb_len); dwarfstring_append(&m, " runs past the end of the section. " "Corrupt Dwarf."); _dwarf_error_string(dbg, error, DW_DLE_ATTR_OUTSIDE_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } *return_exprlen = exprlen; *block_ptr = addr + leb_len; return DW_DLV_OK; } { dwarfstring m; const char *name = ""; unsigned mform = attr->ar_attribute_form; dwarfstring_constructor(&m); dwarf_get_FORM_name (mform,&name); dwarfstring_append_printf_u(&m, "DW_DLE_ATTR_EXPRLOC_FORM_BAD: " "The form is 0x%x ", mform); dwarfstring_append_printf_s(&m, "(%s) but should be DW_FORM_exprloc. " "Corrupt Dwarf.",(char *)name); _dwarf_error_string(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); } return DW_DLV_ERROR; } libdwarf-20210528/libdwarf/LGPL.txt0000664000175000017500000006350413644370703013604 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libdwarf-20210528/libdwarf/dwarf_elf_load_headers.c0000664000175000017500000016752314004650727017100 00000000000000/* Copyright 2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This reads elf headers and creates generic-elf structures containing the Elf headers. These two enums used for type safety in passing values. See dwarf_elfread.h enum RelocRela enum RelocOffsetSize dwarf_elfread.c calls _dwarf_load_elf_relx(intfc,i,...,enum RelocRela,errcode) calls _dwarf_elf_load_a_relx_batch(ep,...enum RelocRela, enum RelocOffsetSize,errcode) which calls generic_rel_from_rela32(ep,gsh,relp,grel or calls generic_rel_from_rela64(ep,gsh,relp,grel or calls generic_rel_from_rel32(ep,gsh,relp,grel... or calls generic_rel_from_rel64(ep,gsh,relp,grel... */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* For memcpy etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* for open() */ #endif /* HAVE_SYS_STAT_H */ #include /* for open() */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "memcpy_swap.h" #include "dwarf_elfstructs.h" #include "dwarf_reading.h" #include "dwarf_elf_defines.h" #include "dwarf_elfread.h" #include "dwarf_object_detector.h" #include "dwarf_object_read_common.h" #include "dwarf_util.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define TRUE 1 #define FALSE 0 #if 0 /* One example of calling this. place just before DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE dumpsizes(__LINE__,strsectlength,strpsh->gh_offset, ep->f_filesize); */ static void dumpsizes(int line,Dwarf_Unsigned s, Dwarf_Unsigned o, Dwarf_Unsigned fsz) { Dwarf_Unsigned tlen = s + o; printf("Size Error DEBUGONLY sz 0x%llx off 0x%llx fsx 0x%llx " "sum 0x%llx line %d \n", s,o,fsz,tlen,line); } #endif #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int _dwarf_load_elf_section_is_dwarf(const char *sname, int *is_rela,int *is_rel) { *is_rel = FALSE; *is_rela = FALSE; if (_dwarf_ignorethissection(sname)) { return FALSE; } if (!strncmp(sname,".rel",4)) { if (!strncmp(sname,".rela.",6)) { *is_rela = TRUE; return TRUE; } if (!strncmp(sname,".rel.",5)) { *is_rela = TRUE; return TRUE; } /* Else something is goofy/Impossible */ return FALSE; } if (!strncmp(sname,".debug_",7)) { return TRUE; } if (!strncmp(sname,".zdebug_",8)) { return TRUE; } if (!strcmp(sname,".eh_frame")) { return TRUE; } if (!strncmp(sname,".gdb_index",10)) { return TRUE; } return FALSE; } static int is_empty_section(Dwarf_Unsigned type) { if (type == SHT_NOBITS) { return TRUE; } if (type == SHT_NULL) { return TRUE; } return FALSE; } #if 0 int dwarf_construct_elf_access_path(const char *path, dwarf_elf_object_access_internals_t **mp,int *errcode) { int fd = -1; int res = 0; dwarf_elf_object_access_internals_t *mymp = 0; fd = open(path, O_RDONLY|O_BINARY); if (fd < 0) { *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; return DW_DLV_ERROR; } res = dwarf_construct_elf_access(fd, path,&mymp,errcode); if (res != DW_DLV_OK) { close(fd); return res; } mymp->f_destruct_close_fd = TRUE; *mp = mymp; return res; } #endif /* 0 */ /* Here path is not essential. Pass in with "" if unknown. */ int dwarf_construct_elf_access(int fd, const char *path, dwarf_elf_object_access_internals_t **mp,int *errcode) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; dwarf_elf_object_access_internals_t *mfp = 0; int res = 0; res = dwarf_object_detector_fd(fd, &ftype,&endian,&offsetsize, &filesize, errcode); if (res != DW_DLV_OK) { return res; } mfp = calloc(1,sizeof(dwarf_elf_object_access_internals_t)); if (!mfp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* For non-libelf Elf, call it 'F'. Libelf Elf uses 'E' */ mfp->f_ident[0] = 'F'; mfp->f_ident[1] = 1; mfp->f_fd = fd; mfp->f_destruct_close_fd = FALSE; mfp->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); mfp->f_filesize = filesize; mfp->f_offsetsize = offsetsize; mfp->f_pointersize = offsetsize; mfp->f_endian = endian; mfp->f_ftype = ftype; mfp->f_path = strdup(path); *mp = mfp; return DW_DLV_OK; } /* Caller must zero the passed in pointer after this returns to remind the caller to avoid use of the pointer. */ int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t* ep, UNUSEDARG int *errcode) { struct generic_shdr *shp = 0; Dwarf_Unsigned shcount = 0; Dwarf_Unsigned i = 0; free(ep->f_ehdr); shp = ep->f_shdr; shcount = ep->f_loc_shdr.g_count; for (i = 0; i < shcount; ++i,++shp) { free(shp->gh_rels); shp->gh_rels = 0; free(shp->gh_content); shp->gh_content = 0; free(shp->gh_sht_group_array); shp->gh_sht_group_array = 0; shp->gh_sht_group_array_count = 0; } free(ep->f_shdr); free(ep->f_phdr); free(ep->f_elf_shstrings_data); free(ep->f_dynamic); free(ep->f_symtab_sect_strings); free(ep->f_dynsym_sect_strings); free(ep->f_symtab); free(ep->f_dynsym); /* if TRUE close f_fd on destruct.*/ if (ep->f_destruct_close_fd) { close(ep->f_fd); } ep->f_ident[0] = 'X'; free(ep->f_path); free(ep); return DW_DLV_OK; } static int generic_ehdr_from_32(dwarf_elf_object_access_internals_t *ep, struct generic_ehdr *ehdr, dw_elf32_ehdr *e, UNUSEDARG int *errcode) { int i = 0; for (i = 0; i < EI_NIDENT; ++i) { ehdr->ge_ident[i] = e->e_ident[i]; } ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); ep->f_machine = ehdr->ge_machine; ep->f_ehdr = ehdr; ep->f_loc_ehdr.g_name = "Elf File Header"; ep->f_loc_ehdr.g_offset = 0; ep->f_loc_ehdr.g_count = 1; ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf32_ehdr); ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf32_ehdr); return DW_DLV_OK; } static int generic_ehdr_from_64(dwarf_elf_object_access_internals_t* ep, struct generic_ehdr *ehdr, dw_elf64_ehdr *e, UNUSEDARG int *errcode) { int i = 0; for (i = 0; i < EI_NIDENT; ++i) { ehdr->ge_ident[i] = e->e_ident[i]; } ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); ep->f_machine = ehdr->ge_machine; ep->f_ehdr = ehdr; ep->f_loc_ehdr.g_name = "Elf File Header"; ep->f_loc_ehdr.g_offset = 0; ep->f_loc_ehdr.g_count = 1; ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf64_ehdr); ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf64_ehdr); return DW_DLV_OK; } #if 0 /* not used */ static int generic_phdr_from_phdr32(dwarf_elf_object_access_internals_t* ep, struct generic_phdr **phdr_out, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf32_phdr *pph =0; dw_elf32_phdr *orig_pph =0; struct generic_phdr *gphdr =0; struct generic_phdr *orig_gphdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; pph = (dw_elf32_phdr *)calloc(count , entsize); if (pph == 0) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); if (gphdr == 0) { free(pph); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_pph = pph; orig_gphdr = gphdr; res = RRMOA(ep->f_fd,pph,offset,count*entsize, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(pph); free(gphdr); return res; } for ( i = 0; i < count; ++i, pph++,gphdr++) { ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); } free(orig_pph); *phdr_out = orig_gphdr; *count_out = count; ep->f_phdr = orig_gphdr; ep->f_loc_phdr.g_name = "Program Header"; ep->f_loc_phdr.g_offset = offset; ep->f_loc_phdr.g_count = count; ep->f_loc_phdr.g_entrysize = sizeof(dw_elf32_phdr); ep->f_loc_phdr.g_totalsize = sizeof(dw_elf32_phdr)*count; return DW_DLV_OK; } static int generic_phdr_from_phdr64(dwarf_elf_object_access_internals_t* ep, struct generic_phdr **phdr_out, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf64_phdr *pph =0; dw_elf64_phdr *orig_pph =0; struct generic_phdr *gphdr =0; struct generic_phdr *orig_gphdr =0; int res = 0; Dwarf_Unsigned i = 0; *count_out = 0; pph = (dw_elf64_phdr *)calloc(count , entsize); if (pph == 0) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); if (gphdr == 0) { free(pph); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_pph = pph; orig_gphdr = gphdr; res = RRMOA(ep->f_fd,pph,offset,count*entsize, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(pph); free(gphdr); return res; } for ( i = 0; i < count; ++i, pph++,gphdr++) { ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); } free(orig_pph); *phdr_out = orig_gphdr; *count_out = count; ep->f_phdr = orig_gphdr; ep->f_loc_phdr.g_name = "Program Header"; ep->f_loc_phdr.g_offset = offset; ep->f_loc_phdr.g_count = count; ep->f_loc_phdr.g_entrysize = sizeof(dw_elf64_phdr); ep->f_loc_phdr.g_totalsize = sizeof(dw_elf64_phdr)*count; return DW_DLV_OK; } #endif /* not used */ static int generic_shdr_from_shdr32(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf32_shdr *psh =0; dw_elf32_shdr *orig_psh =0; struct generic_shdr *gshdr =0; struct generic_shdr *orig_gshdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; psh = (dw_elf32_shdr *)calloc(count , entsize); if (!psh) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); if (!gshdr) { free(psh); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_psh = psh; orig_gshdr = gshdr; res = RRMOA(ep->f_fd,psh,offset,count*entsize, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(psh); free(gshdr); return res; } for (i = 0; i < count; ++i, psh++,gshdr++) { gshdr->gh_secnum = i; ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ gshdr->gh_reloc_target_secnum = gshdr->gh_info; } } free(orig_psh); *count_out = count; ep->f_shdr = orig_gshdr; ep->f_loc_shdr.g_name = "Section Header"; ep->f_loc_shdr.g_count = count; ep->f_loc_shdr.g_offset = offset; ep->f_loc_shdr.g_entrysize = sizeof(dw_elf32_shdr); ep->f_loc_shdr.g_totalsize = sizeof(dw_elf32_shdr)*count; return DW_DLV_OK; } static int generic_shdr_from_shdr64(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf64_shdr *psh =0; dw_elf64_shdr *orig_psh =0; struct generic_shdr *gshdr =0; struct generic_shdr *orig_gshdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; psh = (dw_elf64_shdr *)calloc(count , entsize); if (!psh) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); if (gshdr == 0) { free(psh); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_psh = psh; orig_gshdr = gshdr; res = RRMOA(ep->f_fd,psh,offset,count*entsize, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(psh); free(gshdr); return res; } for ( i = 0; i < count; ++i, psh++,gshdr++) { gshdr->gh_secnum = i; ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ gshdr->gh_reloc_target_secnum = gshdr->gh_info; } } free(orig_psh); *count_out = count; ep->f_shdr = orig_gshdr; ep->f_loc_shdr.g_name = "Section Header"; ep->f_loc_shdr.g_count = count; ep->f_loc_shdr.g_offset = offset; ep->f_loc_shdr.g_entrysize = sizeof(dw_elf64_shdr); ep->f_loc_shdr.g_totalsize = sizeof(dw_elf64_shdr)*count; return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols32( dwarf_elf_object_access_internals_t *ep, struct generic_symentry **gsym_out, Dwarf_Unsigned offset,Dwarf_Unsigned size, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; dw_elf32_sym *psym = 0; dw_elf32_sym *orig_psym = 0; struct generic_symentry * gsym = 0; struct generic_symentry * orig_gsym = 0; int res = 0; ecount = (long)(size/sizeof(dw_elf32_sym)); size2 = ecount * sizeof(dw_elf32_sym); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } psym = calloc(ecount,sizeof(dw_elf32_sym)); if (!psym) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gsym = calloc(ecount,sizeof(struct generic_symentry)); if (!gsym) { free(psym); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,psym,offset,size, ep->f_filesize,errcode); if (res!= DW_DLV_OK) { free(psym); free(gsym); return res; } orig_psym = psym; orig_gsym = gsym; for ( i = 0; i < ecount; ++i,++psym,++gsym) { Dwarf_Unsigned bind = 0; Dwarf_Unsigned type = 0; ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); bind = gsym->gs_info >> 4; type = gsym->gs_info & 0xf; gsym->gs_bind = bind; gsym->gs_type = type; } *count_out = ecount; *gsym_out = orig_gsym; free(orig_psym); return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols64( dwarf_elf_object_access_internals_t *ep, struct generic_symentry **gsym_out, Dwarf_Unsigned offset,Dwarf_Unsigned size, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; dw_elf64_sym *psym = 0; dw_elf64_sym *orig_psym = 0; struct generic_symentry * gsym = 0; struct generic_symentry * orig_gsym = 0; int res = 0; ecount = (long)(size/sizeof(dw_elf64_sym)); size2 = ecount * sizeof(dw_elf64_sym); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } psym = calloc(ecount,sizeof(dw_elf64_sym)); if (!psym) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gsym = calloc(ecount,sizeof(struct generic_symentry)); if (!gsym) { free(psym); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,psym,offset,size, ep->f_filesize,errcode); if (res!= DW_DLV_OK) { free(psym); free(gsym); *errcode = DW_DLE_ALLOC_FAIL; return res; } orig_psym = psym; orig_gsym = gsym; for ( i = 0; i < ecount; ++i,++psym,++gsym) { Dwarf_Unsigned bind = 0; Dwarf_Unsigned type = 0; ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); bind = gsym->gs_info >> 4; type = gsym->gs_info & 0xf; gsym->gs_bind = bind; gsym->gs_type = type; } *count_out = ecount; *gsym_out = orig_gsym; free(orig_psym); return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols( dwarf_elf_object_access_internals_t *ep, int secnum, struct generic_shdr *psh, struct generic_symentry **gsym_out, Dwarf_Unsigned *count_out,int *errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; if (!secnum) { return DW_DLV_NO_ENTRY; } if (psh->gh_size > ep->f_filesize) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if (ep->f_offsetsize == 32) { res = dwarf_generic_elf_load_symbols32(ep, &gsym, psh->gh_offset,psh->gh_size, &count,errcode); } else if (ep->f_offsetsize == 64) { res = dwarf_generic_elf_load_symbols64(ep, &gsym, psh->gh_offset,psh->gh_size, &count,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res == DW_DLV_OK) { *gsym_out = gsym; *count_out = count; } return res; } #if 0 int dwarf_load_elf_dynsym_symbols( dwarf_elf_object_access_internals_t *ep, int*errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned secnum = ep->f_dynsym_sect_index; struct generic_shdr * psh = 0; if (!secnum) { return DW_DLV_NO_ENTRY; } psh = ep->f_shdr + secnum; if we ever use this... gh_size big? res = dwarf_generic_elf_load_symbols(ep, secnum, psh, &gsym, &count,errcode); if (res == DW_DLV_OK) { ep->f_dynsym = gsym; ep->f_loc_dynsym.g_count = count; } return res; } #endif /* 0 */ int _dwarf_load_elf_symtab_symbols( dwarf_elf_object_access_internals_t *ep, int*errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned secnum = ep->f_symtab_sect_index; struct generic_shdr * psh = 0; if (!secnum) { return DW_DLV_NO_ENTRY; } psh = ep->f_shdr + secnum; if (psh->gh_size > ep->f_filesize) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } res = dwarf_generic_elf_load_symbols(ep, secnum, psh, &gsym, &count,errcode); if (res == DW_DLV_OK) { ep->f_symtab = gsym; ep->f_loc_symtab.g_count = count; } return res; } static int generic_rel_from_rela32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf32_rela *relp, struct generic_rela *grel, int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; ecount = size/sizeof(dw_elf32_rela); size2 = ecount * sizeof(dw_elf32_rela); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); /* addend signed */ ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); grel->gr_sym = grel->gr_info>>8; /* ELF32_R_SYM */ grel->gr_type = grel->gr_info & 0xff; grel->gr_is_rela = TRUE; } return DW_DLV_OK; } static int generic_rel_from_rela64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf64_rela *relp, struct generic_rela *grel, int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); int ismips64 = (ep->f_machine == EM_MIPS); int issparcv9 = (ep->f_machine == EM_SPARCV9); ecount = size/sizeof(dw_elf64_rela); size2 = ecount * sizeof(dw_elf64_rela); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); if (ismips64 && objlittleendian ) { char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; grel->gr_type2 = relp->r_info[6]; grel->gr_type3 = relp->r_info[5]; } else if (issparcv9) { /* Always Big Endian? */ char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; } else { grel->gr_sym = grel->gr_info >> 32; grel->gr_type = grel->gr_info & 0xffffffff; } grel->gr_is_rela = TRUE; } return DW_DLV_OK; } static int generic_rel_from_rel32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf32_rel *relp, struct generic_rela *grel,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; ecount = size/sizeof(dw_elf32_rel); size2 = ecount * sizeof(dw_elf32_rel); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); grel->gr_addend = 0; /* Unused for plain .rel */ grel->gr_sym = grel->gr_info >>8; /* ELF32_R_SYM */ grel->gr_is_rela = FALSE; grel->gr_type = grel->gr_info & 0xff; } return DW_DLV_OK; } static int generic_rel_from_rel64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf64_rel *relp, struct generic_rela *grel,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); int ismips64 = (ep->f_machine == EM_MIPS); int issparcv9 = (ep->f_machine == EM_SPARCV9); ecount = size/sizeof(dw_elf64_rel); size2 = ecount * sizeof(dw_elf64_rel); if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); grel->gr_addend = 0; /* Unused for plain .rel */ if (ismips64 && objlittleendian ) { char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; grel->gr_type2 = relp->r_info[6]; grel->gr_type3 = relp->r_info[5]; } else if (issparcv9) { /* Always Big Endian? */ char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; } else { grel->gr_sym = grel->gr_info >>32; grel->gr_type = grel->gr_info & 0xffffffff; } grel->gr_is_rela = FALSE; } return DW_DLV_OK; } #if 0 int dwarf_load_elf_dynstr( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *strpsh = 0; int res = 0; Dwarf_Unsigned strsectindex =0; Dwarf_Unsigned strsectlength = 0; if (!ep->f_dynsym_sect_strings_sect_index) { return DW_DLV_NO_ENTRY; } strsectindex = ep->f_dynsym_sect_strings_sect_index; strsectlength = ep->f_dynsym_sect_strings_max; strpsh = ep->f_shdr + strsectindex; /* Alloc an extra byte as a guaranteed NUL byte at the end of the strings in case the section is corrupted and lacks a NUL at end. */ ep->f_dynsym_sect_strings = calloc(1,strsectlength+1); if (!ep->f_dynsym_sect_strings) { ep->f_dynsym_sect_strings = 0; ep->f_dynsym_sect_strings_max = 0; ep->f_dynsym_sect_strings_sect_index = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,ep->f_dynsym_sect_strings, strpsh->gh_offset, strsectlength, ep->f_filesize,errcode); if (res != DW_DLV_OK) { ep->f_dynsym_sect_strings = 0; ep->f_dynsym_sect_strings_max = 0; ep->f_dynsym_sect_strings_sect_index = 0; return res; } return DW_DLV_OK; } #endif /* 0 */ int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *strpsh = 0; int res = 0; Dwarf_Unsigned strsectindex =0; Dwarf_Unsigned strsectlength = 0; if (!ep->f_symtab_sect_strings_sect_index) { return DW_DLV_NO_ENTRY; } strsectindex = ep->f_symtab_sect_strings_sect_index; strsectlength = ep->f_symtab_sect_strings_max; strpsh = ep->f_shdr + strsectindex; /* Alloc an extra byte as a guaranteed NUL byte at the end of the strings in case the section is corrupted and lacks a NUL at end. */ if (strsectlength > ep->f_filesize || strpsh->gh_offset >ep->f_filesize || (strsectlength + strpsh->gh_offset) > ep->f_filesize) { *errcode = DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE; return DW_DLV_ERROR; } ep->f_symtab_sect_strings = calloc(1,strsectlength+1); if (!ep->f_symtab_sect_strings) { ep->f_symtab_sect_strings = 0; ep->f_symtab_sect_strings_max = 0; ep->f_symtab_sect_strings_sect_index = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,ep->f_symtab_sect_strings, strpsh->gh_offset, strsectlength, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(ep->f_symtab_sect_strings); ep->f_symtab_sect_strings = 0; ep->f_symtab_sect_strings_max = 0; ep->f_symtab_sect_strings_sect_index = 0; return res; } return DW_DLV_OK; } static int _dwarf_elf_load_sectstrings( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned stringsection, int *errcode) { int res = 0; struct generic_shdr *psh = 0; Dwarf_Unsigned secoffset = 0; ep->f_elf_shstrings_length = 0; if (stringsection >= ep->f_ehdr->ge_shnum) { *errcode = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } psh = ep->f_shdr + stringsection; secoffset = psh->gh_offset; if (is_empty_section(psh->gh_type)) { *errcode = DW_DLE_ELF_STRING_SECTION_MISSING; return DW_DLV_ERROR; } if (secoffset >= ep->f_filesize || psh->gh_size > ep->f_filesize || (secoffset + psh->gh_size) > ep->f_filesize) { *errcode = DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE; return DW_DLV_ERROR; } if (psh->gh_size > ep->f_elf_shstrings_max) { free(ep->f_elf_shstrings_data); ep->f_elf_shstrings_data = (char *)malloc(psh->gh_size); ep->f_elf_shstrings_max = psh->gh_size; if (!ep->f_elf_shstrings_data) { ep->f_elf_shstrings_max = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } } ep->f_elf_shstrings_length = psh->gh_size; res = RRMOA(ep->f_fd,ep->f_elf_shstrings_data,secoffset, psh->gh_size, ep->f_filesize,errcode); return res; } static int elf_load_sectheaders32( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned offset,Dwarf_Unsigned entsize, Dwarf_Unsigned count,int *errcode) { Dwarf_Unsigned generic_count = 0; int res = 0; if (count == 0) { return DW_DLV_NO_ENTRY; } if (entsize < sizeof(dw_elf32_shdr)) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (entsize > 200)|| (count > ep->f_filesize) || ((count *entsize +offset) > ep->f_filesize)) { *errcode = DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE; return DW_DLV_ERROR; } res = generic_shdr_from_shdr32(ep,&generic_count, offset,entsize,count,errcode); if (res != DW_DLV_OK) { return res; } if (generic_count != count) { *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; return DW_DLV_ERROR; } return DW_DLV_OK; } static int elf_load_sectheaders64( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned offset,Dwarf_Unsigned entsize, Dwarf_Unsigned count,int*errcode) { Dwarf_Unsigned generic_count = 0; int res = 0; if (count == 0) { return DW_DLV_NO_ENTRY; } if (entsize < sizeof(dw_elf64_shdr)) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (entsize > 200)|| (count > ep->f_filesize) || ((count *entsize +offset) > ep->f_filesize)) { *errcode = DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE; return DW_DLV_ERROR; } res = generic_shdr_from_shdr64(ep,&generic_count, offset,entsize,count,errcode); if (res != DW_DLV_OK) { return res; } if (generic_count != count) { *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; return DW_DLV_ERROR; } return DW_DLV_OK; } static int _dwarf_elf_load_a_relx_batch( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, struct generic_rela ** grel_out, Dwarf_Unsigned *count_out, enum RelocRela localrela, enum RelocOffsetSize localoffsize, int *errcode) { Dwarf_Unsigned count = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned sizeg = 0; Dwarf_Unsigned offset = 0; int res = 0; Dwarf_Unsigned object_reclen = 0; struct generic_rela *grel = 0; /* ASSERT: Caller guarantees localoffsetsize is a valid 4 or 8. */ /* ASSERT: Caller guarantees localrela is one of the 2 valid values 1 or 2 */ offset = gsh->gh_offset; size = gsh->gh_size; if (size == 0) { return DW_DLV_NO_ENTRY; } if ((offset > ep->f_filesize)|| (size > ep->f_filesize) || ((size +offset) > ep->f_filesize)) { *errcode = DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE; return DW_DLV_ERROR; } if (localoffsize == RelocOffset32) { if (localrela == RelocIsRela) { object_reclen = sizeof(dw_elf32_rela); count = (long)(size/object_reclen); size2 = count * object_reclen; if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } } else { object_reclen = sizeof(dw_elf32_rel); count = (long)(size/object_reclen); size2 = count * object_reclen; if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } } } else { if (localrela == RelocIsRela) { object_reclen = sizeof(dw_elf64_rela); count = (long)(size/object_reclen); size2 = count * object_reclen; if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } } else { object_reclen = sizeof(dw_elf64_rel); count = (long)(size/object_reclen); size2 = count * object_reclen; if (size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } } } sizeg = count*sizeof(struct generic_rela); grel = (struct generic_rela *)malloc(sizeg); if (!grel) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } if (localoffsize == RelocOffset32) { if (localrela == RelocIsRela) { dw_elf32_rela *relp = 0; relp = (dw_elf32_rela *)malloc(size); if (!relp) { free(grel); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(relp); free(grel); return res; } res = generic_rel_from_rela32(ep,gsh,relp,grel,errcode); free(relp); } else { dw_elf32_rel *relp = 0; relp = (dw_elf32_rel *)malloc(size); if (!relp) { free(grel); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(relp); free(grel); return res; } res = generic_rel_from_rel32(ep,gsh,relp,grel,errcode); free(relp); } } else { if (localrela == RelocIsRela) { dw_elf64_rela *relp = 0; relp = (dw_elf64_rela *)malloc(size); if (!relp) { free(grel); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(relp); free(grel); return res; } res = generic_rel_from_rela64(ep,gsh,relp,grel,errcode); free(relp); } else { dw_elf64_rel *relp = 0; relp = (dw_elf64_rel *)malloc(size); if (!relp) { free(grel); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(relp); free(grel); return res; } res = generic_rel_from_rel64(ep,gsh,relp,grel,errcode); free(relp); } } if (res == DW_DLV_OK) { gsh->gh_relcount = count; gsh->gh_rels = grel; *count_out = count; *grel_out = grel; return res; } /* Some sort of issue */ count_out = 0; free(grel); return res; } /* Is this rel/rela section related to dwarf at all? set oksecnum zero if not. Else set targ secnum. Never returns DW_DLV_NO_ENTRY. */ static int this_rel_is_a_section_dwarf_related( dwarf_elf_object_access_internals_t *ep, struct generic_shdr *gshdr, unsigned *oksecnum_out, int *errcode) { unsigned oksecnum = 0; struct generic_shdr *gstarg = 0; if (gshdr->gh_type != SHT_RELA && gshdr->gh_type != SHT_REL) { *oksecnum_out = 0; return DW_DLV_OK; } oksecnum = gshdr->gh_reloc_target_secnum; if (oksecnum >= ep->f_loc_shdr.g_count) { *oksecnum_out = 0; *errcode = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } gstarg = ep->f_shdr+oksecnum; if (!gstarg->gh_is_dwarf) { *oksecnum_out = 0; /* no reloc needed. */ return DW_DLV_OK; } *oksecnum_out = oksecnum; return DW_DLV_OK; } /* Secnum here is the secnum of rela. Not the target of the relocations. This also loads .rel. */ int _dwarf_load_elf_relx( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum, enum RelocRela localr, int *errcode) { struct generic_shdr *gshdr = 0; Dwarf_Unsigned seccount = 0; unsigned offsetsize = 0; struct generic_rela *grp = 0; Dwarf_Unsigned count_read = 0; int res = 0; unsigned oksec = 0; enum RelocOffsetSize localoffsize = RelocOffset32; /* ASSERT: Caller guarantees localr is a valid RelocRela */ if (!ep) { *errcode = DW_DLE_INTERNAL_NULL_POINTER; return DW_DLV_ERROR; } offsetsize = ep->f_offsetsize; seccount = ep->f_loc_shdr.g_count; if (secnum >= seccount) { *errcode = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } gshdr = ep->f_shdr +secnum; if (is_empty_section(gshdr->gh_type)) { return DW_DLV_NO_ENTRY; } res = this_rel_is_a_section_dwarf_related(ep,gshdr, &oksec,errcode); if (res == DW_DLV_ERROR) { return res; } if (!oksec) { return DW_DLV_OK; } /* We will actually read these relocations. */ if (offsetsize == 64) { localoffsize = RelocOffset64; } else if (offsetsize == 32) { localoffsize = RelocOffset32; } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } /* ASSERT: localoffsize is now a valid enum value, one of the two defined. */ res = _dwarf_elf_load_a_relx_batch(ep, gshdr,&grp,&count_read,localr,localoffsize,errcode); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } gshdr->gh_rels = grp; gshdr->gh_relcount = count_read; return DW_DLV_OK; } static int validate_section_name_string(Dwarf_Unsigned section_length, Dwarf_Unsigned string_loc_index, const char * strings_start, int * errcode) { const char *endpoint = strings_start + section_length; const char *cur = 0; if (section_length <= string_loc_index) { *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; return DW_DLV_ERROR; } cur = string_loc_index+strings_start; for ( ; cur < endpoint;++cur) { if (!*cur) { return DW_DLV_OK; } } *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; return DW_DLV_ERROR; } static int _dwarf_elf_load_sect_namestring( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *gshdr = 0; Dwarf_Unsigned generic_count = 0; Dwarf_Unsigned i = 1; const char *stringsecbase = 0; stringsecbase = ep->f_elf_shstrings_data; gshdr = ep->f_shdr; generic_count = ep->f_loc_shdr.g_count; for (i = 0; i < generic_count; i++, ++gshdr) { const char *namestr = ""; int res = 0; res = validate_section_name_string(ep->f_elf_shstrings_length, gshdr->gh_name, stringsecbase, errcode); if (res != DW_DLV_OK) { gshdr->gh_namestring = namestr; return res; } gshdr->gh_namestring = stringsecbase + gshdr->gh_name; } return DW_DLV_OK; } static int elf_load_elf_header32( dwarf_elf_object_access_internals_t *ep,int *errcode) { int res = 0; dw_elf32_ehdr ehdr32; struct generic_ehdr *ehdr = 0; res = RRMOA(ep->f_fd,&ehdr32,0,sizeof(ehdr32), ep->f_filesize,errcode); if (res != DW_DLV_OK) { return res; } ehdr = (struct generic_ehdr *)calloc(1, sizeof(struct generic_ehdr)); if (!ehdr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_ehdr_from_32(ep,ehdr,&ehdr32,errcode); return res; } static int elf_load_elf_header64( dwarf_elf_object_access_internals_t *ep,int *errcode) { int res = 0; dw_elf64_ehdr ehdr64; struct generic_ehdr *ehdr = 0; res = RRMOA(ep->f_fd,&ehdr64,0,sizeof(ehdr64), ep->f_filesize,errcode); if (res != DW_DLV_OK) { return res; } ehdr = (struct generic_ehdr *)calloc(1, sizeof(struct generic_ehdr)); if (!ehdr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_ehdr_from_64(ep,ehdr,&ehdr64,errcode); return res; } static int validate_struct_sizes( #ifdef HAVE_ELF_H int*errcode #else UNUSEDARG int*errcode #endif ) { #ifdef HAVE_ELF_H /* This is a sanity check when we have an elf.h to check against. */ if (sizeof(Elf32_Ehdr) != sizeof(dw_elf32_ehdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Ehdr) != sizeof(dw_elf64_ehdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Shdr) != sizeof(dw_elf32_shdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Shdr) != sizeof(dw_elf64_shdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Phdr) != sizeof(dw_elf32_phdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Phdr) != sizeof(dw_elf64_phdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Rel) != sizeof(dw_elf32_rel)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Rel) != sizeof(dw_elf64_rel)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Rela) != sizeof(dw_elf32_rela)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Rela) != sizeof(dw_elf64_rela)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Sym) != sizeof(dw_elf32_sym)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Sym) != sizeof(dw_elf64_sym)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } #endif /* HAVE_ELF_H */ return DW_DLV_OK; } int _dwarf_load_elf_header( dwarf_elf_object_access_internals_t *ep,int*errcode) { unsigned offsetsize = ep->f_offsetsize; int res = 0; res = validate_struct_sizes(errcode); if (res != DW_DLV_OK) { return res; } if (offsetsize == 32) { res = elf_load_elf_header32(ep,errcode); } else if (offsetsize == 64) { if (sizeof(Dwarf_Unsigned) < 8) { *errcode = DW_DLE_INTEGER_TOO_SMALL; return DW_DLV_ERROR; } res = elf_load_elf_header64(ep,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int validate_links( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned knownsect, Dwarf_Unsigned string_sect, int *errcode) { struct generic_shdr* pshk = 0; if (!knownsect) { return DW_DLV_OK; } if (!string_sect) { *errcode = DW_DLE_ELF_STRING_SECTION_ERROR; return DW_DLV_ERROR; } pshk = ep->f_shdr + knownsect; if (string_sect != pshk->gh_link) { *errcode = DW_DLE_ELF_SECTION_LINK_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } static int string_endswith(const char *n,const char *q) { unsigned long len = strlen(n); unsigned long qlen = strlen(q); const char *startpt = 0; if ( len < qlen) { return FALSE; } startpt = n + (len-qlen); if (strcmp(startpt,q)) { return FALSE; } return TRUE; } /* We are allowing either SHT_GROUP or .group to indicate a group section, but really one should have both or neither! */ static int elf_sht_groupsec(Dwarf_Unsigned type, const char *sname) { /* ARM compilers name SHT group "__ARM_grp" not .group */ if ((type == SHT_GROUP) || (!strcmp(sname,".group"))){ return TRUE; } return FALSE; } static int elf_flagmatches(Dwarf_Unsigned flagsword,Dwarf_Unsigned flag) { if ((flagsword&flag) == flag) { return TRUE; } return FALSE; } /* For SHT_GROUP sections. */ static int read_gs_section_group( dwarf_elf_object_access_internals_t *ep, struct generic_shdr* psh, int *errcode) { Dwarf_Unsigned i = 0; int res = 0; if (!psh->gh_sht_group_array) { Dwarf_Unsigned seclen = psh->gh_size; char *data = 0; char *dp = 0; Dwarf_Unsigned* grouparray = 0; char dblock[4]; Dwarf_Unsigned va = 0; Dwarf_Unsigned count = 0; int foundone = 0; if (seclen < DWARF_32BIT_SIZE) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } data = malloc(seclen); if (!data) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } dp = data; if (psh->gh_entsize != DWARF_32BIT_SIZE) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); return DW_DLV_ERROR; } if (!psh->gh_entsize) { free(data); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } count = seclen/psh->gh_entsize; if (count > ep->f_loc_shdr.g_count) { /* Impossible */ free(data); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,data,psh->gh_offset,seclen, ep->f_filesize,errcode); if (res != DW_DLV_OK) { free(data); return res; } grouparray = malloc(count * sizeof(Dwarf_Unsigned)); if (!grouparray) { free(data); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memcpy(dblock,dp,DWARF_32BIT_SIZE); ASNAR(memcpy,va,dblock); /* There is ambiguity on the endianness of this stuff. */ if (va != 1 && va != 0x1000000) { /* Could be corrupted elf object. */ *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); free(grouparray); return DW_DLV_ERROR; } grouparray[0] = 1; dp = dp + DWARF_32BIT_SIZE; for ( i = 1; i < count; ++i,dp += DWARF_32BIT_SIZE) { Dwarf_Unsigned gseca = 0; Dwarf_Unsigned gsecb = 0; struct generic_shdr* targpsh = 0; memcpy(dblock,dp,DWARF_32BIT_SIZE); ASNAR(memcpy,gseca,dblock); ASNAR(_dwarf_memcpy_swap_bytes,gsecb,dblock); if (!gseca) { free(data); free(grouparray); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } grouparray[i] = gseca; if (gseca > ep->f_loc_shdr.g_count) { /* Might be confused endianness by the compiler generating the SHT_GROUP. This is pretty horrible. */ if (gsecb > ep->f_loc_shdr.g_count) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); free(grouparray); return DW_DLV_ERROR; } /* Ok. Yes, ugly. */ gseca = gsecb; grouparray[i] = gseca; } targpsh = ep->f_shdr + gseca; if (targpsh->gh_section_group_number) { /* multi-assignment to groups. Oops. */ free(data); free(grouparray); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } targpsh->gh_section_group_number = ep->f_sg_next_group_number; foundone = 1; } if (foundone) { ++ep->f_sg_next_group_number; ++ep->f_sht_group_type_section_count; } free(data); psh->gh_sht_group_array = grouparray; psh->gh_sht_group_array_count = count; } return DW_DLV_OK; } /* Does related things. A) Counts the number of SHT_GROUP and for each builds an array of the sections in the group (which we expect are all DWARF-related) and sets the group number in each mentioned section. B) Counts the number of SHF_GROUP flags. C) If gnu groups: ensure all the DWARF sections marked with right group based on A(we will mark unmarked as group 1, DW_GROUPNUMBER_BASE). D) If arm groups (SHT_GROUP zero, SHF_GROUP non-zero): Check the relocations of all SHF_GROUP section FIXME: algorithm needed. If SHT_GROUP and SHF_GROUP this is GNU groups. If no SHT_GROUP and have SHF_GROUP this is arm cc groups and we must use relocation information to identify the group members. It seems(?) impossible for an object to have both dwo sections and (SHF_GROUP or SHT_GROUP), but we do not rule that out here. */ static int _dwarf_elf_setup_all_section_groups( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr* psh = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned count = 0; int res = 0; count = ep->f_loc_shdr.g_count; psh = ep->f_shdr; /* Does step A and step B */ for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (!elf_sht_groupsec(psh->gh_type,name)) { /* Step B */ if (elf_flagmatches(psh->gh_flags,SHF_GROUP)) { ep->f_shf_group_flag_section_count++; } continue; } /* Looks like a section group. Do Step A. */ res =read_gs_section_group(ep,psh,errcode); if (res != DW_DLV_OK) { return res; } } /* Any sections not marked above or here are in grep DW_GROUPNUMBER_BASE (1). Section C. */ psh = ep->f_shdr; for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; int is_rel = FALSE; int is_rela = FALSE; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (elf_sht_groupsec(psh->gh_type,name)) { continue; } /* Not a section group */ if (string_endswith(name,".dwo")) { if (psh->gh_section_group_number) { /* multi-assignment to groups. Oops. */ *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } psh->gh_is_dwarf = TRUE; psh->gh_section_group_number = DW_GROUPNUMBER_DWO; ep->f_dwo_group_section_count++; } else if (_dwarf_load_elf_section_is_dwarf(name, &is_rela,&is_rel)) { if (!psh->gh_section_group_number) { psh->gh_section_group_number = DW_GROUPNUMBER_BASE; } psh->gh_is_dwarf = TRUE; } else { /* Do nothing. */ } } if (ep->f_sht_group_type_section_count) { /* Not ARM. Done. */ } if (!ep->f_shf_group_flag_section_count) { /* Nothing more to do. */ return DW_DLV_OK; } return DW_DLV_OK; } static int _dwarf_elf_find_sym_sections( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr* psh = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned count = 0; int res = 0; count = ep->f_loc_shdr.g_count; psh = ep->f_shdr; for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (!strcmp(name,".dynsym")) { ep->f_dynsym_sect_index = i; ep->f_loc_dynsym.g_offset = psh->gh_offset; } else if (!strcmp(name,".dynstr")) { ep->f_dynsym_sect_strings_sect_index = i; ep->f_dynsym_sect_strings_max = psh->gh_size; } else if (!strcmp(name,".symtab")) { ep->f_symtab_sect_index = i; ep->f_loc_symtab.g_offset = psh->gh_offset; } else if (!strcmp(name,".strtab")) { ep->f_symtab_sect_strings_sect_index = i; ep->f_symtab_sect_strings_max = psh->gh_size; } else if (!strcmp(name,".dynamic")) { ep->f_dynamic_sect_index = i; ep->f_loc_dynamic.g_offset = psh->gh_offset; } } #if 0 res = validate_links(ep,ep->f_dynsym_sect_index, ep->f_dynsym_sect_strings_sect_index,errcode); if (res!= DW_DLV_OK) { return res; } #endif /* 0 */ res = validate_links(ep,ep->f_symtab_sect_index, ep->f_symtab_sect_strings_sect_index,errcode); if (res!= DW_DLV_OK) { return res; } return DW_DLV_OK; } int _dwarf_load_elf_sectheaders( dwarf_elf_object_access_internals_t *ep,int*errcode) { int res = 0; if (ep->f_offsetsize == 32) { res = elf_load_sectheaders32(ep,ep->f_ehdr->ge_shoff, ep->f_ehdr->ge_shentsize, ep->f_ehdr->ge_shnum,errcode); } else if (ep->f_offsetsize == 64) { res = elf_load_sectheaders64(ep,ep->f_ehdr->ge_shoff, ep->f_ehdr->ge_shentsize, ep->f_ehdr->ge_shnum,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_load_sectstrings(ep, ep->f_ehdr->ge_shstrndx,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_load_sect_namestring(ep,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_find_sym_sections(ep,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_setup_all_section_groups(ep,errcode); return res; } libdwarf-20210528/libdwarf/pro_dnames.c0000664000175000017500000000407713764007262014600 00000000000000/* Copyright 2018-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif /* HAVE_ELFACCESS_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_arange.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_dnames.h" #define FALSE 0 #define TRUE 1 int dwarf_force_debug_names(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Dnames dn; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } dn = (Dwarf_P_Dnames) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Dnames_s)); if (dn == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (!dbg->de_dnames) { dbg->de_dnames = dn; } dn->dn_create_section = TRUE; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_xu_index.c0000664000175000017500000007655114004647417015465 00000000000000/* Copyright (C) 2014-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The file and functions have 'xu' because the .debug_cu_index and .debug_tu_index sections have the same layout and this deals with both. This is DebugFission, part of DWARF5. It allows fast section access in a .dwp object file with debug-information to locate offsets within and between sections. See the DWARF5 Standard: section 7.3.5 and examples in Appendix F.3. A note about the index field from the index table. See DWARF5 7.5.3.5. The index table array index values are [1,S) These value ae used to call functions requesting values from the offset table and size table. Inside the code in this file we subtract 1 and use 0 origin as that is how we arranged the table access here. A zero in the index table is an unused signature table signature and unused index. By subtracting one and arranging things properly in the offset table and size table we can refer to the tables in an identical simple fashion These tables are thus U rows and N columns. Technically the Offset table physically row zero is a separate set of numbers translating the column number to a DW_SECT* value so callers can request specific bases(offsets) and sizes from the offset and size tables. But we change things a little internally so both tables look zero-origin. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_xu_index.h" #include "dwarfstring.h" #define HASHSIGNATURELEN 8 #define LEN32BIT 4 #define TRUE 1 #define FALSE 0 /* The following actually assumes (as used here) that t is 8 bytes (integer) while s is also 8 bytes (Dwarf_Sig8 struct). */ #ifdef WORDS_BIGENDIAN #define ASNAR(t,s,l) \ do { \ unsigned tbyte = sizeof(t) - l; \ if (sizeof(t) < l) { \ _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \ return DW_DLV_ERROR; \ } \ t = 0; \ dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(t,s,l) \ do { \ t = 0; \ if (sizeof(t) < l) { \ _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \ return DW_DLV_ERROR; \ } \ dbg->de_copy_word(&t,&s[0],l); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* zerohashkey used as all-zero-bits for comparison. */ static const Dwarf_Sig8 zerohashkey; #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif /* Precondition: headerline_offset + N*32 is within the section. */ static int fill_in_offsets_headerline(Dwarf_Debug dbg, Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned headerline_offset, Dwarf_Unsigned num_sects, Dwarf_Error *err) { Dwarf_Small *section_start = xuhdr->gx_section_data; Dwarf_Small *section_end = xuhdr->gx_section_data+ xuhdr->gx_section_length; Dwarf_Small *data = 0; unsigned i = 0; data = section_start +headerline_offset; for ( ; i < num_sects ; ++i) { Dwarf_Unsigned v = 0; READ_UNALIGNED_CK(dbg,v, Dwarf_Unsigned, data,LEN32BIT, err,section_end); data += LEN32BIT; if (v > DW_SECT_RNGLISTS) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR The " "section number of %u ",v); dwarfstring_append(&s," is too high. " "Sections 1-8 are listed in " "DWARF5 Table 7.1."); _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } xuhdr->gx_section_id[i] = v; } return DW_DLV_OK; } /* Read in a cu or tu section and return overview information. For libdwarf-internal lookups dwarf_init*() calls dwarf_get_xu_index_header() when the object file is opened and dwarf_xu_header_free() is called by dwarf_finish(), there is no need for users to do this. If one wants to call the various tu/cu functions oneself (possibly to print the .debug_cu_index or .debug_tu_index sections). then you will need to call dwarf_get_xu_index_header() and eventually dwarf_xu_header_free(). The libdwarf-internal data is kept in Dwarf_Debug fields de_cu_hashindex_data/de_tu_hashindex_data. */ int dwarf_get_xu_index_header(Dwarf_Debug dbg, /* Pass in section_type "tu" or "cu" */ const char * section_type, Dwarf_Xu_Index_Header * xuptr, Dwarf_Unsigned * version, Dwarf_Unsigned * number_of_columns, /* L section count.*/ Dwarf_Unsigned * number_of_CUs, /* U unit count */ Dwarf_Unsigned * number_of_slots, /* S slot count */ /* Standard says S > U DWARF5 sec 7.3.5.3 */ const char ** section_name, Dwarf_Error * error) { Dwarf_Xu_Index_Header indexptr = 0; int res = DW_DLV_ERROR; struct Dwarf_Section_s *sect = 0; Dwarf_Unsigned local_version = 0; Dwarf_Unsigned num_secs = 0; Dwarf_Unsigned num_CUs = 0; Dwarf_Unsigned num_slots = 0; Dwarf_Small *data = 0; Dwarf_Unsigned tables_end_offset = 0; Dwarf_Unsigned hash_tab_offset = 0; Dwarf_Unsigned indexes_tab_offset = 0; Dwarf_Unsigned section_offsets_tab_offset = 0; Dwarf_Unsigned section_offsets_headerline_offset = 0; Dwarf_Unsigned section_sizes_tab_offset = 0; unsigned datalen32 = LEN32BIT; Dwarf_Small *section_end = 0; if (!strcmp(section_type,"cu") ) { sect = &dbg->de_debug_cu_index; } else if (!strcmp(section_type,"tu") ) { sect = &dbg->de_debug_tu_index; } else { _dwarf_error(dbg, error, DW_DLE_XU_TYPE_ARG_ERROR); return DW_DLV_ERROR; } if (!sect->dss_size) { return DW_DLV_NO_ENTRY; } if (!sect->dss_data) { res = _dwarf_load_section(dbg, sect,error); if (res != DW_DLV_OK) { return res; } } data = sect->dss_data; section_end = data + sect->dss_size; if (sect->dss_size < (4*datalen32) ) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: " "The size of the %s ", (char *)section_type); dwarfstring_append_printf_u(&m, "is just %u bytes, much to small to be " " a correct section", sect->dss_size); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,local_version, Dwarf_Unsigned, data,datalen32, error,section_end); data += datalen32; /* reading N */ READ_UNALIGNED_CK(dbg,num_secs, Dwarf_Unsigned, data,datalen32, error,section_end); if (num_secs > DW_SECT_RNGLISTS) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_XU_NAME_COL_ERROR: " " %s index section header ", (char *)section_type); dwarfstring_append_printf_u(&m, "shows N, the sections count, " "as %u but only values " " 1 through 8 (DW_SECT_RNGLISTS) are valid.", num_secs); _dwarf_error_string(dbg,error,DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } data += datalen32; /* reading U */ READ_UNALIGNED_CK(dbg,num_CUs, Dwarf_Unsigned, data,datalen32, error,section_end); data += datalen32; /* reading S */ READ_UNALIGNED_CK(dbg,num_slots, Dwarf_Unsigned, data,datalen32, error,section_end); hash_tab_offset = datalen32*4; indexes_tab_offset = hash_tab_offset + (num_slots * HASHSIGNATURELEN); /* Look for corrupt section data. */ if (num_slots > sect->dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: " "The size of the %s ",(char *)section_type); dwarfstring_append_printf_u(&m, " is just %u bytes,",sect->dss_size); dwarfstring_append_printf_u(&m, "while the number of slots (S) is %u. " "which is clearly wrong",num_slots ); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if ( (4*num_slots) > sect->dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: " "The size of the %s ",(char *)section_type); dwarfstring_append_printf_u(&m, " is just %u bytes,",sect->dss_size); dwarfstring_append_printf_u(&m, "while the number of slots bytes (S) is at least %u. " "which is clearly wrong",num_slots*4); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* This offset is to 1 row of N columns, each 32bit. */ section_offsets_headerline_offset = indexes_tab_offset + (num_slots *datalen32); /* Now we can make the real table part index normally. This offset is to U row of N columns, each 32bit. */ section_offsets_tab_offset = section_offsets_headerline_offset + (num_secs*datalen32); if ( num_secs > sect->dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: " "The size of the %s ",(char *)section_type); dwarfstring_append_printf_u(&m, " is just %u bytes,",sect->dss_size); dwarfstring_append_printf_u(&m, "while the number of sections/columns (S) is %u. " "which is clearly wrong",num_secs ); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if ( (datalen32*num_secs) > sect->dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: " "The size of the %s ",(char *)section_type); dwarfstring_append_printf_u(&m, " is just %u bytes,",sect->dss_size); dwarfstring_append_printf_u(&m, "while the number of sections/columns bytes (S)" " is at least %u. " "which is clearly wrong",num_secs*4); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } section_sizes_tab_offset = section_offsets_tab_offset + (num_CUs *num_secs* datalen32) ; tables_end_offset = section_sizes_tab_offset + (num_CUs * num_secs * datalen32); if ( tables_end_offset > sect->dss_size) { /* Something is badly wrong here. */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m,"ERROR: " "DW_DLE_ERRONEOUS_XU_INDEX_SECTION as the end offset " "0x%lx is greater than ",tables_end_offset); dwarfstring_append_printf_u(&m,"the section size " "0x%lx.",sect->dss_size); _dwarf_error_string(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } indexptr = (Dwarf_Xu_Index_Header) _dwarf_get_alloc(dbg,DW_DLA_XU_INDEX,1); if (indexptr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Only "cu" or "tu" allowed, that is checked above. But for safety we just copy the allowed bytes*/ indexptr->gx_type[0] = section_type[0]; indexptr->gx_type[1] = section_type[1]; indexptr->gx_type[2] = 0; indexptr->gx_dbg = dbg; indexptr->gx_section_length = sect->dss_size; indexptr->gx_section_data = sect->dss_data; indexptr->gx_section_name = sect->dss_name; indexptr->gx_version = local_version; indexptr->gx_column_count_sections = num_secs; indexptr->gx_units_in_index = num_CUs; indexptr->gx_slots_in_hash = num_slots; indexptr->gx_hash_table_offset = hash_tab_offset; indexptr->gx_index_table_offset = indexes_tab_offset; indexptr->gx_section_offsets_headerline_offset= section_offsets_headerline_offset; indexptr->gx_section_offsets_offset= section_offsets_tab_offset; indexptr->gx_section_sizes_offset = section_sizes_tab_offset; res = fill_in_offsets_headerline(dbg,indexptr, section_offsets_headerline_offset, num_secs,error); if (res != DW_DLV_OK) { return res; } *xuptr = indexptr; *version = indexptr->gx_version; *number_of_columns = indexptr->gx_column_count_sections; *number_of_CUs = indexptr->gx_units_in_index; *number_of_slots = indexptr->gx_slots_in_hash; *section_name = indexptr->gx_section_name; return DW_DLV_OK; } int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header xuhdr, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** typename, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** sectionname, UNUSEDARG Dwarf_Error * err) { *typename = &xuhdr->gx_type[0]; *sectionname = xuhdr->gx_section_name; return DW_DLV_OK; } /* Index values 0 to S-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned index, /* returns the hash value. 64 bits. */ Dwarf_Sig8 * hash_value, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * index_to_sections, Dwarf_Error * err) { Dwarf_Debug dbg = xuhdr->gx_dbg; Dwarf_Small *hashtab = xuhdr->gx_section_data + xuhdr->gx_hash_table_offset; Dwarf_Small *indextab = xuhdr->gx_section_data + xuhdr->gx_index_table_offset; Dwarf_Small *indexentry = 0; Dwarf_Small *hashentry = 0; Dwarf_Sig8 hashval; Dwarf_Unsigned indexval = 0; Dwarf_Small *section_end = xuhdr->gx_section_data + xuhdr->gx_section_length; hashval = zerohashkey; if (xuhdr->gx_slots_in_hash > 0) { if (index >= xuhdr->gx_slots_in_hash) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_XU_HASH_ROW_ERROR the index passed in, " " %u, is greater than the number of slots " " in the hash table.",index); _dwarf_error_string(dbg, err, DW_DLE_XU_HASH_ROW_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } hashentry = hashtab + (index * HASHSIGNATURELEN); memcpy(&hashval,hashentry,sizeof(hashval)); } else { _dwarf_error_string(dbg, err, DW_DLE_XU_HASH_ROW_ERROR, "DW_DLE_XU_HASH_ROW_ERROR the number of slots is zero" " which seems wrong."); return DW_DLV_ERROR; } indexentry = indextab + (index * LEN32BIT); memcpy(hash_value,&hashval,sizeof(hashval)); READ_UNALIGNED_CK(dbg,indexval,Dwarf_Unsigned, indexentry, LEN32BIT, err,section_end); indexentry += LEN32BIT; if (indexval > xuhdr->gx_units_in_index) { _dwarf_error(dbg, err, DW_DLE_XU_HASH_INDEX_ERROR); return DW_DLV_ERROR; } *index_to_sections = indexval; return DW_DLV_OK; } static const char * dwp_secnames[] = { "No name for zero", "DW_SECT_INFO" /* 1 */ /*".debug_info.dwo"*/, "DW_SECT_TYPES" /* 2 */ /*".debug_types.dwo"*/, "DW_SECT_ABBREV" /* 3 */ /*".debug_abbrev.dwo"*/, "DW_SECT_LINE" /* 4 */ /*".debug_line.dwo"*/, "DW_SECT_LOC" /* 5 */ /*".debug_loc.dwo"*/, "DW_SECT_STR_OFFSETS" /* 6 */ /*".debug_str_offsets.dwo"*/, "DW_SECT_MACRO" /* 7 */ /*".debug_macro.dwo"*/, "DW_SECT_RNGLISTS" /* 8 */ /*".debug_rnglists.dwo"*/, "No name > 8", }; /* Row 0 of the Table of Section Offsets, columns 0 to L-1, are the section id's, and names, such as DW_SECT_INFO (ie, 1) */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned column_index, Dwarf_Unsigned* number, const char ** name, Dwarf_Error * err) { Dwarf_Unsigned sec_num = 0; Dwarf_Debug dbg = xuhdr->gx_dbg; if ( column_index >= xuhdr->gx_column_count_sections) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR as the " "column index of %u ",column_index); dwarfstring_append_printf_u(&s," is too high. " "There are %u sections.", xuhdr->gx_column_count_sections); _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } sec_num = xuhdr->gx_section_id[column_index]; if (sec_num < 1) { return DW_DLV_NO_ENTRY; } *number = sec_num; *name = dwp_secnames[sec_num]; return DW_DLV_OK; } /* Rows 0 to U-1 col 0 to L-1 are section offset and length values from the Table of Section Offsets and Table of Section Sizes. The formally the table of section offsets is a header line of the section offsets we subtract 1 from the incoming irow_index as our tables are now zero origin. */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned irow_index, Dwarf_Unsigned column_index, Dwarf_Unsigned* sec_offset, Dwarf_Unsigned* sec_size, Dwarf_Error * err) { /* We use zero origin in the arrays, Users see one origin from the hash table. */ Dwarf_Debug dbg = xuhdr->gx_dbg; /* get to base of tables first. */ Dwarf_Small *offsetrow = xuhdr->gx_section_offsets_offset + xuhdr->gx_section_data; Dwarf_Small *sizerow = xuhdr->gx_section_sizes_offset + xuhdr->gx_section_data; Dwarf_Small *offsetentry = 0; Dwarf_Small *sizeentry = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned column_count = xuhdr->gx_column_count_sections; Dwarf_Small *section_end = xuhdr->gx_section_data + xuhdr->gx_section_length; Dwarf_Unsigned row_index = irow_index-1; if (!irow_index) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append(&s, "ERROR: DW_DLE_ERRONEOUS_XU_INDEX_SECTION " "The row index passed to dwarf_get_xu_section_offset() " "is zero, which is not a valid row in " " the offset-table or the size table as we think" " of them as 1-origin."); _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } if (row_index >= xuhdr->gx_units_in_index) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR as the " "row index of %u ",row_index); dwarfstring_append_printf_u(&s," is too high. " "Valid units must be < %u ",xuhdr->gx_units_in_index); _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } if (column_index >= xuhdr->gx_column_count_sections) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR as the " "column index of %u ",column_index); dwarfstring_append_printf_u(&s," is too high. " "Valid column indexes must be < %u ", xuhdr->gx_column_count_sections); _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } /* As noted above we have hidden the extra initial row from the offsets table so it is just 0 to U-1. */ offsetrow = offsetrow + (row_index*column_count * LEN32BIT); offsetentry = offsetrow + (column_index * LEN32BIT); sizerow = sizerow + (row_index*column_count * LEN32BIT); sizeentry = sizerow + (column_index * LEN32BIT); { READ_UNALIGNED_CK(dbg,offset,Dwarf_Unsigned, offsetentry, LEN32BIT,err,section_end); offsetentry += LEN32BIT; READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned, sizeentry, LEN32BIT,err,section_end); sizeentry += LEN32BIT; } *sec_offset = offset; *sec_size = size; return DW_DLV_OK; } static int _dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg, Dwarf_Xu_Index_Header xuhdr, Dwarf_Sig8 *key_in, Dwarf_Unsigned * percu_index_out, Dwarf_Error *error) { Dwarf_Unsigned key = 0; Dwarf_Unsigned primary_hash = 0; Dwarf_Unsigned hashprime = 0; Dwarf_Unsigned slots = xuhdr->gx_slots_in_hash; Dwarf_Unsigned mask = slots -1; Dwarf_Sig8 hashentry_key; Dwarf_Unsigned percu_index = 0; hashentry_key = zerohashkey; /* Look for corrupt section data. */ if (slots > xuhdr->gx_section_length) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR as the " "slots count of %u ",slots); dwarfstring_append_printf_u(&s," is too high. " "given the section length of %u\n", xuhdr->gx_section_length); _dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } if ( (4*slots) > xuhdr->gx_section_length) { dwarfstring s; dwarfstring_constructor(&s); dwarfstring_append_printf_u(&s, "ERROR: DW_DLE_XU_NAME_COL_ERROR as the " "slots count *4 of %u ",slots*4); dwarfstring_append_printf_u(&s," is too high. " "given the section length of %u\n", xuhdr->gx_section_length); _dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR, dwarfstring_string(&s)); dwarfstring_destructor(&s); return DW_DLV_ERROR; } if (sizeof (key) != sizeof(key_in)) { /* The hash won't work right in this case */ _dwarf_error(dbg, error, DW_DLE_XU_HASH_ROW_ERROR); } ASNAR(key,key_in,sizeof(*key_in)); primary_hash = key & mask; hashprime = (((key >>32) &mask) |1); while (1) { int res = 0; res = dwarf_get_xu_hash_entry(xuhdr, primary_hash,&hashentry_key, &percu_index,error); if (res != DW_DLV_OK) { return res; } if (percu_index == 0 && !memcmp(&hashentry_key,&zerohashkey,sizeof(Dwarf_Sig8))) { return DW_DLV_NO_ENTRY; } if (!memcmp(key_in,&hashentry_key,sizeof(Dwarf_Sig8))) { /* FOUND */ *percu_index_out = percu_index; return DW_DLV_OK; } primary_hash = (primary_hash + hashprime) % slots; } /* ASSERT: Cannot get here. */ return DW_DLV_NO_ENTRY; } /* Slow. Consider tsearch. */ /* For type units and for CUs. */ /* We're finding an index entry refers to a global offset in some CU and hence is unique in the target. */ static int _dwarf_search_fission_for_offset(Dwarf_Debug dbg, Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned offset, Dwarf_Unsigned dfp_sect_num, /* DW_SECT_INFO or TYPES */ Dwarf_Unsigned * percu_index_out, Dwarf_Sig8 * key_out, Dwarf_Error *error) { Dwarf_Unsigned i = 0; Dwarf_Unsigned m = 0; int secnum_index = -1; /* N index */ int res = 0; for ( i = 0; i< xuhdr->gx_column_count_sections; i++) { /* We could put the secnums array into xuhdr if looping here is too slow. */ const char *name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error); if (res != DW_DLV_OK) { return res; } if (num == dfp_sect_num) { secnum_index = i; break; } } if (secnum_index == -1) { _dwarf_error(dbg,error,DW_DLE_FISSION_SECNUM_ERR); return DW_DLV_ERROR; } for ( m = 0; m < xuhdr->gx_slots_in_hash; ++m) { Dwarf_Sig8 hash; Dwarf_Unsigned indexn = 0; Dwarf_Unsigned sec_offset = 0; Dwarf_Unsigned sec_size = 0; res = dwarf_get_xu_hash_entry(xuhdr,m,&hash,&indexn,error); if (res != DW_DLV_OK) { return res; } if (indexn == 0 && !memcmp(&hash,&zerohashkey,sizeof(Dwarf_Sig8))) { /* Empty slot. */ continue; } res = dwarf_get_xu_section_offset(xuhdr, indexn,secnum_index,&sec_offset,&sec_size,error); if (res != DW_DLV_OK) { return res; } if (sec_offset != offset) { continue; } *percu_index_out = indexn; *key_out = hash; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int _dwarf_get_xuhdr(Dwarf_Debug dbg, const char *sigtype, Dwarf_Xu_Index_Header *xuout, Dwarf_Error *error) { if (!strcmp(sigtype,"tu")) { if (!dbg->de_tu_hashindex_data) { return DW_DLV_NO_ENTRY; } *xuout = dbg->de_tu_hashindex_data; } else if (!strcmp(sigtype,"cu")) { if (!dbg->de_cu_hashindex_data) { return DW_DLV_NO_ENTRY; } *xuout = dbg->de_cu_hashindex_data; } else { _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING); return DW_DLV_ERROR; } return DW_DLV_OK; } static int transform_xu_to_dfp(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned percu_index, Dwarf_Sig8 *key, const char *sig_type, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error *error) { unsigned i = 0; unsigned l = 0; unsigned n = 1; unsigned max_cols = xuhdr->gx_column_count_sections; /* L */ unsigned secnums[DW_FISSION_SECT_COUNT]; int res; for ( i = 0; i< max_cols; i++) { /* We could put the secnums array into xuhdr if recreating it is too slow. */ const char *name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error); if (res != DW_DLV_OK) { return res; } secnums[i] = num; } n = percu_index; for (l = 0; l < max_cols; ++l) { /* L */ Dwarf_Unsigned sec_off = 0; Dwarf_Unsigned sec_size = 0; unsigned l_as_sect = secnums[l]; res = dwarf_get_xu_section_offset(xuhdr,n,l, &sec_off,&sec_size,error); if (res != DW_DLV_OK) { return res; } percu_out->pcu_offset[l_as_sect] = sec_off; percu_out->pcu_size[l_as_sect] = sec_size; } percu_out->pcu_type = sig_type; percu_out->pcu_index = percu_index; percu_out->pcu_hash = *key; return DW_DLV_OK; } /* This should only be called for a CU, never a TU. For a TU the type hash is known while reading the TU Header. Not so for a CU. */ int _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg, Dwarf_Off offset_wanted, const char * key_type, /* "cu" or "tu" */ struct Dwarf_Debug_Fission_Per_CU_s * percu_out, Dwarf_Error *error) { Dwarf_Xu_Index_Header xuhdr = 0; int sres = 0; Dwarf_Unsigned percu_index = 0; Dwarf_Unsigned sect_index_base = 0; Dwarf_Sig8 key; sect_index_base = DW_SECT_INFO; key = zerohashkey; sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error); if (sres != DW_DLV_OK) { return sres; } sres = _dwarf_search_fission_for_offset(dbg, xuhdr,offset_wanted, sect_index_base, &percu_index, &key, error); if (sres != DW_DLV_OK) { return sres; } sres = transform_xu_to_dfp(xuhdr,percu_index,&key, key_type,percu_out, error); return sres; } int dwarf_get_debugfission_for_key(Dwarf_Debug dbg, Dwarf_Sig8 * key /* pointer to hash signature */, const char * key_type /* "cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error ) { int sres = 0; Dwarf_Unsigned percu_index = 0; Dwarf_Xu_Index_Header xuhdr = 0; sres = _dwarf_load_debug_info(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } sres = _dwarf_load_debug_types(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } /* Returns already existing xuhdr */ sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error); if (sres != DW_DLV_OK) { return sres; } /* Search in that xu data. */ sres = _dwarf_search_fission_for_key(dbg, xuhdr,key,&percu_index,error); if (sres != DW_DLV_OK) { return sres; } sres = transform_xu_to_dfp(xuhdr,percu_index,key, key_type,percu_out,error); return sres; } void dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr) { if (indexptr) { Dwarf_Debug dbg = indexptr->gx_dbg; dwarf_dealloc(dbg,indexptr,DW_DLA_XU_INDEX); } } libdwarf-20210528/libdwarf/pro_reloc_symbolic.c0000664000175000017500000002300513764007262016326 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2016-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ /*#include */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_symbolic.h" #ifndef SHT_REL #define SHT_REL 9 #endif /* SHT_REL */ #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif /* SHN_UNDEF */ /* Return DW_DLV_ERROR on malloc error. Return DW_DLV_OK otherwise */ int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { /* get a slot, fill in the slot entry */ void *relrec_to_fill = 0; int res = 0; struct Dwarf_Relocation_Data_s *slotp; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; slotp->drd_type = type; slotp->drd_length = reltarget_length; slotp->drd_offset = offset; slotp->drd_symbol_index = symidx; return DW_DLV_OK; } /* Return DW_DLV_ERROR on malloc error. Return DW_DLV_OK otherwise */ int _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type type, int reltarget_length) { /* get a slot, fill in the slot entry */ void *relrec_to_fill = 0; int res = 0; struct Dwarf_Relocation_Data_s *slotp1 = 0; struct Dwarf_Relocation_Data_s *slotp2 = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ slotp1->drd_type = type; slotp1->drd_length = reltarget_length; slotp1->drd_offset = offset; slotp1->drd_symbol_index = start_symidx; slotp2->drd_type = dwarf_drt_second_of_length_pair; slotp2->drd_length = reltarget_length; slotp2->drd_offset = offset; slotp2->drd_symbol_index = end_symidx; return DW_DLV_OK; } /* Ensure each stream is a single buffer and add that single buffer to the set of stream buffers. By creating a new buffer and copying if necessary. (If > 1 block, reduce to 1 block) Free the input set of buffers if we consolidate. We pass back *new_sec_count as zero because we are not creating normal sections for a .o, but symbolic relocations, separately counted. Return -1 on error (malloc failure) Return DW_DLV_OK on success. Any other return indicates malloc failed. */ int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { int i = 0; Dwarf_Error error = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { int sec_index = 0; Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect + i; unsigned long ct = p_reloc->pr_reloc_total_count; int err = 0; if (ct == 0) { /* No relocations in here. Nothing to do. */ continue; } /* total_size = ct *len; */ sec_index = p_reloc->pr_sect_num_of_reloc_sect; if (sec_index == 0) { /* sec_index zero means we have not processed this section of relocations yet. */ /* Call de_callback_func getting section number of reloc section. */ int rel_section_index = 0; Dwarf_Unsigned name_idx = 0; /* This is a bit of a fake, as we do not really have true elf sections at all. Just the data such might contain. But this lets the caller eventually link things together: without this call we would not know what rel data goes with what section when we are asked for the real arrays. */ if (dbg->de_callback_func) { /* For symbolic relocations de_callback_func may well return 0. */ rel_section_index = dbg->de_callback_func(_dwarf_rel_section_names[i], dbg->de_relocation_record_size, /* type */ SHT_REL, /* flags */ 0, /* link to symtab, which we cannot know */ SHN_UNDEF, /* sec rels apply to */ dbg->de_elf_sects[i], &name_idx, dbg->de_user_data,&err); } if (rel_section_index == -1) { { _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR); return DW_DLV_ERROR; } } p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; } /* If pr_block_count 0 or 1 then the blocks are an array (with 0 or 1 entries) so we'll just return to the for loop. No more work to do here. */ if (p_reloc->pr_block_count < 2) { continue; } { /* Since more than one relocation on the section we now convert the list of relocation blocks into a proper array of blocks. */ struct Dwarf_P_Relocation_Block_s *new_blk = 0; struct Dwarf_P_Relocation_Block_s *p_blk = 0; Dwarf_Small *data = 0; int res = 0; p_blk = p_reloc->pr_first_block; /* Do not zero pr_sect_num_of_reloc_sect */ p_reloc->pr_reloc_total_count = 0; p_reloc->pr_first_block = 0; p_reloc->pr_last_block = 0; p_reloc->pr_block_count = 0; /* Now we know a number making a single array. Replaces DEFAULT_SLOTS_PER_BLOCK */ p_reloc->pr_slots_per_block_to_alloc = ct; /* Creating new single block for all 'ct' entries. Assigns a pointer value to pr_first_block (which means our p_reloc). It updates p_reloc->pr_first_block */ res = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, p_reloc,ct); if (res != DW_DLV_OK) { return res; } new_blk = p_reloc->pr_first_block; data = (Dwarf_Small *) new_blk->rb_data; /* The following loop does the consolidation to a single block and frees the input block(s). p_blk points to the old singly-linked-list and is the only access to that list. data is a pointer to the new array of ct entries which is our target(destination) of the copies. */ do { struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; /* len identifies the data in all the slots in use in this block. */ unsigned long len = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, len); data += len; p_blk_last = p_blk; p_blk = p_blk->rb_next; _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } while (p_blk); /* ASSERT: the dangling p_blk list all dealloc'd which is really a no-op, all deallocations take place at producer_finish(). */ /* ASSERT: sum of len copied == total_size */ new_blk->rb_next_slot_to_use = ct; new_blk->rb_where_to_add_next = (char *) data; p_reloc->pr_reloc_total_count = ct; /* Have now created a single block, but no change in slots used (pr_reloc_total_count) */ } } /* There is no section data with symbolic, so there is no count. */ *new_sec_count = 0; return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_reloc_386.h0000644000175000017500000000673613743575426015360 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_386_H #define DWARF_RELOC_386_H /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for i386 architecture */ #define R_386_NONE 0 #define R_386_32 1 #define R_386_PC32 2 #define R_386_GOT32 3 #define R_386_PLT32 4 #define R_386_COPY 5 #define R_386_GLOB_DAT 6 #define R_386_JMP_SLOT 7 #define R_386_RELATIVE 8 #define R_386_GOTOFF 9 #define R_386_GOTPC 10 #define R_386_32PLT 11 #define R_386_TLS_TPOFF 14 #define R_386_TLS_IE 15 #define R_386_TLS_GOTIE 16 #define R_386_TLS_LE 17 #define R_386_TLS_LDM 19 #define R_386_16 20 #define R_386_PC16 21 #define R_386_8 22 #define R_386_PC8 23 #define R_386_TLS_GD_32 24 #define R_386_TLS_GD_PUSH 25 #define R_386_TLS_GD_CALL 26 #define R_386_TLS_GD_POP 27 #define R_386_TLS_LDM_32 28 #define R_386_TLS_LDM_PUSH 29 #define R_386_TLS_LDM_CALL 30 #define R_386_TLS_LDM_POP 31 #define R_386_TLS_LDO_32 32 #define R_386_TLS_IE_32 33 #define R_386_TLS_LE_32 34 #define R_386_TLS_DTPMOD32 35 #define R_386_TLS_DTPOFF32 36 #define R_386_TLS_TPOFF32 37 #define R_386_SIZE32 38 #define R_386_TLS_GOTDESC 39 #define R_386_TLS_DESC_CALL 40 #define R_386_TLS_DESC 41 #define R_386_IRELATIVE 42 #define R_386_NUM 43 /* Keep this the last entry. */ #define R_X86_64_NUM 39 #endif /* _WIN32 */ /* Relocation types for X86_64 */ static const char *reloc_type_names_386[] = { "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32", "R_386_PLT32", "R_386_COPY", /* 5 */ "R_386_GLOB_DAT", "R_386_JMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC", /* 10 */ "R_386_32PLT", "R_386_TLS_TPOFF", "R_386_TLS_IE", "R_386_TLS_GOTIE", "R_386_TLS_LE", "R_386_TLS_LDM", "R_386_16", /* 20 */ "R_386_PC16", "R_386_8", "R_386_PC8", "R_386_TLS_GD_32", "R_386_TLS_GD_PUSH", /* 25 */ "R_386_TLS_GD_CALL", "R_386_TLS_GD_POP", "R_386_TLS_LDM_32", "R_386_TLS_LDM_PUSH", "R_386_TLS_LDM_CALL", /* 30 */ "R_386_TLS_LDM_POP", "R_386_TLS_LDO_32", "R_386_TLS_IE_32", "R_386_TLS_LE_32", "R_386_TLS_DTPMOD32", /* 35 */ "R_386_TLS_DTPOFF32", "R_386_TLS_TPOFF32", "R_386_SIZE32", "R_386_TLS_GOTDESC", "R_386_TLS_DESC_CALL", /* 40 */ "R_386_TLS_DESC", "R_386_IRELATIVE", /* 42 */ }; #endif /* DWARF_RELOC_386_H */ libdwarf-20210528/libdwarf/libdwarfdefs.h0000644000175000017500000000245213743575426015114 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* libdwarfdefs.h */ #ifndef LIBDWARFDEFS_H #define LIBDWARFDEFS_H #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define DWARF_HALF_SIZE 2 #endif /* LIBDWARFDEFS_H */ libdwarf-20210528/libdwarf/libdwarf.h.in0000664000175000017500000065106414051002670014645 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct Elf Elf; typedef struct Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; /* Dwarf_Bool as int is wasteful, but for compatibility it must stay as int, not unsigned char. */ typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain location information functions, a frame expression function, and also used with DW_FORM_block<> functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* See libdwarf.h DW_LKIND* */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location description */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW July 2020. */ /* This provides access to data from sections .debug_gnu_pubtypes or .debug_gnu_pubnames. These are not standard DWARF, and can appear with gcc -gdwarf-5 */ struct Dwarf_Gnu_Index_Head_s; typedef struct Dwarf_Gnu_Index_Head_s * Dwarf_Gnu_Index_Head; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_number2; Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { /* Offset of string attribute data */ Dwarf_Unsigned sa_offset; Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s *Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s *Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ /* Dwarf_Frame Block (not used) */ #define DW_DLA_FRAME_BLOCK 0x17 #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x34 (52) reserved for internal to libdwarf types. */ /* .debug_gnu_typenames/pubnames, 2020 */ #define DW_DLA_GNU_INDEX_HEAD 0x35 #define DW_DLA_RNGLISTS_HEAD 0x36 /* .debug_rnglists DW5 */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ /* struct Dwarf_Str_Offsets_Table_s */ #define DW_DLA_STR_OFFSETS 0x40 /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() 'access' argument values. Used for reading/consuming DWARF, not relevant to the producer portion of libdwarf. None of the following three arguments do anything. The following short set is useless. Only DW_DLC_READ has a documented effect but... it is useless and irrelevant as it means 'do the default'. In the 1990's there was an option DW_DLC_MMAP (deleted from libdwarf.h many years ago). The old option libdwarf told IRIX libelf to mmap the object file. */ #define DW_DLC_READ 0 /* Pointless. Ok to use. */ #define DW_DLC_WRITE 1 /* DO NOT USE */ #define DW_DLC_RDWR 2 /* DO NOT USE */ /* ===== the following DW_DLC options are for producing DWARF, not used for reading/consuming DWARF. */ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so. See the Dwarf_Rel_Type enum relocation indicators. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* old spelling */ #define DW_DLC_POINTER64 0x40000000 /* correct spelling */ /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* old spelling */ #define DW_DLC_POINTER32 0x20000000 /* correct spelling */ /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* DO NOT USE */ /* DW_DLC_OFFSET32 is the default, the bit is not checked. */ #define DW_DLC_OFFSET32 0x00010000 /* default offset size */ /* 64-bit offset-size DWARF offsets */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* old spelling */ #define DW_DLC_OFFSET64 0x10000000 /* correct spelling */ /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* DO NOT USE. */ /* Special for IRIX only. For producing DWARF with Elf 64bit offset headers and non-standard IRIX 64bit offset DWARF .debug_info etc compilation unit headers. */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Old style Elf binary relocation (.rel) records. The default. For producing DWARF */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* ===== END DW_DLC options LIBDWARF */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 #define DW_DLE_ELF_RELOC_SECTION_ERROR 466 #define DW_DLE_USER_DECLARED_ERROR 467 #define DW_DLE_RNGLISTS_ERROR 468 #define DW_DLE_LOCLISTS_ERROR 469 #define DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE 470 #define DW_DLE_GDBINDEX_STRING_ERROR 471 #define DW_DLE_GNU_PUBNAMES_ERROR 472 #define DW_DLE_GNU_PUBTYPES_ERROR 473 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES 474 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES 475 #define DW_DLE_DEBUG_SUP_STRING_ERROR 476 #define DW_DLE_DEBUG_SUP_ERROR 477 #define DW_DLE_LOCATION_ERROR 478 #define DW_DLE_DEBUGLINK_PATH_SHORT 479 #define DW_DLE_SIGNATURE_MISMATCH 480 #define DW_DLE_MACRO_VERSION_ERROR 481 #define DW_DLE_NEGATIVE_SIZE 482 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 482 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the separation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN = 0, DW_FORM_CLASS_ADDRESS = 1, DW_FORM_CLASS_BLOCK = 2, DW_FORM_CLASS_CONSTANT =3, DW_FORM_CLASS_EXPRLOC = 4, DW_FORM_CLASS_FLAG = 5, DW_FORM_CLASS_LINEPTR = 6, DW_FORM_CLASS_LOCLISTPTR=7, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR = 8, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR=9, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE=10, DW_FORM_CLASS_STRING = 11, DW_FORM_CLASS_FRAMEPTR= 12, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR= 13, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR = 14, /* DWARF5 */ DW_FORM_CLASS_LOCLIST = 15, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR=16, /* DWARF5 */ DW_FORM_CLASS_RNGLIST =17, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR=18, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR=19 /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects and Elf SHT_GROUP blocks of DWARF sections. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*==================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur, nor will the GNU_debuglink processing occur. In case GNU debuglink data was followed or MacOS dSYM applies the true_path_out will not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* New October 2020. Following GNU debuglink to the true-path with DWARF if there is appropriate debuglink data available. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. In case GNU debuglink data was followed the true_path_out will not match path. If debuglink missing from the Elf executable or shared-object (ie, it is a normal object!) or unusable by libdwarf or true_path_buffer len is zero or true_path_out_buffer is zero the accepts the path given as the object to report on. Passing dl_path_array and dl_path_array size zero suffices unless one has unusual locations for debuglink objects. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur either. */ int dwarf_init_path_dl(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, char ** /* dl_path array */, unsigned int /* dl_path array size */, unsigned char * /* path_source */, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned int /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned int /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* New 4 February 2021. returns DIE and is_info flag if it finds the referenced DW_UT_split_type or DW_UT_type CU. */ int dwarf_find_die_given_sig8(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*ref*/, Dwarf_Die * /*die_out*/, Dwarf_Bool * /*is_info*/, Dwarf_Error * /*error*/); /* Returns the is_info flag. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New December 2020. Any Dwarf_Die will work. The values returned are about the CU itself, not a DIE. */ int dwarf_cu_header_basics(Dwarf_Die die, Dwarf_Half * /*version*/, Dwarf_Bool * /*is_info*/, Dwarf_Bool * /*is_dwo*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*extension_size*/, Dwarf_Sig8 ** /*signature*/, Dwarf_Off * /*offset_of_length*/, Dwarf_Unsigned * /*total_byte_length*/, Dwarf_Error * /*error*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* Reading a CU DIE with DW_AT_low_pc an indexed value can be problematic as that interacts with DW_AT_addr_base in that DIE. Here is a test readers may find useful */ Dwarf_Bool dwarf_addr_form_is_indexed(int form); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/, Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: debug_gnu_pubnames/typenames access, calling these Gnu_Index as a general reference. */ int dwarf_get_gnu_index_head(Dwarf_Debug /*dbg*/, /* The following arg false to select gnu_pubtypes */ Dwarf_Bool /*for_gdb_pubnames*/ , Dwarf_Gnu_Index_Head * /*index_head_out*/, Dwarf_Unsigned * /*index_block_count_out*/, Dwarf_Error * /*error*/); /* Frees all resources used for the indexes. */ void dwarf_gnu_index_dealloc(Dwarf_Gnu_Index_Head /*head*/); int dwarf_get_gnu_index_block(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*number*/, Dwarf_Unsigned * /*block_length */, Dwarf_Half * /*version */, Dwarf_Unsigned * /*offset_into_debug_info*/, Dwarf_Unsigned * /*size_of_debug_info_area*/, Dwarf_Unsigned * /*count_of_index_entries*/, Dwarf_Error * /*error*/); int dwarf_get_gnu_index_block_entry(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*blocknumber*/, Dwarf_Unsigned /*entrynumber*/, Dwarf_Unsigned * /*offset_in_debug_info*/, const char ** /*name_string*/, unsigned char * /*flagbyte*/, unsigned char * /*staticorglobal*/, unsigned char * /*typeofentry*/, Dwarf_Error * /*error*/); /* END: debug_gnu_pubnames/typenames access, */ /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); #define DW_LKIND_expression 0 /* DWARF2,3,4*/ #define DW_LKIND_loclist 1 /* DWARF 2,3,4 */ #define DW_LKIND_GNU_exp_list 2 /* GNU DWARF4 .dwo extension */ #define DW_LKIND_loclists 5 /* DWARF5 loclists */ #define DW_LKIND_unknown 99 /* DWARF2 kind is 2. DWARF3/4 kind is 3, DWARF5 kind is 5 */ int dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c /*ll_header*/, unsigned int * /*lkind*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Unsigned * /*rawlowpc*/, Dwarf_Unsigned * /*rawhipc*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); /* New June 2020 for DWARF5 (and all earlier). */ int dwarf_get_location_op_value_d(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*rawop1*/, Dwarf_Unsigned * /*rawop2*/, Dwarf_Unsigned * /*rawop3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count( Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data( Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/ Separate-Debug-Files.html If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. Caller frees space returned by debuglink_fullpath_returned. See libdwarf2.1.mm revision 3.13 or later for additional important details. */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*debuglink_path_returned */, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_fullpath_returned free this*/, unsigned int * /*debuglink_path_count_returned */, unsigned int * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned int * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned int * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* Only useful inside dwarfexample/dwdebuglink.c so we can show all that is going on. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* crc32 used for debuglink crc calculation. Caller passes pointer to array of 4 unsigned char provided by the caller and if this returns DW_DLV_OK that is filled in. */ int dwarf_crc32 (Dwarf_Debug /*dbg*/,unsigned char * /*crcbuf*/, Dwarf_Error * /*error*/); /* Public interface to the real crc calculation just in case some find it useful. */ unsigned int dwarf_basic_crc32 (const unsigned char * /*buf*/, unsigned long /*len*/, unsigned int /*init*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Special for dwarfdump. Sets a flag in the dbg. Always returns DW_DLV_OK and (as of March 2020) never touches error */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* jUser-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) DO NOT USE, it cannot deal with recent dwarf or CUs with different address sizes. Use dwarf_get_locdesc_entry_c() instead. */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned /*indx*/, Dwarf_Bool /*filter_outliers*/, Dwarf_Unsigned * /*returned_attr_num*/, Dwarf_Unsigned * /*returned_form*/, Dwarf_Signed * /*returned_implicit_const*/, Dwarf_Off * /*offset*/, Dwarf_Error * /*error*/); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable3* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); /* New December 2020. Sometimes its necessary to know a context total length including macro 5 header */ int dwarf_macro_context_total_length(Dwarf_Macro_Context /*head*/, Dwarf_Unsigned * /*mac_total_len*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned int * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. The last op has 0 as opcode_number,operand_count and operand_array */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file( Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. Use dwarf_check_lineheader_b() (new 14 April 2020) in place of dwarf_check_lineheader(). */ int dwarf_check_lineheader_b(Dwarf_Die /*cu_die*/, int * /*errcount_out*/, Dwarf_Error * /*error*/); void dwarf_check_lineheader(Dwarf_Die /*cu_die*/, int * /*errcount_out*/); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. Completely different than .debug_gnu_pubnames or .debug_gnu_pubtypes sections. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); void dwarf_error_creation(Dwarf_Debug /*dbg*/ , Dwarf_Error * /*error*/, char * /*errmsg*/); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Never Implemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* These convenience functions allow type checking at the call, whereas dwarf_dealloc itself uses void * so ... easy to misuse. */ void dwarf_dealloc_error(Dwarf_Debug /*dbg*/, Dwarf_Error /*err*/); void dwarf_dealloc_die( Dwarf_Die /*die*/); void dwarf_dealloc_attribute(Dwarf_Attribute /*attr*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New July 2020 for testing DWARF5 */ int dwarf_add_debug_sup(Dwarf_P_Debug /*dbg*/, Dwarf_Half /*version*/, Dwarf_Small /*is_supplementary*/, char * /*filename*/, Dwarf_Unsigned /*checksum_len*/, Dwarf_Small * /*checksum*/, Dwarf_Error * /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* Adds return of the final offset to accommodate DWARF4 GNU split-dwarf. Other than for split-dwarf the realoffset will be set by the function to be the same as rangesoffset. New September 10, 2020. */ int dwarf_get_ranges_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /*diepointer */, Dwarf_Off * /*realoffset */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New July 2020 for DWARF5 */ int dwarf_get_debug_sup(Dwarf_Debug /*dbg*/, Dwarf_Half * /*version*/, Dwarf_Small * /*is_supplementary*/, char ** /*filename*/, Dwarf_Unsigned * /*checksum_len*/, Dwarf_Small ** /*checksum*/, Dwarf_Error * /*error*/); /* ======= START .debug_rnglists interfaces. New May 2020 */ struct Dwarf_Rnglists_Entry_s; typedef struct Dwarf_Rnglists_Entry_s * Dwarf_Rnglists_Entry; struct Dwarf_Rnglists_Head_s; typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; /* For DWARF5 DW_AT_ranges: DW_FORM_sec_offset DW_FORM_rnglistx */ int dwarf_rnglists_get_rle_head(Dwarf_Attribute /*attr*/, Dwarf_Half /*theform*/, Dwarf_Unsigned /*index_or_offset_value*/, Dwarf_Rnglists_Head * /*head_out*/, Dwarf_Unsigned * /*count_of_entries_in_head*/, Dwarf_Unsigned * /*global_offset_of_rle_set*/, Dwarf_Error * /*error*/); /* Get the rnglist entries details */ int dwarf_get_rnglists_entry_fields_a( Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned * /*entrylen*/, unsigned * /*rle_value_out*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*err*/); /* The following is not complete. DO NOT USE. Use dwarf_get_rnglists_entry_fields_a() instead. */ int dwarf_get_rnglists_entry_fields(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); int dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head ); /* Loads all the rnglists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of rnglists headers in the section through rnglists_count. */ int dwarf_load_rnglists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*rnglists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th rangelists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_rnglists section offset of the range list. */ int dwarf_get_rnglist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_rnglists_index_get_rle_head() or dwarf_rnglists_offset_get_rle_head. */ int dwarf_get_rnglist_head_basics(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned * /*rle_count*/, Dwarf_Unsigned * /*rnglists_version*/, Dwarf_Unsigned * /*rnglists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*rnglists_base_present*/, Dwarf_Unsigned * /*rnglists_base*/, Dwarf_Bool * /*rnglists_base_address_present*/, Dwarf_Unsigned * /*rnglists_base_address*/, Dwarf_Bool * /*rnglists_debug_addr_base_present*/, Dwarf_Unsigned * /*rnglists_debug_addr_base*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_rnglists section may contain any number of Range List Table Headers with their details. */ int dwarf_get_rnglist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_rangeentry*/, Dwarf_Unsigned * /*offset_past_last_rangeentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_rangeentry. Stop when the returned *next_entry_offset is == offset_past_last_rangentry (from dwarf_get_rnglist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single rnglist header, meaning a a single Dwarf_Rnglists_Context. This interface assumes there is no segment selector. */ int dwarf_get_rnglist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_rnglist_rle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Error * /*err*/); /* ======= END .debug_rnglists interfaces. */ /* ======= START .debug_loclists interfaces. New May 2020 */ /* These interfaces allow reading the .debug_loclists section. Normal use of .debug_loclists uses dwarf_get_loclist_c() to open access to any kind of location or loclist and uses dwarf_loc_head_c_dealloc() to deallocate that memory once one is finished with that data. So for most purposes you do not need to use these functions */ struct Dwarf_Loclists_Entry_s; typedef struct Dwarf_Loclists_Entry_s * Dwarf_Loclists_Entry; /* See dwarf_get_loclist_c() to open a Dwarf_Loc_Head_c on any type of location list or expression. */ /* Get the loclists entries details */ int dwarf_get_loclists_entry_fields(Dwarf_Loc_Head_c /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); /* Loads all the loclists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of loclists headers in the section through loclists_count. */ int dwarf_load_loclists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*loclists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th loclists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_loclists section offset of the range list. */ int dwarf_get_loclist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_loclists_index_get_lle_head() or dwarf_loclists_offset_get_lle_head. */ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c /*head*/, Dwarf_Small * /*lkind*/, Dwarf_Unsigned * /*lle_count*/, Dwarf_Unsigned * /*loclists_version*/, Dwarf_Unsigned * /*loclists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*loclists_base_present*/, Dwarf_Unsigned * /*loclists_base*/, Dwarf_Bool * /*loclists_base_address_present*/, Dwarf_Unsigned * /*loclists_base_address*/, Dwarf_Bool * /*loclists_debug_addr_base_present*/, Dwarf_Unsigned * /*loclists_debug_addr_base*/, Dwarf_Unsigned * /*offset_this_lle_area*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_loclists section may contain any number of Location List Table Headers with their details. */ int dwarf_get_loclist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_locentry*/, Dwarf_Unsigned * /*offset_past_last_locentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_locentry. Stop when the returned *next_entry_offset is == offset_past_last_locentry (from dwarf_get_loclist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single loclist header, meaning a a single Dwarf_Loclists_Context. This interface assumes there is no segment selector. */ int dwarf_get_loclist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_loclist_lle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*expr_ops_blocksize*/, Dwarf_Unsigned * /*expr_ops_offset*/, Dwarf_Small ** /*expr_opsdata*/, Dwarf_Error * /*err*/); /* ======= END .debug_loclists interfaces. */ /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned int /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned int * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned int dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned int /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIKIND_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIVIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is for a GNU extension. Not defined by the GNU folks nor a DWARF standard but it seemed essential. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ extern int dwarf_get_FORM_CLASS_name(enum Dwarf_Form_Class /*fc*/, const char ** /*s_out*/); /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* New May 2017. So users can find out what groups (dwo or COMDAT) are in the object and how much to allocate so one can get the group-section map data. */ int dwarf_sec_group_sizes(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' values and this function fills in the array entries. Output ordered by group number and section number. */ int dwarf_sec_group_map(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/)) (void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Same for LEB decoding routines. caller sets endptr to an address one past the last valid address the library should be allowed to access. */ int dwarf_decode_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Unsigned * /*outval*/, char * /*endptr*/); int dwarf_decode_signed_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Signed * /*outval*/, char * /*endptr*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ /* Defined March 7 2020. Allows a caller to avoid most tracking by the de_alloc_tree hash table if called with v of zero. Returns the value the flag was before this call. */ int dwarf_set_de_alloc_flag(int v); /* Solely looks for debuglink */ int dwarf_object_detector_path(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); /* Solely looks for debuglink */ int dwarf_object_detector_path_b(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, char ** /* gl_pathnames*/, unsigned /* gl_pathcount*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, unsigned char * /*pathsource*/, int * /*errcode*/); /* Solely looks for dSYM */ int dwarf_object_detector_path_dSYM( const char *path, char *outpath, unsigned long outpath_len, char ** gl_pathnames, unsigned gl_pathcount, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, unsigned char *pathsource, int *errcode); #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 #define DW_PATHSOURCE_dsym 2 /* MacOS dSYM */ #define DW_PATHSOURCE_debuglink 3 /* GNU debuglink */ /* Returns the pathsource value set up at init time*/ int dwarf_get_path_source_type(Dwarf_Debug /* dbg*/, unsigned char * /*path_source*/, Dwarf_Error * /*error*/); int dwarf_object_detector_fd(int /*fd*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ libdwarf-20210528/libdwarf/ChangeLog20160000664000175000017500000013003313644370703014360 000000000000002016-12-25 David Anderson * dwarf.h: DWARF5 changed DW_FORM_ref_sup to DW_FORM_ref_sup4 and added DW_FORM_ref_sup8. 2016-12-20 David Anderson * libdwarfdefs.h: Removed definition of SHF_COMPRESSED. There was no reason to define it early in a local header file. * dwarf_init_finish.c: Added definition of SHF_COMPRESSED. Making it a late definition avoids a conflict with Centos-7.3. 2016-12-06 David Anderson * dwarf.h: Comments mention certain values unused in DWARF2 and later as being from DWARF1. 2016-11-24 David Anderson * libdwarf/gennames.c: Update version string. 2016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-16 David Anderson * dwarf_die_deliv.c(dwarf_child): Added a check for 'at end of DIEs', removed pointless parens in returns, and added {} to make an if() follow normal form. * dwarf_query.c: Removed pointless parens in return. * dwarf_util.c(_dwarf_get_size_of_val): Changed return 0 to return DW_DLV_OK so it reads as is supposed to. For DW_FORM_block1 check a pointer for validity before dereferencing. In _dwarf_check_string_valid() added comments clarifying the intent of the function. 2016-11-11 David Anderson * dwarf_init_finish.c: Remove a few bytes of trailing whitespace. * dwarf_leb.c(_dwarf_decode_s_leb128_chk): Now we avoid using code with undefined behavior. And add new test cases in the #ifdef TESTING code that shows the problem is fixed. 2016-11-04 David Anderson * libdwarf.h.in: Removed trailing whitespace, three places. Added DW_DLE_ZLIB_UNCOMPRESS_ERROR. * dwarf_arange.c(dwarf_get_aranges_list): Add checks for the sanity of aranges headers and values to catch corrupted dwarf.. * dwarf_errmsg_list.c: Add DW_DLE_ZLIB_UNCOMPRESS_ERROR to identify impossible zlib compression. * dwarf_form.c:(dwarf_formblock): Check for overrun of a section-end. Return witw DW_DLE_FORM_BLOCK_LENGTH_ERROR as the error when such corrupt dwarf is encountered. * dwarf_init_finish.c(do_decompress_zlib): Check for corrupted zlib compression information and set DW_DLE_ZLIB_UNCOMPRESS_ERROR when a corrupted expanded-length is found. * dwarf_macro5.c(_dwarf_skim_forms): For DW_FORM_STRING call _dwarf_check_string_valid() to ensure a string does not run off the end of a malloc block. * dwarf_util.c(_dwarf_check_string_valid): Remove and add a blank line to get the usual way functions begin with declarations, a blank line, then code. No change in logic. 2016-11-01 David Anderson * dwarf.h: Adding Ada GNAT gcc attributes DW_AT_GNU_numerator, DW_AT_GNU_denominator, DW_AT_GNU_bias. 2016-10-21 David Anderson * gennames.c: Update version string. 2016-10-15 David Anderson * libdwarf.h.in: Added DWARF5 values to enum Dwarf_Form_Class. * dwarf_query.c(dwarf_get_form_class): Added DWARF5 support. 2016-10-11 David Anderson * pro_forms.c, pro_section.c: Restoring DW_AT_MIPS_linkage_name and DW_AT_MIPS_abstract_name (lost by accident in July 2007) and adding DW_AT_linkage_name (DWARF5, but usable in earlier DWARF versions if you wish to use it). 2016-10-07 David Anderson * libdwarf2p.1.mm: Improved the documentation of dwarf_pro_set_default_string_form(). * libdwarf2p.1.pdf: Version 1.46. Regenerated. * pro_die.c: Now the code allows modification of the start of real strings in .debug_str easily. Was a bit brittle before, allowed offset of 1 to work but not zero. * pro_opaque.h: Add dse_has_table_offset member to eliminate brittleness in the logic for .debug_str. * pro_init.c: Use dse_has_table_offset member to eliminate brittleness in the logic for .debug_str. 2016-10-04 David Anderson * dwarf_elf_access.c: Remove trailing whitespace. * dwarf_form.c: Fix an indent. * dwarf_init_finish.c: Comment the #if 0 so it is clear these are for debugging only. * dwarf_leb.c: Remove trailing whitespace. * dwarf_line.c: Remove unused #if 0/#endif code. * dwarf_macro5.c: Remove some obsolete #if 0 code. Comment the remaining #if 0 so it is clear these are for debugging only. Remove trailing whitespace. * dwarf_util.h: Delete obsolete #if 0 macro. * dwgetopt.c: Comment the #if 0 so it is clear these are for debugging only. * pro_frame.h: Delete never-used #if 0 macro. 2016-10-04 David Anderson * dwarf_util.c(_dwarf_check_string_valid): removed accidental test code. 2016-10-04 David Anderson * dwarf_leb.c: The 'make tests' test code had some warnings, which are now fixed. * libdwarf.h.in: Adding error codes. * dwarf_util.c(_dwarf_check_string_valid): Uses passed-in error code in case pointer out of bounds. _dwarf_get_size_of_val now calls _dwarf_check_string_valid() on a DW_FORM_string. * dwarf_util.h: _dwarf_check_string_valid() interface changed. * dwarf_errmsg_list.c: Adding error codes. * dwarf_form.c, dwarf_frame2.c, dwarf_global.c, dwarf_line.c, dwarf_line_table_reader_common.c, dwarf_macro.c, dwarf_macro5.c, dwarf_string.c: Using the new _dwarf_check_string_valid interface and new error codes. * dwarf_elf_access.c: Added commentary about a libelf call and possible outcomes. 2016-10-03 David Anderson * Makefile.in: Now run tests at build time to ensure DW_DLE macros correct. * dwarf_errmsg_list.c: Add new error code and add test code to verify DW_DLE_ macros specified correctly. * dwarf_sort_line.c: While this file is not used, for consistency it uses the checking macros so deleting the non-checking ones would not look odd. * dwarf_util.c: Add a check for running off end of abbreviation data at a spot that was missed till now. * dwarf_util.h: Delete unused non-checking DECODE_LEB128_UWORD and DECODE_LEB128_SWORD and SKIP_LEB128_WORD macros. * libdwarf.h.in: Add DW_DLE_ABBREV_OFF_END and correct the numbering (again). Now critical parts are checked at build time. 2016-09-30 David Anderson * dwarf_leb.c: One comparison was accidentally signed vs unsigned. Now both unsigned. 2016-09-30 David Anderson * Makefile.in: Ensure test executable removed by make clean. 2016-09-30 David Anderson * dwarf_leb.c: Fix decode and encode leb to avoid runtime warning from left-shift signed value, we got into undefined behavior. Add test code used by 'make tests'. * Makefile.in: Add leb testing to 'make tests' * configure.in: Add additional -fsanitize tests. * configure: Regenerated. 2016-09-28 David Anderson * dwarf_opaque.h: New interface for _dwarf_extract_string_offset_via_str_offsets(). Remove duplicate declaration of the function. * dwarf_form.c(_dwarf_extract_string_offset_via_str_offsets): Had a test for end of section on what was sometimes the wrong section. Now section end passed in and correct. Depending on circumstances such as where elf data was in memory, the result was a single regression test would get a DW_DLE_LEB_IMPROPER error ... or not get it. * dwarf_macro5.c: A test for DW_DLV_OK was testing the wrong local variable. 2016-09-28 David Anderson * dwarf_errmsg_list.c: Added error codes for duplicated DWARF5 .debug_loclists and .debug_rnglists sections. * dwarf_init_finish.c: Adds incomplete support for DWARF5 .debug_names.c, .debug_loclists, and .debug_rnglists Adds dwarf_get_section_max_offsets_d() to return all the possible DWARF section sizes across all DWARF2..5 * dwarf_line_table_reader_common.c: DW_LNCT renamed as DW_LNCT_GNU as the DWARF5 standard has some differences from the experimental version (no named)DW_LNCT_GNU. * dwarf_loc2.c: Renames DW_LLE to DW_LLEX as these are the non-standard experimental version (not the same as the DWARF5 standard). * dwarf_opaque.h: Updated version number comments. Added new section support data in Dwarf_Debug_s. * dwarf_ranges.c(dwarf_get_ranges_a): deleted unused local variable. * libdwarf.h.in: New error codes. Declaration for dwarf_get_section_max_offsets_d() added. Now has all the DWARF5 dwarf_get_*_name() function declarations too. * dwarf_error.h: Deleted two unwanted blank lines. 2016-09-28 David Anderson * gennames.c: Now the comparison function to qsort guarantees a stable sort by also referencing the original array location (a new data item in the struct). Needed for consistent output. 2016-09-28 David Anderson * dwarf_alloc.c: Special function _dwarf_special_no_dbg_error_malloc() was failing to return a value. Serious bug. Now it returns a value. 2016-09-27 David Anderson * dwarf.h: The previous experimental DW_LLE_ non-standard names are renamed as DW_LLEX_ temporarily. Do not use the LLEX names. 2016-09-27 David Anderson * dwarf.h: Added commentary about DW_children_yes[no] which are non-standard. Use DW_CHILDREN_yes[no] instead. 2016-09-27 David Anderson * dwarf.h: Update with the probably-final DWARF5 tags, attributes, etc. 2016-09-26 David Anderson * dwarf_query.c: Removed four lines of code associated with DWARF5 DW_MACRO_define_strx that should not have existed. There are as yet no testcases using strx, though one fuzzed testcase (liu/NULLdereference0519.elf) made it appear such was in use. 2016-09-25 David Anderson * dwarf_opaque.h: Accidentally had a function pointer definition _dwarf_get_elf_flags_func_ptr but now has a typedef of _dwarf_get_elf_flags_func_ptr_type instead. * dwarf_init_finish.c: Add definition of _dwarf_get_elf_flags_func. 2016-09-23 David Anderson * gennames.c: gennames -t generated incorrect tables. gcc -fsanitize=address noticed out of bounds references in the generated code. The code has been wrong for quite a while. It's likely no one was using the table form, gennames -s is generally better to use anyway. * pro_frame.c: Was using strdup() and now uses _dwarf_p_get_alloc() and strcpy() so we do not leak a string. 2016-09-22 David Anderson * dwarf_abbrev.c: Was calling _dwarf_error() with NULL dbg when a real dbg was available. fixed. * dwarf_alloc.c: Was testing for the static DW_DLA_ERROR too late in dwarf_dealloc(). So the address sanitizer reported the erroneous address calculation that resulted. * dwarf_error.c,dwarf_error.h: Now DE_STANDARD,DE_STATIC,DE_MALLOC let dwarf_dealloc free up Dwarf_Error resources properly. 2016-09-22 David Anderson * dwarf_ranges.c: dwarf_get_ranges_a() was allocating at the wrong place and not freeing all it should. 2016-09-21 David Anderson * dwarf_errmsg_list.c,libdwarf.h.in: Added DW_DLE_LINE_TABLE_BAD. * dwarf_line_table_reader_common.c: Added tests to prevent running off end of line table. Second commit is fix 3 line indent error. 2016-09-21 David Anderson * configure.in: Support --enable-sanitize * configure: Regenerated. * dwarf_alloc.c: Rearrange DW_DLA_STRING check to avoid calculating and using an address that may not exist. And check earlier for a NULL dbg. * dwarf_die_deliv.c: Add offset and length checks to catch corrupt dwarf. * dwarf_errmsg_list.c: Add DW_DLE_LOCLIST_OFFSET_BAD error code. * dwarf_form.c: Delete three completely blank lines for consistency in formatting.. * dwarf_loc.c: Add offset and length checks to catch corrupt dwarf. Correct the initialization of loc_section_end in _dwarf_read_loc_section(). * dwarf_ranges.c: Add free() in two places to avoid memory leak. * dwarf_util.c: Add length error checks for DW_FORM_block* . Correct initialization of end_abbrev_ptr in _dwarf_get_abbrev_for_code(). * libdwarf.h.in: Add DW_DLE_LOCLIST_OFFSET_BAD. 2016-09-17 David Anderson * libdwarf.h.in: Added error code DW_DLE_SIBLING_LIST_IMPROPER. * dwarf_errmsg_list.c: Added DW_DLE_SIBLING_LIST_IMPROPER. * dwarf_die_deliv.c: Vulnerability DW201609-001. Added a check to catch invalid DWARF instead of reading a byte inappropriately (that might not even be addressable). The error code generated is DW_DLE_SIBLING_LIST_IMPROPER. 2016-09-15 David Anderson * configure.in: Add check for unistd.h . * configure: Regenerated. * gennames.c: Add HAVE_UNISTD_H check for the include of unistd.h. 2016-09-15 David Anderson * dwarf_elf_access.c: Depends on libelf.h, so if libelf.h is missing (as shown in the generated config.h) the compile stops with an error. 2016-09-15 David Anderson * libdwarf.h.in: New interface functions dwarf_producer_finish_a() and dwarf_add_die_to_debug_a() declared, providing libdwarf-standard int return value. * libdwarf2p.1.mm: Document dwarf_producer_finish_a() and dwarf_add_die_to_debug_a(). * libdwarf2p.1.pdf: Regenerated. Rev 1.45. * pro_init.c: Remove use of C99 type uint32_t and use DW_TSHASHTYPE instead. * pro_finish.c: Implement dwarf_producer_finish_a(). * pro_die.c: Implement dwarf_add_die_to_debug_a(). 2016-09-14 David Anderson * dwarf_dsc.h: Removed accidental typedef redeclaration of Dwarf_Dsc_Head: it is already in libdwarf.h and FreeBSD compiler complained. * pro_section.c: Removed trailing whitespace from three lines. Fixed indentation on one line. 2016-09-13 David Anderson * pro_section.c: new interface dwarf_get_section_bytes_a(). * libdwarf.h.in: Declaration for dwarf_get_section_bytes_a() added. * libdwarf2p.1.mm: Document dwarf_get_section_bytes_a(). * libdwarf2p.1.pdf: Regenerated. Rev 1.44. 2016-09-12 David Anderson * libdwarf.h.in: Declaring dwarf_new_die_a() and dwarf_die_link_a(). Renamed yesterday's new function dwarf_transform_to_disk_form_b() to dwarf_transform_to_disk_form_a() for consistency with the new dwarf_new_die_a(). * pro_die.c: Implementing dwarf_new_die_a() and dwarf_die_link_a() with easier to use error handling than dwarf_new_die() and dwarf_die_link(). * libdwarf2p.1.mm: Document the new and renamed *_a() functions. * libdwarf2p.1.pdf: Regenerated. Rev 1.43. 2016-09-11 David Anderson * dwarf_errmsg_list.c: Adding DW_DLE_LEB_OUT_ERROR. * libdwarf.h.in: Adding DW_DLE_LEB_OUT_ERROR and dwarf_transform_to_disk_form_b(), first steps to making type-safe producer functions. * libdwarf2p.1.mm: Document dwarf_transform_to_disk_form_b(). * libdwarf2p.1.pdf: Rev 1.42. * pro_arange.c: Altered internal interface to _dwarf_transform_arange_to_disk(). * pro_die.c: Altered internal error return to use DW_DLV_ERROR. * pro_macinfo.c,pro_macinfo.h: Altered internal interface to _dwarf_pro_transform_macro_info_to_disk(). * pro_section.c: Implemented dwarf_transform_to_disk_form_b() and changed internals to use DW_DLV_OK/DW_DLV_ERROR. Many places where errors were ignored now have checks for error. * pro_section.h: Added GET_CHUNK_ERR to return DW_DLV_ERROR on error. Altered internal function _dwarf_transform_arange_to_disk() and _dwarf_transform_simplename_to_disk() to the newer interface. * pro_types.h: Internal declaration of _dwarf_transform_simplename_to_disk() now uses the new interface. 2016-09-11 David Anderson * dwarf_dsc.c: Set the internal flag so we do not redo the leb decoding over and over. 2016-09-08 David Anderson * Makefile.in: Add dwarf_dsc.c to the build to access DW_AT_discr_list attributes. * dwarf.h: Added comment that DW_AT_discr_list is DWARF2. * dwarf_alloc.c, dwarf_alloc.h: Added DW_DLA_DSC_HEAD support. * dwarf_dsc.c: Implement the new discriminant list functions. * dwarf_dsc.h: Internal discriminant types. * libdwarf.h.in: A new opaque type and new functions dwarf_discr_list etc. * dwarf_errmsg_list.c: New error code for discriminants: DW_DLE_DISCR_ARRAY_ERROR. * checkexample.c: Added a new example. for dwarf_descr_list(). 2016-09-01 David Anderson * libdwarf2.1.mm: Improved the wording for dwarf_diename() and dwarf_die_text(). * libdwarf2.1.pdf: Regenerated as Version 2.51. 2016-08-28 David Anderson * libdwarf.h.in: Added dwarf_pro_get_string_stats() for producer library users to know how libdwarf handled DW_AT_name etc. * pro_die.c: Corrected the tsearch-related compare/hash functions to work correctly. * pro_finish.c: Implements dwarf_pro_get_string_stats(). * pro_init.c: Hash function for tsearch implemented correctly now. * pro_opaque.h: Changed the hash data structure so it can work correctly. Added the statistics struct to the Dwarf_P_Debug structure. * libdwarf2p.1.mm: Documents dwarf_pro_get_string_stats(). * libdwarf2p.1.pdf: Revision 1.41. Regenerated. 2016-08-27 David Anderson * pro_section.c, pro_reloc_stream.c: In a couple of places names were shadowing other names. Fixed. No change in functionality. 2016-08-25 David Anderson * libdwarf.h.in: Added new error code relating to DW_FORM_strp relocations. * dwarf_errmsg_list.c: Added DW_DLE_DEBUGSTR_UNEXPECTED_REL string. * pro_die.c: Added a comment related to DW_FORM_strp. * pro_opaque.h: Added/modified commentary. * pro_section.c: Now sets the correct section symbol for relocations for strings in .debug_str. * pro_reloc.c: Added commentary, deleted blank lines. * pro_reloc_stream.c: Moved declarations to inner contexts where possible. Refined looping for clarity. 2016-08-23 David Anderson * libdwarf2p.1.mm: Document dwarf_pro_set_default_string_form. * libdwarf2p.1.pdf: Regenerated. Rev 1.40. 2016-08-23 David Anderson * dwarf_alloc.c,dwarf_frame.c: Remove trailing whitespace. * dwarf_errmsg_list.c: Has four new error codes to deal with emitting .debug_str from the producer. * gennames.c: Added 'static' to a static function to avoid compiler warnings. * libdwarf.h.in: Four new error codes. A new producer function: dwarf_pro_set_default_string_form() which causes debug_info strings to be emitted in .debug_str where that seems like it might save space. * pro_alloc.c: A new debug_str producer string hashtab free helper function to clean up the .debug_str hash table.. * pro_die.c: Now calls a single function to emit strings and can emit in either .debug_info or .debug_str. * pro_die.h: Declares _dwarf_pro_set_string_attr() now. * pro_forms.c: Some local variables are always initialized now at declaration point. Now uses common code to set up strings. * pro_init.c: Initializes debug_str hash table for strings And sets up the section properly. Defines the hashfunc. * pro_opaque.h: Fixes some spacing awkwardness. Adds .debug_str hash data and eliminates unused data. * pro_section.c: Now emits .debug_str when such is wanted. 2016-06-13 David Anderson * dwarf_alloc.c: Dwarf_Fde_s now has a destructor. * dwarf_frame.c,dwarf_frame.h: Now dwarf_get_fde_info_for_reg3 memoizes frame data making one pattern of use (from dwarfdump) much much faster. 2016-06-13 David Anderson * dwarf_frame.c: Revised some local assignments so we are sure the same value used as intended. Added some {} on if for consistency with libdwarf use. * gennames.c: Update version string. 2016-06-12 David Anderson * libdwarf/gennames.c: Update version string. 2016-06-12 David Anderson * dwarf_frame.c: Adding dwarf_get_fde_info_for_cfa_reg3_b() which lets dwarfdump print frame data a bit more quickly. It is unclear whether other applications will find this new interface to be of value. * dwarf_frame.h,dwarf_frame3.c: Internal interfaces changed slightly to allow the new function to work. * libdwarf.h.in: Added dwarf_get_fde_info_for_cfa_reg3_b() declaration. * libdwarf2.1.mm: Documents dwarf_get_fde_info_for_cfa_reg3_b(). Rev.2.50 * libdwarf2.1.pdf: Regenerated. 2016-06-08 David Anderson * dwarf_init_finish.c, dwarf_line_table_reader_common.c: Remove trailing whitespace. Fix one indent. 2016-06-08 David Anderson * gennames.c: Update version string. 2016-06-07 David Anderson * Makefile.in: Use $(SONAME) rather than libdwarf.so.1 whereever possible. 2016-06-01 David Anderson * Makefile.in: Tweaks for debian build compatibility. * gennames.c: Use DW_VERSION_DATE_STR instead of __DATE__ __TIME__ 2016-05-23 David Anderson * dwarf_errmsg_list.c, libdwarf.h.in: Added DW_DLE_COMPRESSED_EMPTY_SECTION. * dwarf_init_finish.c: If load_section gets DW_DLV_NO_ENTRY just return that. If requres-decompress but has no data call it a corrupt Elf section (given what sections libdwarf is interested in). * dwarf_line_table_reader_common.c: Only deal with line table format entries if the count is > 0. 2016-05-23 David Anderson * Makefile.in: add SONAME libdwarf.so.1 to dynamic section when building shared libdwarf.so We have not made an incompatible interface change since May 19, 2014 (and that was to the producer code not to what DWARF readers use). 2016-05-22 David Anderson * libdwarf.h.in, dwarf_errmsg_list.c: Adding DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH error code. Fixed unsigned/signed comparison warning in the table test code. * dwarf_line.c: If we find a null pointer from include directores we substitute "" for the reader. * dwarf_line_table_reader_common.c: Detect a corrupted DWARF5 directory count vs directory format count problem and return an error. 2016-05-20 David Anderson * dwarf_macro5.c: Was failing to initialize mc_cu_context leading to coredump. If dwarf_srcfiles() returned zero as the count of source files an erroneous calloc() would result in an objection from valgrind: an erroneous calloc of zero bytes of srcfiles pointers would never be freed. 2016-05-19 David Anderson * Makefile.in: HOST_CFLAGS now references CFLAGS at the request of the Debian project. * configure.in: Now defaults to -fPIC always (though in a nonshared build one could reasonably turn it off with --disable-fpic) Adds several messages reporting configure actions. * configure: Regenerated. 2016-05-18 David Anderson * dwarf_form.c: Directly check expression length against section length in case expression length very very large. * dwarf_query.c: _dwarf_calculate_info_section_*() routines made clearer and the *_start_ptr() instance also now returns the length (via a pointer arg). * dwarf_xu_index.c: Check data read from the section so a wildly large columns count or slots count will be caught and an error returned. 2016-05-16 David Anderson * dwarf_elf_access.c: Check more thoroughly for corrupt relocation records and return an error if such found. * dwarf_macro5.c: Remove trailing whitespace. 2016-05-10 David Anderson * dwarf_arange.c,dwarf_die_deliv.c: All read operations check for overrun. * dwarf_errmsg_list.c: DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE, DW_DLE_LOCEXPR_OFF_SECTION_END, and DW_DLE_POINTER_SECTION_UNKNOWN added to error values. * dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_global.c,dwarf_line.c, dwarf_line_table_reader_common.c,dwarf_loc.c,dwarf_loc2.c, dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, dwarf_ranges.c,dwarf_util.c, dwarf_xu_index.c: All read operations check for overrun. * dwarf_opaque.h: Put the 4 SGI-only section data items next to each other to make it clear they are such. * dwarf_util.h: Added some checks to READ_AREA_LENGTH_CK * libdwarf.h.in: Defined the new error names. 2016-05-07-b David Anderson * libdwarf2.1.mm,libdwarf2p.1.mm: Fixed spelling errors. * libdwarf2.1.pdf,libdwarf2p.1.pdf: Regenerated. 2016-05-07 David Anderson * libdwarf.h.in, dwarf_errmsg_list.c: New error codes for stopping due to corrupted frame data. * dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_line.c: Notice frame area overrun and generate error. 2016-05-06 David Anderson * dwarf_errmsg_list.c: Added DW_DLE_ZLIB_SECTION_SHORT. * dwarf_form.c: Now checking for section overrun. * dwarf_init_finish.c: Now checking zlib reading for section overrun. * dwarf_macro5.c: Now checking for section overrun and also fixing double delete caused by having _dwarf_get_alloc() space pointing at other _dwarf_get_alloc() space. Because in case of error the order of free of such is unpredictable! * dwarf_macro5.h: Added comment on mc_srcfiles member. * libdwarf.h.in: Added DW_DLE_ZLIB_SECTION_SHORT. 2016-05-05 David Anderson * dwarf_form.c: Add a test so that a really large form_block length will not be considered safe (due to unsigned arithmetic overflow). Fixed the new check-code reading string offsets section so the endpoint in the check is that section, not debug_info. * dwarf_query.c: New function _dwarf_calculate_info_section_start_ptr() helps in some checking. * dwarf_util.h: Add a test so arithmetic overflow will not show a bogus value as being ok. * libdwarf.h.in,dwarf_errmsg_list.c: Add error code DW_DLE_FORM_BLOCK_LENGTH_ERROR so we have a specific error for this case. * dwarf_line.c: %lld switched to "%" DW_PR_DSd * dwarf_opaque.h: Added function declaration for _dwarf_calculate_info_section_start_ptr(). 2016-05-04 David Anderson * dwarf_macro5.c(construct_at_path_from_parts): Move 3 lines of code up to test for NULL pointer. So we do not dereference the pointer. 2016-05-03 David Anderson * dwarf_die_deliv.c: Add checks for overrun of end of section due to corrupted DWARF. * dwarf_arange.c,dwarf_util.c: first use of READ_UNALIGNED_CK. * dwarf_errmsg_list.c, libdwarf.h.in: DW_DLE_READ_LITTLEENDIAN_ERROR and DW_DLE_READ_BIGENDIAN_ERROR are errors possible in READ_UNALIGNED_CK. DW_DLE_LINE_OFFSET_WRONG_FORM gives a more meaningful description of a particular corruption problem (not a new test, just a new error name). * dwarf_elf_access.c: Add a check on relocations to ensure we do not write off the end of the section. * dwarf_query.c: Using local variables for shorter lines. * dwarf_util.h: Implement READ_UNALIGNED_CK macros. * dwarf_leb.c: Improve a couple comments. * dwarf_line.c: Now use DW_DLE_LINE_OFFSET_WRONG_FORM. Add operandmismatch() to get better debug information in case of corrupted dwarf. Revise the code for clarity. * dwarf_macro5.c: Duplicate free() could result if dwarf_finish() was used to clean up from a dwarf macro context. Two functions are really static so the function type set properly now. 2016-04-30 David Anderson * dwarf_frame.c, dwarf_line_table_reader_common.c, dwarf_loc2.c: switch to using DECODE_LEB*_CK. * dwarf_frame.c: Delete unused local variables. Use DECODE_LEB*_CK for better error checking. * dwarf_frame2.c, dwarf_frame.h: Internal functions get new arguments to support DECODE_LEB*_CK. * dwarf_arange.c: Using UNUSEDARG to suppress warning. * dwarf_line_table_reader_common.c: Use DECODE_LEB*_CK for better error checking. * dwarf_loc2.c: Use DECODE_LEB*_CK for better error checking. 2016-04-30 David Anderson * dwarf_die_deliv.c: Deleted unused local variable. * dwarf_form.c,dwarf_macro.c, dwarf_macro5.c: Now uses DCODE_LEB128*_CK nearly everywhere for better checking for corrupted data. * dwarf_opaque.h:New argument to _dwarf_get_addr_index_itself() for better data checks.. * dwarf_query.c: Uses revised _dwarf_get_addr_index_itself() interface. * dwarf_util.c: Fixed formatting errors. 2016-04-29 David Anderson * dwarf_line_table_reader_common.c, dwarf_macro.c, dwarf_macro5.c, dwarf_util.c, dwarf_util.h: Now use DECODE_LEB128_*CK macros simplifying the code while catching errors/corruption in DWARF data. 2016-04-28 David Anderson * dwarf_die_deliv.c: Now _dwarf_next_die_info_ptr() has a section length argument. * dwarf_query.c, dwarf_util.c: Now uses the checked version of leb reading. * dwarf_util.h: Now _dwarf_get_size_of_val() has section_end_ptr argument for checking leb values do not overrun end of section. 2016-04-27 David Anderson * dwarf_frame2.c: Now notices a frame-length field which is too large to be meaningful and returns an error.. 2016-04-27 David Anderson * Makefile.in: Now dwarf_error.o dependency on dwarf_errmsg_list.c is explicit. * dwarf_errmsg_list.c: New error strings. * libdwarf.h.in: New error values for when running off end of section and line range and address size where zero leads to trouble.. * dwarf_abbrev.c,dwarf_die_deliv.c, dwarf_frame.c, dwarf_frame.h, dwarf_frame2.c,dwarf_frame3.c,dwarf_leb.c, dwarf_line.c, dwarf_line.h, dwarf_line_table_reader_common.c, dwarf_query.c,dwarf_util.c,dwarf_util.h: Add checks for running off end of section. 2016-04-26 David Anderson * Makefile.in: The new errmsg_check dependency line was a bit wrong. libdwarf.h should not have $(srcdir) 2016-04-25 David Anderson * dwarf_errmsg_list.c: When -DTESTING ensure all the error messages have a value in () so we can check that value. 2016-04-25 David Anderson * dwarf_tied.c: A C11-ism crept in. Fixed. Added 'static' to local function declaration. Removed unused local variable. * dwarf_errmsg_list.c: Now checks that the number in () matches the index (and still checks that the array size is the declared size) when compiled -DTESTING. 2016-04-25 David Anderson * dwarf_errmsg_list.c: Fixed indent mistakes. * dwarf_leb.c: Fixed places were leb128_length was assumed non-null (dwarf_form.c passes NULL!). 2016-04-25 David Anderson * Makefile.in: Added testing of the _dwarf_errmsgs array. * dwarf_error.c: Moved _dwarf_errmsgs out of dwarf_error.c into dwarf_errmsg_list.c * dwarf_errmsg_list.c: Now has error strings and test code. 2016-04-25 David Anderson * dwarf_error.c: The error description "DW_DLE_GDB_INDEX_INDEX_ERROR(264)" was missing the comma so following errors were reporting the wrong string. 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-14 David Anderson * dwarf_util.c: Changed 'byte' to 'byte pair' in a comment. Where we read abbreviation AT/FORM lists. 2016-03-14 David Anderson * dwarf_error.c(_dwarf_errno): Now prints to stdout and does abort(1) when it has to give up. Instead of using stderr and abort(). It is not a good idea for applications to fail to provide error handling, so no one should notice this change. * libdwarf2.1.mm: Documents behavior in case there is no error handling provided by our caller. * libdwarf2.1.pdf: Regenerated. Rev 2.48. 2016-03-14 David Anderson * libdwarf2.1.mm: Documents Dwarf_Handler error handler function. * libdwarf2.1.pdf: Regenerated. Rev 2.47. 2016-03-13 David Anderson * dwarf_query.c: Use dwarf_formstring to read string attributes as it handles all the string types already. Now dwarf_diename() and dwarf_die_text() call dwarf_formstring() so DW_FORM_strp_sup and DW_FORM_GNU_strp_alt are properly handled(along with all the other string FORMs). * dwarf_form.c: Handle an error in dwarf_formstring() (for tied files, or the lack thereof) differently so it all works properly even if the incoming error argument is null. 2016-03-12 David Anderson * dwarf_abbrev.c: Uses renamed fields abbrev internal struct. Removes some gratuitous (). Adds clarifying {} * dwarf_abbrev.h: renames Dwarf_Abbrev_s struct fields from ab_tag to dab_tag, etc. Adds global section offset to the fields. * dwarf_die_deliv.c: Uses renamed Abbrev_List fields. Adds dwarf_die_abbrev_global_offset() function so clients can properly identify where an abbrev entry is in .debug_abbrev. * dwarf_die_deliv.h: renames Dwarf_Abbrev_List struct fields from ab_tag to abl_tag etc. Adds abl_goffset, abl_count. * dwarf_query.c,dwarf_util.c: Uses renamed Dwarf_Abbrev_List fields. * libdwarf.h.in: Adds function dwarf_die_abbrev_global_offset(). * libdwarf2.1.mm: Documents dwarf_die_abbrev_global_offset(). * libdwarf2.1.pdf: Regenerated. Rev 2.46. 2016-03-11 David Anderson * dwarf_die_deliv.c: Fixed issues with handling NULL Dwarf_Error* and with mistakes treating DW_DLV_NO_ENTRY as if it were DW_DLV_ERROR. * dwarf_form.c: Only do dwarf_errno(*error) when error is non-null. * dwarf_macro5.c, dwarf_query.c, dwarf_ranges.c: Avoid the possibility of doing dwarf_errno(*error) when error is null. * dwarf_util.c(_dwarf_error_mv_s_to_t): Added code to ensure that nothing crash-worthy happens even if a future internal caller calls it with one or more NULL arguments. * libdwarf2.1.mm: Added a few words about Error Handling in general to clarify earlier wording (earlier wording was not as explicit as it should have been). * libdwarf2.1.pdf: Regenerated. Version 2.45 * dwarf_sort_line.c: Though no longer built or used, added an initializer to a local variable for correctness. * dwarf_addr_finder.c: Though no longer compiled or used (is IRIX only), cleaned up local variable declarations that were not up to the current standard usage in libdwarf. 2016-03-11 David Anderson * Makefile.in: Added a comment about pr and pdf-building. 2016-03-09 David Anderson * libdwarf2.1.mm: Slightly altered the dwarf_offsets_list() documentation. * libdwarf2.1.pdf: Rev 2.44. Regenerated. 2016-03-09 David Anderson * dwarf_form.c: Correct and amplify a comment. 2016-03-01 David Anderson * libdwarf2.1.mm: Documented dwarf_dietype() and dwarf_offset_list(). * libdwarf2.1.pdf: Regenerated. Rev 2.43 * checkexamples.c: Added example for dwarf_offset_list(). 2016-02-19 Carlos Alberto Enciso * dwarf_alloc.h, dwarf_alloc.c, dwarf_base_types.h, dwarf_opaque.h: New allocator type (DW_DLA_CHAIN_2), to allow a list of addressed types (address, offset). There was Memory corruption due to incorrect usage of memory allocator type. * dwarf_query.c: Use the new allocator type. 2016-02-14 David Anderson * libdwarf2.1.mm: dwarf_exprloc -> dwarf_formexprloc. The spelling error was introduced in version 2.41. * libdwarf2.1.pdf: Regenerated. Version 2.42 2016-02-13 David Anderson * libdwarf2.1.mm: Added dwarf_lineoff_b() documentation. Fixed a typo in dwarf_formexprloc() documentation. * libdwarf2.1.pdf: Regenerated. Version 2.41 * Makefile.in: Add HOSTCFLAGS HOSTLDFLAGS HOSTCC to make it easier to cross-compile. Remove common.c, common.h (a few lines of code moved to gennames.c). * README: document use of HOSTCC * common.c,common.h: Delete. A few lines of code moved to gennames.c. * configure.in: for AC_TRY_RUN add [],[] for else and for cross-compile cases. * configure: Regenerated. * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_line.c, dwarf_macro5.c, dwarf_print_lines.c, dwarf_ranges.c: Renamed to avoid shadowing variables with same name. For clarity. * gennames.c: Incorporates a few lines from common.c so common.c, common.h can be deleted. 2016-02-10 David Anderson * README: Improved a comment about Dwarf_Obj_Access_Methods. * dwarf_elf_access.c: New function _dwarf_get_elf_flags_func() extracts the sh_flags field from Elf sections. In an odd way so we preserve binary and source compatibility.+ * dwarf_error.c,libdwarf.h.in: New error DW_DLE_ELF_FLAGS_NOT_AVAILABLE. * dwarf_init_finish.c: Use new (global) function pointer _dwarf_get_elf_flags_func_ptr to access extra Elf data without breaking compatibility. Add additional way (SHF_COMPRESSED) to detect zlib compression and expand the compressed data. 2016-02-08 David Anderson * dwarf_alloc.c: Drop VALTYPE, use DW_TSHASHTYPE instead. Use DW_TSHASHTYPE in the hash functions. * dwarf_tied.c: Use DW_TSHASHTYPE in the hash function. * dwarf_tsearchhash.c: Add back the UNUSEDARG to avoid unused argument warnings. 2016-02-07 David Anderson * dwarf_init_finish.c: Fix indents. remove a trailing space. * dwarf_tsearch.h,dwarf_tsearchhash.c: Now DW_TSHASHTYPE (if not defined otherwise) defines the type returned by the hash function used in tsearchhash. * pro_alloc.c: Removed trailing whitespace. 2016-02-07 David Anderson * README: Mention https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp * dwarf_init_finish.c: If SHT_RELA not defined define it as 4 in hopes that will not cause trouble for mingw. For Elf objects 4 is the correct value and is defined in elf.h 2016-02-06 David Anderson * dwarf_elf_access.c,dwarf_original_elf_init.c,dwarf_tsearchhash.c, libdwarfdefs.h: Remove trailing whitespace. 2016-02-06 David Anderson * configure.in: defines HAVE_UNUSED_ATTRIBUTE if the gcc '__attribute__ ((unused))' compiles ok. * config.h.in, configure: Regenerated. * libdwarfdefs.h: Test HAVE_UNUSED_ATTRIBUTE and define UNUSEDARG appropriately. * dwarf_alloc.c,dwarf_elf_access.c,dwarf_form.c,dwarf_frame2.c, dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, dwarf_line_table_reader_common.c,dwarf_macro5.c, dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_ranges.c, dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, pro_alloc.c,pro_frame.c,pro_init.c,pro_reloc.c, pro_reloc_stream.c,pro_section.c: Use UNUSEDARG to suppress meaningless unused-parameter warnings from gcc. 2016-02-06 David Anderson * dwarf_tsearchhash.c: The original default hash table size (a prime number) was very small. Now its closer to 100. 2016-02-06 David Anderson * dwarf_frame.h: Added fde_fd_eh_table_value. Added fde->fd_gnu_eh_aug_present so presence/absence is unambiguous. * dwarf_frame.c: Added code to set fd_eh_table_value when appropriate, though there is no interface for dwarfdump to get the value yet. * dwarf_frame2.c: Update the new fields appropriately. Corrected some comments about the eh_frame cie_id field. 2016-02-05 David Anderson * dwarf_frame2.c: Comments in get_cieptr_given_offset() were slightly incorrect and one calculation was pointlessly full of casts. Fixed commentary about the CIE_pointer (CIE id or FDE id) field in a frame header. * dwarf_loc2.c: Fixed compiler warning on signed/unsigned comparison by changing local variable int->Dwarf_Unsigned.. * pro_init.c: Removed extraneous semicolon to avoid warning for C90. 2016-01-26 David Anderson * dwarf_abbrev.c: Remove useless blank line. * dwarf_macro5.c: Add check for macro_import offset correctness. 2016-01-21 David Anderson * libdwarf.h.in: Typo, */* fixed to be * /* * configure.in: Added new gcc compiler options to --enable-wall. * configure: regenerated. * dwarf_die_deliv.c dwarf_frame.c,dwarf_frame2.c,dwarf_gdbindex.c, dwarf_gdbindex.h,dwarf_line.c,dwarf_line.h, dwarf_line_table_reader_common.c,dwarf_macro5.c,dwarf_query.c, dwarf_tsearchhash.c: Eliminated use of int/Dwarf_Signed in favor of unsigned types where signed served no purpose. Added ommitted return DW_DLV_NO_ERROR in dwarf_frame2.c. Other than 'unused parameter' fixed the warnings from gcc. No interfaces changed though. To keep binary compatibility. 2016-01-20 David Anderson * dwarf_query.c: New function dwarf_die_text() is a general way to get strings from various attributes in a DIE. * libdwarf.h.in: Add prototype for dwarf_die_text(). * libdwarf2.1.mm: Document dwarf_die_text(). * libdwarf2.1.pdf: Regenerated. Version 2.40. 2016-01-19 David Anderson * Makefile.in: Remove dwarf_stubs.o. * configure.in: Add various gcc opts to --enable-wall to get appropriate coverage. * configure: regenerated. * dwarf_macro5.c: File-local functions now declared static. * dwarf_query.c: File-local functions now declared static. * dwarf_stubs.c: No longer this function. It never had a prototype declaration and never had more than return DW_DLV_ERROR as an implementation. * dwarf_util.c: Remove trailing whitespace. * dwarf_original_elf_init.c(dwarf_set_tied_dbg): Added check for null dbg. * dwgetopt.c: Add include of dwgetopt.h. #if 0 a testing-only function. All functions prototyped, no (). * libdwarf.h.in: Comment out argument names for safety. Added dwarf_get_tied_dbg(), dwarf_dietype_offset(), dwarf_pubtype_type_die_offset() declarations. Sorted the dwarf_get_TAG_name() etc function names. * pro_alloc.c: Documented and commented a useless function, dwarf_p_dealloc(). . * pro_alloc.h: Prototyped both the useful and useless global-to-libdwarf producer functions _dwarf_p_dealloc and dwarf_p_dealloc. * libdwarf2.1.mm: Documented dwarf_get_tied_dbg(), dwarf_fde_section_offset(), and dwarf_cie_section_offset() * libdwarf2.1.pdf: Regenerated. Rev 2.39 2016-01-19 David Anderson * dwarf_form.c,dwarf_macro5.c: Ensure declarations before executable statements * dwarf_loc.c: Cast pointer to Dwarf_Small* so pointer arithmetic works (standard conformance). Ensure declarations before executable statements * dwarf_macro5.c: Ensure declarations before executable statements. * dwarf_query.c: Ensure declarations before executable statements. Add dwarf_dietype_offset() convenience function. * dwarf_util.c: Use a local name that does not conflict with standards. use mydw_errno, not errno. * dwarf_frame2.c(dwarf_read_cie_fde_prefix): Add tests to ensure we do not access past end of a section. 2016-01-19 David Anderson * dwarf_form.c, dwarf_frame2.c,: Fix indentation and trailing whitespace. 2016-01-19 David Anderson * dwarf_line.c, dwarf_line_table_reader_common.c, dwarf_loc.c, dwarf_macro5.c, dwarf_query.c, pro_die.c: Remove silly second ; from ;; where appropriate. 2016-01-19 David Anderson * libdwarf.h.in, dwarf_error.c: New error numbers. DW_DLE_LINE_STRP_OFFSET_BAD, DW_DLE_STRING_FORM_IMPROPER. * dwarf_form.c: Added suport for DW_FORM_line_strp into dwarf_form_string(). 2016-01-17 David Anderson * dwarf_frame2.c: Added additional checks for bad frame section. Looking for premature end of frame data. 2016-01-16 David Anderson * libdwarf2.1.mm: Documented DWARF5 macro operations. Version 2.38 * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.pdf: Regenerated following a trivial clarification on cie production made a couple days ago. 2016-01-15 David Anderson * pro_frame.h, pro_frame.c: The code adding a CIE for output (dwarf_add_frame_cie()) was simply assuming that the augmentation string passed in was in stable storage. Now it uses strdup() to guarantee there no surprises. 2016-01-14 David Anderson * dwarf_query.c(dwarf_die_offsets): 'res ==' corrected to 'res ='. 2016-01-12 David Anderson * dwarf_macro5.c: Fixed DW_MACRO_define/undef calls of _dwarf_check_string_valid(). Arranged to get the macro unit offset out when creating context. * libdwarf.h.in: Fixed declaration of dwarf_get_macro_context() to get the macro unit offset out of it so it can work properly in all contexts. libdwarf-20210528/libdwarf/dwarf_tsearchhash.c0000664000175000017500000004703714004647331016127 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch or any hashing code. An additional interface is added (compared to a real tsearch) to let the caller identify a 'hash' function with each hash table (called a tree below, but that is a misnomer). So read 'tree' below as hash table. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.4 This uses a hash based on the key. Collision resolution is by chaining. twalk() and tdestroy() walk in a random order. The 'preorder' etc labels mean nothing in a hash, so everything is called a leaf. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #ifdef HAVE_STDLIB_H #include "stdlib.h" /* for malloc, free() etc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include /* for printf() */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DUu "I64u" #else #define DW_PR_DUx "llx" #define DW_PR_DUu "llu" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* A table of primes used to size and resize the hash table. From public sources of prime numbers, arbitrarily chosen to approximately double in size at each step. */ static unsigned long primes[] = { #if 0 /* for testing only */ 5,11, 17,23, 31, 47, 53, #endif 79, 1009, 5591, 10007, 21839, 41413, 99907, 199967, 400009, 800029, 1600141, 3000089, 6000121, 12000257, 24000143, 48000203, 100000127, 200001611, 400000669, 800000573, 0 /* Here we are giving up */ }; static unsigned long allowed_fill_percent = 90; struct hs_base { unsigned long tablesize_; unsigned long tablesize_entry_index_; unsigned long allowed_fill_; /* Record_count means number of active records, counting all records on chains. When the record_count is > 90% of a full tablesize_ we redo the table before adding a new entry. */ unsigned long record_count_; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ struct ts_entry * hashtab_; DW_TSHASHTYPE (*hashfunc_)(const void *key); }; struct ts_entry { const void * keyptr; /* So that a keyptr of 0 (if added) is not confused with an empty hash slot, we must mark used slots as used in the hash tab */ unsigned char entryused; struct ts_entry *next; }; enum search_intent_t { want_insert, only_find, want_delete }; static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, struct ts_entry **parent_ptr); static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), int depth); /* A trivial integer-based percentage calculation. Percents >100 are reasonable for a hash-with-chains situation (even if they might not be the best choice for performance). */ static unsigned long calculate_allowed_fill(unsigned long fill_percent, unsigned long ct) { unsigned long v = 0; if (ct < 100000) { unsigned long v2 = (ct *fill_percent)/100; return v2; } v = (ct /100)*fill_percent; return v; } /* Initialize the hash and pass in the hash function. If the entry count needed is unknown, pass in 0 as a count estimate, but if the number of hash entries needed can be estimated, pass in the estimate (which need not be prime, we actually use the nearest higher prime from the above table). If the estimated count is Return the tree base, or return NULL if insufficient memory. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE(*hashfunc)(const void *key), unsigned long size_estimate) { unsigned long prime_to_use = primes[0]; unsigned entry_index = 0; unsigned k = 0; struct hs_base *base = 0; base = *(struct hs_base **)treeptr; if (base) { /* initalized already. */ return base ; } base = calloc(sizeof(struct hs_base),1); if (!base) { /* Out of memory. */ return NULL ; } prime_to_use = primes[0]; while(size_estimate && (size_estimate > prime_to_use)) { k = k +1; prime_to_use = primes[k]; if (prime_to_use == 0) { /* Oops. Too large. */ free(base); return NULL; } entry_index = k; } base->tablesize_ = prime_to_use; base->allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if (base->allowed_fill_< (base->tablesize_/2)) { free(base); /* Oops. We are in trouble. Coding mistake here. */ return NULL; } base->record_count_ = 0; base->tablesize_entry_index_ = entry_index; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ base->hashfunc_ = hashfunc; base->hashtab_ = calloc(sizeof(struct ts_entry),base->tablesize_); if (!base->hashtab_) { free(base); return NULL; } *treeptr = base; return base; } /* We don't really care whether hashpos or chainpos are 32 or 64 bits. 32 suffices. */ static void print_entry(struct ts_entry *t,const char *descr, char *(* keyprint)(const void *), unsigned long hashpos, unsigned long chainpos) { char *v = 0; if (!t->entryused) { return; } v = keyprint(t->keyptr); printf("[%4lu.%02lu] 0x%08" DW_PR_DUx " %s\n", hashpos,chainpos, (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, v, descr); } /* For debugging */ static void dumptree_inner(const struct hs_base *h, char *(* keyprint)(const void *), const char *descr, int printdetails) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; unsigned long hashused = 0; unsigned long maxchainlength = 0; unsigned long chainsgt1 = 0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " size %" DW_PR_DUu " entries %" DW_PR_DUu " allowed %" DW_PR_DUu " %s\n", (Dwarf_Unsigned)(uintptr_t)h, (Dwarf_Unsigned)h->tablesize_, (Dwarf_Unsigned)h->record_count_, (Dwarf_Unsigned)h->allowed_fill_, descr); for ( ; ix < tsize; ix++,p++) { unsigned long chainlength = 0; struct ts_entry*n = 0; int chainpos = 0; if (p->entryused) { ++hashused; chainlength = 1; if (printdetails) { print_entry(p,"head",keyprint,ix,chainpos); } } chainpos++; for (n = p->next; n ; n = n->next) { chainlength++; if (printdetails) { print_entry(n,"chain",keyprint,ix,chainpos); } } if (chainlength > maxchainlength) { maxchainlength = chainlength; } if (chainlength > 1) { chainsgt1++; } } printf("Hashtable: %lu of %lu hash entries used.\n", hashused,tsize); printf("Hashtable: %lu chains length longer than 1. \n", chainsgt1); printf("Hashtable: %lu is maximum chain length.\n", maxchainlength); } /* Dumping the tree. */ void dwarf_tdump(const void*headp_in, char *(* keyprint)(const void *), const char *msg) { const struct hs_base *head = (const struct hs_base *)headp_in; if (!head) { printf("dumptree null tree ptr : %s\n",msg); return; } dumptree_inner(head,keyprint,msg,1); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = 0; e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } e->keyptr = key; e->entryused = 1; e->next = 0; return e; } static void resize_table(struct hs_base *head, int (*compar)(const void *, const void *)) { struct hs_base newhead; unsigned new_entry_index = 0; unsigned long prime_to_use = 0; /* Copy the values we have. */ newhead = *head; /* But drop the hashtab_ from new. calloc below. */ newhead.hashtab_ = 0; newhead.record_count_ = 0; new_entry_index = head->tablesize_entry_index_ +1; prime_to_use = primes[new_entry_index]; if (!prime_to_use) { /* Oops, too large. Leave table size as is, though it will get slow as it overfills. */ return; } newhead.tablesize_ = prime_to_use; newhead.allowed_fill_ = calculate_allowed_fill( allowed_fill_percent, prime_to_use); if (newhead.allowed_fill_< (newhead.tablesize_/2)) { /* Oops. We are in trouble. */ return; } newhead.tablesize_entry_index_ = new_entry_index; newhead.hashtab_ = calloc(sizeof(struct ts_entry), newhead.tablesize_); if (!newhead.hashtab_) { /* Oops, too large. Leave table size as is, though things will get slow as it overfills. */ free(newhead.hashtab_); return; } { /* Insert all the records from the old table into the new table. */ int fillnewfail = 0; unsigned long ix = 0; unsigned long tsize = head->tablesize_; struct ts_entry *p = &head->hashtab_[0]; for ( ; ix < tsize; ix++,p++) { int inserted = 0; struct ts_entry*n = 0; if (fillnewfail) { break; } if (p->keyptr) { tsearch_inner(p->keyptr, &newhead,compar, want_insert, &inserted, 0); if (!inserted) { fillnewfail = 1; break; } } for (n = p->next; n ; n = n->next) { inserted = 0; tsearch_inner(n->keyptr, &newhead,compar, want_insert, &inserted, 0); if (!inserted) { fillnewfail = 1; break; } } } if (fillnewfail) { free(newhead.hashtab_); return; } } /* Now get rid of the chain entries of the old table. */ dwarf_tdestroy_inner(head,0,0); /* Now get rid of the old table itself. */ free(head->hashtab_); head->hashtab_ = 0; *head = newhead; return; } /* Inner search of the hash and synonym chains. */ static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, /* owner_ptr used for delete. Only set if the to-be-deleted item is on a chain, not in the hashtab. Points to the item pointing to the to-be-deleted-item.*/ struct ts_entry **owner_ptr) { struct ts_entry *s =0; struct ts_entry *c =0; struct ts_entry *q =0; int kc = 0; DW_TSHASHTYPE keyhash = 0; DW_TSHASHTYPE hindx = 0; struct ts_entry *chain_parent = 0; if (! head->hashfunc_) { /* Not fully initialized. */ return NULL; } keyhash = head->hashfunc_(key); if (intent == want_insert) { if (head->record_count_ > head->allowed_fill_) { resize_table(head,compar); } } hindx = keyhash%head->tablesize_; s = &head->hashtab_[hindx]; if (!s->entryused) { /* Not found. */ if (intent != want_insert) { return NULL; } /* Insert in the base hash table in an empty slot. */ *inserted = 1; head->record_count_++; s->keyptr = (const void *)key; s->entryused = 1; s->next = 0; return s; } kc = compar(key,s->keyptr); if (kc == 0 ) { /* found! */ if (want_delete) { *owner_ptr = 0; } return (void *)&(s->keyptr); } chain_parent = s; for (c = s->next; c; c = c->next) { kc = compar(key,c->keyptr); if (kc == 0 ) { /* found! */ if (want_delete) { *owner_ptr = chain_parent; } return (void *)&(c->keyptr); } chain_parent = c; } if (intent != want_insert) { return NULL; } /* Insert following head record of the chain. */ q = allocate_ts_entry(key); if (!q) { return q; } q->next = s->next; s->next = q; head->record_count_++; *inserted = 1; return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct hs_base **rootp = (struct hs_base **)headin; struct hs_base *head = *rootp; struct ts_entry *r = 0; int inserted = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!head) { /* something is wrong here, not initialized. */ return NULL; } r = tsearch_inner(key,head,compar,want_insert,&inserted,&nullme); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const *rootp, int (*compar)(const void *, const void *)) { /* Nothing will change, but we discard const so we can use tsearch_inner(). */ struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *r = 0; /* inserted flag won't be set. */ int inserted = 0; /* nullme won't be set. */ struct ts_entry * nullme = 0; /* Get to actual tree. */ if (!head) { return NULL; } r = tsearch_inner(key,head,compar,only_find,&inserted,&nullme); if (!r) { return NULL; } return (void *)(&(r->keyptr)); } /* Unlike the simple binary tree case, a fully-empty hash situation does not null the *rootp */ void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *found = 0; /* inserted flag won't be set. */ int inserted = 0; struct ts_entry * parentp = 0; if (!head) { return NULL; } found = tsearch_inner(key,head,compar,want_delete,&inserted, &parentp); if (found) { if (parentp) { /* Delete a chain entry. */ head->record_count_--; parentp->next = found->next; /* We free our storage. It would be up to caller to do a tfind to find a record and delete content if necessary. */ free(found); return (void *)&(parentp->keyptr); } /* So found is the head of a chain. */ if (found->next) { /* Delete a chain entry, pull up to hash tab, freeing up the chain entry. */ struct ts_entry *pullup = found->next; *found = *pullup; free(pullup); head->record_count_--; return (void *)&(found->keyptr); } else { /* Delete a main hash table entry. Problem: what the heck to return as a keyptr pointer? Well, we return NULL. As in the standard tsearch, returning NULL does not mean failure! Here it just means 'empty chain somewhere'. */ head->record_count_--; found->next = 0; found->keyptr = 0; found->entryused = 0; return NULL; } } return NULL; } static void dwarf_twalk_inner(const struct hs_base *h, struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth), UNUSEDARG unsigned level) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; for ( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; if (p->keyptr) { action((void *)(&(p->keyptr)),dwarf_leaf,level); } for (n = p->next; n ; n = n->next) { action((void *)(&(n->keyptr)),dwarf_leaf,level); } } } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth)) { const struct hs_base *head = (const struct hs_base *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->hashtab_; /* Get to actual tree. */ dwarf_twalk_inner(head,root,action,0); } static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), UNUSEDARG int depth) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; for ( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; struct ts_entry*prev = 0; if (p->keyptr && p->entryused) { if (free_node) { free_node((void *)(p->keyptr)); } --h->record_count_; } /* Now walk and free up the chain entries. */ for (n = p->next; n ; ) { if (free_node) { free_node((void *)(n->keyptr)); } --h->record_count_; prev = n; n = n->next; free(prev); } } } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct hs_base *head = (struct hs_base *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->hashtab_; dwarf_tdestroy_inner(head,free_node,0); free(root); free(head); } libdwarf-20210528/libdwarf/pro_reloc_stream.c0000664000175000017500000002114313764007262016001 00000000000000/* Copyright (C) 2000,2001,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2020 David Anderson, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef DWARF_WITH_LIBELF #include "libdwarfdefs.h" #include #ifdef HAVE_ELFACCESS_H #include #else /* Set r_info as defined by ELF generic ABI */ #define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t)) #define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t)) #endif #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_stream.h" /* Return DW_DLV_ERROR on malloc error or reltarget_length error. Return DW_DLV_OK otherwise */ /*ARGSUSED*/ int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { #if HAVE_ELF64_GETEHDR REL64 *elf64_reloc = 0; void *relrec_to_fill = 0; int res = 0; int rel_type = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; if (type == dwarf_drt_data_reloc) { if (reltarget_length == dbg->de_dwarf_offset_size) { rel_type = dbg->de_offset_reloc; } else if (reltarget_length == dbg->de_pointer_size) { rel_type = dbg->de_ptr_reloc; } else { return DW_DLV_ERROR; } } else if (type == dwarf_drt_segment_rel) { rel_type = dbg->de_exc_reloc; } else { /* We are in trouble: improper use of stream relocations. Someone else will diagnose */ rel_type = 0; } elf64_reloc = (REL64 *)relrec_to_fill; elf64_reloc->r_offset = offset; Set_REL64_info(*elf64_reloc, symidx, rel_type); return DW_DLV_OK; #else /* !HAVE_ELF64_GETEHDR */ return DW_DLV_ERROR; #endif /* #if HAVE_ELF64_GETEHDR */ } /* Return DW_DLV_ERROR on malloc error or reltarget_length error. Return DW_DLV_OK otherwise a binary reloc: 32bit ABI */ int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { REL32 *elf32_reloc = 0; void *relrec_to_fill = 0; int res = 0; int rel_type = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; if (type == dwarf_drt_data_reloc) { if (reltarget_length == dbg->de_dwarf_offset_size) { rel_type = dbg->de_offset_reloc; } else if (reltarget_length == dbg->de_pointer_size) { rel_type = dbg->de_ptr_reloc; } else { return DW_DLV_ERROR; } } else if (type == dwarf_drt_segment_rel) { rel_type = dbg->de_exc_reloc; } else { /* We are in trouble: improper use of stream relocations. Someone else will diagnose */ rel_type = 0; } elf32_reloc = (REL32*)relrec_to_fill; elf32_reloc->r_offset = (Elf32_Addr) offset; Set_REL32_info(*elf32_reloc, symidx, rel_type); return DW_DLV_OK; /* get a slot, fill in the slot entry */ } /* Return DW_DLV_OK. Never can really do anything: lengths cannot be represented as end-start in a stream. */ /*ARGSUSED*/ int _dwarf_pro_reloc_length_stream(UNUSEDARG Dwarf_P_Debug dbg, UNUSEDARG int base_sec_index, UNUSEDARG Dwarf_Unsigned offset, /* r_offset of reloc */ UNUSEDARG Dwarf_Unsigned start_symidx, UNUSEDARG Dwarf_Unsigned end_symidx, UNUSEDARG enum Dwarf_Rel_Type type, UNUSEDARG int reltarget_length) { /* get a slot, fill in the slot entry */ return DW_DLV_OK; } /* Ensure each stream is a single buffer and add that single buffer to the set of stream buffers. By creating a new buffer and copying if necessary. Free the input set of buffers if we consolidate. Return -1 on error (malloc failure) Return DW_DLV_OK on success. Any other return indicates malloc failed. */ int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { unsigned long total_size = 0; int i = 0; Dwarf_Error erre = 0; Dwarf_Error *error = &erre; Dwarf_Signed sec_count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect +i; Dwarf_Small *data = 0; int sec_index = 0; unsigned long ct = p_reloc->pr_reloc_total_count; unsigned len = 0; struct Dwarf_P_Relocation_Block_s *p_blk = 0; struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; Dwarf_P_Per_Reloc_Sect prb = 0; if (ct == 0) { continue; } prb = &dbg->de_reloc_sect[i]; len = dbg->de_relocation_record_size; ++sec_count; total_size = ct * len; sec_index = prb->pr_sect_num_of_reloc_sect; if (sec_index == 0) { /* Call de_callback_func or de_callback_func_b or _c, getting section number of reloc section. */ int rel_section_index = 0; Dwarf_Unsigned name_idx = 0; int erri = 0; if (dbg->de_callback_func) { rel_section_index = dbg->de_callback_func(_dwarf_rel_section_names[i], /* size */ dbg->de_relocation_record_size, /* type */ SHT_REL, /* flags */ 0, /* link to symtab, which we cannot know */ 0, /* info == link to sec rels apply to */ dbg->de_elf_sects[i], &name_idx, dbg->de_user_data, &erri); } if (rel_section_index == -1) { { _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR); return DW_DLV_ERROR; } } prb->pr_sect_num_of_reloc_sect = rel_section_index; sec_index = rel_section_index; } GET_CHUNK(dbg, sec_index, data, total_size, &erri); p_blk = p_reloc->pr_first_block; /* Following loop executes at least once. Effects the consolidation to a single block or, if already a single block, simply copies to the output buffer. And frees the input block. The new block is in the de_debug_sects list. */ while (p_blk) { unsigned long lenk = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, lenk); data += lenk; p_blk_last = p_blk; p_blk = p_blk->rb_next; _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } /* ASSERT: sum of len copied == total_size */ /* We have copied the input, now drop the pointers to it. For debugging, leave the other data untouched. */ p_reloc->pr_first_block = 0; p_reloc->pr_last_block = 0; } *new_sec_count = sec_count; return DW_DLV_OK; } #else /* DWARF_WITH_LIBELF */ /* avoids empty file warning if no libelf */ int dwarf_dummy_pro_reloc_stream = 2; #endif /* DWARF_WITH_LIBELF */ libdwarf-20210528/libdwarf/dwarf_print_lines.c0000664000175000017500000010763414051763356016170 00000000000000/* Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarfstring.h" #define PRINTING_DETAILS 1 /* for dwarfstring_constructor_static, saving lots of malloc and free but beware: make sure each routine using this DOES NOT call another routine using it. would be safer to have a buffer per function, but currently not necessary. */ static char locallinebuf[200]; static void print_line_header(Dwarf_Debug dbg, Dwarf_Bool is_single_tab, Dwarf_Bool is_actuals_tab) { if (!is_single_tab) { /* Ugly indenting follows, it makes lines shorter to see them better. Best to use a wider text window to really see how it looks.*/ if (is_actuals_tab) { _dwarf_printf(dbg,"\nActuals Table\n"); _dwarf_printf(dbg, " be\n" " ls\n" " ce\n" " section op kq\n" " offset code address/index row isa ??\n"); return; } else { _dwarf_printf(dbg,"\nLogicals Table\n"); _dwarf_printf(dbg, " " " s pe\n" " " " tirp\n" " " " msoi\n" " section op " " tall\n" " offset row code address/indx fil l" "ne col disc cntx subp ????\n"); return; } } /* Single level table */ _dwarf_printf(dbg, " " "s b e p e i d\n" " " "t l s r p s i\n" " " "m c e o i a s\n" " section op col " "t k q l l c\n" " offset code address file line umn ? ? ? ? ?\n" ); } /* End of function with ugly indenting. */ static void print_line_detail( Dwarf_Debug dbg, const char *prefix, int opcode, unsigned curr_line, struct Dwarf_Line_Registers_s * regs, Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table) { dwarfstring m1; dwarfstring_constructor_static(&m1,locallinebuf, sizeof(locallinebuf)); if (!is_single_table && is_actuals_table) { dwarfstring_append_printf_s(&m1,"%-15s ",(char *)prefix); dwarfstring_append_printf_i(&m1,"%3d ",opcode); dwarfstring_append_printf_u(&m1,"0x%" DW_PR_XZEROS DW_PR_DUx, regs->lr_address); dwarfstring_append_printf_u(&m1,"/%01u",regs->lr_op_index); dwarfstring_append_printf_u(&m1," %5lu", regs->lr_line); dwarfstring_append_printf_u(&m1," %3u",regs->lr_isa); dwarfstring_append_printf_i(&m1," %1d", regs->lr_basic_block); dwarfstring_append_printf_i(&m1,"%1d\n", regs->lr_end_sequence); _dwarf_printf(dbg,dwarfstring_string(&m1)); dwarfstring_destructor(&m1); return; } if (!is_single_table && !is_actuals_table) { dwarfstring_append_printf_i(&m1, "[%3d] " /* row number */, curr_line); dwarfstring_append_printf_s(&m1, "%-15s ",(char *)prefix); dwarfstring_append_printf_i(&m1, "%3d ",opcode); dwarfstring_append_printf_u(&m1, "x%" DW_PR_XZEROS DW_PR_DUx, regs->lr_address); dwarfstring_append_printf_u(&m1, "/%01u", regs->lr_op_index); dwarfstring_append_printf_u(&m1," %2lu ",regs->lr_file); dwarfstring_append_printf_u(&m1,"%4lu ",regs->lr_line); dwarfstring_append_printf_u(&m1,"%1lu",regs->lr_column); if (regs->lr_discriminator || regs->lr_prologue_end || regs->lr_epilogue_begin || regs->lr_isa || regs->lr_is_stmt || regs->lr_call_context || regs->lr_subprogram) { dwarfstring_append_printf_u(&m1, " x%02" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */ dwarfstring_append_printf_u(&m1, " x%02" DW_PR_DUx, regs->lr_call_context); /* EXPERIMENTAL */ dwarfstring_append_printf_u(&m1, " x%02" DW_PR_DUx , regs->lr_subprogram); /* EXPERIMENTAL */ dwarfstring_append_printf_i(&m1, " %1d", regs->lr_is_stmt); dwarfstring_append_printf_i(&m1, "%1d", (int) regs->lr_isa); dwarfstring_append_printf_i(&m1, "%1d", regs->lr_prologue_end); /* DWARF3 */ dwarfstring_append_printf_i(&m1, "%1d", regs->lr_epilogue_begin); /* DWARF3 */ } dwarfstring_append(&m1,"\n"); _dwarf_printf(dbg,dwarfstring_string(&m1)); dwarfstring_destructor(&m1); return; } /* In the first quoted line below: 3d looks better than 2d, but best to do that as separate change and test from two-level-line-tables. */ dwarfstring_append_printf_s(&m1, "%-15s ",(char *)prefix); dwarfstring_append_printf_i(&m1, "%2d ",opcode); dwarfstring_append_printf_u(&m1, "0x%" DW_PR_XZEROS DW_PR_DUx " ", regs->lr_address); dwarfstring_append_printf_u(&m1, "%2lu ", regs->lr_file); dwarfstring_append_printf_u(&m1, "%4lu ", regs->lr_line); dwarfstring_append_printf_u(&m1, "%2lu ", regs->lr_column); dwarfstring_append_printf_i(&m1, "%1d ",regs->lr_is_stmt); dwarfstring_append_printf_i(&m1, "%1d ", regs->lr_basic_block); dwarfstring_append_printf_i(&m1, "%1d",regs->lr_end_sequence); if (regs->lr_discriminator || regs->lr_prologue_end || regs->lr_epilogue_begin || regs->lr_isa) { dwarfstring_append_printf_i(&m1, " %1d", regs->lr_prologue_end); /* DWARF3 */ dwarfstring_append_printf_i(&m1, " %1d", regs->lr_epilogue_begin); /* DWARF3 */ dwarfstring_append_printf_i(&m1, " %1d", regs->lr_isa); /* DWARF3 */ dwarfstring_append_printf_u(&m1, " 0x%" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */ } dwarfstring_append(&m1, "\n"); _dwarf_printf(dbg,dwarfstring_string(&m1)); dwarfstring_destructor(&m1); } #include "dwarf_line_table_reader_common.h" static void print_include_directory_details(Dwarf_Debug dbg, unsigned int line_version, Dwarf_Line_Context line_context) { Dwarf_Unsigned u = 0; dwarfstring m4; Dwarf_Unsigned indexbase = 0; Dwarf_Unsigned indexlimit = 0; dwarfstring_constructor_static(&m4,locallinebuf, sizeof(locallinebuf)); if (line_version == DW_LINE_VERSION5) { unsigned i = 0; unsigned dfcount = line_context->lc_directory_entry_format_count; dwarfstring_constructor(&m4); dwarfstring_append_printf_u(&m4, " directory entry format count %u\n",dfcount); _dwarf_printf(dbg,dwarfstring_string(&m4)); dwarfstring_reset(&m4); for ( ; i < dfcount;++i) { struct Dwarf_Unsigned_Pair_s *valpair = 0; const char *tname = 0; const char *fname = 0; int res; valpair = line_context->lc_directory_format_values +i; dwarfstring_append_printf_u(&m4, " format [%2u] ",i); res = dwarf_get_LNCT_name(valpair->up_first, &tname); if ( res != DW_DLV_OK) { tname = ""; } dwarfstring_append_printf_u (&m4, " type 0x%" DW_PR_XZEROS DW_PR_DUx, valpair->up_first); dwarfstring_append_printf_s (&m4, " %-20s\n",(char *)tname); res = dwarf_get_FORM_name(valpair->up_second,&fname); if ( res != DW_DLV_OK) { fname = ""; } dwarfstring_append_printf_u(&m4, " code 0x%" DW_PR_XZEROS DW_PR_DUx , valpair->up_second); dwarfstring_append_printf_s(&m4, " %-20s\n", (char *)fname); _dwarf_printf(dbg,dwarfstring_string(&m4)); dwarfstring_reset(&m4); } } /* Common print of the directories. For DWARF 2,3,4 it has always started the indexing at 0 even though the directory index in line entries starts at 1 (zero meaning current directory at compile time). That is odd, given the non-dash-v printed starting at 1. So lets adjust for consistency. */ if (line_version == DW_LINE_VERSION5) { dwarfstring_append_printf_i(&m4, " include directories count %d\n", (int) line_context->lc_include_directories_count); } else { if (!line_context->lc_include_directories_count) { dwarfstring_append_printf_i(&m4, " include directories count %d\n", (int) line_context->lc_include_directories_count); } else { dwarfstring_append_printf_i(&m4, " include directories count %d" " (index starts at 1)\n", (int) line_context->lc_include_directories_count); } } _dwarf_printf(dbg,dwarfstring_string(&m4)); dwarfstring_reset(&m4); if (line_version == DW_LINE_VERSION5) { indexbase = 0; indexlimit = line_context->lc_include_directories_count; } else { indexbase = 1; indexlimit = 1 + line_context->lc_include_directories_count; } for (u = indexbase; u < indexlimit; ++u) { dwarfstring_append_printf_u(&m4, " include dir[%u] ",u); dwarfstring_append_printf_s(&m4, "%s\n",(char *) line_context->lc_include_directories[u-indexbase]); _dwarf_printf(dbg,dwarfstring_string(&m4)); dwarfstring_reset(&m4); } dwarfstring_destructor(&m4); } static void print_just_file_entry_details(Dwarf_Debug dbg, Dwarf_Line_Context line_context) { unsigned fiu = 0; Dwarf_File_Entry fe = line_context->lc_file_entries; Dwarf_File_Entry fe2 = fe; dwarfstring m3; unsigned increment = 1; if (line_context->lc_version_number == DW_LINE_VERSION5 ) { increment = 0; } dwarfstring_constructor_static(&m3,locallinebuf, sizeof(locallinebuf)); dwarfstring_append_printf_i(&m3, " file names count %d\n", line_context->lc_file_entry_count); _dwarf_printf(dbg,dwarfstring_string(&m3)); dwarfstring_reset(&m3); for (fiu = 0 ; fe2 ; fe2 = fe->fi_next,++fiu ) { Dwarf_Unsigned tlm2 = 0; unsigned filenum = 0; fe = fe2; tlm2 = fe->fi_time_last_mod; filenum = fiu+increment; /* The space character at the end of line is silly, but lets leave it there for the moment to avoid changing output. */ if (line_context->lc_file_entry_count > 9) { dwarfstring_append_printf_u(&m3, " file[%2u] ",fiu); } else { dwarfstring_append_printf_u(&m3, " file[%u] ", fiu); } /* DWARF5 can have a null fi_file_name if the format code in the line table header is unknown, such as in a corrupt object file. */ dwarfstring_append_printf_s(&m3, "%-20s ", fe->fi_file_name? (char *) fe->fi_file_name: ""); dwarfstring_append_printf_u(&m3, "(file-number: %u)\n", filenum); _dwarf_printf(dbg,dwarfstring_string(&m3)); dwarfstring_reset(&m3); if (fe->fi_dir_index_present) { Dwarf_Unsigned di = 0; di = fe->fi_dir_index; dwarfstring_append_printf_i(&m3, " dir index %d\n", di); } if (fe->fi_time_last_mod_present) { time_t tt = (time_t) tlm2; /* ctime supplies newline */ dwarfstring_append_printf_u(&m3, " last time 0x%x ",tlm2); dwarfstring_append(&m3,(char *)ctime(&tt)); } if (fe->fi_file_length_present) { Dwarf_Unsigned fl = 0; fl = fe->fi_file_length; dwarfstring_append_printf_i(&m3, " file length %ld ",fl); dwarfstring_append_printf_u(&m3, "0x%lx\n",fl); } if (fe->fi_md5_present) { char *c = (char *)&fe->fi_md5_value; char *end = c+sizeof(fe->fi_md5_value); dwarfstring_append(&m3, " file md5 value 0x"); while(c < end) { dwarfstring_append_printf_u(&m3, "%02x",0xff&*c); ++c; } dwarfstring_append(&m3,"\n"); } if (fe->fi_llvm_source) { dwarfstring_append_printf_s(&m3, "%-20s\n", (char *) fe->fi_llvm_source); } if (fe->fi_gnu_subprogram_name) { dwarfstring_append_printf_s(&m3, "%-20s\n", (char *) fe->fi_gnu_subprogram_name); } if (fe->fi_gnu_decl_file_present) { Dwarf_Unsigned di = 0; di = fe->fi_gnu_decl_file; dwarfstring_append_printf_i(&m3, " gnu decl file %d\n", di); } if (fe->fi_gnu_decl_line_present) { Dwarf_Unsigned di = 0; di = fe->fi_gnu_decl_line; dwarfstring_append_printf_i(&m3, " gnu decl line %d\n", di); } if (dwarfstring_strlen(&m3)) { _dwarf_printf(dbg,dwarfstring_string(&m3)); dwarfstring_reset(&m3); } } dwarfstring_destructor(&m3); } static void print_file_entry_details(Dwarf_Debug dbg, unsigned int line_version, Dwarf_Line_Context line_context) { dwarfstring m5; dwarfstring_constructor_static(&m5,locallinebuf, sizeof(locallinebuf)); if (line_version == DW_LINE_VERSION5) { unsigned i = 0; unsigned dfcount = line_context->lc_file_name_format_count; dwarfstring_append_printf_u(&m5, " file entry format count %u\n",dfcount); for ( ; i < dfcount;++i) { struct Dwarf_Unsigned_Pair_s *valpair = 0; const char *tname = 0; const char *fname = 0; int res; valpair = line_context->lc_file_format_values +i; dwarfstring_append_printf_u(&m5, " format [%2u] ",i); res = dwarf_get_LNCT_name(valpair->up_first,&tname); if ( res != DW_DLV_OK) { tname = ""; } dwarfstring_append_printf_u(&m5, " type 0x%" DW_PR_XZEROS DW_PR_DUx, valpair->up_first); dwarfstring_append_printf_s(&m5, " %-20s\n",(char *)tname); res = dwarf_get_FORM_name(valpair->up_second,&fname); if ( res != DW_DLV_OK) { fname = ""; } dwarfstring_append_printf_u(&m5, " code 0x%" DW_PR_XZEROS DW_PR_DUx, valpair->up_second); dwarfstring_append_printf_s(&m5, " %-20s\n", (char *)fname); _dwarf_printf(dbg,dwarfstring_string(&m5)); dwarfstring_reset(&m5); } dwarfstring_destructor(&m5); print_just_file_entry_details(dbg,line_context); } else { print_just_file_entry_details(dbg,line_context); dwarfstring_destructor(&m5); } } static void print_experimental_subprograms_list(Dwarf_Debug dbg, Dwarf_Line_Context line_context) { /* Print the subprograms list. */ Dwarf_Unsigned count = line_context->lc_subprogs_count; Dwarf_Unsigned exu = 0; Dwarf_Subprog_Entry sub = line_context->lc_subprogs; dwarfstring m6; dwarfstring_constructor_static(&m6,locallinebuf, sizeof(locallinebuf)); dwarfstring_append_printf_u(&m6, " subprograms count %" DW_PR_DUu "\n",count); if (count > 0) { dwarfstring_append(&m6," indx file line name\n"); } _dwarf_printf(dbg,dwarfstring_string(&m6)); dwarfstring_reset(&m6); for (exu = 0 ; exu < count ; exu++,sub++) { dwarfstring_append_printf_u(&m6, " [%2" DW_PR_DUu,exu+1); dwarfstring_append_printf_u(&m6, "] %4" DW_PR_DUu,sub->ds_decl_file); dwarfstring_append_printf_u(&m6, " %4" DW_PR_DUu ,sub->ds_decl_line); dwarfstring_append_printf_s(&m6, " %s\n",(char *)sub->ds_subprog_name); _dwarf_printf(dbg,dwarfstring_string(&m6)); dwarfstring_reset(&m6); } dwarfstring_destructor(&m6); } static void do_line_print_now(Dwarf_Debug dbg,int line_version, Dwarf_Small * comp_dir, Dwarf_Line_Context line_context) ; static void print_experimental_counts(Dwarf_Debug dbg, int line_version, Dwarf_Line_Context line_context); static int print_actuals_and_locals(Dwarf_Debug dbg, Dwarf_Line_Context line_context, Dwarf_Unsigned bogus_bytes_count, Dwarf_Small *bogus_bytes_ptr, Dwarf_Small *orig_line_ptr, Dwarf_Small *line_ptr, Dwarf_Small *section_start, Dwarf_Small *line_ptr_actuals, Dwarf_Small *line_ptr_end, Dwarf_Half address_size, int * err_count_out, Dwarf_Error *err); /* return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR If err_count_out is non-NULL, this is a special 'check' call. */ static int _dwarf_internal_printlines(Dwarf_Die die, int * err_count_out, int only_line_header, Dwarf_Error * error) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; Dwarf_Small *orig_line_ptr = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; /* Pointer to DW_AT_comp_dir attribute in die. */ Dwarf_Attribute comp_dir_attr = 0; /* Pointer to name of compilation directory. */ Dwarf_Small *comp_dir = NULL; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in bytes. */ Dwarf_Half attrform = 0; /* In case there are weird bytes 'after' the line table prologue this lets us print something. This is a gcc compiler bug and we expect the bytes count to be 12. */ Dwarf_Small* bogus_bytes_ptr = 0; Dwarf_Unsigned bogus_bytes_count = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned fission_offset = 0; unsigned line_version = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Line_Context line_context = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; int res = DW_DLV_ERROR; Dwarf_Small *line_ptr_actuals = 0; Dwarf_Small *line_ptr_end = 0; Dwarf_Small *section_start = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_line.dss_size) { return DW_DLV_NO_ENTRY; } address_size = _dwarf_get_address_size(dbg, die); resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } /* The list of relevant FORMs is small. DW_FORM_data4, DW_FORM_data8, DW_FORM_sec_offset */ lres = dwarf_whatform(stmt_list_attr,&attrform,error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR); return lres; } if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 && attrform != DW_FORM_sec_offset ) { dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } section_start = dbg->de_debug_line.dss_data; { Dwarf_Unsigned fission_size = 0; int resfis = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if (resfis != DW_DLV_OK) { dwarf_dealloc(dbg,stmt_list_attr, DW_DLA_ATTR); return resfis; } } orig_line_ptr = section_start + line_offset + fission_offset; line_ptr = orig_line_ptr; dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); /* If die has DW_AT_comp_dir attribute, get the string that names the compilation directory. */ resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *cdir = 0; cres = dwarf_formstring(comp_dir_attr, &cdir, error); if (cres == DW_DLV_ERROR) { return cres; } else if (cres == DW_DLV_OK) { comp_dir = (Dwarf_Small *) cdir; } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); } line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } { Dwarf_Small *newlinep = 0; int dres = _dwarf_read_line_table_header(dbg, cu_context, section_start, line_ptr, dbg->de_debug_line.dss_size, &newlinep, line_context, &bogus_bytes_ptr, &bogus_bytes_count, error, err_count_out); if (dres == DW_DLV_ERROR) { dwarf_srclines_dealloc_b(line_context); return dres; } if (dres == DW_DLV_NO_ENTRY) { dwarf_srclines_dealloc_b(line_context); return dres; } line_ptr_end = line_context->lc_line_ptr_end; line_ptr = newlinep; if (line_context->lc_actuals_table_offset > 0) { line_ptr_actuals = line_context->lc_line_prologue_start + line_context->lc_actuals_table_offset; } } line_version = line_context->lc_version_number; line_context->lc_compilation_directory = comp_dir; if (only_line_header) { /* Just checking for header errors, nothing more here.*/ dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } do_line_print_now(dbg,line_version,comp_dir,line_context); print_include_directory_details(dbg,line_version,line_context); print_file_entry_details(dbg,line_version,line_context); print_experimental_counts(dbg, line_version,line_context); res = print_actuals_and_locals(dbg, line_context, bogus_bytes_count,bogus_bytes_ptr, orig_line_ptr, line_ptr, section_start, line_ptr_actuals, line_ptr_end, address_size, err_count_out, error); if (res != DW_DLV_OK) { return res; } return DW_DLV_OK; } static void do_line_print_now(Dwarf_Debug dbg, int line_version, Dwarf_Small *comp_dir, Dwarf_Line_Context line_context) { dwarfstring m7; Dwarf_Unsigned i = 0; dwarfstring_constructor(&m7); dwarfstring_append_printf_i(&m7, "total line info length %ld bytes,", line_context->lc_total_length); dwarfstring_append_printf_u(&m7, " line offset 0x%" DW_PR_XZEROS DW_PR_DUx, line_context->lc_section_offset); dwarfstring_append_printf_u(&m7, " %" DW_PR_DUu "\n", line_context->lc_section_offset); if (line_version <= DW_LINE_VERSION5) { dwarfstring_append_printf_i(&m7, " line table version %d\n", (int) line_context->lc_version_number); } else { dwarfstring_append_printf_u(&m7, " line table version 0x%x\n", (int) line_context->lc_version_number); } if (line_version == DW_LINE_VERSION5) { dwarfstring_append_printf_i(&m7, " address size %d\n", line_context->lc_address_size); dwarfstring_append_printf_i(&m7, " segment selector size %d\n", line_context->lc_segment_selector_size); } _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); dwarfstring_append_printf_i(&m7, " line table length field length %d\n", line_context->lc_length_field_length); dwarfstring_append_printf_i(&m7, " prologue length %d\n", line_context->lc_prologue_length); dwarfstring_append_printf_s(&m7, " compilation_directory %s\n", comp_dir ? ((char *) comp_dir) : ""); dwarfstring_append_printf_i(&m7, " min instruction length %d\n", line_context->lc_minimum_instruction_length); _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); if (line_version == DW_LINE_VERSION5 || line_version == DW_LINE_VERSION4 || line_version == EXPERIMENTAL_LINE_TABLES_VERSION) { dwarfstring_append_printf_u(&m7, " maximum ops per instruction %u\n", line_context->lc_maximum_ops_per_instruction); _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); } if (line_version == EXPERIMENTAL_LINE_TABLES_VERSION) { dwarfstring_append_printf_u(&m7, " actuals table offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", line_context->lc_actuals_table_offset); dwarfstring_append_printf_u(&m7," logicals table offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", line_context->lc_logicals_table_offset); _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); } dwarfstring_append_printf_i(&m7, " default is stmt %d\n", (int)line_context->lc_default_is_stmt); dwarfstring_append_printf_i(&m7, " line base %d\n", (int)line_context->lc_line_base); dwarfstring_append_printf_i(&m7, " line_range %d\n", (int)line_context->lc_line_range); dwarfstring_append_printf_i(&m7, " opcode base %d\n", (int)line_context->lc_opcode_base); dwarfstring_append_printf_i(&m7, " standard opcode count %d\n", (int)line_context->lc_std_op_count); _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); for (i = 1; i < line_context->lc_opcode_base; i++) { dwarfstring_append_printf_i(&m7, " opcode[%2d] length", (int) i); dwarfstring_append_printf_i(&m7, " %d\n", (int) line_context->lc_opcode_length_table[i - 1]); _dwarf_printf(dbg,dwarfstring_string(&m7)); dwarfstring_reset(&m7); } dwarfstring_destructor(&m7); } static void print_experimental_counts(Dwarf_Debug dbg, int line_version, Dwarf_Line_Context line_context) { if (line_version == EXPERIMENTAL_LINE_TABLES_VERSION) { print_experimental_subprograms_list(dbg,line_context); } } static int print_actuals_and_locals(Dwarf_Debug dbg, Dwarf_Line_Context line_context, Dwarf_Unsigned bogus_bytes_count, Dwarf_Small *bogus_bytes_ptr, Dwarf_Small *orig_line_ptr, Dwarf_Small *line_ptr, Dwarf_Small *section_start, Dwarf_Small *line_ptr_actuals, Dwarf_Small *line_ptr_end, Dwarf_Half address_size, int * err_count_out, Dwarf_Error *error) { int res = 0; dwarfstring m8; Dwarf_Unsigned offset = 0; dwarfstring_constructor(&m8); if (bogus_bytes_count > 0) { Dwarf_Unsigned wcount = bogus_bytes_count; Dwarf_Unsigned boffset = bogus_bytes_ptr - section_start; dwarfstring_append_printf_u(&m8, "*** DWARF CHECK: the line table prologue header_length " " is %" DW_PR_DUu " too high, we pretend it is smaller.", wcount); dwarfstring_append_printf_u(&m8, "Section offset: 0x%" DW_PR_XZEROS DW_PR_DUx, boffset); dwarfstring_append_printf_u(&m8, " (%" DW_PR_DUu ") ***\n", boffset); *err_count_out += 1; } offset = line_ptr - section_start; dwarfstring_append_printf_u(&m8, " statement prog offset in section: 0x%" DW_PR_XZEROS DW_PR_DUx, offset); dwarfstring_append_printf_u(&m8, " (%" DW_PR_DUu ")\n", offset); _dwarf_printf(dbg,dwarfstring_string(&m8)); dwarfstring_reset(&m8); { Dwarf_Bool doaddrs = false; Dwarf_Bool dolines = true; if (!line_ptr_actuals) { /* Normal single level line table. */ Dwarf_Bool is_single_table = true; Dwarf_Bool is_actuals_table = false; print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error, err_count_out); if (res != DW_DLV_OK) { dwarfstring_destructor(&m8); dwarf_srclines_dealloc_b(line_context); return res; } } else { Dwarf_Bool is_single_table = false; Dwarf_Bool is_actuals_table = false; if (line_context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) { dwarf_srclines_dealloc_b(line_context); dwarfstring_destructor(&m8); _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } /* Read Logicals */ print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr, line_ptr_actuals, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error,err_count_out); if (res != DW_DLV_OK) { dwarfstring_destructor(&m8); dwarf_srclines_dealloc_b(line_context); return res; } if (line_context->lc_actuals_table_offset > 0) { is_actuals_table = true; /* Read Actuals */ print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr_actuals, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error, err_count_out); if (res != DW_DLV_OK) { dwarfstring_destructor(&m8); dwarf_srclines_dealloc_b(line_context); return res; } } } } dwarfstring_destructor(&m8); dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } /* This is support for dwarfdump: making it possible for clients wanting line detail info on stdout to get that detail without including internal libdwarf header information. Caller passes in compilation unit DIE. The _dwarf_ version is obsolete (though supported for compatibility). The dwarf_ version is preferred. The functions are intentionally identical: having _dwarf_print_lines call dwarf_print_lines might better emphasize they are intentionally identical, but that seemed slightly silly given how short the functions are. Interface adds error_count (output value) February 2009. These *print_lines() functions print two-level tables in full even when the user is not asking for both (ie, when the caller asked for dwarf_srclines(). It was an accident, but after a short reflection this seems like a good idea for -vvv. */ int dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error, int *error_count) { int only_line_header = 0; int res = _dwarf_internal_printlines(die, error_count, only_line_header,error); return res; } int _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) { int only_line_header = 0; int err_count = 0; int res = _dwarf_internal_printlines(die, &err_count, only_line_header,error); /* No way to get error count back in this interface */ return res; } /* The check is in case we are not printing full line data, this gets some of the issues noted with .debug_line, but not all. Call dwarf_print_lines() to get all issues. Intended for apps like dwarfdump. dwarf_check_lineheader_b() new 14 April 2020. */ int dwarf_check_lineheader_b(Dwarf_Die die, int *err_count_out, Dwarf_Error *err) { int res = 0; int only_line_header = 1; res = _dwarf_internal_printlines(die,err_count_out, only_line_header,err); return res; } /* This is ugly, no way to detect errors. They get ignored. see dwarf_check_lineheader_b() above. */ void dwarf_check_lineheader(Dwarf_Die die, int *err_count_out) { int res = 0; Dwarf_Error err = 0; int only_line_header = 1; res = _dwarf_internal_printlines(die,err_count_out, only_line_header,&err); if (res == DW_DLV_ERROR) { Dwarf_CU_Context c = 0; Dwarf_Debug dbg = 0; c = die->di_cu_context; if (!c) { return; } dbg = c->cc_dbg; dwarf_dealloc(dbg,err,DW_DLA_ERROR); err = 0; } } libdwarf-20210528/libdwarf/dwarf_machoread.c0000664000175000017500000007414313764007262015560 00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of an Apple mach-o object file appropriate to reading DWARF debugging data. Overview: _dwarf_macho_setup() Does all macho setup. calls _dwarf_macho_access_init() calls _dwarf_macho_object_access_internals_init() Creates internals record 'M', dwarf_macho_object_access_internals_t Sets flags/data in internals record Loads macho object data needed later. Sets methods struct to access macho object. calls _dwarf_object_init_b() Creates Dwarf_Debug, independent of any macho code. Sets internals record into dbg. ---------------------- _dwarf_destruct_macho_access(). This frees the macho internals record created in _dwarf_macho_object_access_internals_init() in case of errors during setup or when dwarf_finish() is called. Works safely for partially or fully set-up macho internals record. Other than in _dwarf_macho_setup() the macho code knows nothing about Dwarf_Debug, and the rest of libdwarf knows nothing about the content of the macho internals record. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* open() */ #endif /* HAVE_SYS_STAT_H */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_machoread.h" #include "dwarf_object_detector.h" #include "dwarf_macho_loader.h" #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* MACH-O and dwarf section names */ static struct macho_sect_names_s { char const *ms_moname; char const *ms_dwname; } const SectionNames [] = { { "", "" }, /* ELF index-0 entry */ { "__debug_abbrev", ".debug_abbrev" }, { "__debug_aranges", ".debug_aranges" }, { "__debug_frame", ".debug_frame" }, { "__debug_info", ".debug_info" }, { "__debug_line", ".debug_line" }, { "__debug_macinfo", ".debug_macinfo" }, { "__debug_loc", ".debug_loc" }, { "__debug_pubnames", ".debug_pubnames" }, { "__debug_pubtypes", ".debug_pubtypes" }, { "__debug_str", ".debug_str" }, { "__debug_ranges", ".debug_ranges" }, { "__debug_macro", ".debug_macro" }, { "__debug_gdb_scri", ".debug_gdb_scripts" } }; static int _dwarf_macho_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static Dwarf_Endianness macho_get_byte_order (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_endian; } static Dwarf_Small macho_get_length_size (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_offsetsize/8; } static Dwarf_Small macho_get_pointer_size (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_pointersize/8; } static Dwarf_Unsigned macho_get_section_count (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_dwarf_sectioncount; } static int macho_get_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); if (section_index < macho->mo_dwarf_sectioncount) { struct generic_macho_section *sp = 0; sp = macho->mo_dwarf_sections + section_index; return_section->addr = 0; return_section->type = 0; return_section->size = sp->size; return_section->name = sp->dwarfsectname; return_section->link = 0; return_section->info = 0; return_section->entrysize = 0; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int macho_load_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); if (0 < section_index && section_index < macho->mo_dwarf_sectioncount) { int res = 0; struct generic_macho_section *sp = macho->mo_dwarf_sections + section_index; if (sp->loaded_data) { *return_data = sp->loaded_data; return DW_DLV_OK; } if (!sp->size) { return DW_DLV_NO_ENTRY; } if ((sp->size + sp->offset) > macho->mo_filesize) { *error = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } sp->loaded_data = malloc((size_t)sp->size); if (!sp->loaded_data) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(macho->mo_fd, sp->loaded_data, (off_t)sp->offset, (size_t)sp->size, (off_t)macho->mo_filesize, error); if (res != DW_DLV_OK) { free(sp->loaded_data); sp->loaded_data = 0; return res; } *return_data = sp->loaded_data; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } void _dwarf_destruct_macho_access( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_macho_object_access_internals_t *mp = 0; Dwarf_Unsigned i = 0; if (!aip) { return; } mp = (dwarf_macho_object_access_internals_t *)aip->object; if (mp->mo_destruct_close_fd) { close(mp->mo_fd); mp->mo_fd = -1; } if (mp->mo_commands){ free(mp->mo_commands); mp->mo_commands = 0; } if (mp->mo_segment_commands){ free(mp->mo_segment_commands); mp->mo_segment_commands = 0; } free((char *)mp->mo_path); if (mp->mo_dwarf_sections) { struct generic_macho_section *sp = 0; sp = mp->mo_dwarf_sections; for ( i=0; i < mp->mo_dwarf_sectioncount; ++i,++sp) { if (sp->loaded_data) { free(sp->loaded_data); sp->loaded_data = 0; } } free(mp->mo_dwarf_sections); mp->mo_dwarf_sections = 0; } free(mp); free(aip); return; } /* load_macho_header32(dwarf_macho_object_access_internals_t *mfp)*/ static int load_macho_header32(dwarf_macho_object_access_internals_t *mfp, int *errcode) { struct mach_header mh32; int res = 0; if (sizeof(mh32) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &mh32, 0, sizeof(mh32), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* Do not adjust endianness of magic, leave as-is. */ ASNAR(memcpy,mfp->mo_header.magic,mh32.magic); ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh32.cputype); ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype, mh32.cpusubtype); ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh32.filetype); ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh32.ncmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds, mh32.sizeofcmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh32.flags); mfp->mo_header.reserved = 0; mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; mfp->mo_command_start_offset = sizeof(mh32); return DW_DLV_OK; } /* load_macho_header64(dwarf_macho_object_access_internals_t *mfp) */ static int load_macho_header64(dwarf_macho_object_access_internals_t *mfp, int *errcode) { struct mach_header_64 mh64; int res = 0; if (sizeof(mh64) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &mh64, 0, sizeof(mh64), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* Do not adjust endianness of magic, leave as-is. */ ASNAR(memcpy,mfp->mo_header.magic,mh64.magic); ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh64.cputype); ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype, mh64.cpusubtype); ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh64.filetype); ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh64.ncmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds, mh64.sizeofcmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh64.flags); ASNAR(mfp->mo_copy_word,mfp->mo_header.reserved,mh64.reserved); mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; mfp->mo_command_start_offset = sizeof(mh64); return DW_DLV_OK; } int dwarf_load_macho_header(dwarf_macho_object_access_internals_t *mfp, int *errcode) { int res = 0; if (mfp->mo_offsetsize == 32) { res = load_macho_header32(mfp,errcode); } else if (mfp->mo_offsetsize == 64) { res = load_macho_header64(mfp,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int load_segment_command_content32( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_command *mmp, struct generic_macho_segment_command *msp, Dwarf_Unsigned mmpindex, int *errcode) { struct segment_command sc; int res = 0; Dwarf_Unsigned filesize = mfp->mo_filesize; Dwarf_Unsigned segoffset = mmp->offset_this_command; Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); if (mmp->offset_this_command > filesize || mmp->cmdsize > filesize || (mmp->cmdsize + mmp->offset_this_command) > filesize ) { *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), (off_t)filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); strncpy(msp->segname,sc.segname,16); msp->segname[15] =0; ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); if (msp->fileoff > mfp->mo_filesize || msp->filesize > mfp->mo_filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if ((msp->fileoff+msp->filesize ) > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); msp->macho_command_index = mmpindex; msp->sectionsoffset = afterseghdr; return DW_DLV_OK; } static int load_segment_command_content64( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_command *mmp, struct generic_macho_segment_command *msp, Dwarf_Unsigned mmpindex,int *errcode) { struct segment_command_64 sc; int res = 0; Dwarf_Unsigned filesize = mfp->mo_filesize; Dwarf_Unsigned segoffset = mmp->offset_this_command; Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); if (mmp->offset_this_command > filesize || mmp->cmdsize > filesize || (mmp->cmdsize + mmp->offset_this_command) > filesize ) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), (off_t)filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); strncpy(msp->segname,sc.segname,16); msp->segname[16] =0; ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); if (msp->fileoff > filesize || msp->filesize > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if ((msp->fileoff+msp->filesize ) > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); msp->macho_command_index = mmpindex; msp->sectionsoffset = afterseghdr; return DW_DLV_OK; } static int dwarf_macho_load_segment_commands( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned i = 0; struct generic_macho_command *mmp = 0; struct generic_macho_segment_command *msp = 0; if (mfp->mo_segment_count < 1) { return DW_DLV_OK; } mfp->mo_segment_commands = (struct generic_macho_segment_command *) calloc(sizeof(struct generic_macho_segment_command), (size_t)mfp->mo_segment_count); if (!mfp->mo_segment_commands) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mmp = mfp->mo_commands; msp = mfp->mo_segment_commands; for (i = 0 ; i < mfp->mo_command_count; ++i,++mmp) { unsigned cmd = (unsigned)mmp->cmd; int res = 0; if (cmd == LC_SEGMENT) { res = load_segment_command_content32(mfp,mmp,msp, i,errcode); ++msp; } else if (cmd == LC_SEGMENT_64) { res = load_segment_command_content64(mfp,mmp,msp, i,errcode); ++msp; } if (res != DW_DLV_OK) { return res; } } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details32( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi, int *errcode) { Dwarf_Unsigned seci = 0; Dwarf_Unsigned seccount = segp->nsects; Dwarf_Unsigned secalloc = seccount+1; Dwarf_Unsigned curoff = segp->sectionsoffset; Dwarf_Unsigned shdrlen = sizeof(struct section); struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( sizeof(struct generic_macho_section), (size_t)secalloc); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_OK; } mfp->mo_dwarf_sections = secs; mfp->mo_dwarf_sectioncount = secalloc; if ((curoff > mfp->mo_filesize) || (seccount > mfp->mo_filesize) || (curoff+(seccount*sizeof(struct section)) > mfp->mo_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } secs->offset_of_sec_rec = curoff; /* Leave 0 section all zeros except our offset, elf-like in a sense */ secs->dwarfsectname = ""; ++secs; seci = 1; for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { struct section mosec; int res = 0; res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } strncpy(secs->sectname,mosec.sectname,16); secs->sectname[16] = 0; strncpy(secs->segname,mosec.segname,16); secs->segname[16] = 0; ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); ASNAR(mfp->mo_copy_word,secs->size,mosec.size); ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); ASNAR(mfp->mo_copy_word,secs->align,mosec.align); ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); if (secs->offset > mfp->mo_filesize || secs->size > mfp->mo_filesize || (secs->offset+secs->size) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } secs->reserved1 = 0; secs->reserved2 = 0; secs->reserved3 = 0; secs->generic_segment_num = segi; secs->offset_of_sec_rec = curoff; } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details64( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi, int *errcode) { Dwarf_Unsigned seci = 0; Dwarf_Unsigned seccount = segp->nsects; Dwarf_Unsigned secalloc = seccount+1; Dwarf_Unsigned curoff = segp->sectionsoffset; Dwarf_Unsigned shdrlen = sizeof(struct section_64); struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( sizeof(struct generic_macho_section), (size_t)secalloc); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mfp->mo_dwarf_sections = secs; mfp->mo_dwarf_sectioncount = secalloc; secs->offset_of_sec_rec = curoff; /* Leave 0 section all zeros except our offset, elf-like in a sense */ secs->dwarfsectname = ""; ++secs; if ((curoff > mfp->mo_filesize) || (seccount > mfp->mo_filesize) || (curoff+(seccount*sizeof(struct section_64)) > mfp->mo_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } seci = 1; for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { int res = 0; struct section_64 mosec; res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } strncpy(secs->sectname,mosec.sectname,16); secs->sectname[16] = 0; strncpy(secs->segname,mosec.segname,16); secs->segname[16] = 0; ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); ASNAR(mfp->mo_copy_word,secs->size,mosec.size); ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); ASNAR(mfp->mo_copy_word,secs->align,mosec.align); ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); if (secs->offset > mfp->mo_filesize || secs->size > mfp->mo_filesize || (secs->offset+secs->size) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_OK; } secs->reserved1 = 0; secs->reserved2 = 0; secs->reserved3 = 0; secs->offset_of_sec_rec = curoff; secs->generic_segment_num = segi; } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi,int *errcode) { int res = 0; if (mfp->mo_offsetsize == 32) { res = dwarf_macho_load_dwarf_section_details32(mfp, segp,segi,errcode); } else if (mfp->mo_offsetsize == 64) { res = dwarf_macho_load_dwarf_section_details64(mfp, segp,segi,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int dwarf_macho_load_dwarf_sections( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned segi = 0; struct generic_macho_segment_command *segp = mfp->mo_segment_commands; for ( ; segi < mfp->mo_segment_count; ++segi,++segp) { int res = 0; if (strcmp(segp->segname,"__DWARF")) { continue; } /* Found DWARF, for now assume only one such. */ res = dwarf_macho_load_dwarf_section_details(mfp, segp,segi,errcode); return res; } return DW_DLV_OK; } /* Works the same, 32 or 64 bit */ int dwarf_load_macho_commands( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned cmdi = 0; Dwarf_Unsigned curoff = mfp->mo_command_start_offset; Dwarf_Unsigned cmdspace = 0; struct load_command mc; struct generic_macho_command *mcp = 0; unsigned segment_command_count = 0; int res = 0; if (mfp->mo_command_count >= mfp->mo_filesize) { /* corrupt object. */ *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } if ((curoff + mfp->mo_command_count * sizeof(mc)) >= mfp->mo_filesize) { /* corrupt object. */ *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } mfp->mo_commands = (struct generic_macho_command *) calloc( mfp->mo_command_count,sizeof(struct generic_macho_command)); if (!mfp->mo_commands) { /* out of memory */ *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mcp = mfp->mo_commands; for ( ; cmdi < mfp->mo_header.ncmds; ++cmdi,++mcp ) { res = RRMOA(mfp->mo_fd, &mc, (off_t)curoff, sizeof(mc), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,mcp->cmd,mc.cmd); ASNAR(mfp->mo_copy_word,mcp->cmdsize,mc.cmdsize); mcp->offset_this_command = curoff; curoff += mcp->cmdsize; cmdspace += mcp->cmdsize; if (mcp->cmdsize > mfp->mo_filesize || curoff > mfp->mo_filesize) { /* corrupt object */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if (mcp->cmd == LC_SEGMENT || mcp->cmd == LC_SEGMENT_64) { segment_command_count++; } } mfp->mo_segment_count = segment_command_count; res = dwarf_macho_load_segment_commands(mfp,errcode); if (res != DW_DLV_OK) { return res; } res = dwarf_macho_load_dwarf_sections(mfp,errcode); return res; } int _dwarf_macho_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_macho_object_access_internals_t *intfc = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_macho_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_macho_access(binary_interface); return res; } intfc = binary_interface->object; intfc->mo_path = strdup(true_path); return res; } static Dwarf_Obj_Access_Methods const macho_methods = { macho_get_section_info, macho_get_byte_order, macho_get_length_size, macho_get_pointer_size, macho_get_section_count, macho_load_section, /* We do not do macho relocations. dsym files do not require it. */ NULL }; /* On any error this frees internals argument. */ static int _dwarf_macho_object_access_internals_init( dwarf_macho_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_macho_object_access_internals_t * intfc = internals; Dwarf_Unsigned i = 0; struct generic_macho_section *sp = 0; struct Dwarf_Obj_Access_Interface_s *localdoas; int res = 0; /* Must malloc as _dwarf_destruct_macho_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); intfc->mo_ident[0] = 'M'; intfc->mo_ident[1] = '1'; intfc->mo_fd = fd; intfc->mo_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->mo_offsetsize = offsetsize; intfc->mo_pointersize = offsetsize; intfc->mo_filesize = filesize; intfc->mo_ftype = ftype; #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; intfc->mo_endian = DW_OBJECT_LSB; } else { intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; intfc->mo_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; intfc->mo_endian = DW_OBJECT_LSB; } else { intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; intfc->mo_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ res = dwarf_load_macho_header(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_macho_access(localdoas); return res; } /* Load sections */ res = dwarf_load_macho_commands(intfc,errcode); if (res != DW_DLV_OK) { localdoas->methods = 0; localdoas->object = intfc; _dwarf_destruct_macho_access(localdoas); return res; } sp = intfc->mo_dwarf_sections+1; for (i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) { int j = 1; int lim = sizeof(SectionNames)/sizeof(SectionNames[0]); sp->dwarfsectname = ""; for ( ; j < lim; ++j) { if (!strcmp(sp->sectname,SectionNames[j].ms_moname)) { sp->dwarfsectname = SectionNames[j].ms_dwname; break; } } } free(localdoas); return DW_DLV_OK; } static int _dwarf_macho_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_macho_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_macho_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_macho_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ /* *err is already set and the call freed internals. */ return DW_DLV_ERROR; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &macho_methods; *binary_interface = intfc; return DW_DLV_OK; } libdwarf-20210528/libdwarf/ChangeLog20100000664000175000017500000002177213644370703014363 000000000000002010-10-13 DavidAnderson * dwarf.h: Added DW_LANG_Go as 0x0015 per discussion on mailing list. 2010-09-29 DavidAnderson * README: Document that there is no install target and update some of the old references to postscript to refer to pdf. * Makefile.in: A dummy install target provided though it gets ignored by make. 2010-09-20 DavidAnderson * libdwarf/libdwarf.h: Added commentary about markers. * libdwarf/libdwarf2p.1.mm: Documented the marker calls. * libdwarf/libdwarf2p.1.pdf: Regeenerated, ver 1.29. 2010-06-30 DavidAnderson * dwarf.h: Add DW_ISA_ARM values for DW_LNS_set_isa. 2010-06-01 DavidAnderson * README: Document issues with building on MacOSX and how to deal with them. * Makefile.in: Added comment about ar -s for MacOSX users. * dwarf.h: Added comment about the gap in FORM number use just before 0x20. 2010-03-30 DavidAnderson * dwarf_frame2.c: Tightned up a harmless error message string and deleted an unused local variable. * dwarf_harmless.c: Detected more errors in the implementation and fixed them. * dwarf_elf_access.c: If EM_MIPS not defined, define it to 8, the standard value for EM_MIPS. Refine the rela relocations code for MIPS 64 BE vs LE. * dwarf_arange.h: Added new fields to properly represent segments in aranges as documented in DWARF4. * dwarf_arange.c: dwarf_get_aranges was thinking an entry with 0,0 (end of a set) was the end of the aranges for a CU. But that is not guaranteed by the DWARF standards, there can be multiple sets in one CU, see the standard, section 7.20 (DWARF2,3,4). Created local function, removing lots of duplicated code. Added some support for DWARF4 segment value in tuples. Added dwarf_get_arange_info_b() so all DWARF4 information can be retrieved by client code. * libdwarf.h: Aded new interface dwarf_get_arange_info_b(), 2010-03-28 DavidAnderson * libdwarf.h: Adding dwarf_get_harmless_error_list(), dwarf_insert_harmless_error(), and dwarf_set_harmless_error_list_size() functions. Some errors that are detectable are not sufficient to warrant rejecting an object or refusing to process it. * dwarf_harmless.c: Implementing the harmless error functions. * dwarf_harmless.h: Declaration of the libdwarf_internal dwarf_harmless_init and dwarf_harmless_cleanout functions. * dwarf_error.c: Added DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE error string. * dwarf_util.h: Clarify some comments on READ_AREA_LENGTH macro. * dwarf_opaque.h: Add structure and field to record harmless errors for a dbg. * dwarf_frame.h: Add commentary. Change ci_length from Dwarf_Word to Dwarf_Unsigned for consistency with other such length fields. * Makefile.in: Add dwarf_harmless.o to the list of objects. * dwarf_alloc.c: Add call to dwarf_harmless_cleanout() on close of a dbg. * dwarf_init_finish.c: Add call to dwarf_harmless_init to initialize the fields for recording harmless errors. * dwarf_frame2.c: Add handling of Arm "armcc+" augmentation string. Create validate_length() local function to check that the fde/cie length matches the requirements of the specification, implementing the DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE test (a harmless error). Removed an earlier formally incorrect test. * libdwarf2.1.mm: Documented the harmless error calls. The version is now 1.90. * libdwarf2.1.pdf: Regenerated as 1.90. 2010-02-14 DavidAnderson * dwarf.h: Add GNU template defines. * libdwarf.h: Add new error code DW_DLE_NOT_REF_FORM for the DWARF 4 case where DW_FORM_data4/8 no longer valid global reference forms. * libdwarf2.1.mm: Document the manner that DW_OP_implicit_value is returned as a location description set. * libdwarf2.1.pdf: Regenerate. Rev 1.89. * dwarf_error.c: Add two new DW_DLE error strings. * dwarf_frame.h: define DW_DEBUG_FRAME_VERSION4 for DWARF4 support. Add address size and segment size fields to the internal CIE structure. * dwarf_query.c: The form-class code was not correct, DWARF4 has DW_FORM_sec_offset, not DWARF3. Some places did not use the CU context address size when reading an address. * dwarf_form.c: Use the CU-context address size instead of the overall object address/offset size. Initialize all local variables at the point of declaration. Refine some commentary. Use the CU version number to guide processing of some FORMs. * dwarf_print_lines.c, dwarf_query.c: Use the CU-context address size instead of the overall object address/offset size. Handle DW_LNE user extensions as well as possible. * dwarf_arange.c: Delete some erroneous code (already ifdefd out) as the address size need not match the de_pointer_size. If segment-selector non-zero, read it properly. DWARF2 and DWARF3 left this documented in an incorrect and unusable fashion (DWARF4 documents it properly). * dwarf_die_deliv.c: Delete erroneous code (previously ifdefd out) as the address size need not match the de_pointer_size. * dwarf_sort_line.c, dwarf_line.c: Deal with DW_DLE extended line operations past those defined by the standard (such as user-defined operations). * dwarf_line.h: For user-defined line extended operations, provide a sanity check of DW_LNE_LEN_MAX. * dwarf_base_types.h: Add DW_CIE_VERSION4 for DWARF4. Add other defines so each defined version number (sections differ) has a name for the relevant section. * dwarf_frame2.c: Add address size to argument lists so the proper CIE address size (a new field in DWARF4 CIEs) are honored. Also read the new DWARF4 segment_size field. Use the address size instead of the object-derived de_pointer_size. * dwarf_util.c: Return address_size instead of de_pointer_size. * dwarf_loc.c: DWARF4 uses DW_FORM_sec_offset, not DW_FORM_data4 or DW_FORM_data8 when specifying offsets to other sections. Add DWARF4 DW_OP_implicit_value and DW_OP_stack_value. * dwarf_frame.c: Initialize a local variable at the point of declaration. 2010-02-04 DavidAnderson * libdwarf2.1.mm: Fix a spelling error. * libdwarf2.1.mm: Regenerate. Rev 1.88. 2010-02-01 DavidAnderson * dwarf_frame.c: The DW_CFA_remember_state and DW_CFA_restore_state operations were not recording/restoring the cfa_rule, now they do. 2010-01-27 DavidAnderson * dwarf_form.c: form_refsig8() had an uninitialized local variable. 2010-01-25 DavidAnderson * libdwarf2.1.mm: Rev 1.87. Improved the discussion of frame information. * libdwarf2.1.pdf: regenerated. 2010-01-25 DavidAnderson * pro_opaque.h, pro_init.c, pro_section.c, pro_reloc_stream.c, pro_reloc_symbolic.c: Rename the function pointer members de_func and de_func_b to de_callback_func and de_callback_func_b respectively. 2010-01-17 DavidAnderson * dwarf.h, libdwarf.h: Updated commentary about frame interfaces. * libdwarf2.1.mm: New descriptions of DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3. Document rev 1.86 . * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Fixed a couple of typos. Rev 1.28. * libdwarf2p.1.pdf: Regenerated. * configure.in: Added support for configure --enable-oldframcol. * config.h.in: Added support for configure --enable-oldframcol. * dwarf_init_finish.c: Added support for configure --enable-oldframecol (see DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3). By default the frame column is now DW_FRAME_CFA_COL3. --enable-oldframecol changes the default to DW_FRAME_CFA_COL. * configure: Regenerated. * dwarf_opaque.h: Added one blank line and deleted one, hopefully aiding clarity. * dwarf_frame.c: Added commentary about the frame interfaces to emphasize the newer ones. 2010-01-13 DavidAnderson * dwarf_print_lines.c: Changed 'include files count' to 'files count'. 2010-01-04 DavidAnderson * pro_section.c, pro_opaque.h: A pretty-print tool generated some odd formatting (long ago) and there were silly blank lines present as well. This makes things more readable. 2010-01-03 DavidAnderson * common.h, common.c: Remove line end characters. Update copyright for 2010. * All other files: Update copyright year. libdwarf-20210528/libdwarf/test_dwarfstring.c0000664000175000017500000004040314047260266016033 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* for printf */ #include #include #include "dwarfstring.h" #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ static int errcount; static void check_string(const char *msg,char *exp, char *actual,int line) { if (!strcmp(exp,actual)) { printf("PASS got \"%s\" line %d\n",exp,line); return; } printf("FAIL %s expected \"%s\" got \"%s\" test line %d\n", msg,exp,actual,line); ++errcount; } static void check_value_i(const char *msg,unsigned long exp, unsigned long actual,int line) { if (exp == actual) { return; } printf("FAIL %s expected %lu got %lu test line %d\n", msg,exp,actual,line); ++errcount; } /* Checks the return value of the dwarfstring function. */ static void check_value(const char *msg,unsigned long exp, unsigned long actual,int line) { if (exp == actual) { return; } printf("FAIL %s return expected %lu got %lu test line %d\n", msg,exp,actual,line); ++errcount; } static int test1(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *bigstr = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbyyyybbbbbbbbbbbbccc"; char *mediumstr = "1234567890aaaaabbbbbb0123"; dwarfstring_constructor(&g); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); /* Caller coding error here, works no % but we call it TRUE anyway */ res = dwarfstring_append_printf_i(&g,"\nabc\n",54); check_value_i("expected TRUE ",FALSE,res,__LINE__); check_string("expected ",(char *)"\nabc\n" "", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); res = dwarfstring_append_printf_s(&g,"x%-15sy",mediumstr); check_value_i("expected TRUE ",TRUE,res,__LINE__); check_string("expected ",(char *)"x1234567890aaaaabbbbbb0123y", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); res = dwarfstring_append_printf_i(&g,"\nabc%d\n",54); check_value("expected TRUE ",TRUE,res,__LINE__); check_string("expected ",(char *)"\nabc54\n", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); res = dwarfstring_append_printf_i(&g,"\nabc%d\n",54); check_value("expected TRUE ",TRUE,res,__LINE__); check_string("expected ",(char *)"\nabc54\n", dwarfstring_string(&g),__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); res = dwarfstring_append_printf_i(&g,"\nabc%lld\n",-54); check_value("expected ok ",TRUE,res,__LINE__); check_string("expected ",(char *)"\nabc-54\n", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); /* in this call a %x is not allowed */ res = dwarfstring_append_printf_i(&g,"\nabc%x\n",-54); check_value("expected error ",FALSE,res,__LINE__); check_string("expected ", (char *)"\nabc", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); res = dwarfstring_append_printf_u(&g,"\nabc%x\n",-54); check_value("expected error ",FALSE,res,__LINE__); check_string("expected ",(char *)"\nabcffffffffffffffca\n", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); res = dwarfstring_append_printf_u(&g,"\nabc 0x%x\n",-54); check_value("expected error ",FALSE,res,__LINE__); check_string("expected ",(char *)"\nabc 0xffffffffffffffca\n", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); #if 0 res = dwarfstring_append_printf_i(&g,"\nabc%x\n",-54); check_value("expected error ",FALSE,res,__LINE__); check_string("expected ",(char *)"\nabc0xffffffffffffffca\n", dwarfstring_string(&g),__LINE__); dwarfstring_reset(&g); #endif res = dwarfstring_append(&g,"abc"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abc ",(char *)"abc",d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); res = dwarfstring_append(&g,"xy"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abcxy ",(char *)"xy",d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected bigstring ",bigstr,d,__LINE__); biglen = dwarfstring_strlen(&g); check_value("expected 120 ",strlen(bigstr),biglen,__LINE__); dwarfstring_append_length(&g,"xxyyzz",3); biglen = dwarfstring_strlen(&g); check_value("expected 123 ",strlen(bigstr)+3,biglen,__LINE__); dwarfstring_destructor(&g); return 0; } static int test2(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *bigstr = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbyyyybbbbbbbbbbbbccc"; dwarfstring_constructor_fixed(&g,10); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,"abc"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abc ",(char *)"abc",d,__LINE__); res = dwarfstring_append(&g,"xy"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abcxy ",(char *)"abcxy",d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor_fixed(&g,3); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected bigstring ",bigstr,d,__LINE__); biglen = dwarfstring_strlen(&g); check_value("expected 120 ",strlen(bigstr),biglen,__LINE__); dwarfstring_destructor(&g); return 0; } static int test3(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; char *bigstr = "a012345"; char *targetbigstr = "a012345xy"; dwarfstring_constructor_fixed(&g,10); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected a012345 ",(char *)bigstr,d,__LINE__); res = dwarfstring_append_length(&g,"xyzzz",2); check_value("expected TRUE ",TRUE,res,__LINE__); check_value("expected 9 ", 9,(unsigned)dwarfstring_strlen(&g), __LINE__); d = dwarfstring_string(&g); check_string("expected a012345xy ", (char *)targetbigstr,d,__LINE__); dwarfstring_destructor(&g); return 0; } static int test4(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; char *mystr = "a01234"; char *targetmystr = "a01234xyz"; char fixedarea[7]; dwarfstring_constructor_static(&g,fixedarea,sizeof(fixedarea)); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,mystr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected a01234 ",(char *)mystr,d,__LINE__); if (d != fixedarea) { printf(" FAIL reallocated but should not line %d ", __LINE__); ++errcount; } res = dwarfstring_append(&g,"xyz"); d = dwarfstring_string(&g); check_string("expected a01234xyz ",(char *)targetmystr, d,__LINE__); check_value("expected 9",9,dwarfstring_strlen(&g),__LINE__); if (d == fixedarea) { printf(" FAIL not reallocated but should be! line %d ", __LINE__); ++errcount; } dwarfstring_destructor(&g); return 0; } static int test5(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; unsigned long biglen = 0x654a; signed long lminus= -55; char *mystr = "a01234"; dwarfstring_constructor(&g); dwarfstring_append_printf_s(&g,"initialstring-%s-finalstring", mystr); d = dwarfstring_string(&g); expstr = "initialstring-a01234-finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"initialstring--0x%x-finalstring", biglen); d = dwarfstring_string(&g); expstr = "initialstring--0x654a-finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"initialstring: %d (", lminus); dwarfstring_append_printf_u(&g,"0x%08x) -finalstring", lminus); d = dwarfstring_string(&g); expstr = "initialstring: -55 (0xffffffffffffffc9) -finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"smallhex (0x%08x) -finalstring", biglen); d = dwarfstring_string(&g); expstr = "smallhex (0x0000654a) -finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"longlead (%08u) -end", 20); d = dwarfstring_string(&g); expstr = "longlead (00000020) -end"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); return 0; } static int test6(int tnum) { dwarfstring g; char *d = 0; const char *expstr = 0; dwarfstring_constructor(&g); dwarfstring_append(&g,0); d = dwarfstring_string(&g); expstr = ""; check_string("from append",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_s(&g,"%s",0); d = dwarfstring_string(&g); expstr=""; check_string("from _s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_s(&g,0,"abc"); d = dwarfstring_string(&g); expstr=""; check_string("from _s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,0,12); d = dwarfstring_string(&g); expstr= ""; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,0,12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"%s",12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"%x",12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"%Xx",12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"%llld",12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"%+-d",12); d = dwarfstring_string(&g); expstr=""; check_string("from _i",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,0,43); d = dwarfstring_string(&g); expstr=""; check_string("from _s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"aa%- bb",100); d = dwarfstring_string(&g); expstr="aa"; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"aa%s bb",77); d = dwarfstring_string(&g); expstr="aa"; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"aa%xXd ubb",77); d = dwarfstring_string(&g); expstr="aa"; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"aa%llld ubb",77); d = dwarfstring_string(&g); expstr="aa"; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"aa%ld ubb",77); d = dwarfstring_string(&g); expstr="aa"; check_string("from _u",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); return 0; } int main() { test1(1); test2(2); test3(3); test4(4); test5(5); test6(6); if (errcount) { exit(1); } exit(0); } libdwarf-20210528/libdwarf/pro_dnames.h0000664000175000017500000000520213763272400014571 00000000000000/* Copyright (C) 2018 David Anderson All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The numbers here are almost all 32 bits. Not long long ever. In the public function interfaces we'll use Dwarf_Unsigned though, for call consistency with everything else. Here we use Dwarf_Unsigned to avoid having to even know what is or is not 32 bits. */ typedef Dwarf_Unsigned dn_type; struct Dwarf_P_Dnames_Head_s { Dwarf_Unsigned dh_unit_length; unsigned dh_version; dn_type dh_comp_unit_count; dn_type dh_local_type_unit_count; dn_type dh_foreign_type_unit_count; dn_type dh_bucket_count; dn_type dh_name_count; dn_type dh_abbrev_table_size; dn_type dh_augmentation_string_size; const char * dh_augmentation_string; }; struct Dwarf_P_Dnames_uarray_s { dn_type dne_allocated; dn_type dne_used; dn_type *dne_values; }; struct Dwarf_P_Dnames_sarray_s { dn_type dne_allocated; dn_type dne_used; Dwarf_Sig8 *dne_values; }; struct Dwarf_P_Dnames_s { Dwarf_Small dn_create_section; struct Dwarf_P_Dnames_Head_s dn_header; struct Dwarf_P_Dnames_uarray_s dn_cunit_offset; struct Dwarf_P_Dnames_uarray_s dn_tunit_offset; struct Dwarf_P_Dnames_sarray_s dn_sunit_sigs; struct Dwarf_P_Dnames_uarray_s dn_buckets; /* Hashes count applies to string offsets and entry offsets arrays too. */ struct Dwarf_P_Dnames_uarray_s dn_hashes; struct Dwarf_P_Dnames_uarray_s dn_string_offsets; struct Dwarf_P_Dnames_uarray_s dn_entry_pool; Dwarf_Small *dn_index_entry_pool; Dwarf_Small dn_index_entry_pool_size; Dwarf_Small dn_index_entry_pool_used; }; libdwarf-20210528/libdwarf/dwarf_pubtypes.c0000664000175000017500000000707313764007262015506 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Reads DWARF3 .debug_pubtypes section. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" int dwarf_get_pubtypes(Dwarf_Debug dbg, Dwarf_Type ** types, Dwarf_Signed * ret_type_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_pubtypes,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_pubtypes.dss_size) { return DW_DLV_NO_ENTRY; } res = _dwarf_internal_get_pubnames_like_data(dbg, ".debug_pubtypes", dbg->de_debug_pubtypes.dss_data, dbg->de_debug_pubtypes.dss_size, (Dwarf_Global **) types, /* Type punning for sections with identical format. */ ret_type_count, error, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES, so use DW_DLA_GLOBAL. */ DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD, DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR); return res; } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count); return; } int dwarf_pubtypename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; if (type == NULL) { _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return DW_DLV_ERROR; } *ret_name = (char *) (type->gl_name); return DW_DLV_OK; } int dwarf_pubtype_type_die_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_die_offset(type, ret_offset, error); } int dwarf_pubtype_cu_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_cu_offset(type, ret_offset, error); } int dwarf_pubtype_name_offsets(Dwarf_Type type_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_name_offsets(type, returned_name, die_offset, cu_die_offset, error); } libdwarf-20210528/libdwarf/dwarf_debug_names.h0000664000175000017500000000671113701441253016100 00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Only 5 abbrev DW_IDX defined, we allow three user defined (arbitrarily) */ #define ABB_PAIRS_MAX 8 struct abbrev_pair_s { unsigned ap_index; unsigned ap_form; }; struct Dwarf_D_Abbrev_s { struct Dwarf_D_Abbrev_s * da_next; unsigned da_abbrev_code; unsigned da_tag; unsigned da_pairs_count; struct abbrev_pair_s da_pairs[ABB_PAIRS_MAX]; }; #define DWARF_DNAMES_VERSION5 5 struct Dwarf_Dnames_index_header_s { Dwarf_Debug din_dbg; struct Dwarf_Dnames_index_header_s *din_next; /* The .debug_names section offset of 1st byte of a header record. */ Dwarf_Unsigned din_section_offset; /* For offset and pointer sanity calculations. */ Dwarf_Small * din_indextable_data; Dwarf_Unsigned din_indextable_length; unsigned din_offset_size; Dwarf_Unsigned din_version; Dwarf_Unsigned din_comp_unit_count; Dwarf_Unsigned din_local_type_unit_count; Dwarf_Unsigned din_foreign_type_unit_count; Dwarf_Unsigned din_bucket_count; Dwarf_Unsigned din_name_count; Dwarf_Unsigned din_abbrev_table_size; /* bytes */ Dwarf_Unsigned din_entry_pool_size; /* bytes */ Dwarf_Unsigned din_augmentation_string_size; /* Since we cannot assume the string is NUL terminated we allocate a sufficient string space and NUL terminate the string. The DWARF5 standard does not specify it as null-terminated. We copy it into calloc area so not 'const' */ char * din_augmentation_string; Dwarf_Small * din_cu_list; Dwarf_Small * din_local_tu_list; Dwarf_Small * din_foreign_tu_list; Dwarf_Small * din_buckets; Dwarf_Small * din_hash_table; Dwarf_Small * din_string_offsets; Dwarf_Small * din_entry_offsets; Dwarf_Small * din_abbreviations; Dwarf_Small * din_entry_pool; unsigned din_abbrev_list_count; /* An array of size din_abbrev_list_count. */ struct Dwarf_D_Abbrev_s * din_abbrev_list; }; struct Dwarf_Dnames_Head_s { Dwarf_Debug dn_dbg; Dwarf_Small * dn_section_data; Dwarf_Small * dn_section_end; Dwarf_Unsigned dn_section_size; unsigned dn_inhdr_count; /* Becomes an array of these structs, dn_inhdr_count of them. */ struct Dwarf_Dnames_index_header_s * dn_inhdr_first; }; void _dwarf_debugnames_destructor(void *m); libdwarf-20210528/libdwarf/LIBDWARFCOPYRIGHT0000644000175000017500000000304513743575426014714 00000000000000 ====== Update January 31, 2015: The SGI postal address and oss.sgi.com address in the original copyright are no longer correct. So the final 8 lines of the original copyright have been deleted from the current copyright. ====== original copyright example. Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan libdwarf-20210528/libdwarf/dwarf_arange.c0000664000175000017500000006130514004665617015070 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_arange.h" #include "dwarf_global.h" /* for _dwarf_fixup_* */ #include "dwarfstring.h" static void free_aranges_chain(Dwarf_Debug dbg, Dwarf_Chain head) { Dwarf_Chain cur = head; Dwarf_Chain next = 0; if (!head) { return; } next = head->ch_next; for ( ;cur; cur = next) { void *item = cur->ch_item; int type = cur->ch_itemtype; next = cur->ch_next; if (item && type) { dwarf_dealloc(dbg,item,type); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); } } } /* Common code for two user-visible routines to share. Errors here result in memory leaks, but errors here are serious (making aranges unusable) so we assume callers will not repeat the error often or mind the leaks. */ static int dwarf_get_aranges_list(Dwarf_Debug dbg, Dwarf_Chain * chain_out, Dwarf_Signed * chain_count_out, Dwarf_Error * error) { /* Sweeps through the arange. */ Dwarf_Small *arange_ptr = 0; Dwarf_Small *arange_ptr_start = 0; /* Start of arange header. Used for rounding offset of arange_ptr to twice the tuple size. Libdwarf requirement. */ Dwarf_Small *header_ptr = 0; /* Version of .debug_aranges header. */ Dwarf_Unsigned version = 0; /* Offset of current set of aranges into .debug_info. */ Dwarf_Off info_offset = 0; /* Size in bytes of addresses in target. */ Dwarf_Small address_size = 0; /* Size in bytes of segment offsets in target. */ Dwarf_Small segment_size = 0; /* Count of total number of aranges. */ Dwarf_Signed arange_count = 0; Dwarf_Arange arange = 0; Dwarf_Unsigned section_size = 0; Dwarf_Byte_Ptr arange_end_section = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; if (!dbg->de_debug_aranges.dss_size) { return DW_DLV_NO_ENTRY; } arange_ptr = dbg->de_debug_aranges.dss_data; arange_ptr_start = arange_ptr; section_size = dbg->de_debug_aranges.dss_size; arange_end_section = arange_ptr + section_size; do { /* Length of current set of aranges. This is local length, which begins just after the length field itself. */ Dwarf_Unsigned area_length = 0; Dwarf_Small remainder = 0; Dwarf_Unsigned range_entry_size = 0; int local_length_size; int local_extension_size = 0; Dwarf_Small *end_this_arange = 0; int res = 0; header_ptr = arange_ptr; if (header_ptr >= arange_end_section) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } res = _dwarf_read_area_length_ck_wrapper(dbg,&area_length, &arange_ptr,&local_length_size,&local_extension_size, section_size,arange_end_section,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } /* arange_ptr has been incremented appropriately past the length field by READ_AREA_LENGTH. */ if (area_length > dbg->de_debug_aranges.dss_size) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if ((area_length + local_length_size + local_extension_size) > dbg->de_debug_aranges.dss_size) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } end_this_arange = arange_ptr + area_length; if (end_this_arange > arange_end_section) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if (!area_length) { /* We read 4 bytes of zero, so area-length zero. Keep scanning. First seen Nov 27, 2018 in GNU-cc in windows dll. */ continue; } res = _dwarf_read_unaligned_ck_wrapper(dbg,&version, arange_ptr,DWARF_HALF_SIZE,end_this_arange,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_ptr += DWARF_HALF_SIZE; if (arange_ptr >= end_this_arange) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if (version != DW_ARANGES_VERSION2) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } res = _dwarf_read_unaligned_ck_wrapper(dbg,&info_offset, arange_ptr,local_length_size,end_this_arange,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_ptr += local_length_size; if (arange_ptr >= end_this_arange) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } /* This applies to debug_info only, not to debug_types. */ if (info_offset >= dbg->de_debug_info.dss_size) { FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, "arange info offset.a"); if (info_offset >= dbg->de_debug_info.dss_size) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return DW_DLV_ERROR; } } address_size = *(Dwarf_Small *) arange_ptr; if (address_size > sizeof(Dwarf_Addr)) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); return DW_DLV_ERROR; } if (address_size == 0) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); return DW_DLV_ERROR; } /* It is not an error if the sizes differ. Unusual, but not an error. */ arange_ptr = arange_ptr + sizeof(Dwarf_Small); /* The following deref means we better check the pointer for off-end. */ if (arange_ptr >= end_this_arange) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return DW_DLV_ERROR; } /* Even DWARF2 had a segment_size field here, meaning size in bytes of a segment descriptor on the target system. */ segment_size = *(Dwarf_Small *) arange_ptr; if (segment_size > sizeof(Dwarf_Addr)) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); return DW_DLV_ERROR; } arange_ptr = arange_ptr + sizeof(Dwarf_Small); /* Code below will check for == end_this_arange as appropriate. */ if (arange_ptr > end_this_arange) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return DW_DLV_ERROR; } range_entry_size = 2*address_size + segment_size; /* Round arange_ptr offset to next multiple of address_size. */ remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % (range_entry_size); if (remainder != 0) { arange_ptr = arange_ptr + (2 * address_size) - remainder; } do { Dwarf_Addr range_address = 0; Dwarf_Unsigned segment_selector = 0; Dwarf_Unsigned range_length = 0; /* For segmented address spaces, the first field to read is a segment selector (new in DWARF4). The version number DID NOT CHANGE from 2, which is quite surprising. Also surprising since the segment_size was always there in the table header! */ /* We want to test cu_version here but currently with no way to do that. So we just hope no one using segment_selectors, really. FIXME */ if (segment_size) { /* Only applies if cu_version >= 4. */ res = _dwarf_read_unaligned_ck_wrapper(dbg, &segment_selector, arange_ptr,segment_size,end_this_arange,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_ptr += address_size; } res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_address, arange_ptr,address_size,end_this_arange,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_ptr += address_size; res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_length, arange_ptr,address_size,end_this_arange,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_ptr += address_size; { /* We used to suppress all-zero entries, but now we return all aranges entries so we show the entire content. March 31, 2010. */ arange = (Dwarf_Arange) _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); if (arange == NULL) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } arange->ar_segment_selector = segment_selector; arange->ar_segment_selector_size = segment_size; arange->ar_address = range_address; arange->ar_length = range_length; arange->ar_info_offset = info_offset; arange->ar_dbg = dbg; arange_count++; curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_chain->ch_item = arange; curr_chain->ch_itemtype = DW_DLA_ARANGE; if (head_chain == NULL) head_chain = prev_chain = curr_chain; else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } /* The current set of ranges is terminated by range_address 0 and range_length 0, but that does not necessarily terminate the ranges for this CU! There can be multiple sets in that DWARF does not explicitly forbid multiple sets. DWARF2,3,4 section 7.20 We stop short to avoid overrun of the end of the CU. */ } while (end_this_arange >= (arange_ptr + range_entry_size)); /* A compiler could emit some padding bytes here. dwarf2/3 (dwarf4 sec 7.20) does not clearly make extra padding bytes illegal. */ if (end_this_arange < arange_ptr) { Dwarf_Unsigned pad_count = arange_ptr - end_this_arange; Dwarf_Unsigned offset = arange_ptr - arange_ptr_start; dwarfstring aramsg; dwarfstring_constructor(&aramsg); /* Safe. Length strictly limited. */ dwarfstring_append_printf_u(&aramsg, "DW_DLE_ARANGE_LENGTH_BAD." " 0x%" DW_PR_XZEROS DW_PR_DUx, pad_count); dwarfstring_append_printf_u(&aramsg, " pad bytes at offset 0x%" DW_PR_XZEROS DW_PR_DUx " in .debug_aranges", offset); dwarf_insert_harmless_error(dbg, dwarfstring_string(&aramsg)); dwarfstring_destructor(&aramsg); } /* For most compilers, arange_ptr == end_this_arange at this point. But not if there were padding bytes */ arange_ptr = end_this_arange; } while (arange_ptr < arange_end_section); if (arange_ptr != arange_end_section) { free_aranges_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); return DW_DLV_ERROR; } *chain_out = head_chain; *chain_count_out = arange_count; return DW_DLV_OK; } /* This function returns the count of the number of aranges in the .debug_aranges section. It sets aranges to point to a block of Dwarf_Arange's describing the arange's. It returns DW_DLV_ERROR on error. Must be identical in most aspects to dwarf_get_aranges_addr_offsets! */ int dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange ** aranges, Dwarf_Signed * returned_count, Dwarf_Error * error) { /* Count of total number of aranges. */ Dwarf_Signed arange_count = 0; Dwarf_Arange *arange_block = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Signed i = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error); if (res != DW_DLV_OK) { return res; } /* aranges points in to info, so if info needs expanding we have to load it. */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { free_aranges_chain(dbg,head_chain); return res; } arange_block = (Dwarf_Arange *) _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); if (arange_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); free_aranges_chain(dbg,head_chain); return DW_DLV_ERROR; } /* See also free_aranges_chain() above */ curr_chain = head_chain; for (i = 0; i < arange_count; i++) { /* Copies pointers. No dealloc of ch_item, */ *(arange_block + i) = curr_chain->ch_item; curr_chain->ch_item = 0; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } *aranges = arange_block; *returned_count = (arange_count); return DW_DLV_OK; } /* This function returns DW_DLV_OK if it succeeds and DW_DLV_ERR or DW_DLV_OK otherwise. count is set to the number of addresses in the .debug_aranges section. For each address, the corresponding element in an array is set to the address itself(aranges) and the section offset (offsets). Must be identical in most aspects to dwarf_get_aranges! */ int _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrs, Dwarf_Off ** offsets, Dwarf_Signed * count, Dwarf_Error * error) { Dwarf_Signed i = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Signed arange_count = 0; Dwarf_Addr *arange_addrs = 0; Dwarf_Off *arange_offsets = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (error != NULL) *error = NULL; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error); if (res != DW_DLV_OK) { return res; } /* aranges points in to info, so if info needs expanding we have to load it. */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { return res; } arange_addrs = (Dwarf_Addr *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); if (arange_addrs == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } arange_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); if (arange_offsets == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curr_chain = head_chain; for (i = 0; i < arange_count; i++) { Dwarf_Arange ar = curr_chain->ch_item; int itemtype = curr_chain->ch_itemtype; curr_chain->ch_item = 0; arange_addrs[i] = ar->ar_address; arange_offsets[i] = ar->ar_info_offset; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; if (ar && itemtype) { dwarf_dealloc(dbg, ar, itemtype); } dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } *count = arange_count; *offsets = arange_offsets; *addrs = arange_addrs; return DW_DLV_OK; } /* This function takes a pointer to a block of Dwarf_Arange's, and a count of the length of the block. It checks if the given address is within the range of an address range in the block. If yes, it returns the appropriate Dwarf_Arange. Otherwise, it returns DW_DLV_ERROR. */ int dwarf_get_arange(Dwarf_Arange * aranges, Dwarf_Unsigned arange_count, Dwarf_Addr address, Dwarf_Arange * returned_arange, Dwarf_Error * error) { Dwarf_Arange curr_arange = 0; Dwarf_Unsigned i = 0; if (aranges == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); return DW_DLV_ERROR; } for (i = 0; i < arange_count; i++) { curr_arange = *(aranges + i); if (address >= curr_arange->ar_address && address < curr_arange->ar_address + curr_arange->ar_length) { *returned_arange = curr_arange; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* This function takes an Dwarf_Arange, and returns the offset of the first die in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. For an arange, the cu_die can only be from debug_info, not debug_types, it seems. */ int dwarf_get_cu_die_offset(Dwarf_Arange arange, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Off offset = 0; Dwarf_Unsigned headerlen = 0; int cres = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return DW_DLV_ERROR; } dbg = arange->ar_dbg; offset = arange->ar_info_offset; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *returned_offset = headerlen + offset; return DW_DLV_OK; } /* This function takes an Dwarf_Arange, and returns the offset of the CU header in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. Ensures .debug_info loaded so the cu_offset is meaningful. */ int dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, Dwarf_Off * cu_header_offset_returned, Dwarf_Error * error) { Dwarf_Debug dbg = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return DW_DLV_ERROR; } dbg = arange->ar_dbg; /* This applies to debug_info only, not to debug_types. */ /* Like dwarf_get_arange_info this ensures debug_info loaded: the cu_header is in debug_info and will be used else we would not call dwarf_get_arange_cu_header_offset. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } *cu_header_offset_returned = arange->ar_info_offset; return DW_DLV_OK; } /* This function takes a Dwarf_Arange, and returns true if it is not NULL. It also stores the start address of the range in *start, the length of the range in *length, and the offset of the first die in the compilation-unit in *cu_die_offset. It returns false on error. If cu_die_offset returned ensures .debug_info loaded so the cu_die_offset is meaningful. */ int dwarf_get_arange_info(Dwarf_Arange arange, Dwarf_Addr * start, Dwarf_Unsigned * length, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return DW_DLV_ERROR; } if (start != NULL) *start = arange->ar_address; if (length != NULL) *length = arange->ar_length; if (cu_die_offset != NULL) { Dwarf_Debug dbg = arange->ar_dbg; Dwarf_Off headerlen = 0; Dwarf_Off offset = arange->ar_info_offset; int cres = 0; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *cu_die_offset = headerlen + offset; } return DW_DLV_OK; } /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b(Dwarf_Arange arange, Dwarf_Unsigned* segment, Dwarf_Unsigned* segment_entry_size, Dwarf_Addr * start, Dwarf_Unsigned* length, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return DW_DLV_ERROR; } if (segment != NULL) { *segment = arange->ar_segment_selector; } if (segment_entry_size != NULL) { *segment_entry_size = arange->ar_segment_selector_size; } if (start != NULL) *start = arange->ar_address; if (length != NULL) *length = arange->ar_length; if (cu_die_offset != NULL) { Dwarf_Debug dbg = arange->ar_dbg; Dwarf_Off offset = arange->ar_info_offset; Dwarf_Unsigned headerlen = 0; int cres = 0; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *cu_die_offset = offset + headerlen; } return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_opaque.h0000664000175000017500000005111014012266121014602 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "libdwarfdefs.h" #define true 1 #define false 0 /* The DISTINGUISHED VALUE is 4 byte value defined by DWARF since DWARF3. */ #define DISTINGUISHED_VALUE_ARRAY(x) unsigned char x[4] = \ { 0xff,0xff,0xff,0xff } #define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ /* to identify a cie */ #define DW_CIE_ID ~(0x0) #define DW_CIE_VERSION 1 typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; /* On any change that makes libdwarf producer incompatible, increment this number. 1->2->3 ... */ #define PRO_VERSION_MAGIC 0xdead1 #define DWARF_HALF_SIZE 2 #define DWARF_32BIT_SIZE 4 #define DWARF_64BIT_SIZE 8 /* producer: This struct is used to hold information about all debug* sections. On creating a new section, section names and indices are added to this struct definition in pro_section.h */ typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data; /* producer: This struct holds file entries or include file entries for the statement prologue. Defined in pro_line.h */ typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry; /* producer: This struct holds information for each cie. Defn in pro_frame.h */ typedef struct Dwarf_P_Cie_s *Dwarf_P_Cie; /* producer: Struct to hold line number information, different from Dwarf_Line opaque type. */ typedef struct Dwarf_P_Line_s *Dwarf_P_Line; /* For a .debug_sup section creation. */ typedef struct Dwarf_P_Debug_Sup_s *Dwarf_P_Debug_Sup; /* producer: Struct to hold information about address ranges. */ typedef struct Dwarf_P_Simple_nameentry_s *Dwarf_P_Simple_nameentry; typedef struct Dwarf_P_Simple_name_header_s * Dwarf_P_Simple_name_header; typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange; typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect; typedef struct Dwarf_P_Per_Sect_String_Attrs_s * Dwarf_P_Per_Sect_String_Attrs; typedef struct Dwarf_P_Dnames_s *Dwarf_P_Dnames; /* Defined to get at the elf section numbers and section name indices in symtab for the dwarf sections Must match .rel.* names in _dwarf_rel_section_names exactly. */ #define DEBUG_INFO 0 #define DEBUG_LINE 1 #define DEBUG_ABBREV 2 #define DEBUG_FRAME 3 #define DEBUG_ARANGES 4 #define DEBUG_PUBNAMES 5 #define DEBUG_FUNCNAMES 6 #define DEBUG_TYPENAMES 7 #define DEBUG_VARNAMES 8 #define DEBUG_WEAKNAMES 9 #define DEBUG_MACINFO 10 /* DWARF 2,3,4 only */ #define DEBUG_LOC 11 #define DEBUG_RANGES 12 #define DEBUG_TYPES 13 #define DEBUG_PUBTYPES 14 #define DEBUG_NAMES 15 /* DWARF5. aka dnames */ #define DEBUG_STR 16 #define DEBUG_LINE_STR 17 #define DEBUG_MACRO 18 /* DWARF 5. */ #define DEBUG_LOCLISTS 19 /* DWARF 5. */ #define DEBUG_RNGLISTS 20 /* DWARF 5. */ #define DEBUG_SUP 21 /* DWARF 5. */ /* Maximum number of debug_* sections not including the relocations */ #define NUM_DEBUG_SECTIONS 22 /* The FORM codes available are defined in DWARF5 on page 158, DW_LNCT_path */ struct Dwarf_P_Line_format_s { /* DW_LNCT_path etc. */ unsigned def_content_type; /* DW_FORM_string or DW_FORM_strp or DW_FORM_strp or DW_FORM_strp_sup or for dwo, some others. */ unsigned def_form_code; }; #define DW_LINE_FORMATS_MAX 6 /* Describes the data needed to generate line table header info so we can vary the init at runtime. */ struct Dwarf_P_Line_Inits_s { unsigned pi_linetable_version; /* line table version number */ unsigned pi_default_is_stmt; /* default value for is_stmt */ /* Size of the smallest instruction, in bytes. */ unsigned pi_minimum_instruction_length; /* Normally opcode_base is determined by pi_version, but we allow manual setting here so we can generate data like GNU with a DWARF3 opcode base in a DWARF2 section. This determines how much of the header_opcode_lengths table is emitted in the line table header */ unsigned pi_opcode_base; int pi_line_base; /* For line table header. */ int pi_line_range; /* For line table header. */ /* Make this >1 for VLIW machines. DWARF4,DWARF5 */ unsigned pi_maximum_operations_per_instruction; /* DWARF 5 */ unsigned pi_segment_selector_size; unsigned pi_address_size; unsigned pi_segment_size; unsigned pi_directory_entry_format_count; struct Dwarf_P_Line_format_s pi_incformats[DW_LINE_FORMATS_MAX]; unsigned pi_file_entry_format_count; struct Dwarf_P_Line_format_s pi_fileformats[DW_LINE_FORMATS_MAX]; }; /* To enable DWARF5 testing. July 2020 */ struct Dwarf_P_Debug_Sup_s { Dwarf_Half ds_version; /* 2 */ Dwarf_Small ds_is_supplementary; /* 0 or 1 */ char *ds_filename; Dwarf_Unsigned ds_checksum_len; Dwarf_Small *ds_checksum; Dwarf_P_Debug ds_dbg; }; struct Dwarf_P_Die_s { Dwarf_Unsigned di_offset; /* offset in debug info */ char *di_abbrev; /* abbreviation */ Dwarf_Unsigned di_abbrev_nbytes; /* # of bytes in abbrev */ Dwarf_Tag di_tag; Dwarf_P_Die di_parent; /* parent of current die */ Dwarf_P_Die di_child; /* first child */ /* The last child field makes linking up children an O(1) operation, See pro_die.c. */ Dwarf_P_Die di_last_child; Dwarf_P_Die di_left; /* left sibling */ Dwarf_P_Die di_right; /* right sibling */ Dwarf_P_Attribute di_attrs; /* list of attributes */ Dwarf_P_Attribute di_last_attr; /* last attribute */ int di_n_attr; /* number of attributes */ Dwarf_P_Debug di_dbg; /* For memory management */ Dwarf_Unsigned di_marker; /* used to attach symbols to dies */ }; /* producer fields */ struct Dwarf_P_Attribute_s { Dwarf_Half ar_attribute; /* Attribute Value. */ Dwarf_Half ar_attribute_form; /* Attribute Form. */ Dwarf_P_Die ar_ref_die; /* die pointer if form ref */ char *ar_data; /* data, format given by form */ Dwarf_Unsigned ar_nbytes; /* no. of bytes of data */ Dwarf_Unsigned ar_rel_symidx; /* when attribute has a relocatable value, holds index of symbol in SYMTAB */ Dwarf_Unsigned ar_debug_str_offset; /* Offset in .debug_str if non-zero. Zero offset never assigned a string. */ Dwarf_Ubyte ar_rel_type; /* relocation type */ Dwarf_Unsigned ar_rel_offset; /* Offset of reloc within block */ char ar_reloc_len; /* Number of bytes that relocation applies to. 4 or 8. Unused and may be 0 if if ar_rel_type is R_MIPS_NONE */ Dwarf_P_Attribute ar_next; /* set if form = DW_FORM_implicit_const; */ Dwarf_Signed ar_implicit_const; }; /* A block of .debug_macinfo data: this forms a series of blocks. ** Each macinfo input is compressed immediately and put into ** the current block if room, else a newblock allocated. ** The space allocation is such that the block and the macinfo ** data are one malloc block: free with a pointer to this and the ** mb_data is freed automatically. ** Like the struct hack, but legal ANSI C. */ struct dw_macinfo_block_s { struct dw_macinfo_block_s *mb_next; unsigned long mb_avail_len; unsigned long mb_used_len; unsigned long mb_macinfo_data_space_len; char *mb_data;/* original malloc ptr. */ }; /* dwarf_sn_kind is for the array of similarly-treated name -> cu ties */ enum dwarf_sn_kind { dwarf_snk_pubname, /* .debug_pubnames */ dwarf_snk_funcname, /* SGI extension. */ dwarf_snk_weakname, /* SGI extension. */ dwarf_snk_typename, /* SGI extension. */ dwarf_snk_varname, /* SGI extension. */ dwarf_snk_pubtype, /* .debug_pubtypes */ dwarf_snk_entrycount /* this one must be last */ }; /* The calls to add a varname etc use a list of these as the list. */ struct Dwarf_P_Simple_nameentry_s { Dwarf_P_Die sne_die; char *sne_name; int sne_name_len; Dwarf_P_Simple_nameentry sne_next; }; /* An array of these, each of which heads a list of Dwarf_P_Simple_nameentry */ struct Dwarf_P_Simple_name_header_s { Dwarf_P_Simple_nameentry sn_head; Dwarf_P_Simple_nameentry sn_tail; Dwarf_Signed sn_count; /* Length that will be generated, not counting fixed header or trailer */ Dwarf_Signed sn_net_len; }; typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,/* r_offset */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length); typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,/* r_offset */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type type, int reltarget_length); typedef int (*_dwarf_pro_transform_relocs_func_ptr) (Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); /* Each slot in a block of slots could be: a binary stream relocation entry (32 or 64bit relocation data) a SYMBOLIC relocation entry. During creation sometimes we create multiple chained blocks, but sometimes we create a single long block. Before returning reloc data to caller, we switch to a single, long-enough, block. We make counters here Dwarf_Unsigned so that we get sufficient alignment. Since we use space after the struct (at malloc time) for user data which must have Dwarf_Unsigned alignment, this struct must have that alignment too. */ struct Dwarf_P_Relocation_Block_s { Dwarf_Unsigned rb_slots_in_block; /* slots in block, as created */ Dwarf_Unsigned rb_next_slot_to_use; /* counter, start at 0. */ struct Dwarf_P_Relocation_Block_s *rb_next; char *rb_where_to_add_next; /* pointer to next slot (might be past end, depending on rb_next_slot_to_use) */ char *rb_data; /* data area */ }; /* One of these per potential relocation section So one per actual dwarf section. Left zeroed when not used (some sections have no relocations). */ struct Dwarf_P_Per_Reloc_Sect_s { unsigned long pr_reloc_total_count; /* total number of entries across all blocks */ unsigned long pr_slots_per_block_to_alloc; /* at Block alloc, this is the default number of slots to use */ int pr_sect_num_of_reloc_sect; /* sect number returned by de_callback_func() or de_callback_func_b() or_c() call, this is the sect number of the relocation section. */ /* singly-linked list. add at and ('last') with count of blocks */ struct Dwarf_P_Relocation_Block_s *pr_first_block; struct Dwarf_P_Relocation_Block_s *pr_last_block; unsigned long pr_block_count; }; #define DEFAULT_SLOTS_PER_BLOCK 3 typedef struct memory_list_s { struct memory_list_s *prev; struct memory_list_s *next; } memory_list_t; struct Dwarf_P_Per_Sect_String_Attrs_s { int sect_sa_section_number; unsigned sect_sa_n_alloc; unsigned sect_sa_n_used; Dwarf_P_String_Attr sect_sa_list; }; struct Dwarf_P_debug_str_entry_s { Dwarf_P_Debug dse_dbg; /* Name used initially with tfind. */ char *dse_name; Dwarf_Unsigned dse_slen; /* includes space for NUL terminator */ /* See dse_has_table_offset below. */ Dwarf_Unsigned dse_table_offset; /* For tsearch a hash table exists and we have a table offset. dse_dbg->de_debug_str->ds_data + dse_table_offset points to the string iff dse_has_table_offset != 0. */ unsigned char dse_has_table_offset; }; struct Dwarf_P_Str_stats_s { Dwarf_Unsigned ps_strp_count_debug_str; Dwarf_Unsigned ps_strp_len_debug_str; Dwarf_Unsigned ps_strp_len_debug_line_str; Dwarf_Unsigned ps_strp_reused_count; Dwarf_Unsigned ps_strp_reused_len; }; struct Dwarf_P_Stats_s { Dwarf_Unsigned ps_str_count; Dwarf_Unsigned ps_str_total_length; struct Dwarf_P_Str_stats_s ps_strp; struct Dwarf_P_Str_stats_s ps_line_strp; }; /* Fields used by producer */ struct Dwarf_P_Debug_s { /* Used to catch dso passing dbg to another DSO with incompatible version of libdwarf See PRO_VERSION_MAGIC */ int de_version_magic_number; Dwarf_Handler de_errhand; /* de_user_data is provided so users can use it to readily tie a callback to anything they desire. The contents are not used by libdwarf except to pass the data as a callback argument. New in June 2011. Available in dwarf_pro_init_c() and its callback function. */ void * de_user_data; Dwarf_Ptr de_errarg; /* Call back function, used to create .debug* sections. Provided by library user. */ Dwarf_Callback_Func de_callback_func; /* Flags from producer_init call */ Dwarf_Unsigned de_flags; /* This holds information on debug info section stream output, including the stream data */ Dwarf_P_Section_Data de_debug_sects; /* Defaults set as DW_FORM_string, meaning not using .debug_str by default. This intended for the .debug_info section. */ int de_debug_default_str_form; /* If form DW_FORM_strp */ Dwarf_P_Section_Data de_debug_str; void *de_debug_str_hashtab; /* for tsearch */ /* .debug_line_str section data if form DW_FORM_line_strp */ Dwarf_P_Section_Data de_debug_line_str; void *de_debug_line_str_hashtab; /* for tsearch */ /* Pointer to the 'current active' section */ Dwarf_P_Section_Data de_current_active_section; /* Number of debug data streams globs. */ Dwarf_Unsigned de_n_debug_sect; /* File entry information, null terminated singly-linked list */ Dwarf_P_F_Entry de_file_entries; Dwarf_P_F_Entry de_last_file_entry; Dwarf_Unsigned de_n_file_entries; /* Has the directories used to search for source files */ Dwarf_P_F_Entry de_inc_dirs; Dwarf_P_F_Entry de_last_inc_dir; Dwarf_Unsigned de_n_inc_dirs; /* Has all the line number info for the stmt program */ Dwarf_P_Line de_lines; Dwarf_P_Line de_last_line; /* List of cie's for the debug unit */ Dwarf_P_Cie de_frame_cies; Dwarf_P_Cie de_last_cie; Dwarf_Unsigned de_n_cie; /* Singly-linked list of fde's for the debug unit */ Dwarf_P_Fde de_frame_fdes; Dwarf_P_Fde de_last_fde; Dwarf_Unsigned de_n_fde; /* It's just one small record */ struct Dwarf_P_Debug_Sup_s de_debug_sup; /* First die, leads to all others */ Dwarf_P_Die de_dies; /* Pointer to chain of aranges */ Dwarf_P_Arange de_arange; Dwarf_P_Arange de_last_arange; Dwarf_Signed de_arange_count; /* debug_names de_dnames is base of dnames info before disk form */ Dwarf_P_Dnames de_dnames; Dwarf_P_Section_Data de_dnames_sect; /* macinfo controls. */ /* first points to beginning of the list during creation */ struct dw_macinfo_block_s *de_first_macinfo; /* current points to the current, unfilled, block */ struct dw_macinfo_block_s *de_current_macinfo; /* Pointer to the first section, to support reset_section_bytes */ Dwarf_P_Section_Data de_first_debug_sect; /* Handles pubnames, weaknames, etc. See dwarf_sn_kind in pro_opaque.h */ struct Dwarf_P_Simple_name_header_s de_simple_name_headers[dwarf_snk_entrycount]; /* Relocation data. not all sections will actally have relocation info, of course. de_reloc_sect, de_elf_sects, and de_sect_name_idx arrays are exactly in parallel. Not every de_elf_sect has any relocations for it, of course. */ struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS]; int de_reloc_next_to_return; /* iterator on reloc sections (SYMBOLIC output) */ /* Used in remembering sections. See de_reloc_sect above. */ int de_elf_sects[NUM_DEBUG_SECTIONS]; /* elf sect number of the section itself, DEBUG_LINE for example */ /* Section name index or handle for the name of the symbol for DEBUG_LINE for example */ Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; int de_offset_reloc; /* offset reloc type, R_MIPS_32 for example. Specific to the ABI being produced. Relocates offset size field */ int de_exc_reloc; /* reloc type specific to exception table relocs. */ int de_ptr_reloc; /* standard reloc type, R_MIPS_32 for example. Specific to the ABI being produced. relocates pointer size field */ unsigned char de_irix_exc_augmentation; /* If non-zero means that producing an IRIX exception-table offset in a CIE header is allowed (depending on the augmentation string). */ unsigned char de_dwarf_offset_size; /* dwarf offset size. */ unsigned char de_elf_offset_size; /* object sec offset size. */ unsigned char de_pointer_size; /* size of address in target. */ /* Added April 19, 2017. For DWARF5 */ unsigned char de_segment_selector_size; unsigned char de_relocation_record_size; /* reloc record size varies by ABI and relocation-output method (stream or symbolic) */ unsigned char de_64bit_extension;/* non-zero if creating 64 bit offsets using dwarf2-99 extension proposal */ unsigned char de_output_version; /* 2,3,4, or 5. The version number of the output. (not necessarily that of each section, which depends on the base version). */ /* Defaults will be mostly useless, but such do exist */ unsigned de_big_endian; /* if 0 target is little-endian */ /* data8, data4 abi &version dependent */ int de_ar_data_attribute_form; int de_ar_ref_attr_form; /* ref8 ref4 , abi dependent */ /* simple name relocations */ _dwarf_pro_reloc_name_func_ptr de_relocate_by_name_symbol; /* relocations for a length, requiring a pair of symbols */ _dwarf_pro_reloc_length_func_ptr de_relocate_pair_by_symbol; _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk; /* following used for macro buffers */ unsigned long de_compose_avail; unsigned long de_compose_used_len; unsigned char de_same_endian; void (*de_copy_word) (void *, const void *, unsigned long); /* Add new fields at the END of this struct to preserve some hope of sensible behavior on dbg passing between DSOs linked with mismatched libdwarf producer versions. */ Dwarf_P_Marker de_markers; /* pointer to array of markers */ unsigned de_marker_n_alloc; unsigned de_marker_n_used; int de_sect_sa_next_to_return; /* Iterator on sring attrib secs */ /* String attributes data of each section. */ struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS]; /* Hold data needed to init line output flexibly. */ struct Dwarf_P_Line_Inits_s de_line_inits; struct Dwarf_P_Stats_s de_stats; }; #define CURRENT_VERSION_STAMP 2 int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, enum dwarf_sn_kind entrykind, Dwarf_Error * error); enum dwarf_which_hash { _dwarf_hash_debug_str, _dwarf_hash_debug_line_str, _dwarf_hash_debug_str_sup }; int _dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, char *name, enum dwarf_which_hash, unsigned slen, /* includes space for trailing NUL */ Dwarf_Unsigned *offset_in_debug_str, Dwarf_Error *error); int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err); libdwarf-20210528/libdwarf/dwarf_util.h0000664000175000017500000005147614012266121014607 00000000000000#ifndef DWARF_UTIL_H #define DWARF_UTIL_H /* Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Decodes unsigned leb128 encoded numbers. Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_u_leb128() which did not work correctly if Dwarf_Unsigned was 64 bits. April 2016: now uses a reader that is careful. 'return' only in case of error else falls through. */ void _dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned targ, Dwarf_Unsigned sectionlen); #define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen, \ &lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ value = lu_local; \ ptr += lu_leblen; \ } while (0) #define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,\ errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr, \ &lu_leblen,&lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ value = lu_local; \ ptr += lu_leblen; \ leblen = lu_leblen; \ } while (0) /* Decodes signed leb128 encoded numbers. Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_s_leb128() which did not work correctly if Dwarf_Unsigned was 64 bits. */ #define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned uleblen = 0; \ Dwarf_Signed local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen, \ &local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);\ return DW_DLV_ERROR; \ } \ value = local; \ ptr += uleblen; \ } while (0) #define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,\ errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Signed lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\ &lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);\ return DW_DLV_ERROR; \ } \ leblen = lu_leblen; \ value = lu_local; \ ptr += lu_leblen; \ } while (0) /* Any error found here represents a bug that cannot be dealloc-d as the caller will not know there was no dbg */ #define CHECK_DIE(die, error_ret_value) \ do { \ if (die == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ return(error_ret_value); \ } \ if (die->di_cu_context == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ return(error_ret_value); \ } \ if (die->di_cu_context->cc_dbg == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ return(error_ret_value); \ } \ } while (0) /* Reads 'source' for 'length' bytes from unaligned addr. Avoids any constant-in-conditional warnings and avoids a test in the generated code (for non-const cases, which are in the majority.) Uses a temp to avoid the test. The decl here should avoid any problem of size in the temp. This code is ENDIAN DEPENDENT The memcpy args are the endian issue. Does not update the 'source' field. for READ_UNALIGNED_CK the error code refers to host endianness. */ typedef Dwarf_Unsigned BIGGEST_UINT; #ifdef WORDS_BIGENDIAN #define READ_UNALIGNED_CK(dbg,dest,desttype, source,\ length,error,endptr) \ do { \ BIGGEST_UINT _ltmp = 0; \ Dwarf_Byte_Ptr readend = source+length; \ if (readend < source) { \ _dwarf_error_string(dbg, error, \ DW_DLE_READ_BIGENDIAN_ERROR, \ "DW_DLE_READ_BIGENDIAN_ERROR " \ "Read would start past the end of section"); \ return DW_DLV_ERROR; \ } \ if (readend > endptr) { \ _dwarf_error_string(dbg, error, \ DW_DLE_READ_BIGENDIAN_ERROR, \ "DW_DLE_READ_BIGENDIAN_ERROR " \ "Read would end past the end of section"); \ return DW_DLV_ERROR; \ } \ dbg->de_copy_word( (((char *)(&_ltmp)) + \ sizeof(_ltmp) - length),source, length) ; \ dest = (desttype)_ltmp; \ } while (0) /* This macro sign-extends a variable depending on the length. It fills the bytes between the size of the destination and the length with appropriate padding. This code is ENDIAN DEPENDENT but dependent only on host endianness, not object file endianness. The memcpy args are the issue. */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + \ sizeof(dest) - length) < 0) { \ memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ sizeof(dest) - length); \ } \ } while (0) #else /* LITTLE ENDIAN */ #define READ_UNALIGNED_CK(dbg,dest,desttype, source,\ length,error,endptr) \ do { \ BIGGEST_UINT _ltmp = 0; \ Dwarf_Byte_Ptr readend = source+length; \ if (readend < source) { \ _dwarf_error_string(dbg, error, \ DW_DLE_READ_LITTLEENDIAN_ERROR, \ "DW_DLE_READ_LITTLEENDIAN_ERROR "\ "Read starts past the end of section");\ return DW_DLV_ERROR; \ } \ if (readend > endptr) { \ _dwarf_error_string(dbg, error, \ DW_DLE_READ_LITTLEENDIAN_ERROR, \ "DW_DLE_READ_LITTLEENDIAN_ERROR "\ "Read would end past the end of section");\ return DW_DLV_ERROR; \ } \ dbg->de_copy_word( (char *)(&_ltmp) , \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) /* This macro sign-extends a variable depending on the length. It fills the bytes between the size of the destination and the length with appropriate padding. This code is ENDIAN DEPENDENT but dependent only on host endianness, not object file endianness. The memcpy args are the issue. */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \ memcpy((char *)&dest+length, \ "\xff\xff\xff\xff\xff\xff\xff\xff", \ sizeof(dest) - length); \ } \ } while (0) #endif /* ! LITTLE_ENDIAN */ /* READ_AREA LENGTH reads the length (the older way of pure 32 or 64 bit or the dwarf v3 64bit-extension way) It reads the bits from where rw_src_data_p points to and updates the rw_src_data_p to point past what was just read. It updates w_length_size (to the size of an offset, either 4 or 8) and w_exten_size (set 0 unless this frame has the DWARF3 and later 64bit extension, in which case w_exten_size is set to 4). r_dbg is just the current dbg pointer. w_target is the output length field. r_targtype is the output type. Always Dwarf_Unsigned so far. */ /* This one handles the v3 64bit extension and 32bit (and SGI/MIPS fixed 64 bit via the dwarf_init-set r_dbg->de_length_size).. It does not recognize any but the one distinguished value (the only one with defined meaning). It assumes that no CU will have a length 0xffffffxx (32bit length) or 0xffffffxx xxxxxxxx (64bit length) which makes possible auto-detection of the extension. This depends on knowing that only a non-zero length is legitimate (AFAICT), and for IRIX non-standard -64 dwarf that the first 32 bits of the 64bit offset will be zero (because the compiler could not handle a truly large value as of Jan 2003 and because no app has that much debug info anyway, at least not in the IRIX case). At present not testing for '64bit elf' here as that does not seem necessary (none of the 64bit length seems appropriate unless it's ident[EI_CLASS] == ELFCLASS64). */ /* The w_target > r_sectionlen compare is done without adding in case the w_target value read is so large any addition would overflow. A basic value sanity check. */ #define READ_AREA_LENGTH_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p,w_length_size,w_exten_size,w_error, \ r_sectionlen,r_endptr) \ do { \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE, \ w_error,r_endptr); \ if (w_target == DISTINGUISHED_VALUE) { \ /* dwarf3 64bit extension */ \ w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \ w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE,\ w_error,r_endptr); \ if (w_target > r_sectionlen) { \ _dwarf_create_area_len_error(r_dbg,w_error, \ w_target,r_sectionlen); \ return DW_DLV_ERROR; \ } \ rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ } else { \ if (w_target == 0 && r_dbg->de_big_endian_object) {\ /* Might be IRIX: We have to distinguish between */\ /* 32-bit DWARF format and IRIX 64-bit \ DWARF format. */ \ if (r_dbg->de_length_size == 8) { \ /* IRIX 64 bit, big endian. This test */ \ /* is not a truly precise test, a precise test*/ \ /* would check if the target was IRIX. */ \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,\ rw_src_data_p, \ DISTINGUISHED_VALUE_OFFSET_SIZE, \ w_error,r_endptr); \ if (w_target > r_sectionlen) { \ _dwarf_create_area_len_error(r_dbg,w_error,\ w_target,r_sectionlen); \ return DW_DLV_ERROR; \ } \ w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE;\ rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;\ w_exten_size = 0; \ } else { \ /* 32 bit, big endian */ \ w_length_size = ORIGINAL_DWARF_OFFSET_SIZE;\ rw_src_data_p += w_length_size; \ w_exten_size = 0; \ } \ } else { \ if (w_target > r_sectionlen) { \ _dwarf_create_area_len_error(r_dbg,w_error,\ w_target,r_sectionlen); \ return DW_DLV_ERROR; \ } \ /* Standard 32 bit dwarf2/dwarf3 */ \ w_exten_size = 0; \ w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ rw_src_data_p += w_length_size; \ } \ } \ } while (0) /* Fuller checking. Returns DW_DLV_ERROR or DW_DLV_OK Caller must set Dwarf_Error */ int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr); int _dwarf_format_TAG_err_msg(Dwarf_Debug dbg, Dwarf_Unsigned tag,const char *m, Dwarf_Error *error); int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr); int _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Half cu_version, Dwarf_Half address_size, Dwarf_Small * val_ptr, int v_length_size, Dwarf_Unsigned *size_out, Dwarf_Small *section_end_ptr, Dwarf_Error *error); struct Dwarf_Hash_Table_Entry_s; /* This single struct is the base for the hash table. The intent is that once the total_abbrev_count across all the entries is greater than 10*current_table_entry_count one should build a new Dwarf_Hash_Table_Base_s, rehash all the existing entries, and delete the old table and entries. (10 is a heuristic, nothing magic about it, but once the count gets to 30 or 40 times current_table_entry_count things really slow down a lot. One (500MB) application had 127000 abbreviations in one compilation unit) The incoming 'code' is an abbrev number and those simply increase linearly so the hashing is perfect always. */ struct Dwarf_Hash_Table_s { unsigned long tb_table_entry_count; unsigned long tb_total_abbrev_count; /* Each table entry is a list of abbreviations. */ struct Dwarf_Hash_Table_Entry_s *tb_entries; }; /* This struct is used to build a hash table for the abbreviation codes for a compile-unit. */ struct Dwarf_Hash_Table_Entry_s { Dwarf_Abbrev_List at_head; }; int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Abbrev_List *list_out, Dwarf_Unsigned * highest_known_code, Dwarf_Error *error); /* return 1 if string ends before 'endptr' else ** return 0 meaning string is not properly terminated. ** Presumption is the 'endptr' pts to end of some dwarf section data. */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *startptr, void *endptr, int suggested_error, Dwarf_Error *error); int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Bool is_info, Dwarf_Unsigned *area_length_out, Dwarf_Error *error); Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug, Dwarf_Bool dinfo); int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error); int _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error *error); void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg, struct Dwarf_Hash_Table_s* hash_table); int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die); int _dwarf_reference_outside_section(Dwarf_Die die, Dwarf_Small * startaddr, Dwarf_Small * pastend); void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt); int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, const char **comp_name_out, Dwarf_Error *error); int _dwarf_what_section_are_we(Dwarf_Debug dbg, Dwarf_Small *our_pointer, const char ** section_name_out, Dwarf_Small **sec_start_ptr_out, Dwarf_Unsigned *sec_len_out, Dwarf_Small **sec_end_ptr_out, Dwarf_Error *error); /* wrappers return either DW_DLV_OK or DW_DLV_ERROR. Never DW_DLV_NO_ENTRY. */ int _dwarf_read_unaligned_ck_wrapper(Dwarf_Debug dbg, Dwarf_Unsigned *out_value, Dwarf_Small *readfrom, int readlength, Dwarf_Small *end_arange, Dwarf_Error *err); int _dwarf_read_area_length_ck_wrapper(Dwarf_Debug dbg, Dwarf_Unsigned *out_value, Dwarf_Small **readfrom, int * length_size_out, int * exten_size_out, Dwarf_Unsigned sectionlength, Dwarf_Small *endsection, Dwarf_Error *err); int _dwarf_leb128_uword_wrapper(Dwarf_Debug dbg, Dwarf_Small ** startptr, Dwarf_Small * endptr, Dwarf_Unsigned *out_value, Dwarf_Error * error); int _dwarf_leb128_sword_wrapper(Dwarf_Debug dbg, Dwarf_Small ** startptr, Dwarf_Small * endptr, Dwarf_Signed *out_value, Dwarf_Error * error); #endif /* DWARF_UTIL_H */ libdwarf-20210528/libdwarf/dwarf_debug_names.c0000664000175000017500000012130113764007262016073 00000000000000/* Portions Copyright (C) 2017-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This provides access to the DWARF5 .debug_names section. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_global.h" #include "dwarf_debug_names.h" #include "dwarfstring.h" #define FALSE 0 #define TRUE 1 /* freedabs attempts to do some cleanup in the face of an error. */ static void freedabs(struct Dwarf_D_Abbrev_s *dab) { struct Dwarf_D_Abbrev_s *tmp = 0; for (; dab; dab = tmp) { tmp = dab->da_next; free(dab); } } /* Encapsulates DECODE_LEB128_UWORD_CK so the caller can free resources in case of problems. */ static int read_uword_ab(Dwarf_Small **lp, Dwarf_Unsigned *out_p, Dwarf_Debug dbg, Dwarf_Error *err, Dwarf_Small *lpend) { Dwarf_Small *inptr = *lp; Dwarf_Unsigned out = 0; /* The macro updates inptr */ DECODE_LEB128_UWORD_CK(inptr, out, dbg,err,lpend); *lp = inptr; *out_p = out; return DW_DLV_OK; } static int fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn, Dwarf_Error * error) { Dwarf_Small *abdata = dn->din_abbreviations; Dwarf_Unsigned ablen = dn->din_abbrev_table_size; Dwarf_Small *tabend = abdata+ablen; Dwarf_Small *abcur = 0; Dwarf_Unsigned code = 0; Dwarf_Unsigned tag = 0; int foundabend = FALSE; unsigned abcount = 0; struct Dwarf_D_Abbrev_s *firstdab = 0; struct Dwarf_D_Abbrev_s *lastdab = 0; struct Dwarf_D_Abbrev_s *curdab = 0; Dwarf_Debug dbg = dn->din_dbg; for (abcur = abdata; abcur < tabend; ) { Dwarf_Unsigned idx = 0; Dwarf_Unsigned form = 0; Dwarf_Small *inner = 0; unsigned idxcount = 0; int res = 0; res = read_uword_ab(&abcur,&code,dbg,error,tabend); if (res != DW_DLV_OK) { freedabs(firstdab); return res; } if (code == 0) { foundabend = TRUE; break; } res = read_uword_ab(&abcur,&tag,dbg,error,tabend); if (res != DW_DLV_OK) { freedabs(firstdab); return res; } inner = abcur; curdab = (struct Dwarf_D_Abbrev_s *)calloc(1, sizeof(struct Dwarf_D_Abbrev_s)); if (!curdab) { freedabs(firstdab); firstdab = 0; _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curdab->da_tag = tag; curdab->da_abbrev_code = code; abcount++; for (;;) { res = read_uword_ab(&inner,&idx,dbg,error,tabend); if (res != DW_DLV_OK) { free(curdab); freedabs(firstdab); firstdab = 0; return res; } res = read_uword_ab(&inner,&form,dbg,error,tabend); if (res != DW_DLV_OK) { free(curdab); freedabs(firstdab); firstdab = 0; return res; } if (!idx && !form) { break; } if (idxcount >= ABB_PAIRS_MAX) { free(curdab); freedabs(firstdab); firstdab = 0; _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW); return DW_DLV_ERROR; } curdab->da_pairs[idxcount].ap_index = idx; curdab->da_pairs[idxcount].ap_form = form; idxcount++; } curdab->da_pairs_count = idxcount; abcur = inner +1; if (!firstdab) { firstdab = curdab; lastdab = curdab; } else { /* Add new on the end, last */ lastdab->da_next = curdab; } } if (!foundabend) { freedabs(firstdab); _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); return DW_DLV_OK; } { unsigned ct = 0; struct Dwarf_D_Abbrev_s *tmpa = 0; dn->din_abbrev_list = (struct Dwarf_D_Abbrev_s *)calloc( abcount,sizeof(struct Dwarf_D_Abbrev_s)); if (!dn->din_abbrev_list) { freedabs(firstdab); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dn->din_abbrev_list_count = abcount; tmpa = firstdab; for (ct = 0; tmpa && ct < abcount; ++ct) { struct Dwarf_D_Abbrev_s *tmpb =tmpa->da_next; /* da_next no longer means anything */ dn->din_abbrev_list[ct] = *tmpa; dn->din_abbrev_list[ct].da_next = 0; tmpa = tmpb; } freedabs(firstdab); tmpa = 0; firstdab = 0; lastdab = 0; /* Now the list has turned into an array. We can ignore the list aspect. */ } return DW_DLV_OK; } static int get_inhdr_cur(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, struct Dwarf_Dnames_index_header_s **cur, Dwarf_Error *error) { Dwarf_Debug dbg = 0; if (!dn) { _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_NULL_POINTER); return DW_DLV_ERROR; } dbg = dn->dn_dbg; if (index_number >= dn->dn_inhdr_count) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } *cur = dn->dn_inhdr_first + index_number; return DW_DLV_OK; } static int read_uword_val(Dwarf_Debug dbg, Dwarf_Small **ptr_in, Dwarf_Small *endptr, int errcode, Dwarf_Unsigned *val_out, Dwarf_Unsigned area_length, Dwarf_Error *error) { Dwarf_Unsigned val = 0; Dwarf_Small *ptr = *ptr_in; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); ptr += DWARF_32BIT_SIZE; if (ptr >= endptr) { _dwarf_error(dbg, error,errcode); return DW_DLV_ERROR; } /* Some of the fields are not length fields, but if non-zero the size will be longer than the value, so we do the following overall sanity check to avoid overflows. */ if (val > area_length) { _dwarf_error(dbg, error,errcode); return DW_DLV_ERROR; } *val_out = val; *ptr_in = ptr; return DW_DLV_OK; } /* We do not alter the dn data here. */ static int read_a_name_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned section_offset, Dwarf_Small **curptr_in, Dwarf_Small *end_section, Dwarf_Unsigned remaining_section_size, struct Dwarf_Dnames_index_header_s ** index_header_out, Dwarf_Error *error) { Dwarf_Unsigned area_length = 0; int local_length_size; int local_extension_size = 0; Dwarf_Small *past_length = 0; Dwarf_Small *end_dnames = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; Dwarf_Unsigned comp_unit_count = 0; Dwarf_Unsigned local_type_unit_count = 0; Dwarf_Unsigned foreign_type_unit_count = 0; Dwarf_Unsigned bucket_count = 0; Dwarf_Unsigned name_count = 0; Dwarf_Unsigned abbrev_table_size = 0; /* bytes */ Dwarf_Unsigned augmentation_string_size = 0; /* bytes */ int res = 0; const char *str_utf8 = 0; Dwarf_Small *curptr = *curptr_in; struct Dwarf_Dnames_index_header_s *di_header = 0; Dwarf_Debug dbg = dn->dn_dbg; READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned, curptr, local_length_size, local_extension_size,error, remaining_section_size,end_section); /* curptr now points past the length field */ past_length = curptr; /* Two stage length test so overflow is caught. */ if (area_length > remaining_section_size) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if ((area_length + local_length_size + local_extension_size) > remaining_section_size) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } end_dnames = curptr + area_length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, curptr, DWARF_HALF_SIZE, error,end_dnames); curptr += DWARF_HALF_SIZE; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if (version != DWARF_DNAMES_VERSION5) { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, padding, Dwarf_Half, curptr, DWARF_HALF_SIZE, error,end_dnames); curptr += DWARF_HALF_SIZE; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if (padding) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &comp_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &local_type_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &foreign_type_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &bucket_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &name_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &abbrev_table_size,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &augmentation_string_size,area_length,error); if (res != DW_DLV_OK) { return res; } str_utf8 = (const char *) curptr; curptr+= augmentation_string_size; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header = (struct Dwarf_Dnames_index_header_s *) calloc(1,sizeof(*di_header)); if (!di_header) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } di_header->din_dbg = dbg; di_header->din_section_offset = section_offset; di_header->din_indextable_data = past_length; di_header->din_indextable_length = area_length; di_header->din_version = version; di_header->din_comp_unit_count = comp_unit_count; di_header->din_local_type_unit_count = local_type_unit_count ; di_header->din_foreign_type_unit_count = foreign_type_unit_count ; di_header->din_bucket_count = bucket_count ; di_header->din_name_count = name_count ; di_header->din_abbrev_table_size = abbrev_table_size; di_header->din_augmentation_string_size = augmentation_string_size; di_header->din_augmentation_string = calloc(1, augmentation_string_size +1); strncpy(di_header->din_augmentation_string,str_utf8, augmentation_string_size); { /* This deals with a zero length string too. */ Dwarf_Unsigned len = augmentation_string_size; char *cp = 0; char *cpend = 0; Dwarf_Bool foundnull = FALSE; cp = di_header->din_augmentation_string; cpend = cp + len; for ( ; cpdin_cu_list = curptr; curptr += dbg->de_length_size * comp_unit_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_local_tu_list = curptr; curptr += dbg->de_length_size * local_type_unit_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_foreign_tu_list = curptr; curptr += sizeof(Dwarf_Sig8) * foreign_type_unit_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_buckets = curptr; curptr += DWARF_32BIT_SIZE * bucket_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_hash_table = curptr; curptr += sizeof(Dwarf_Sig8) * name_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_string_offsets = curptr; curptr += DWARF_32BIT_SIZE * name_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_entry_offsets = curptr; curptr += DWARF_32BIT_SIZE * name_count; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_abbreviations = curptr; curptr += abbrev_table_size; if (curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_entry_pool = curptr; di_header->din_offset_size = local_length_size; di_header->din_entry_pool_size = end_dnames - curptr; *curptr_in = curptr; *index_header_out = di_header; res = fill_in_abbrevs_table(di_header,error); if (res != DW_DLV_OK) { free(di_header->din_augmentation_string); free(di_header); return res; } return DW_DLV_OK; } #define FAKE_LAST_USED 0xffffffff static void free_inhdr_content(struct Dwarf_Dnames_index_header_s *f) { free(f->din_augmentation_string); free(f->din_abbrev_list); } static void free_inhdr_list(struct Dwarf_Dnames_index_header_s *f) { struct Dwarf_Dnames_index_header_s *tmp = 0; for ( ; f ; f = tmp) { tmp = f->din_next; free_inhdr_content(f); free(f); } } /* There may be one debug index for an entire object file, for multiple CUs or there can be individual indexes for some CUs. see DWARF5 6.1.1.3 Per_CU versus Per-Module Indexes. */ int dwarf_debugnames_header(Dwarf_Debug dbg, Dwarf_Dnames_Head * dn_out, Dwarf_Unsigned * dn_count_out, Dwarf_Error *error) { Dwarf_Unsigned remaining = 0; Dwarf_Dnames_Head dn_header = 0; Dwarf_Unsigned section_size; Dwarf_Small *start_section = 0; Dwarf_Small *end_section = 0; Dwarf_Small *curptr = 0; struct Dwarf_Dnames_index_header_s *inhdr_last = 0; struct Dwarf_Dnames_index_header_s *inhdr_first = 0; unsigned inhdr_count = 0; int res = 0; if (!dbg) { _dwarf_error(dbg, error,DW_DLE_DBG_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_names, error); if (res != DW_DLV_OK) { return res; } section_size = dbg->de_debug_names.dss_size; if (!section_size){ return DW_DLV_NO_ENTRY; } start_section = dbg->de_debug_names.dss_data; curptr = start_section; end_section = start_section + section_size; remaining = section_size; dn_header = (Dwarf_Dnames_Head)_dwarf_get_alloc(dbg, DW_DLA_DNAMES_HEAD, 1); if (!dn_header) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: dwarf_get_alloc of " "a Dwarf_Dnames head record failed."); return DW_DLV_ERROR; } dn_header->dn_section_data = start_section; dn_header->dn_section_size = section_size; dn_header->dn_section_end = start_section + section_size; dn_header->dn_dbg = dbg; for ( ; curptr < end_section; ) { struct Dwarf_Dnames_index_header_s * index_header = 0; Dwarf_Small *curptr_start = curptr; Dwarf_Unsigned usedspace = 0; Dwarf_Unsigned section_offset = curptr - start_section; res = read_a_name_index(dn_header, section_offset, &curptr, end_section, remaining, &index_header, error); if (res == DW_DLV_ERROR) { free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); return res; } if (res == DW_DLV_NO_ENTRY) { /* Impossible. A bug. Or possibly a bunch of zero pad? */ free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); break; } /* Add the new one to the list. */ if (!inhdr_first) { inhdr_count = 1; inhdr_first = index_header; inhdr_last = index_header; } else { struct Dwarf_Dnames_index_header_s *tmp = inhdr_last; inhdr_last = index_header; tmp->din_next = index_header; inhdr_count++; } usedspace = curptr - curptr_start; remaining -= - usedspace; if (remaining < 5) { /* No more in here, just padding. Check for zero in padding. */ if ((curptr +remaining) < end_section) { free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_OFF_END); return DW_DLV_ERROR; } for ( ; curptr < end_section; ++curptr) { if (*curptr) { /* One could argue this is a harmless error, but for now assume it is real corruption. */ free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_PAD_NON_ZERO); return DW_DLV_ERROR; } } } } { struct Dwarf_Dnames_index_header_s *cur = 0; int n = 0; dn_header->dn_inhdr_first = (struct Dwarf_Dnames_index_header_s *) calloc(inhdr_count, sizeof(struct Dwarf_Dnames_index_header_s)); if (!dn_header->dn_inhdr_first) { free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); _dwarf_error_string(dbg, error,DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: calloc of a Dwarf_Dnames index" " header failed."); return DW_DLV_ERROR; } for (n = 0,cur = inhdr_first; cur; ++n ) { /* We are copying these structs so do not free them at this time. */ struct Dwarf_Dnames_index_header_s *tmp = cur->din_next; dn_header->dn_inhdr_first[n] = *cur; cur = tmp; } } *dn_out = dn_header; *dn_count_out = inhdr_count; return DW_DLV_OK; } int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned * section_offset, Dwarf_Unsigned * version, /* 5 */ Dwarf_Unsigned * offset_size, /* 4 or 8 */ /* The counts are entry counts, not bye sizes. */ Dwarf_Unsigned * comp_unit_count, Dwarf_Unsigned * local_type_unit_count, Dwarf_Unsigned * foreign_type_unit_count, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * name_count, /* The following are counted in bytes */ Dwarf_Unsigned * indextable_overall_length, Dwarf_Unsigned * abbrev_table_size, Dwarf_Unsigned * entry_pool_size, Dwarf_Unsigned * augmentation_string_size, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; int res = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } if (section_offset) { *section_offset = cur->din_section_offset; } if (version) { *version = cur->din_version; } if (offset_size) { *offset_size = cur->din_offset_size; } if (comp_unit_count) { *comp_unit_count = cur->din_comp_unit_count; } if (local_type_unit_count) { *local_type_unit_count = cur->din_local_type_unit_count; } if (foreign_type_unit_count) { *foreign_type_unit_count = cur->din_foreign_type_unit_count; } if (bucket_count) { *bucket_count = cur->din_bucket_count; } if (name_count) { *name_count = cur->din_name_count; } if (abbrev_table_size) { *abbrev_table_size = cur->din_abbrev_table_size; } if (entry_pool_size) { *entry_pool_size = cur->din_entry_pool_size; } if (augmentation_string_size) { *augmentation_string_size = cur->din_augmentation_string_size; } if (indextable_overall_length) { *indextable_overall_length = cur->din_indextable_length; } return DW_DLV_OK; } int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_number >= cur->din_comp_unit_count) { if (offset_count) { *offset_count = cur->din_comp_unit_count; } return DW_DLV_NO_ENTRY; } if (offset) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_cu_list + offset_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_local_tu_list; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, cur->din_offset_size, error,endptr); *offset = offsetval; } if (offset_count) { *offset_count = cur->din_comp_unit_count; } return DW_DLV_OK; } int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_number >= cur->din_local_type_unit_count) { if (offset_count) { *offset_count = cur->din_local_type_unit_count; } return DW_DLV_NO_ENTRY; } if (offset) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_local_tu_list + offset_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_foreign_tu_list; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, cur->din_offset_size, error,endptr); *offset = offsetval; } if (offset_count) { *offset_count = cur->din_local_type_unit_count; } return DW_DLV_OK; } /* Here the sig_number ranges from local_type_unit_count to local_type_unit_count+foreign_type_unit_count-1 because the foreign indices are a continuation of the local tu indices. */ int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned sig_number, /* these index starting at local_type_unit_count */ Dwarf_Unsigned * sig_minimum, Dwarf_Unsigned * sig_count, Dwarf_Sig8 * signature, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; unsigned legal_low = 0; unsigned legal_high = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; legal_low = cur->din_local_type_unit_count; legal_high = legal_low + cur->din_foreign_type_unit_count; if (sig_number < legal_low) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } if (sig_number >= legal_high) { if (sig_minimum) { *sig_minimum = legal_low; } if (sig_count) { *sig_count = cur->din_foreign_type_unit_count; } return DW_DLV_NO_ENTRY; } if (signature) { Dwarf_Small *ptr = cur->din_foreign_tu_list + sig_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_hash_table; if ((ptr +sizeof(Dwarf_Sig8)) > endptr) { _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } memcpy(signature,ptr,sizeof(Dwarf_Sig8)); } if (sig_minimum) { *sig_minimum = legal_low; } if (sig_count) { *sig_count = cur->din_foreign_type_unit_count; } return DW_DLV_OK; } /* The hash table is composed of the buckets table and the hashes table. If there is no buckets table (bucket_count == 0) the hashes part still exists. */ int dwarf_debugnames_bucket(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned bucket_number, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * index_of_name_entry, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (bucket_number >= cur->din_bucket_count) { if (bucket_count) { *bucket_count = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } if (index_of_name_entry) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_buckets + bucket_number * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_hash_table; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *index_of_name_entry = offsetval; } if (bucket_count) { *bucket_count = cur->din_bucket_count; } return DW_DLV_OK; } /* Access to the .debug_names name table. */ int dwarf_debugnames_name(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned name_entry, Dwarf_Unsigned * names_count, Dwarf_Sig8 * signature, Dwarf_Unsigned * offset_to_debug_str, Dwarf_Unsigned * offset_in_entrypool, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (name_entry >= cur->din_name_count) { if (names_count) { *names_count = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } if (signature) { Dwarf_Small *ptr = cur->din_hash_table + name_entry *sizeof(Dwarf_Sig8); Dwarf_Small *endptr = cur->din_string_offsets; if ((ptr + sizeof(Dwarf_Sig8)) > endptr) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } memcpy(signature,ptr,sizeof(Dwarf_Sig8)); } if (offset_to_debug_str) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_string_offsets + name_entry * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_abbreviations; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *offset_to_debug_str = offsetval; } if (offset_in_entrypool) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_entry_offsets + name_entry * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_abbreviations; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *offset_in_entrypool = offsetval; } if (names_count) { *names_count = cur->din_name_count; } return DW_DLV_OK; } /* If abbrev_code returned is zero there is no tag returned and we are at the end of the entry pool set for this name entry. abbrev code, tag nameindexattr,form ... 0,0 ... repeat like the above 0 */ /* This provides a way to print the abbrev table by indexing from 0. */ int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * number_of_abbrev, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error *error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; int res = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } if (abbrev_entry >= cur->din_abbrev_list_count) { if (number_of_abbrev) { *number_of_abbrev = cur->din_abbrev_list_count; } return DW_DLV_NO_ENTRY; } abbrev = cur->din_abbrev_list + abbrev_entry; if (abbrev_code) { *abbrev_code = abbrev->da_abbrev_code; } if (tag) { *tag = abbrev->da_tag; } if (number_of_abbrev) { *number_of_abbrev = cur->din_abbrev_list_count; } if (number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } static int _dwarf_internal_abbrev_by_code( struct Dwarf_Dnames_index_header_s *cur, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * number_of_attr_form_entries) { unsigned n = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; abbrev = cur->din_abbrev_list; for (n = 0; n < cur->din_abbrev_list_count; ++n,++abbrev) { if (abbrev_code == abbrev->da_abbrev_code) { if (tag) { *tag = abbrev->da_tag; } if (index_of_abbrev) { *index_of_abbrev = n; } if (number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } } /* Something is wrong, not found! */ return DW_DLV_NO_ENTRY; } /* Access the abbrev by abbrev code (instead of index). */ int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * index_of_abbrev, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_internal_abbrev_by_code(cur, abbrev_code, tag, index_of_abbrev, number_of_attr_form_entries); return res; } int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry_index, Dwarf_Unsigned abbrev_form_index, Dwarf_Unsigned * name_index_attr, Dwarf_Unsigned * form, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; struct abbrev_pair_s *ap = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } if (abbrev_entry_index >= cur->din_abbrev_list_count) { if (number_of_attr_form_entries) { *number_of_attr_form_entries = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } abbrev = cur->din_abbrev_list + abbrev_entry_index; if (abbrev_form_index >= abbrev->da_pairs_count) { return DW_DLV_NO_ENTRY; } ap = abbrev->da_pairs + abbrev_entry_index; if (name_index_attr) { *name_index_attr = ap->ap_index; } if (form) { *form = ap->ap_form; } if (number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_in_entrypool, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * value_count, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * offset_of_initial_value, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Small *entrypool = 0; Dwarf_Small *endentrypool = 0; Dwarf_Unsigned abcode = 0; Dwarf_Unsigned leblen = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_in_entrypool >= cur->din_entry_pool_size) { _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); return DW_DLV_ERROR; } endentrypool = cur->din_entry_pool +cur->din_entry_pool_size; entrypool = cur->din_entry_pool + offset_in_entrypool; DECODE_LEB128_UWORD_LEN_CK(entrypool,abcode,leblen, dbg,error,endentrypool); res = _dwarf_internal_abbrev_by_code(cur, abcode, tag, index_of_abbrev, value_count); if (res != DW_DLV_OK) { /* Never DW_DLV_ERROR (so far) */ return res; } *offset_of_initial_value = offset_in_entrypool + leblen; *abbrev_code = abcode; return DW_DLV_OK; } /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. While an array of structs would be easier for the caller to allocate than parallel arrays, public structs have turned out to be difficult to work with as interfaces (as formats change over time). */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned index_of_abbrev, Dwarf_Unsigned offset_in_entrypool_of_values, Dwarf_Unsigned * array_dw_idx_number, Dwarf_Unsigned * array_form, Dwarf_Unsigned * array_of_offsets, Dwarf_Sig8 * array_of_signatures, /* offset of the next entrypool entry. */ Dwarf_Unsigned * offset_of_next_entrypool, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; Dwarf_Debug dbg = 0; unsigned n = 0; int res = 0; Dwarf_Unsigned abcount = 0; Dwarf_Unsigned pooloffset = offset_in_entrypool_of_values; Dwarf_Small * endpool = 0; Dwarf_Small * poolptr = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; endpool = cur->din_entry_pool + cur->din_entry_pool_size; if (index_of_abbrev >= cur->din_abbrev_list_count) { _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); return DW_DLV_ERROR; } poolptr = cur->din_entry_pool + offset_in_entrypool_of_values; abbrev = cur->din_abbrev_list + index_of_abbrev; abcount = cur->din_abbrev_list_count; for (n = 0; n < abcount ; ++n) { struct abbrev_pair_s *abp = abbrev->da_pairs +n; unsigned idxtype = abp->ap_index; unsigned form = abp->ap_form; array_dw_idx_number[n] = idxtype; array_form[n] = form; if (form == DW_FORM_data8 && idxtype == DW_IDX_type_hash) { if ((poolptr + sizeof(Dwarf_Sig8)) > endpool){ _dwarf_error(dbg,error, DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); return DW_DLV_ERROR; } memcpy(array_of_signatures+n, poolptr,sizeof(Dwarf_Sig8)); poolptr += sizeof(Dwarf_Sig8); pooloffset += sizeof(Dwarf_Sig8); continue; } else if (_dwarf_allow_formudata(form)) { Dwarf_Unsigned val = 0; Dwarf_Unsigned bytesread = 0; res = _dwarf_formudata_internal(dbg,form,poolptr, endpool,&val,&bytesread,error); if (res != DW_DLV_OK) { return res; } poolptr += bytesread; pooloffset += bytesread; array_of_offsets[n] = val; continue; } /* There is some mistake/omission in our code here or in the data. */ { dwarfstring m; const char *name = ""; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_NAMES_UNHANDLED_FORM: Form 0x%x", form); dwarf_get_FORM_name(form,&name); dwarfstring_append_printf_s(&m, " %s is not currently supported in .debug_names ", (char *)name); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_NAMES_UNHANDLED_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); } return DW_DLV_ERROR; } *offset_of_next_entrypool = pooloffset; return DW_DLV_OK; } /* Frees any Dwarf_Dnames_Head_s data that is directly mallocd. */ void _dwarf_debugnames_destructor(void *m) { struct Dwarf_Dnames_Head_s *h = (struct Dwarf_Dnames_Head_s *)m; struct Dwarf_Dnames_index_header_s *cur = 0; unsigned n = 0; cur = h->dn_inhdr_first; for ( ;n < h->dn_inhdr_count ; ++n,++cur) { free_inhdr_content(cur); } free(h->dn_inhdr_first); h->dn_inhdr_first = 0; h->dn_inhdr_count = 0; } libdwarf-20210528/libdwarf/dwarf_global.c0000664000175000017500000010523314004650150015054 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_global.h" #define FALSE 0 #define TRUE 1 #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ /* The 'fixup' here intended for IRIX targets only. With a 2+GB Elf64 IRIX executable (under 4GB in size), some DIE offsets wrongly got the 32bit upper bit sign extended. For the cu-header offset in the .debug_pubnames section and in the .debug_aranges section. the 'varp' here is a pointer to an offset into .debug_info. We fix up the offset here if it seems advisable.. As of June 2005 we have identified a series of mistakes in ldx64 that can cause this (64 bit values getting passed thru 32-bit signed knothole). */ void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, Dwarf_Unsigned * varp, char *caller_site_name) { Dwarf_Unsigned var = *varp; #define UPPER33 0xffffffff80000000LL #define LOWER32 0xffffffffLL /* Restrict the hack to the known case. Upper 32 bits erroneously sign extended from lower 32 upper bit. */ if ((var & UPPER33) == UPPER33) { var &= LOWER32; /* Apply the fix. Dreadful hack. */ *varp = var; } #undef UPPER33 #undef LOWER32 return; } #endif /* __sgi */ static void dealloc_globals_chain(Dwarf_Debug dbg, Dwarf_Chain head_chain) { Dwarf_Chain curr_chain = 0; Dwarf_Chain prev_chain = 0; int chaintype = DW_DLA_CHAIN; Dwarf_Global_Context lastcontext = 0; Dwarf_Global_Context curcontext = 0; curr_chain = head_chain; for (; curr_chain; ) { Dwarf_Global item = 0; int itemtype = 0; item = (Dwarf_Global)curr_chain->ch_item; itemtype = curr_chain->ch_itemtype; curcontext = item->gl_context; if (curcontext && curcontext != lastcontext) { /* First time we see a context, dealloc it. */ lastcontext = curcontext; dwarf_dealloc(dbg,curcontext,curcontext->pu_alloc_type); } prev_chain = curr_chain; dwarf_dealloc(dbg, item,itemtype); prev_chain->ch_item = 0; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, chaintype); } } int dwarf_get_globals(Dwarf_Debug dbg, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_pubnames.dss_size) { return DW_DLV_NO_ENTRY; } res = _dwarf_internal_get_pubnames_like_data(dbg, ".debug_pubnames", dbg->de_debug_pubnames.dss_data, dbg->de_debug_pubnames.dss_size, globals, return_count, error, DW_DLA_GLOBAL_CONTEXT, DW_DLA_GLOBAL, DW_DLE_PUBNAMES_LENGTH_BAD, DW_DLE_PUBNAMES_VERSION_ERROR); return res; } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, dwgl, count); return; } void _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, Dwarf_Signed count) { Dwarf_Signed i = 0; struct Dwarf_Global_Context_s *glcp = 0; struct Dwarf_Global_Context_s *lastglcp = 0; if (!dwgl) { return; } for (i = 0; i < count; i++) { Dwarf_Global dgd = dwgl[i]; if (!dgd) { continue; } /* Avoids duplicate frees of repeated use of contexts (while assuming that all uses of a particular gl_context will appear next to each other. */ glcp = dgd->gl_context; if (glcp && lastglcp != glcp) { lastglcp = glcp; dwarf_dealloc(dbg, glcp, glcp->pu_alloc_type); } dwarf_dealloc(dbg, dgd, dgd->gl_alloc_type); } dwarf_dealloc(dbg, dwgl, DW_DLA_LIST); return; } static void pubnames_error_length(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned spaceneeded, const char *secname, const char *specificloc) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m,"DW_DLE_PUBNAMES_LENGTH_BAD: " " In section "); dwarfstring_append(&m,(char *)secname); dwarfstring_append_printf_u(&m, " %u bytes of space needed " "but the section is out of space ", spaceneeded); dwarfstring_append(&m, "reading "); dwarfstring_append(&m, (char *)specificloc); dwarfstring_append(&m, "."); _dwarf_error_string(dbg,error,DW_DLE_PUBNAMES_LENGTH_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); } /* INVARIANTS: 1) on error does not leak Dwarf_Global 2) glname is not malloc space. Never free. */ static int _dwarf_make_global_add_to_chain(Dwarf_Debug dbg, Dwarf_Unsigned global_DLA_code, Dwarf_Global_Context pubnames_context, Dwarf_Off die_offset_in_cu, unsigned char * glname, Dwarf_Unsigned *global_count, Dwarf_Bool *pubnames_context_on_list, Dwarf_Chain *prev_chain, Dwarf_Chain *head_chain, Dwarf_Error *error) { Dwarf_Chain curr_chain = 0; Dwarf_Global global = 0; global = (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1); if (!global) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } (*global_count)++; /* Recording the same context in another Dwarf_Global */ global->gl_context = pubnames_context; global->gl_alloc_type = global_DLA_code; global->gl_named_die_offset_within_cu = die_offset_in_cu; global->gl_name = glname; /* Finish off current entry chain */ curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (!curr_chain) { dwarf_dealloc(dbg,global,global_DLA_code); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Put current global on singly_linked list. */ curr_chain->ch_item = (Dwarf_Global) global; curr_chain->ch_itemtype = global_DLA_code; if (!*head_chain) { *head_chain = *prev_chain = curr_chain; } else { (*prev_chain)->ch_next = curr_chain; *prev_chain = curr_chain; } *pubnames_context_on_list = TRUE; return DW_DLV_OK; } /* Sweeps the complete section. */ int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, const char *secname, Dwarf_Small * section_data_ptr, Dwarf_Unsigned section_length, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error, int context_DLA_code, int global_DLA_code, int length_err_num, int version_err_num) { Dwarf_Small *pubnames_like_ptr = 0; Dwarf_Off pubnames_section_offset = 0; Dwarf_Small *section_end_ptr = section_data_ptr +section_length; /* Points to the context for the current set of global names, and contains information to identify the compilation-unit that the set refers to. */ Dwarf_Global_Context pubnames_context = 0; Dwarf_Bool pubnames_context_on_list = FALSE; Dwarf_Unsigned version = 0; /* Offset from the start of compilation-unit for the current global. */ Dwarf_Off die_offset_in_cu = 0; Dwarf_Unsigned global_count = 0; /* Used to chain the Dwarf_Global_s structs for creating contiguous list of pointers to the structs. */ Dwarf_Chain prev_chain = 0; Dwarf_Chain head_chain = 0; /* Points to contiguous block of Dwarf_Global to be returned. */ Dwarf_Global *ret_globals = 0; int mres = 0; /* Temporary counter. */ Dwarf_Unsigned i = 0; if (!dbg) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } /* We will eventually need the .debug_info data. Load it now. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } if (section_data_ptr == NULL) { return DW_DLV_NO_ENTRY; } pubnames_like_ptr = section_data_ptr; do { Dwarf_Unsigned length = 0; int local_extension_size = 0; int local_length_size = 0; /* Some compilers emit padding at the end of each cu's area. pubnames_ptr_past_end_cu records the true area end for the pubnames(like) content of a cu. Essentially the length in the header and the 0 terminator of the data are redundant information. The dwarf2/3 spec does not mention what to do if the length is past the 0 terminator. So we take any bytes left after the 0 as padding and ignore them. */ Dwarf_Small *pubnames_ptr_past_end_cu = 0; pubnames_context_on_list = FALSE; pubnames_context = (Dwarf_Global_Context) _dwarf_get_alloc(dbg, context_DLA_code, 1); if (pubnames_context == NULL) { dealloc_globals_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* ========pubnames_context not recorded anywhere yet. */ /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed bytes. */ if ((pubnames_like_ptr + DWARF_32BIT_SIZE + DWARF_HALF_SIZE + DWARF_32BIT_SIZE) > /* A minimum size needed */ section_end_ptr) { pubnames_error_length(dbg,error, DWARF_32BIT_SIZE + DWARF_HALF_SIZE + DWARF_32BIT_SIZE, secname, "header-record"); dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return DW_DLV_ERROR; } mres = _dwarf_read_area_length_ck_wrapper(dbg, &length,&pubnames_like_ptr,&local_length_size, &local_extension_size,section_length,section_end_ptr, error); if (mres != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return mres; } pubnames_context->pu_alloc_type = context_DLA_code; pubnames_context->pu_length_size = local_length_size; pubnames_context->pu_length = length; pubnames_context->pu_extension_size = local_extension_size; pubnames_context->pu_dbg = dbg; pubnames_context->pu_pub_offset = pubnames_section_offset; pubnames_ptr_past_end_cu = pubnames_like_ptr + length; if ((pubnames_like_ptr + (DWARF_HALF_SIZE) ) > /* A minimum size needed */ section_end_ptr) { pubnames_error_length(dbg,error, DWARF_HALF_SIZE, secname,"version-number"); dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return DW_DLV_ERROR; } mres = _dwarf_read_unaligned_ck_wrapper(dbg, &version,pubnames_like_ptr,DWARF_HALF_SIZE, section_end_ptr,error); if (mres != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return mres; } pubnames_context->pu_version = version; pubnames_like_ptr += DWARF_HALF_SIZE; /* ASSERT: DW_PUBNAMES_VERSION2 == DW_PUBTYPES_VERSION2 */ if (version != DW_PUBNAMES_VERSION2) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } _dwarf_error(dbg, error, version_err_num); return DW_DLV_ERROR; } /* Offset of CU header in debug section. */ if ((pubnames_like_ptr + 3*pubnames_context->pu_length_size)> section_end_ptr) { pubnames_error_length(dbg,error, 3*pubnames_context->pu_length_size, secname, "header/DIE offsets"); dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return DW_DLV_ERROR; } mres = _dwarf_read_unaligned_ck_wrapper(dbg, &pubnames_context->pu_offset_of_cu_header, pubnames_like_ptr, pubnames_context->pu_length_size, section_end_ptr,error); if (mres != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return mres; } pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, pubnames_context->pu_offset_of_cu_header, "pubnames cu header offset"); mres = _dwarf_read_unaligned_ck_wrapper(dbg, &pubnames_context->pu_info_length, pubnames_like_ptr, pubnames_context->pu_length_size, section_end_ptr,error); if (mres != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return mres; } pubnames_like_ptr += pubnames_context->pu_length_size; if (pubnames_like_ptr > (section_data_ptr + section_length)) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } /* ====begin pubname */ /* Read initial offset (of DIE within CU) of a pubname, final entry is not a pair, just a zero offset. */ mres = _dwarf_read_unaligned_ck_wrapper(dbg, &die_offset_in_cu, pubnames_like_ptr, pubnames_context->pu_length_size, section_end_ptr,error); if (mres != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } return mres; } pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, die_offset_in_cu, "offset of die in cu"); if (pubnames_like_ptr > (section_data_ptr + section_length)) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } /* Loop thru pairs. DIE off with CU followed by string. */ if (!die_offset_in_cu) { if (dbg->de_return_empty_pubnames) { int res = 0; /* Here we have a pubnames CU with no actual entries so we fake up an entry to hold the header data. There are no 'pairs' here, just the end of list zero value. We do this only if de_return_empty_pubnames is set so that we by default return exactly the same data this always returned, yet dwarfdump can request the empty-cu records get created to test that feature. see dwarf_get_globals_header() */ res = _dwarf_make_global_add_to_chain(dbg, global_DLA_code, pubnames_context, die_offset_in_cu, /* It is a fake global, so empty name */ (unsigned char *)"", &global_count, &pubnames_context_on_list, &prev_chain, &head_chain, error); if (res != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } return res; } /* ========pubnames_context recorded in chain. */ } else { /* The section is empty. Nowhere to record pubnames_context); */ dwarf_dealloc(dbg,pubnames_context,context_DLA_code); pubnames_context = 0; continue; } } while (die_offset_in_cu) { int res = 0; unsigned char *glname = 0; /* non-zero die_offset_in_cu already read, so pubnames_like_ptr points to a string. */ res = _dwarf_check_string_valid(dbg,section_data_ptr, pubnames_like_ptr,section_end_ptr, DW_DLE_STRING_OFF_END_PUBNAMES_LIKE,error); if (res != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } return res; } glname = (unsigned char *)pubnames_like_ptr; pubnames_like_ptr = pubnames_like_ptr + strlen((char *) pubnames_like_ptr) + 1; /* Already read offset and verified string, glname now points to the string. */ res = _dwarf_make_global_add_to_chain(dbg, global_DLA_code, pubnames_context, die_offset_in_cu, glname, &global_count, &pubnames_context_on_list, &prev_chain, &head_chain, error); if (res != DW_DLV_OK) { dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } return res; } /* ========pubnames_context recorded in chain. */ /* Ensure room for a next entry to exist. */ if ((pubnames_like_ptr + pubnames_context->pu_length_size ) > section_end_ptr) { pubnames_error_length(dbg,error, 2*pubnames_context->pu_length_size, secname, "global record offset"); dealloc_globals_chain(dbg,head_chain); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } return DW_DLV_ERROR; } /* Read die offset for the *next* entry */ mres = _dwarf_read_unaligned_ck_wrapper(dbg, &die_offset_in_cu, pubnames_like_ptr, pubnames_context->pu_length_size, section_end_ptr,error); if (mres != DW_DLV_OK) { if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } dealloc_globals_chain(dbg,head_chain); return mres; } pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, die_offset_in_cu, "offset of next die in cu"); if (pubnames_like_ptr > (section_data_ptr + section_length)) { if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); } dealloc_globals_chain(dbg,head_chain); _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } } /* ASSERT: die_offset_in_cu == 0 */ if (pubnames_like_ptr > pubnames_ptr_past_end_cu) { /* This is some kind of error. This simply cannot happen. The encoding is wrong or the length in the header for this cu's contribution is wrong. */ _dwarf_error(dbg, error, length_err_num); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } dealloc_globals_chain(dbg,head_chain); return DW_DLV_ERROR; } /* If there is some kind of padding at the end of the section, as emitted by some compilers, skip over that padding and simply ignore the bytes thus passed-over. With most compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at this point */ { Dwarf_Unsigned increment = pubnames_context->pu_length_size + pubnames_context->pu_length + pubnames_context->pu_extension_size; pubnames_section_offset += increment; } pubnames_like_ptr = pubnames_ptr_past_end_cu; } while (pubnames_like_ptr < section_end_ptr); /* Points to contiguous block of Dwarf_Global. */ ret_globals = (Dwarf_Global *) _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); if (ret_globals == NULL) { if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); } dealloc_globals_chain(dbg,head_chain); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Store pointers to Dwarf_Global_s structs in contiguous block, and deallocate the chain. This ignores the various headers */ { Dwarf_Chain curr_chain = 0; curr_chain = head_chain; for (i = 0; i < global_count; i++) { *(ret_globals + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; prev_chain->ch_item = 0; /* Not actually necessary. */ dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } } *globals = ret_globals; *return_count = (Dwarf_Signed) global_count; return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_name pointer a pointer to the string which is the entry name. */ int dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error) { if (glob == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } *ret_name = (char *) (glob->gl_name); return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_off pointer the global offset of the DIE for this entry. The global offset is the offset within the .debug_info section as a whole. */ int dwarf_global_die_offset(Dwarf_Global global, Dwarf_Off * ret_off, Dwarf_Error * error) { if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } if (global->gl_context == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return DW_DLV_ERROR; } *ret_off = (global->gl_named_die_offset_within_cu + global->gl_context->pu_offset_of_cu_header); return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_off pointer the offset of the compilation unit header of the compilation unit the global is part of. In early versions of this, the value returned was the offset of the compilation unit die, and other cu-local die offsets were faked so adding this to such a cu-local offset got a true section offset. Now things do as they say (adding *cu_header_offset to a cu-local offset gets the section offset). */ int dwarf_global_cu_offset(Dwarf_Global global, Dwarf_Off * cu_header_offset, Dwarf_Error * error) { Dwarf_Global_Context con = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return DW_DLV_ERROR; } /* In early libdwarf, this incorrectly returned the offset of the CU DIE. Now correctly returns the header offset. */ *cu_header_offset = con->pu_offset_of_cu_header; return DW_DLV_OK; } static void build_off_end_msg(Dwarf_Unsigned offval, Dwarf_Unsigned withincr, Dwarf_Unsigned secsize, dwarfstring *m) { const char *msg = "past"; if (offval < secsize){ msg = "too near"; } dwarfstring_append_printf_u(m,"DW_DLE_OFFSET_BAD: " "The CU header offset of %u in a pubnames-like entry ", withincr); dwarfstring_append_printf_s(m, "would put us %s the end of .debug_info. " "No room for a DIE there... " "Corrupt Dwarf.",(char *)msg); return; } /* Give back the pubnames entry (or any other like section) name, symbol DIE offset, and the cu-DIE offset. Various errors are possible. The string pointer returned thru ret_name is not dwarf_get_alloc()ed, so no dwarf_dealloc() DW_DLA_STRING should be applied to it. */ int dwarf_global_name_offsets(Dwarf_Global global, char **ret_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global_Context con = 0; Dwarf_Debug dbg = 0; Dwarf_Off cuhdr_off = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return DW_DLV_ERROR; } cuhdr_off = con->pu_offset_of_cu_header; /* The offset had better not be too close to the end. If it is, _dwarf_length_of_cu_header() will step off the end and therefore must not be used. 10 is a meaningless heuristic, but no CU header is that small so it is safe. An erroneous offset is due to a bug in the tool chain. A bug like this has been seen on IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and with 2 million pubnames entries. */ #define MIN_CU_HDR_SIZE 10 dbg = con->pu_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } /* Cannot refer to debug_types */ if (dbg->de_debug_info.dss_size && ((cuhdr_off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { dwarfstring m; dwarfstring_constructor(&m); build_off_end_msg(cuhdr_off,cuhdr_off+MIN_CU_HDR_SIZE, dbg->de_debug_info.dss_size,&m); _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } #undef MIN_CU_HDR_SIZE /* If global->gl_named_die_offset_within_cu is zero then this is a fake global for a pubnames CU with no pubnames. The offset is from the start of the CU header, so no die can have a zero offset, all valid offsets are positive numbers */ if (die_offset) { if (global->gl_named_die_offset_within_cu) { *die_offset = global->gl_named_die_offset_within_cu + cuhdr_off; } else { *die_offset = 0; } } *ret_name = (char *) global->gl_name; if (cu_die_offset) { /* Globals cannot refer to debug_types */ int cres = 0; Dwarf_Unsigned headerlen = 0; int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } /* The offset had better not be too close to the end. If it is, _dwarf_length_of_cu_header() will step off the end and therefore must not be used. 10 is a meaningless heuristic, but no CU header is that small so it is safe. */ /* Globals cannot refer to debug_types */ if ((cuhdr_off + 10) >= dbg->de_debug_info.dss_size) { dwarfstring m; dwarfstring_constructor(&m); build_off_end_msg(cuhdr_off,cuhdr_off+10, dbg->de_debug_info.dss_size,&m); _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *cu_die_offset = cuhdr_off + headerlen; } return DW_DLV_OK; } /* New February 2019 from better dwarfdump printing of debug_pubnames and pubtypes. For ao the Dwarf_Global records in one pubnames CU group exactly the same data will be returned. */ int dwarf_get_globals_header(Dwarf_Global global, Dwarf_Off *pub_section_hdr_offset, Dwarf_Unsigned *pub_offset_size, Dwarf_Unsigned *pub_cu_length, Dwarf_Unsigned *version, Dwarf_Off *info_header_offset, Dwarf_Unsigned *info_length, Dwarf_Error* error) { Dwarf_Global_Context con = 0; Dwarf_Debug dbg = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return DW_DLV_ERROR; } dbg = con->pu_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (pub_section_hdr_offset) { *pub_section_hdr_offset = con->pu_pub_offset; } if (pub_offset_size) { *pub_offset_size = con->pu_length_size; } if (pub_cu_length) { *pub_cu_length = con->pu_length; } if (version) { *version = con->pu_version; } if (info_header_offset) { *info_header_offset = con->pu_offset_of_cu_header; } if (info_length) { *info_length = con->pu_info_length; } return DW_DLV_OK; } /* We have the offset to a CU header. Return thru outFileOffset the offset of the CU DIE. New June, 2001. Used by SGI IRIX debuggers. No error used to be possible. As of May 2016 an error is possible if the DWARF is corrupted! (IRIX debuggers are no longer built ...) See also dwarf_CU_dieoffset_given_die(). This is assumed to never apply to data in .debug_types, it only refers to .debug_info. */ /* ARGSUSED */ int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Off * out_cu_die_offset, UNUSEDARG Dwarf_Error * err) { Dwarf_Off headerlen = 0; int cres = 0; cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,true, &headerlen,err); if (cres != DW_DLV_OK) { return cres; } *out_cu_die_offset = in_cu_header_offset + headerlen; return DW_DLV_OK; } /* The following version new in October 2011, does allow finding the offset if one knows whether debug_info or debug_types or any .debug_info type including the DWARF5 flavors. It indirectly calls _dwarf_length_of_cu_header() which knows all the varieties of header. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, Dwarf_Off * out_cu_die_offset, UNUSEDARG Dwarf_Error * err) { Dwarf_Off headerlen = 0; int cres = 0; cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,is_info, &headerlen,err); if (cres != DW_DLV_OK) { return cres; } *out_cu_die_offset = in_cu_header_offset + headerlen; return DW_DLV_OK; } /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given (passed-in) die. This information makes it possible for a consumer to find and print context information for any die. Use dwarf_offdie() passing in the offset this returns to get a die pointer to the CU die. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die die, Dwarf_Off* return_offset, Dwarf_Error* error) { Dwarf_Off dieoff = 0; Dwarf_CU_Context cucontext = 0; CHECK_DIE(die, DW_DLV_ERROR); cucontext = die->di_cu_context; dieoff = cucontext->cc_debug_offset; /* The following call cannot fail, so no error check. */ dwarf_get_cu_die_offset_given_cu_header_offset_b( cucontext->cc_dbg, dieoff, die->di_is_info, return_offset,error); return DW_DLV_OK; } /* We do not want to screw up error in case it has something important. So not touching it now. */ int dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag, UNUSEDARG Dwarf_Error *err ) { if (dbg == NULL) { return DW_DLV_OK; } if (flag && flag != 1) { return DW_DLV_OK; } dbg->de_return_empty_pubnames = (unsigned char)flag; return DW_DLV_OK; } libdwarf-20210528/libdwarf/ChangeLog20150000664000175000017500000011246713644370703014372 000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-12-30 David Anderson * dwarf_elf_access.c(dwarf_elf_object_access_load_section): now test for a NULL data pointer from libelf. Problem caused by DWARF related section being marked SHT_NOBITS. 2015-12-29 David Anderson * dwarf_loc2.c: ll_dbg was not set, two places. dwarf_loc_head_c_dealloc() was not iterating through the list of locdescs. Fixed now. 2015-12-19 David Anderson * dwarf_macro5.c: specialcat() had a bug. Fixed indent/trailing whitespace. * dwarf_macro5.n: Fixed indent/trailing whitespace. * dwarf_line.c: Fixed indent/trailing whitespace. * dwarf_opaque.h: Fixed indent/trailing whitespace. 2015-12-19 David Anderson * dwarf_line.c: Rename a function and make it callable from other files: _dwarf_file_name_is_full_path(). Refactor creating _dwarf_internal_get_die_comp_dir(). * dwarf_macro5.c: Use _dwarf_internal_get_die_comp_dir() and _dwarf_file_name_is_full_path() for DWARF4/5 macro file names. * dwarf_macro5.h: New fields in macro context for the base file name. * dwarf_opaque.h: New field of comp_dir name on CU Context. * dwarf_util.c: Implement _dwarf_internal_get_die_comp_dir(). * dwarf_util.h: Declare _dwarf_internal_get_die_comp_dir(). 2015-12-18 David Anderson * dwarf_query: One line had trailing whitespace. Fixed. * dwarf_macro5.c: Was not getting import offset right. Off by one error. 2015-12-16 David Anderson * dwarf_query.c(dwarf_die_offsets): Added commentary.. Revised the code so it's a bit easier to read and reason about. 2015-12-15 David Anderson * dwarf_form.c: Refactored to simplify DWARF5 macro code. * dwarf_macro5.c,dwarf_macro5.h,dwarf_opaque.h,libdwarf.h.in: Now support for DWARF5 macros is nearly complete. 2015-12-13 David Anderson * dwarf_error.c: Add DW_DLE_MACRO_PAST_END * libdwarf.h.in: Add DW_DLE_MACRO_PAST_END and dwarf_get_macro_ops_count() declaration. * dwarf_macro5.c: Implement dwarf_get_macro_ops_count() and refactor a little bit. * dwarf_macro5.h: New fields supporting dwarf_get_macro_ops_count(). 2015-12-12 David Anderson * dwarf_error.c,libdwarf.h.in: Adding DW_DLE_MACRO_OP_UNHANDLED. * dwarf_macro5.c: Now validates form numbers when there is an extension operator. Fixed indents too. 2015-12-11 David Anderson * dwarf_alloc.c: Remove () around simple return value. * dwarf_error.c: Two new error codes for DWARF5 macro section. * dwarf5_macro.c,dwarf5_macro.h: Add functions to let reader read/print .debug_macro section header. Fixed _dwarf_macro_constructor declaration and implementation to return DW_DLV_OK. * libdwarf.h.in: Add functions to let reader read/print .debug_macro section header. 2015-12-08 David Anderson * dwarf.h,dwarf_frame.c: Add DW_CFA_METAWARE_info. * dwarf_frame.h: Add aug_metaware to enum. * dwarf_frame2.c: Add aug_metaware handling. * dwarf_util.c: Delete unused local variable. 2015-12-08 David Anderson * dwarf_die_deliv.c,dwarf_query.c,dwarf_util.c,libdwarf.h.in: Fix indents, remove trailing whitespace. Remove some useless () in return statements. 2015-12-08 David Anderson * dwarf_init_finish.c: Added a cast to strncmp() call to avoid warning. * dwarf_abbrev.c,dwarf_die_deliv.c,dwarf_error.c,dwarf_opaque.h, dwarf_query.c,dwarf_util.c,dwarf_util.h: Now check for valid forms when reading forms. Return error code as appropriate (now _dwarf_get_abbrev_for_code returns DW_DLV* as appropriate instead of a pointer). Left error placeholders for eventual merge with DWARF5 macro code. * libdwarf.h.in: New error code for FORM problems,DW_DLE_UNKNOWN_FORM. 2015-12-03 David Anderson * dwarf_macro5.c, dwarf_macro5.c: sentinal->sentinel. 2015-12-02 David Anderson * Makefile.in: Bug building .so. Change $dwfzlib to $(dwfzlib) to fix. 2015-11-30 David Anderson * dwarf_alloc.c,dwarf_macro5.c,dwarf_macro5.h,libdwarf.h.in: Remove trailing whitespace. 2015-11-30 David Anderson * Makefile.in: Add dwarf_macro5.o to build list. * dwarfdump.c: Add macro_flag flag to signal print of DWARF5 debug_macro data. * dwarf.h: Fix spelling of DWARF5 DW_MACRO fields. * dwarf_alloc.c: Add DW_DLA_MACRO_CONTEXT to alloc list. * dwarf_alloc.h: Add 1 to ALLOC_AREA_INDEX_TABLE_MAX. * dwarf_init_finish.c: New function dwarf_get_section_max_offsets_c returns sizes of all sections, including DWARF5. * dwarf_macro5.c: New,for DWARF5 macro access. Implements dwarf_get_macro_context() etc. * dwarf_macro5.h: Declare new internal macro structs. * libdwarf.h.in: Declare new macro interfaces. 2015-11-28 David Anderson * dwarf_frame.c: Added dwarf_get_frame_section_name(), dwarf_get_frame_section_name_eh_gnu() for better section name reporting for clients that care about that. * libdwarf.h.in: Declared the new section name interfaces. * libdwarf2.1.mm: Documented the new functions. Version 2.36. * libdwarf2.1.pdf: Regenerated. 2015-11-27 David Anderson * dwarf_die_deliv.c: Added dwarf_get_die_section_name_b(). * dwarf_line.c: Added dwarf_get_ranges_section_name() dwarf_get_aranges_section_name(), dwarf_get_line_section_name_from_die(), dwarf_get_string_section_name. * libdwarf.h.in: Added new function names. * libdwarf2.1.mm: Version 2.35. Documented new functions. * libdwarf2.1.pdf: Regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. * libdwarf/dwarf_error.c: New error codes for zlib use. * dwarf_init_finish.c: Supports zlib and .zdebug sections. * dwarf_opaque.h: New fields for zlib support. * libdwarf.h.in: New error codes for zlib use. 2015-11-25 David Anderson * dwarf.h: Removed trailing space. * dwarf_elf_access.c: Small preparation for handling .zdebug. * dwarf_init_finish.c: Preparation for handling .zdebug zlib compressed dwarf .debug_ sections. Uses new function and new SET_UP_SECTION macro to shorten code and ensure no unwanted differences present. * dwarf_tied.c: Remove trailing whitespace. * dwarf_opaque.h: New fields in preparation for .zdebug handling. 2015-11-24 David Anderson * dwarf_tied.c: Code reading tied CU headers only worked by accident but is fixed. Reads only as far as needed in tied for the signature being referenced. 2015-11-15 David Anderson * Makefile.in,configure.in: These now support building in separate clean directory. * configure: Regenerated. 2015-11-11 David Anderson * dwarf_opaque.h: Delete two useless blank lines. 2015-11-09 David Anderson * libdwarf.h.in: Removed unimplemented function declarationfrom the file. * libdwarf2.1.mm: Updated with new interface functions for DWARF5 and split dwarf. Version2.33 * libdwarf2.1.mm: Regenerated. 2015-11-08 David Anderson * dwarf_alloc.c: Fixed indents, trailing whitespace. * dwarf_loc2.c: Fixed indents, trailing whitespace. * dwarf_form.c: Made too-long line into 2 lines. * dwarf_loc.h: Removed duplicate Dwarf_Loc_c_s etc declarations. * dwarf_util.c(_dwarf_error_mv_s_to_t),dwarf_util.h: New function to eliminate duplicative code.: * dwarf_query.c): Fix bug in dwarf_get_offset_size(). Use new _dwarf_error_mv_s_to_t() to get error on correct dbg. Fixed indents, trailing whitespace. * dwarf_ranges.c: Use new _dwarf_error_mv_s_to_t() to get error on correct dbg. Fixed indents, trailing whitespace. 2015-11-07 David Anderson * dwarf_alloc.c: Added new checks so user mixing up tied dbg with regular dbg won't lead to crashes when calling dwarf_dealloc or dwarf_finish(). Zeroed out some fields to recognize space deallocated. * dwarf_die_deliv.c: Added support of split dwarf DW_AT_[GNU_]ranges_base * dwarf_form.c: Load string from tieddbg when appropriate. * dwarf_harmless.c: On free() zero out a field to show that was done. * dwarf_loc.c: Correct the handling of split dwarf loclist. * dwarf_opaque.h: Add cc_ranges_base_present for split dwarf. Add _dwarf_get_ranges_base_attr_from_tied() for split dwarf. * dwarf_query.c: Get and remember skeleton compilaton unit DW_AT_[GNU_]ranges_base from tied objects for split dwarf. * dwarf_ranges.c: If a tied object present, look for ranges there, not in split dwarf object. * dwarf_util.c: Housekeeping zeros out fields to ensure not used after dealloc. 2015-11-01 David Anderson * configure.in: Added -O0 to --enable-wall. So if a coredump while debugging gdb will work well. * configure: Regenerated. 2015-11-01 David Anderson * Makefile.in: Split out dwarf_loc2 to put the DWARF5 expression code all in one place. * dwarf_alloc.c,dwarf_alloc.h: Three new opaque structs for DWARF5 expression interfaces. * dwarf_error.c: New error codes for DWARF5 expression interfaces. * dwarf_frame.c: Altered internal interfaces to support DWARF5 expression reading. * dwarf_loc.c: Refactored to support DWARF5 and moved some code into dwarf_loc2.c to segregate the new interfaces for clarity. * dwarf_loc.h: Definitions of new library-internal structs (opaque to callers). * dwarf_loc2.c: Contains the new DWARF5 location expression interface code. It is not separately compiled, it is #included by dwarf_loc.c. * dwarf_opaque.h: Commentary change. * dwarf_query.c: dwarf_get_offset_size() new. Refactored to avoid duplicating code. * libdwarf.h.in: DWARF5 location expression interfaces refined and commentary improved.q 2015-10-28 David Anderson * dwarf_loc2.c: New file with the new code for DWARF5 location expressions put here. Not separate compile, this is brought into dwarf_loc.c via a #include there 2015-10-26 David Anderson * Makefile.in: Handle the configure --enable-wall option. * configure.in: Add --enable-wall so we can easily get gcc's -Wall option for the build. * configure: Regenerated. * dwarf_error.c: Amplify the text for DW_DLE_LOCLIST_INTERFACE_ERROR. * dwarf_loc.c(_dwarf_read_loc_expr_op): Correct a sanity test recently introduced. Ensure the location fields all set. #if 0 some code that will be fixed with the new location interface set. * dwarf_loc.h: Revised the prototypes and commentary for the new location list interfaces. 2015-10-25 David Anderson * checkexamples.c: Add commentary to example9. * dwarf_alloc.c: Add DW_DLA_LOC_BLOCK_C and DW_CLA_LOCDESC_C allocation descriptions to array. * dwarf_alloc.h: Increase ALLOC_AREA_INDEX_TABLE_MAX to match. * dwarf_base_types.h: Increase MAX_DW_DLA to match. * dwarf_die_deliv.c: Switch some returns from pointer to the standard int DW_DLV_OK etc and return pointer through an argument. Identify which CUs are dwo by checking name for a .dwo ending. Fix whitespace endings. * dwarf_error.c: Add DW_DLE 309 to 311 errors to descriptions array. * dwarf_form.c: Remove trailing whitespace. Reformat one line so it is not so long. * dwarf_line.c: Add {} on if for clarity. Fix whitespace endings. * dwarf_line_table_reader.c: Fix whitespace endings. * dwarf_loc.c: Refactor loc. expr. reader into a routine that reads one expression, _darf_read_loc_expr_op().. Add DWARF5 operators. Add preliminary dwo expression support (which will change but this is a start). Old expression interface now explicitly supports only DWARF 2,3,4. No DWARF5. Add preliminary loclist_c support (it will change). Add commentary about the old loclist interface. * dwarf_loc.h: First cut of new interfaces (functional, not public structs). * dwarf_opaque.h: Add cc_is_dwo flag to cu context struct. * libdwarf.h.in: Rework some loclist commentary. Add first try at new loclist interfaces for DWARF2,3,4,5. New error codes for new loclist/dwo code. * libdwarf2.1.mm: Rev 2.32. New wording on old loclist interfaces. 2015-10-15 David Anderson * dwarf_util.c,dwarf_query.c: Added DW_FORM_strp_sup as same idea as DW_FORM_GNU_strp_alt. 2015-10-15 David Anderson * checkexamples.c: Fixed data type in the example code. * dwarf.h: Updated comment about DW_FORM_GNU_strp_alt * dwarf_elf_access.c: Fixed trailing whitespace and removed debug printf that got left in. * dwarf_error.c: Add new TIED file errors. DW_DLE_NO_TIED_FILE_AVAILABLE, DW_DLE_NO_TIED_STRING_AVAILABLE. * dwarf_form.c: Added support for DW_FORM_GNU_strp_alt. * dwarf_init_finish.c: #if 0 routine all_sig8bits_zero(). * dwarf_line.c: Now always notice windows-like c: etc as start of a full path. Ensure directories with \ are turned to / in line tables. (for full such transforms configure with --enable-windowspath ) Remove some debug #ifdef lines. Alter the linecontext interface to pass back table count, not linecount. * dwarf_line.h: Add commentary and lc_table_count field. * dwarf_line_table_reader_common.c: Fix indent/trailing whitespace. Now sets lc_table_count; * dwarf_opaque.h: Add _dwarf_get_string_from_tied() interface. * dwarf_print_lines.c: Remove trailing whitespace and some debug printf.. * libdwarf.h.in: New error codes. Fix trailing whitespace. Expand commentary. 2015-10-13 David Anderson * dwarf_line.c: Refactored so we have only one piece of code creating file paths from line table data. deleted obsolete code that was #if 0. * libdwarf.h.in: Fleshed out linecontext versions of two-level table readng. Revised a new interface (dwarf_srclines_b) to make it possible to do a read of just the line header. * libdwarf2.1.mm: Documented new functions. Fixed the example code so it is actually correct 2015-10-06 David Anderson * Makefile.in: Removed source files from the build that are only useful to IRIX and only in the context of building an IRIX runtime system. * dwarf_alloc.c: Added constructor/destructor code to Dwarf_Line_Context allocator. * dwarf_elf_access.c: Added additional #defines so we have the IA64 defines we need to compile certain test cases on freebsd. * dwarf_error.c: Two new error codes for Dwarf_Line_Context checking. * dwarf_line_table_reader_common.c: New file. We can compile the line reading with and without detailed print lines for dwarfdump. Now only one body of line reading code to maintain. * dwarf_line.c: Moved code out to dwarf_line_table_reader_common.c Refactored to support skeleton line tables (DWARF5) Eliminated an internal struct, it is no longer needed. a little better. Supports experimental two-level line tables too. * dwarf_print_lines.c: Uses dwarf_line_table_reader_common.c to do much of its work now. * libdwarf.h.in: New interfaces for nicer access to line table headers. * libdwarf2.1.mm: Partial documentation of the new libdwarf line table interfaces. 2015-10-01 David Anderson * dwarf_global.h: Now the last __sgi related macro (else, endif) have /* __sgi */. 2015-09-30 David Anderson * dwarf_global.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_line_table_reader_common.c,dwarf_sort_line.c,libdwarf.h.in: The SGI IRIX only fields in dwarf_line.h ifdef __sgi now. And all code referencing them that way too. Balancing #endif has /* __sgi */ now for searchability. Functions only usable on SGI IRIX only compiled in if __sgi macro defined. * libdwarf2.1.mm: Added a comment related to experimental two-level line tables. 2015-09-29 David Anderson * dwarf_die_deliv.c,dwarf_line.c,dwarf_print_lines.c: Now looks for and adds the extra offset from debug_fission: DW_SECT_LINE. 2015-09-29 David Anderson * dwarf_line.c,dwarf_line.h,dwarf_line_table_reader_common.c, dwarf_print_lines.c: Moved the prefix reading subroutine into common so the prefix-printing can have print code added (with ifdef so production does not have it). 2015-09-29 David Anderson * dwarf_line.c,dwarf_line_table_reader_common.c,dwarf_print_lines.c, dwarf_line.h,dwarf_line2.c,libdwarf.h.in: Moved some code from dwarf_line_table_reader_common.c to dwarf_line.c. Fixed indent and trailing whitespace. Fixed the 'section offset' code by using the proper value from dss_ptr.. 2015-09-28 David Anderson * dwarf_line_table_reader_common.c: New file is the line table reader extracted from dwarf_line.c. Now compiled into dwarf_line.c and dwarf_print_lines.c with correct two-level line table calculations. No more coding the table twice. * dwarf_line.c,dwarf_print_lines.c: Now #include dwarf_line_table_reader_common.c * Makefile.in: Reflects new source depedencies. * dwarf_line2.c: An internal function interface changed, so accomodated it here. * libdwarf.h.in, dwarf_error.c: New error code, DW_DLE_BAD_LINE_TABLE_OPERATION. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: Makefile.in modified: dwarf_error.c modified: dwarf_line.c modified: dwarf_line2.c modified: dwarf_line_table_reader_common.c modified: dwarf_print_lines.c modified: libdwarf.h.in 2015-09-28 David Anderson * dwarf_line.c,dwarf_line.h,dwarf_print_lines.c: made li_ and lr_ line register structs agree on spelling of suffix of each name. Now dwarf_srclines (and two-level) use the line register struct instead of a list of local variables. 2015-09-26 David Anderson * dwarf_elf_access.c: Removed some trailing spaces. * dwarf_line.c: Update the li_is_actuals_table (new field) where a new line is emitted. For later safe dealloc. Fixed indents and removed trailing spaces. Fixed the dwarf_srclines_dealloc to work properly on all the line table variations. * dwarf_line.h: Removed trailing spaces. Added li_is_actuals_table so the dealloc can work properly. * dwarf_print_lines.c: Fixed the Logicals and Actuals table formatting, Now prints the subprograms table too. * libdwarf.h.in: Added dwarf_get_LNCT_name() to function list. 2015-09-25 David Anderson * dwarf_print_lines.c: A first cut at detailed line tables. Not yet computing state register values for all two-level line tables here. 2015-09-25 David Anderson * dwarf_line.h: added a comment. * dwarf_print_lines.c: Now finds actuals and logicals tables and prints them. Incomplete but perhaps useful. 2015-09-24 David Anderson * dwarf_line.c: Renamed a local var for clarity. Added commentary for clarity. Fixed a memory leak for skeleton lined tables. Added required free() calls on error to avoid memory leaks. Moved an 'overrun' check into a loop to check on every loop iteration. * dwarf_line.h: Added commentary. 2015-09-23 David Anderson * dwarf_abbref.c,dwarf_die_deliv.c,dwarf_init_finish.c,dwarf_query.c: Removed unused local variables. * dwarf_line.c: Corrected bugs in the two-level line table support and improved error checking. Revamped the line table header reading code for clarity. See dw-linetableheader.txt . * dw-linetableheader.txt: The line table headers are a bit complicated (mostly by the experimental two-level line table support) so this file shows the header fields in order by version. * dwarf_form.c: Fixed nested comment, removed unused local variables.. * dwarf_loc.c: Cast return from _dwarf_get_alloc() to remove a compile warning. * dwarf_tied.c: Removed unused local variable. * dwarf_xu_index.c: Removed unused local variables. 2015-09-22 David Anderson * libdwarf/dwarf.h,dwarf_elf_access.c,dwarf_form.c,dwarf_line.h: Fixed indentation errors. * dwarf_line.c: Fixed indentation and corrected an error introduced a couple days ago. 2015-09-19 David Anderson * dwarf.h: Adding commentary. a DW_LNS for two-level line tables looks wrong.. * dwarf_die_deliv.c: Adding commentary. * dwarf_line.c: An internal function now has a leading _ and a context argument.. Added local names of popular pointers. * dwarf_print_lines.c,dwarf_sort_line.c: An internal function now has a leading _ and a context argument.. * dwarf_opaque.h: Added cc_segment_selector_size to contex structure. * libdwarf.h.in: Added commentary on two-level line table functions etc. 2015-09-17 David Anderson * dwarf.h, dwarf_alloc.c,dwarf_base_types.h,dwarf_init_finish.c, dwarf_line.c,dwarf_line.h,dwarf_line2.c,dwarf_util.c,libdwarf.h.in: Adding support for experimental 2-level line table. 2015-09-15 David Anderson * dwarf_form.c(_dwarf_extract_string_offset_via_str_offsets): Modified comment to reflect the current DWARF5 draft (we need not guess about correctness). 2015-09-15 David Anderson * dwarf_query.c, dwarf_form.c: We were failing check for off-end-of debug_str_offsets section correctly and had a dwarf_dealloc where it was not wanted. 2015-09-15 David Anderson * dwarf_query.c(_dwarf_extract_address_from_debug_addr): At line 540 we were deleting a dwarf_error that might not be there. Now conditional on DW_DLV_ERROR. This and around line 605 are the very rare situation we can turn one error code off and possibly or definitely substitute another error. Normally we just return the original error as the 'lowest level error.' 2015-09-15 David Anderson * dwarf_elf_access.c: Added conditional R_MIPS_64 and R_MIPS_TLS_TPREL64 defines as the headers I have for freebsd 32bit VM do not define those and we need them for testinga couple object files. 2015-09-15 Carlos Alberto Enciso * dwarf_elf_access.c: For Windows version, some compilers generate EM_PPC64 elf type, but the generated code is 32 bits. Set the correct value for 'dbg->de_pointer_size'. * dwarf_init_finish.c: For Windows version, remove the incorrect hard code value for 'dbg->de_pointer_size'. * dwgetopt.h: Add the guard 'extern "C"'. 2015-09-15 David Anderson and Carlos Alberto Enciso * dwarf_form.c (dwarf_formsig8_const): Was failing to return its return code. * dwarf_xu_index.c (_dwarf_search_fission_for_offset): Was failing to return its return code. 2015-09-14 David Anderson * dwarf_form.c,dwarf_global.c,dwarf_line.c,dwarf_macro.c,dwarf_util.c: Fixed indents and removed trailing whitespace. 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.30. Fixed awkward line in UTF-8 section. * libdwarf2.1.pdf: Regenerated 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.29. Added text to Items Changed section. Added a top level UTF-8 strings section. * libdwarf2.1.pdf: Regenerated 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.28. Now describes dwarf_set_tied_dbg(). * libdwarf2.1.pdf: Regenerated 2015-09-13 David Anderson * libdwarf.h.in,dwarf_error.c: New error code for improved string checking. * dwarf_form.c,dwarf_string.c:Now call the string checker on all strings and do a more thorough check. * dwarf_util.c, dwarf_util.h: Revised the interfaces to the string checker to make it more useful and accurate. 2015-09-12 David Anderson * dwarf_die_deliv.c,dwarf_form.c,dwarf_opaque.h, dwarf_original_elf_init.c,dwarf_query.c,dwarf_tied.c: Now we can find addresses in the base from the dwp. 2015-09-11 David Anderson * Makefile.in: clean now removes test executable ./dwarftied * dwarf.h: Adding DW_AT_GNU_macros attribute, 0x2119. 2015-09-11 David Anderson * dwarf.h: Adding DW_AT_GNU_discriminator attribute, 0x2136. 2015-09-11 David Anderson * Makefile.in,dwarf_alloc.c,dwarf_die_deliv.c,dwarf_error.c,dwarf_form.c, dwarf_opaque.h,dwarf_original_elf_init.c,dwarf_query.ckdwarf_tied.c, libdwarf.h.in: Added dwarf_tied.c and -x tied= options. So libdwarf can follow DW_FORM_addrx to get the address from another object. 2015-09-05 David Anderson * dwarf.h: Fixed indentation of two lines with the 0x values incorrectly indented. 2015-07-12 David Anderson * dwarf_init_finish.c: Added commentary about .rela * dwgetopt.c,dwgetopt.h,dwgetopttest.c: Use dwoptind dwoptarg etc, not optind, optarg, optopt opeerror etc. * gennames.h: use dwoptarg dwoptind, not optarg, optind. 2015-05-08 David Anderson * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_frame2.c, dwarf_frame.c: The debugging-only #if 0 now have comments so grep for 'if 0' is not alarming. * dwgetopt.c,pro_forms.c,pro_section.c: Removed unused code bracketed with '#if 0'. 2015-05-01 David Anderson * dwarf.h: Added DW_DEFAULTED* and DW_IDX* DWARF5 macros. * dwarf_abbrev.c: Expanded comments about the interface used by dwarfdump -a. It is NOT guaranteed to work on all objects. It continues to work usefully on a plain .o . * dwarf_alloc.h: Added code to clean when there are fission package file sections .debug_cu_index or .debug_tu_index. * dwarf_die_deliv.c: Significant changes to internals to support DWARF5 debug fission dwp package objects. Added dwarf_die_from_hash_signature() which lets one find DWP DIE information from a hash signature. * dwarf_error.c: Fifteen new DW_DLE* error messages added related to new DWARF5 sections and to debug fission package files. * dwarf_form.c: New commentary about offsets rrelated to DWP package files. New interface dwarf_formsig8_const() to read the DW_FORM_data8 a DW_AT_dwo_id uses. * dwarf_global.c: Added commentary about an old interface and DWARF5 (the old interface does not support DWARF5, newer (but not new) interfaces do). * dwarf_incl.h: Add dwarf_xu_index.h include. * dwarf_init_finish.c: Removed a couple dwo-section readers (they were not real) Added new DWARF5 section readers and the appropriate .dwo section readers. * dwarf_line.c,dwarf_loc.c: Added support for getting the correct line * dwarf_macro.c: Added comment that .debug_macinfo section not supported in DWP Package File (and .debug_macinfo is not in DWARF5). section offset in a DWP package file. * dwarf_opaque.h: Many New fields for the new sections and DWP Package File support. Various new functions (libdwarf internal) for the new sections. * dwarf_query.c: Added support for DWP Package File offsets. * dwarf_tsearch.h: Added ifndef DWARF_TSEARCH so #include more than once does not lead to difficulty. * dwarf_util.c: Added support for DWP Package File data. * dwarf_xu_index.c: Added support for DWP Package File data so it can all be read properly. * dwarf_xu_index.h: Added ifndef DWARF_XU_INDEX_H so #include more than once does not lead to difficulty. * libdwarf.h.in: Added dwarf_get_IDX_name() and dwarf_get_IDX_name(). Added fifteen new DW_DLE error codes. New function dwarf_die_from_hash_signature(). * libdwarf2.1.mm: Rev 2.27. Documented interfaces dwarf_next_cu_header_d(),dwarf_die_from_hash_signature(), dwarf_get_debugfission_for_die(),dwarf_get_debugfission_for_key(). * libdwarf2.1.pdf: Regenerated. 2015-04-23 David Anderson * dwarf.h: Delete spurious blank lines. * dwarf_base_types.h: New defines. DW_CIE_VERSION* DW_CU_VERSION** DW_ARANGES_VERSION* DW_LINE_VERSION* DW_LOC_VERSION* DW_LINE_STR_VERSION5, DW_MACRO_VERSION5, DW_LINE_LOC, DW_NAMES_VERSION5, DW_PUBNAMES_VERSION*, DW_PUBTYPES_VERSION*, DW_STR_OFFSETS_VERSION5, DW_SUP_VERSION*, DW_CU_INDEX_VERSION5, DW_TU_INDEX_VERSION5, making version comparisons more precise and including DWARF5. * dwarf_arange.c: CURRENT_VERSION_STAMP -> DW_ARANGES_VERSION2 * dwarf_die_deliv.c,dwarf_global.c,dwarf_line.c, : Use the new DW_*_VERSION* version names. * dwarf_init_finish.c: Added to 3 comments. * dwarf_loc.c: Use the new DW_*_VERSION* version names. Use a local variable to simpify some comparisons for readability. * dwarf_opaque.h: Update the comments about version numbers. Added new comments foreshadowing changes for DebugFission and DWP. REMOVE CURRENT_VERSION_STAMP* macros as they are no longer used. 2015-03-10 David Anderson * dwgetopt.c: Was mishandling options missing their required argument. 2015-03-09 David Anderson * dwgetopt.c: Fixed a bug in handling options. See dwarfdump build for testing code and test runs for dwgetopt.c 2015-02-22 David Anderson * dwgetopt.h, dwgetopt.c: Copied from dwarfdump so libdwarf can compile without dwarfdump source present. * Makefile.in: Builds dwgetopt.o * gennames.c: Now uses dwgetopt.o 2015-02-12 David Anderson * dwarf_original_elf_init.c(dwarf_elf_init_file_ownership): When dwarf_elf_object_access_init() returns DW_DLV_ERROR the Dwarf_Error was not getting set. Now it is set. 2015-02-04 David Anderson * dwarf.h: Added new TAGs etc from DWARF5. Since DWARF5 is not a completed standard these new things could change. * dwarf_die_deliv.c: Refactored calculation of end_of CU to ensure uniformity. Added checks to catch attempts to read past end and coredump (can happen when the DWARF is erroneous). Notice when bogus attribute wraps memory so the next DIE would be at an earlier address in memory than the current die (DW_DLE_NEXT_DIE_LOW_ERROR). * dwarf_error.c: DW_DLE_NEXT_DIE_LOW_ERROR error code added. * dwarf_form.c: Added check to ensure we do not run off the end of the string section (.debug_str). * dwarf_opaque.h: Declare new internal function _dwarf_calculate_section_end_ptr(). * dwarf_query.c(dwarf_attrlist): A little bit of refactoring/reordering done to catch errors. Created new function _dwarf_calculate_section_end_ptr(). * dwarf_xu_index.c: Removed trailing space, one line.. * libdwarf.h.in: Added define of DW_DLE_NEXT_DIE_LOW_ERROR. 2015-01-31 David Anderson * Makefile.in,common.c,common.h,dwarf_abbrev.c,dwarf_abbrev.h, dwarf_addr_finder.c,dwarf_alloc.c,dwarf_alloc.h,dwarf_arange.c, dwarf_arange.h,dwarf_base_types.h,dwarf_die_deliv.c,dwarf_die_deliv.h, dwarf_elf_access.c,dwarf_elf_access.h,dwarf_error.h,dwarf_form.c, dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_frame3.c,dwarf_funcs.c, dwarf_funcs.h,dwarf_gdbindex.c,dwarf_global.c,dwarf_global.h, dwarf_incl.h,dwarf_leb.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_loc.c,dwarf_loc.h,dwarf_macro.c,dwarf_macro.h, dwarf_opaque.h,dwarf_original_elf_init.c,dwarf_print_lines.c, dwarf_pubtypes.c,dwarf_query.c,dwarf_ranges.c,dwarf_reloc_arm.h: Removed obsolete postal address and oss.sgi.com address from copyright. 2015-01-30 David Anderson * dwarf_init_finish.c: Now uses Dwarf_Sig8 for .debug_cu_index. * dwarf_opaque.h: Use Dwarf_Sig8 for the dfp_hash field. * libdwarf.h.in: dwarf_get_xu_hash_entry() uses Dwarf_Sig8 now. 2015-01-30 David Anderson * dwarf.h: Adding some DWARF5 defines. Use with caution: DWARF5 is not yet final. * gennames.c: Local array needed to be bigger due to a longer attribute list. 2015-01-28 David Anderson * libdwarf2.1.mm: Fixed .H 2 to .H 3 on dwarf_get_TAG_name etc. Removed duplication of 3 lines of Global Namespace operations. Added doc of dwarf_dwarf_get_debug_str_index() and fixed a level 2 header (starting the quoted string with a period caused trouble in the output). * libdwarf2.1.pdf. Regenerated. Version 2.25. 2015-01-25 David Anderson * dwarf_form.c(dwarf_convert_to_global_offset): Removed yesterday's change. The cu_context offset value already has debugfission offset built in. 2015-01-24 David Anderson * dwarf_form.c: dwarf_convert_to_global_offset() was not accounting for debugfission data (dwp). * dwarf_die_deliv.c(dwarf_offdie_b): Was not adding cc_extension_size into cu header offset (cc_extension_size is rarely non-zero, but its omission was a bug here). * dwarf_util.h: Improved a line of commentary. 2015-01-21 David Anderson * Makefile.in: Now with separate dwarf_names.h and dwarf_names.c rules so parallel make works properly. * dwarf.h: Improved the comment on DW_SECT_TYPES as that is not actually part of DWARF5 but is reserved. * dwarf_die_deliv.c: Added dwarf_get_debugfission_for_die(). Now dwarfdump and other clients can access and print fission data for a specific CU easily. * dwarf_init_finish.c(load_debugfission_tables): Deleted unused local variable. * dwarf_opaque.h: Now uses libdwarf.h DW_FISSION_SECT_COUNT for clarity (libdwarf-only name). * libdwarf.h.in: Add DW_DLE_FISSION_VERSION_ERROR as part of error checking. Add prototype for dwarf_get_debugfission_for_die() and declare its struct argument. 2015-01-18 David Anderson * dwarf_abbrev.c: Added comment, debugfission not supported in the non-cu-specific interface. * dwarf_alloc.c, dwarf_base_types.h: Add DW_DLA_FISSION_PERCU support. * dwarf_die_deliv.c: Added _dwarf_get_fission_addition_die() and _dwarf_get_fission_addition() for debugfission support. * dwarf_error.c: Add DW_DLE_FISSION_INDEX_WRONG error string. * dwarf_form.c: Add debugfission support for str_offsets. * dwarf_init_finish.c: Load debugfission tables if such exist in an object. * dwarf_line.c: Add debugfission support for .debug_line.dwo * dwarf_loc.c: Add debugfission support for .debug_loc.dwo * dwarf_macro.c: Add comment that debugfission not supported in the non-CU-specific interface. * dwarf_opaque.h: Add structures for debugfission: Dwarf_Fission_Offsets_s,Dwarf_Fission_Per_CU_s, Dwarf_Fission_Section_Offset_s. declare the new functions in dwarf_die_deliv.c * dwarf_util.c: Remove a few lines of traling whitespace. * dwarf_uxu_index.c: Correct bogus formatting. * libdwarf.h.in: Add DW_DLE_FISSION_INDEX_WRONG . 2015-01-12 David Anderson * dwarf_init_finish.c(_dwarf_setup): Move freeresult declaration before statements. * dwarf_util.c: Add comments about va_end(). 2015-01-11 David Anderson * dwarf_init_finish.c(_dwarf_setup): For all returns in _dwarf_setup() free the sections malloc space. 2015-01-08 David Anderson * cmplrs/dwarf_addr_finder.h: Fix a comment and remove a trailing whitespace. * dwarf.h: Blank line added accidentally. * dwarf_alloc.c: Removed trailing whitespace. * dwarf_init_finish.c: Remove trailing whitespace. Fix indent. * dwarf_leb.c: Remove trailing whitespace. Fix indent. * dwarf_line.h: Fix macro backslash location, lining things up. * dwarf_util.c: Remove trailing whitespace. 2015-01-06 David Anderson * dwarf_alloc.c, dwarf_base_types.h, dwarf_elf_access.c, dwarf_error.c,dwarf_error.h,dwarf_form.c,dwarf_init_finish.c, dwarf_leb.c,dwarf_query.c,pro_section.c: Fixed indents and removed trailing whitespace. 2015-01-06 David Anderson * dwarf_frame.c( _dwarf_get_fde_info_for_a_pc_row): Cast the pointer returned from _dwarf_get_alloc(), somehow this cast was omitted. * dwarf_alloc.c(dwarf_dealloc): Ensure a NULL 'space' pointer input is not touched before checking if it is set. * dwarf_init_finish.c(_dwarf_setup): For badly formed Elf ensure we do not use stale pointers. 2015-01-05 David Anderson * dwarf_original_elf_init.c(dwarf_finish): If the Dwarf_Debug is not initialized do not use it. 2015-01-03 David Anderson * libdwarf2p.1.mm: Somehow dwarf_transform_to_disk_form() was not documented. Now it is. * libdwarf2p.1.pdf: Regenerated, version 1.38. 2015-01-03 David Anderson * dwarf_allo.c: Comment the allocation table base more carefully. * dwarf_base_types.h: Making DW_DLA defines more readable, more consistent with other instances. * libdwarf.h.in: Adding producer error codes. The producer library has some places error values are misidentified. Main effect: documentation. * dwarf_error.c: Add the strings for the new error codes. 2015-01-01 David Anderson * A new year begins. libdwarf-20210528/libdwarf/pro_frame.c0000664000175000017500000005705014004646753014424 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2017 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_encode_nm.h" #include "pro_frame.h" #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, \ DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm inst); /* This function adds a cie struct to the debug pointer. Its in the form of a linked list. augmenter: string reps augmentation (implementation defined) code_align: alignment of code data_align: alignment of data init_bytes: byts having initial instructions init_n_bytes: number of bytes of initial instructions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small return_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_cie_a(dbg,augmenter, code_align, data_align,return_reg,init_bytes, init_n_bytes, &index,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } int dwarf_add_frame_cie_a(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small return_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_n_bytes, Dwarf_Unsigned * cie_index_out, Dwarf_Error * error) { Dwarf_P_Cie curcie; char *tmpaug = 0; if (dbg->de_frame_cies == NULL) { dbg->de_frame_cies = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (dbg->de_frame_cies == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = dbg->de_frame_cies; dbg->de_n_cie = 1; dbg->de_last_cie = curcie; } else { curcie = dbg->de_last_cie; curcie->cie_next = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (curcie->cie_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = curcie->cie_next; dbg->de_n_cie++; dbg->de_last_cie = curcie; } curcie->cie_version = 1; if (dbg->de_output_version > 2) { curcie->cie_version = dbg->de_output_version; } else { /* V2 dwarf has debug_frame as version 1, there is no 2 used in this section. */ curcie->cie_version = 1; } tmpaug = (char *)_dwarf_p_get_alloc(dbg,strlen(augmenter)+1); if (!tmpaug) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } strcpy(tmpaug,augmenter); curcie->cie_aug = tmpaug; curcie->cie_code_align = code_align; curcie->cie_data_align = data_align; curcie->cie_ret_reg = return_reg; curcie->cie_inst = (char *) init_bytes; curcie->cie_inst_bytes = (long) init_n_bytes; curcie->cie_next = NULL; *cie_index_out = dbg->de_n_cie; return DW_DLV_OK; } /* This functions adds a fde struct to the debug pointer. Its in the form of a linked list. die: subprogram/function die corresponding to this fde cie: cie referred to by this fde, obtained from call to add_frame_cie() routine. virt_addr: beginning address code_len: length of code reps by the fde */ /*ARGSUSED*/ /* pretend all args used */ Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_fde_c(dbg, fde, die, cie, virt_addr, code_len, symidx, 0, 0,&index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } /* There is no dwarf_add_frame_fde_a */ /*ARGSUSED10*/ Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned symidx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_fde_c(dbg,fde,die,cie, virt_addr,code_len,symidx,symidx_of_end, offset_from_end_sym,&index,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } /* New December 2018 */ int dwarf_add_frame_fde_c(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned symidx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Unsigned *index_to_fde, UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; fde->fde_die = die; fde->fde_cie = (long) cie; fde->fde_initloc = virt_addr; fde->fde_r_symidx = symidx; fde->fde_addr_range = code_len; fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; fde->fde_exception_table_symbol = 0; fde->fde_end_symbol_offset = offset_from_end_sym; fde->fde_end_symbol = symidx_of_end; fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { dbg->de_frame_fdes = fde; dbg->de_last_fde = fde; dbg->de_n_fde = 1; } else { curfde->fde_next = fde; dbg->de_last_fde = fde; dbg->de_n_fde++; } *index_to_fde = dbg->de_n_fde; return DW_DLV_OK; } /* This function adds information to an fde. The fde is linked into the linked list of fde's maintained in the Dwarf_P_Debug structure. dbg: The debug descriptor. fde: The fde to be added. die: subprogram/function die corresponding to this fde cie: cie referred to by this fde, obtained from call to add_frame_cie() routine. virt_addr: beginning address code_len: length of code reps by the fde symidx: The symbol id of the symbol wrt to which relocation needs to be performed for 'virt_addr'. offset_into_exception_tables: The start of exception tables for this function (indicated as an offset into the exception tables). A value of -1 indicates that there is no exception table entries associated with this function. exception_table_symbol: The symbol id of the section for exception tables wrt to which the offset_into_exception_tables will be relocated. */ Dwarf_Unsigned dwarf_add_frame_info(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error * error) { Dwarf_Unsigned fde_index = 0; int res = 0; res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, code_len, symidx, /* end_symbol */ 0, /* offset_from_end */ 0, offset_into_exception_tables, exception_table_symbol, &fde_index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return fde_index; } /*ARGSUSED*/ /* pretend all args used */ Dwarf_Unsigned dwarf_add_frame_info_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned end_symidx, Dwarf_Unsigned offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, UNUSEDARG Dwarf_Error * error) { Dwarf_Unsigned fde_index = 0; int res = 0; res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, code_len, symidx, end_symidx, offset_from_end_symbol, offset_into_exception_tables, exception_table_symbol, &fde_index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return fde_index; } int dwarf_add_frame_info_c(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned end_symidx, Dwarf_Unsigned offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Unsigned *fde_index_out, UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; fde->fde_die = die; fde->fde_cie = (long) cie; fde->fde_initloc = virt_addr; fde->fde_r_symidx = symidx; fde->fde_addr_range = code_len; fde->fde_offset_into_exception_tables = offset_into_exception_tables; fde->fde_exception_table_symbol = exception_table_symbol; fde->fde_end_symbol_offset = offset_from_end_symbol; fde->fde_end_symbol = end_symidx; fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { dbg->de_frame_fdes = fde; dbg->de_last_fde = fde; dbg->de_n_fde = 1; } else { curfde->fde_next = fde; dbg->de_last_fde = fde; dbg->de_n_fde++; } *fde_index_out = dbg->de_n_fde; return DW_DLV_OK; } /* This is an alternate to inserting frame instructions one instruction at a time. But use either this or instruction level, not both in one fde. */ int dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes, Dwarf_Error *error) { if (len == 0) { return DW_DLV_OK; } if (fde->fde_block || fde->fde_inst) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, DW_DLV_ERROR); } fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); memcpy(fde->fde_block,ibytes,len); fde->fde_inst_block_size = len; fde->fde_n_bytes += len; return DW_DLV_OK; } /* Create a new fde. */ Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Fde fde = 0; int res = 0; res = dwarf_new_fde_a(dbg,&fde,error); if (res != DW_DLV_OK) { return (Dwarf_P_Fde) DW_DLV_BADADDR; } return fde; } int dwarf_new_fde_a(Dwarf_P_Debug dbg, Dwarf_P_Fde *fde_out, Dwarf_Error * error) { Dwarf_P_Fde fde; fde = (Dwarf_P_Fde) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); if (fde == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, DW_DLV_ERROR); } fde->fde_dbg = dbg; fde->fde_uwordb_size = dbg->de_dwarf_offset_size; *fde_out = fde; return DW_DLV_OK; } /* Add a cfe_offset instruction to the fde passed in. */ Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error * error) { int res = 0; res = dwarf_fde_cfa_offset_a(fde,reg,offset,error); if (res != DW_DLV_OK) { return (Dwarf_P_Fde) DW_DLV_BADADDR; } return fde; } int dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error * error) { Dwarf_Ubyte opc, regno; char *ptr = 0; Dwarf_P_Frame_Pgm curinst; int nbytes = 0; int res = 0; char buff1[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, DW_DLV_ERROR); } opc = DW_CFA_offset; regno = reg; if (regno & 0xc0) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,DW_DLV_ERROR); } opc = opc | regno; /* lower 6 bits are register number */ curinst->dfp_opcode = opc; res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return DW_DLV_OK; } /* Generic routine to add opcode to fde instructions. val1 and val2 are parameters whose interpretation depends on the 'op'. This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as these ops normally are addresses or (DW_CFA_set_loc) or code lengths (DW_DVA_advance_loc*) and such must be represented with relocations and symbol indices for DW_DLC_SYMBOLIC_RELOCATIONS. This does not treat all DW_CFA instructions yet. For certain operations a val? value must be signed (though passed in as unsigned here). Does not check that the frame version is 3(for dwarf3) or 4 (for dwarf4) or 5 when applying operations that are only valid for particular versions. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { int res = 0; res = dwarf_add_fde_inst_a(fde,op,val1,val2,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Fde) DW_DLV_BADADDR); } return fde; } /* December 2018. A more sensible return value. */ int dwarf_add_fde_inst_a(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes = 0; int nbytes1 = 0; int nbytes2 = 0; Dwarf_Ubyte db = 0; Dwarf_Half dh = 0; Dwarf_Unsigned du = 0; char *ptr = 0; int res = 0; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; /* This is a hack telling the code when to transform a value to a signed leb number. */ int signed_second = 0; int signed_first = 0; buff1[0] = 0; buff2[0] = 0; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); return DW_DLV_ERROR; } switch (op) { case DW_CFA_advance_loc: { if (val1 <= 0x3f) { db = val1; op |= db; } else if (!(val1& ~0xff)) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 1); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; } else if (!(val1& (~(Dwarf_Unsigned)0xffff))) { if (sizeof(dh) < SIZEOFT16) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_advance_loc2; dh = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT16); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } /* No byte swapping, assuming running at target endianness. */ ASNOUT((void *) ptr, dh, SIZEOFT16); nbytes = SIZEOFT16; } else if (!(val1& ~(Dwarf_Unsigned)0xffffffff)) { if (sizeof(du) < SIZEOFT32) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_advance_loc4; du = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT32); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ASNOUT((void *) ptr, du, SIZEOFT32); nbytes = SIZEOFT32; } else { if (sizeof(du) < SIZEOFT64) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_MIPS_advance_loc8; du = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT64); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } /* No byte swapping, assuming running at target endianness. */ ASNOUT((void *) ptr, du, SIZEOFT64); nbytes = SIZEOFT64; } break; } case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; op |= db; res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); } else { op = DW_CFA_offset_extended; goto two_leb; } break; case DW_CFA_offset_extended_sf: /* DWARF3 */ signed_second = 1; goto two_leb; case DW_CFA_offset_extended: goto two_leb; case DW_CFA_undefined: case DW_CFA_same_value: goto one_leb; case DW_CFA_val_offset: goto two_leb; case DW_CFA_val_offset_sf: signed_second = 1; goto two_leb; case DW_CFA_def_cfa_sf: signed_second = 1; goto two_leb; case DW_CFA_register: case DW_CFA_def_cfa: two_leb: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } if (!signed_second) { res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); } else { Dwarf_Signed val2s = val2; res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, buff2, sizeof(buff2)); } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; break; case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ signed_first = 1; goto one_leb; case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: one_leb: if (!signed_first) { res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); } else { Dwarf_Signed val1s = val1; res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes, buff1, sizeof(buff1)); } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); break; case DW_CFA_def_cfa_expression: /* DWARF3 */ /* FIXME: argument is dwarf expr, not handled yet. */ case DW_CFA_expression: /* DWARF3 */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ case DW_CFA_val_expression: /* DWARF3f */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ default: _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); return DW_DLV_ERROR; } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return DW_DLV_OK; } /* Instructions are added to an fde in the form of a linked list. This function manages the linked list. */ void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) { if (fde->fde_last_inst) { fde->fde_last_inst->dfp_next = curinst; fde->fde_last_inst = curinst; fde->fde_n_inst++; fde->fde_n_bytes += (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } else { fde->fde_last_inst = curinst; fde->fde_inst = curinst; fde->fde_n_inst = 1; fde->fde_n_bytes = (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } } libdwarf-20210528/libdwarf/dwarf_global.h0000644000175000017500000000730513763460764015105 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context; /* This struct contains header information for a set of pubnames. Essentially, they contain the context for a set of pubnames belonging to a compilation-unit. This is also used for the sgi-specific weaknames, typenames, varnames, funcnames data: the structs for those are incomplete and instances of this are used instead. Also used for DWARF3 .debug_pubtypes. These never refer to .debug_types, only to .debug_info. */ struct Dwarf_Global_Context_s { /* For this context, size of a length. 4 or 8 */ unsigned char pu_length_size; /* Size of the pubnames data for the CU */ unsigned char pu_length; /* For this CU, size of the extension 0 except for dwarf2 extension 64bit, in which case is 4. */ unsigned char pu_extension_size; Dwarf_Half pu_version; /* 2,3, or 4 */ /* offset in pubnames of the pu header. */ Dwarf_Off pu_pub_offset; /* Offset into .debug_info of the compilation-unit header (not DIE) for this set of pubnames. */ Dwarf_Off pu_offset_of_cu_header; /* Size of compilation-unit that these pubnames are in. */ Dwarf_Unsigned pu_info_length; unsigned pu_alloc_type; /* DW_DLA something */ Dwarf_Debug pu_dbg; }; /* This struct contains information for a single pubname. */ struct Dwarf_Global_s { /* Offset from the start of the corresponding compilation-unit of the DIE for the given pubname CU. */ Dwarf_Off gl_named_die_offset_within_cu; /* Points to the given pubname. */ Dwarf_Small *gl_name; /* Context for this pubname. */ Dwarf_Global_Context gl_context; unsigned gl_alloc_type; /* DW_DLA something */ }; int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, const char *secname, Dwarf_Small *section_data_ptr, Dwarf_Unsigned section_length, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error, int context_code, int global_code, int length_err_num, int version_err_num); void _dwarf_internal_globals_dealloc( Dwarf_Debug dbg, Dwarf_Global *dwgl, Dwarf_Signed count); #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, Dwarf_Unsigned *varp, char *caller_site_name); #define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) \ _dwarf_fix_up_offset_irix(ldbg,&var,name) #else /* ! __sgi */ #define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) #endif /* __sgi */ libdwarf-20210528/libdwarf/dwarf_str_offsets.h0000664000175000017500000000521213733470513016171 00000000000000#ifndef DWARF_STR_OFFSETS_H #define DWARF_STR_OFFSETS_H /* Copyright (C) 2018-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ struct Dwarf_Str_Offsets_Table_s { /* pointers are to dwarf-memory valid till Dwarf_Debug is closed.. None are to be deallocated. */ Dwarf_Unsigned so_magic_value; Dwarf_Debug so_dbg; /* Section data. */ Dwarf_Small *so_section_start_ptr; Dwarf_Small *so_section_end_ptr; Dwarf_Unsigned so_section_size; /* Overall data about wasted space in the section. */ Dwarf_Unsigned so_wasted_section_bytes; /* The number of tables processed in the section. */ Dwarf_Unsigned so_table_count; /* Used to iterate through the section getting to each table */ Dwarf_Unsigned so_next_table_offset; /* Per table (ie, a table is a header and array of offsets) inside the section. */ Dwarf_Small *so_header_ptr; Dwarf_Small *so_end_cu_ptr; Dwarf_Small *so_array_ptr; Dwarf_Unsigned so_table_start_offset; Dwarf_Unsigned so_array_start_offset; Dwarf_Unsigned so_array_entry_count; Dwarf_Half so_array_entry_size; }; int _dwarf_trial_read_dwarf_five_hdr(Dwarf_Debug dbg, Dwarf_Small *table_start_ptr, Dwarf_Unsigned secsize, Dwarf_Small * secendptr, Dwarf_Unsigned *length_out, Dwarf_Half *local_offset_size_out, Dwarf_Half *local_extension_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Error *error); int _dwarf_find_all_offsets_via_fission(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Error *error); #endif /* DWARF_STR_OFFSETS_H */ libdwarf-20210528/libdwarf/dwarf_vars.c0000664000175000017500000000662213764007262014605 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_vars.h" #include "dwarf_global.h" int dwarf_get_vars(Dwarf_Debug dbg, Dwarf_Var ** vars, Dwarf_Signed * ret_var_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_varnames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_abbrev.dss_size) { return DW_DLV_NO_ENTRY; } return _dwarf_internal_get_pubnames_like_data(dbg, ".debug_varnames", dbg->de_debug_varnames.dss_data, dbg->de_debug_varnames.dss_size, (Dwarf_Global **) vars, /* Type punning for sections with identical format. */ ret_var_count, error, DW_DLA_VAR_CONTEXT, DW_DLA_VAR, DW_DLE_DEBUG_VARNAMES_LENGTH_BAD, DW_DLE_DEBUG_VARNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_vars_dealloc(Dwarf_Debug dbg, Dwarf_Var * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count); return; } int dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; if (var == NULL) { _dwarf_error(NULL, error, DW_DLE_VAR_NULL); return DW_DLV_ERROR; } *ret_varname = (char *) (var->gl_name); return DW_DLV_OK; } int dwarf_var_die_offset(Dwarf_Var var_in, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_die_offset(var, returned_offset, error); } int dwarf_var_cu_offset(Dwarf_Var var_in, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_cu_offset(var, returned_offset, error); } int dwarf_var_name_offsets(Dwarf_Var var_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_name_offsets(var, returned_name, die_offset, cu_offset, error); } libdwarf-20210528/libdwarf/dwarf_reloc_x86_64.h0000644000175000017500000001354213763274424015763 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DWARF_RELOC_X86_64_H #define DWARF_RELOC_X86_64_H /* Definitions for X86_64 */ #define DWARF_RELOC_X86_64 /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for AMD x86-64 architecture */ #define R_X86_64_NONE 0 /* No reloc */ #define R_X86_64_64 1 /* Direct 64 bit */ #define R_X86_64_PC32 2 /* PC relative 32 bit signed */ #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ #define R_X86_64_PLT32 4 /* 32 bit PLT address */ #define R_X86_64_COPY 5 /* Copy symbol at runtime */ #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ #define R_X86_64_RELATIVE 8 /* Adjust by program base */ #define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative to GOT */ #define R_X86_64_32 10 /* Direct 32 bit zero extended */ #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ #define R_X86_64_16 12 /* Direct 16 bit zero extended */ #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ #define R_X86_64_8 14 /* Direct 8 bit sign extended */ #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ #define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ #define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ #define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ #define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset to two GOT entries for GD symbol */ #define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset to two GOT entries for LD symbol */ #define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ #define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset to GOT entry for IE symbol */ #define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ #define R_X86_64_PC64 24 /* PC relative 64 bit */ #define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ #define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative to GOT */ #define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ #define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative GOT entry */ #define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ #define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ /* 64-bit GOT relative offset to PLT entry */ #define R_X86_64_PLTOFF64 31 #define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ #define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ /* GOT offset for TLS descriptor */ #define R_X86_64_GOTPC32_TLSDESC 34 #define R_X86_64_TLSDESC_CALL 35 /* For for call thru TLS descriptor*/ #define R_X86_64_TLSDESC 36 /* TLS descriptor */ #define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ #define R_X86_64_RELATIVE64 38 /* 64bit adjust by program base */ /* Keep this the last entry. */ #define R_X86_64_NUM 39 #endif /* _WIN32 */ /* Relocation types for X86_64 */ static const char *reloc_type_names_X86_64[] = { "R_X86_64_NONE", /* 00 */ "R_X86_64_64", /* 01 */ "R_X86_64_PC32", /* 02 */ "R_X86_64_GOT32", /* 03 */ "R_X86_64_PLT32", /* 04 */ "R_X86_64_COPY", /* 05 */ "R_X86_64_GLOB_DAT", /* 06 */ "R_X86_64_JUMP_SLOT", /* 07 */ "R_X86_64_RELATIVE", /* 08 */ "R_X86_64_GOTPCREL", /* 09 */ "R_X86_64_32", /* 10 */ "R_X86_64_32S", /* 11 */ "R_X86_64_16", /* 12 */ "R_X86_64_PC16", /* 13 */ "R_X86_64_8", /* 14 */ "R_X86_64_PC8", /* 15 */ "R_X86_64_DTPMOD64", /* 16 */ "R_X86_64_DTPOFF64", /* 17 */ "R_X86_64_TPOFF64", /* 18 */ "R_X86_64_TLSGD", /* 19 */ "R_X86_64_TLSLD", /* 20 */ "R_X86_64_DTPOFF32", /* 21 */ "R_X86_64_GOTTPOFF", /* 22 */ "R_X86_64_TPOFF32", /* 23 */ "R_X86_64_PC64", /* 24 */ "R_X86_64_GOTOFF64", /* 25 */ "R_X86_64_GOTPC32", /* 26 */ "R_X86_64_GOT64", /* 27 */ "R_X86_64_GOTPCREL64", /* 28 */ "R_X86_64_GOTPC64", /* 29 */ "R_X86_64_GOTPLT64", /* 30 */ "R_X86_64_PLTOFF64", /* 31 */ "R_X86_64_SIZE32", /* 32 */ "R_X86_64_SIZE64", /* 33 */ "R_X86_64_GOTPC32_TLSDESC", /* 34 */ "R_X86_64_TLSDESC_CALL", /* 35 */ "R_X86_64_TLSDESC", /* 36 */ "R_X86_64_IRELATIVE", /* 37 */ "R_X86_64_RELATIVE64", /* 38 */ }; #endif /* DWARF_RELOC_X86_64_H */ libdwarf-20210528/libdwarf/dwarf_xu_index.h0000644000175000017500000000427113763273220015454 00000000000000#ifndef DWARF_XU_INDEX_H #define DWARF_XU_INDEX_H /* Copyright (C) 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The following is based on The gdb online documentation at https://gcc.gnu.org/wiki/DebugFissionDWP and the draft DWARF5 standard. */ struct Dwarf_Xu_Index_Header_s { Dwarf_Debug gx_dbg; Dwarf_Small * gx_section_data; Dwarf_Unsigned gx_section_length; Dwarf_Unsigned gx_version; Dwarf_Unsigned gx_column_count_sections; /* N */ Dwarf_Unsigned gx_units_in_index; /* U */ Dwarf_Unsigned gx_slots_in_hash; /* S */ Dwarf_Unsigned gx_hash_table_offset; Dwarf_Unsigned gx_index_table_offset; Dwarf_Unsigned gx_section_offsets_headerline_offset; Dwarf_Unsigned gx_section_offsets_offset; Dwarf_Unsigned gx_section_sizes_offset; /* Taken from gx_section_offsets_headerline, these are the section ids. DW_SECT_* (0 - N-1) */ unsigned long gx_section_id[9]; /* "tu" or "cu" without the quotes, of course. NUL terminated. */ char gx_type[4]; /* Do not free gx_section_name. */ const char * gx_section_name; }; #endif /* DWARF_XU_INDEX_H */ libdwarf-20210528/libdwarf/dwarf_elf_reloc_arm.h0000664000175000017500000002517213644370703016431 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_arm(unsigned long); #ifndef R_ARM_NONE #define R_ARM_NONE 0 #endif /* R_ARM_NONE */ #ifndef R_ARM_PC24 #define R_ARM_PC24 1 #endif /* R_ARM_PC24 */ #ifndef R_ARM_ABS32 #define R_ARM_ABS32 2 #endif /* R_ARM_ABS32 */ #ifndef R_ARM_REL32 #define R_ARM_REL32 3 #endif /* R_ARM_REL32 */ #ifndef R_ARM_LDR_PC_G0 #define R_ARM_LDR_PC_G0 4 #endif /* R_ARM_LDR_PC_G0 */ #ifndef R_ARM_ABS16 #define R_ARM_ABS16 5 #endif /* R_ARM_ABS16 */ #ifndef R_ARM_ABS12 #define R_ARM_ABS12 6 #endif /* R_ARM_ABS12 */ #ifndef R_ARM_THM_ABS5 #define R_ARM_THM_ABS5 7 #endif /* R_ARM_THM_ABS5 */ #ifndef R_ARM_ABS8 #define R_ARM_ABS8 8 #endif /* R_ARM_ABS8 */ #ifndef R_ARM_SBREL32 #define R_ARM_SBREL32 9 #endif /* R_ARM_SBREL32 */ #ifndef R_ARM_THM_CALL #define R_ARM_THM_CALL 10 #endif /* R_ARM_THM_CALL */ #ifndef R_ARM_THM_PC8 #define R_ARM_THM_PC8 11 #endif /* R_ARM_THM_PC8 */ #ifndef R_ARM_BREL_ADJ #define R_ARM_BREL_ADJ 12 #endif /* R_ARM_BREL_ADJ */ #ifndef R_ARM_TLS_DESC #define R_ARM_TLS_DESC 13 #endif /* R_ARM_TLS_DESC */ #ifndef R_ARM_THM_SWI8 #define R_ARM_THM_SWI8 14 #endif /* R_ARM_THM_SWI8 */ #ifndef R_ARM_XPC25 #define R_ARM_XPC25 15 #endif /* R_ARM_XPC25 */ #ifndef R_ARM_THM_XPC22 #define R_ARM_THM_XPC22 16 #endif /* R_ARM_THM_XPC22 */ #ifndef R_ARM_TLS_DTPMOD32 #define R_ARM_TLS_DTPMOD32 17 #endif /* R_ARM_TLS_DTPMOD32 */ #ifndef R_ARM_TLS_DTPOFF32 #define R_ARM_TLS_DTPOFF32 18 #endif /* R_ARM_TLS_DTPOFF32 */ #ifndef R_ARM_TLS_TPOFF32 #define R_ARM_TLS_TPOFF32 19 #endif /* R_ARM_TLS_TPOFF32 */ #ifndef R_ARM_COPY #define R_ARM_COPY 20 #endif /* R_ARM_COPY */ #ifndef R_ARM_GLOB_DAT #define R_ARM_GLOB_DAT 21 #endif /* R_ARM_GLOB_DAT */ #ifndef R_ARM_JUMP_SLOT #define R_ARM_JUMP_SLOT 22 #endif /* R_ARM_JUMP_SLOT */ #ifndef R_ARM_RELATIVE #define R_ARM_RELATIVE 23 #endif /* R_ARM_RELATIVE */ #ifndef R_ARM_GOTOFF32 #define R_ARM_GOTOFF32 24 #endif /* R_ARM_GOTOFF32 */ #ifndef R_ARM_BASE_PREL #define R_ARM_BASE_PREL 25 #endif /* R_ARM_BASE_PREL */ #ifndef R_ARM_GOT_BREL #define R_ARM_GOT_BREL 26 #endif /* R_ARM_GOT_BREL */ #ifndef R_ARM_PLT32 #define R_ARM_PLT32 27 #endif /* R_ARM_PLT32 */ #ifndef R_ARM_CALL #define R_ARM_CALL 28 #endif /* R_ARM_CALL */ #ifndef R_ARM_JUMP24 #define R_ARM_JUMP24 29 #endif /* R_ARM_JUMP24 */ #ifndef R_ARM_THM_JUMP24 #define R_ARM_THM_JUMP24 30 #endif /* R_ARM_THM_JUMP24 */ #ifndef R_ARM_BASE_ABS #define R_ARM_BASE_ABS 31 #endif /* R_ARM_BASE_ABS */ #ifndef R_ARM_ALU_PCREL_7_0 #define R_ARM_ALU_PCREL_7_0 32 #endif /* R_ARM_ALU_PCREL_7_0 */ #ifndef R_ARM_ALU_PCREL_15_8 #define R_ARM_ALU_PCREL_15_8 33 #endif /* R_ARM_ALU_PCREL_15_8 */ #ifndef R_ARM_ALU_PCREL_23_15 #define R_ARM_ALU_PCREL_23_15 34 #endif /* R_ARM_ALU_PCREL_23_15 */ #ifndef R_ARM_LDR_SBREL_11_0_NC #define R_ARM_LDR_SBREL_11_0_NC 35 #endif /* R_ARM_LDR_SBREL_11_0_NC */ #ifndef R_ARM_ALU_SBREL_19_12_NC #define R_ARM_ALU_SBREL_19_12_NC 36 #endif /* R_ARM_ALU_SBREL_19_12_NC */ #ifndef R_ARM_ALU_SBREL_27_20_CK #define R_ARM_ALU_SBREL_27_20_CK 37 #endif /* R_ARM_ALU_SBREL_27_20_CK */ #ifndef R_ARM_TARGET1 #define R_ARM_TARGET1 38 #endif /* R_ARM_TARGET1 */ #ifndef R_ARM_SBREL31 #define R_ARM_SBREL31 39 #endif /* R_ARM_SBREL31 */ #ifndef R_ARM_V4BX #define R_ARM_V4BX 40 #endif /* R_ARM_V4BX */ #ifndef R_ARM_TARGET2 #define R_ARM_TARGET2 41 #endif /* R_ARM_TARGET2 */ #ifndef R_ARM_PREL31 #define R_ARM_PREL31 42 #endif /* R_ARM_PREL31 */ #ifndef R_ARM_MOVW_ABS_NC #define R_ARM_MOVW_ABS_NC 43 #endif /* R_ARM_MOVW_ABS_NC */ #ifndef R_ARM_MOVT_ABS #define R_ARM_MOVT_ABS 44 #endif /* R_ARM_MOVT_ABS */ #ifndef R_ARM_MOVW_PREL_NC #define R_ARM_MOVW_PREL_NC 45 #endif /* R_ARM_MOVW_PREL_NC */ #ifndef R_ARM_MOVT_PREL #define R_ARM_MOVT_PREL 46 #endif /* R_ARM_MOVT_PREL */ #ifndef R_ARM_THM_MOVW_ABS_NC #define R_ARM_THM_MOVW_ABS_NC 47 #endif /* R_ARM_THM_MOVW_ABS_NC */ #ifndef R_ARM_THM_MOVT_ABS #define R_ARM_THM_MOVT_ABS 48 #endif /* R_ARM_THM_MOVT_ABS */ #ifndef R_ARM_THM_MOVW_PREL_NC #define R_ARM_THM_MOVW_PREL_NC 49 #endif /* R_ARM_THM_MOVW_PREL_NC */ #ifndef R_ARM_THM_MOVT_PREL #define R_ARM_THM_MOVT_PREL 50 #endif /* R_ARM_THM_MOVT_PREL */ #ifndef R_ARM_THM_JUMP19 #define R_ARM_THM_JUMP19 51 #endif /* R_ARM_THM_JUMP19 */ #ifndef R_ARM_THM_JUMP6 #define R_ARM_THM_JUMP6 52 #endif /* R_ARM_THM_JUMP6 */ #ifndef R_ARM_THM_ALU_PREL_11_0 #define R_ARM_THM_ALU_PREL_11_0 53 #endif /* R_ARM_THM_ALU_PREL_11_0 */ #ifndef R_ARM_THM_PC12 #define R_ARM_THM_PC12 54 #endif /* R_ARM_THM_PC12 */ #ifndef R_ARM_ABS32_NOI #define R_ARM_ABS32_NOI 55 #endif /* R_ARM_ABS32_NOI */ #ifndef R_ARM_REL32_NOI #define R_ARM_REL32_NOI 56 #endif /* R_ARM_REL32_NOI */ #ifndef R_ARM_ALU_PC_G0_NC #define R_ARM_ALU_PC_G0_NC 57 #endif /* R_ARM_ALU_PC_G0_NC */ #ifndef R_ARM_ALU_PC_G0 #define R_ARM_ALU_PC_G0 58 #endif /* R_ARM_ALU_PC_G0 */ #ifndef R_ARM_ALU_PC_G1_NC #define R_ARM_ALU_PC_G1_NC 59 #endif /* R_ARM_ALU_PC_G1_NC */ #ifndef R_ARM_ALU_PC_G1 #define R_ARM_ALU_PC_G1 60 #endif /* R_ARM_ALU_PC_G1 */ #ifndef R_ARM_ALU_PC_G2 #define R_ARM_ALU_PC_G2 61 #endif /* R_ARM_ALU_PC_G2 */ #ifndef R_ARM_LDR_PC_G1 #define R_ARM_LDR_PC_G1 62 #endif /* R_ARM_LDR_PC_G1 */ #ifndef R_ARM_LDR_PC_G2 #define R_ARM_LDR_PC_G2 63 #endif /* R_ARM_LDR_PC_G2 */ #ifndef R_ARM_LDRS_PC_G0 #define R_ARM_LDRS_PC_G0 64 #endif /* R_ARM_LDRS_PC_G0 */ #ifndef R_ARM_LDRS_PC_G1 #define R_ARM_LDRS_PC_G1 65 #endif /* R_ARM_LDRS_PC_G1 */ #ifndef R_ARM_LDRS_PC_G2 #define R_ARM_LDRS_PC_G2 66 #endif /* R_ARM_LDRS_PC_G2 */ #ifndef R_ARM_LDC_PC_G0 #define R_ARM_LDC_PC_G0 67 #endif /* R_ARM_LDC_PC_G0 */ #ifndef R_ARM_LDC_PC_G1 #define R_ARM_LDC_PC_G1 68 #endif /* R_ARM_LDC_PC_G1 */ #ifndef R_ARM_LDC_PC_G2 #define R_ARM_LDC_PC_G2 69 #endif /* R_ARM_LDC_PC_G2 */ #ifndef R_ARM_ALU_SB_G0_NC #define R_ARM_ALU_SB_G0_NC 70 #endif /* R_ARM_ALU_SB_G0_NC */ #ifndef R_ARM_ALU_SB_G0 #define R_ARM_ALU_SB_G0 71 #endif /* R_ARM_ALU_SB_G0 */ #ifndef R_ARM_ALU_SB_G1_NC #define R_ARM_ALU_SB_G1_NC 72 #endif /* R_ARM_ALU_SB_G1_NC */ #ifndef R_ARM_ALU_SB_G1 #define R_ARM_ALU_SB_G1 73 #endif /* R_ARM_ALU_SB_G1 */ #ifndef R_ARM_ALU_SB_G2 #define R_ARM_ALU_SB_G2 74 #endif /* R_ARM_ALU_SB_G2 */ #ifndef R_ARM_LDR_SB_G0 #define R_ARM_LDR_SB_G0 75 #endif /* R_ARM_LDR_SB_G0 */ #ifndef R_ARM_LDR_SB_G1 #define R_ARM_LDR_SB_G1 76 #endif /* R_ARM_LDR_SB_G1 */ #ifndef R_ARM_LDR_SB_G2 #define R_ARM_LDR_SB_G2 77 #endif /* R_ARM_LDR_SB_G2 */ #ifndef R_ARM_LDRS_SB_G0 #define R_ARM_LDRS_SB_G0 78 #endif /* R_ARM_LDRS_SB_G0 */ #ifndef R_ARM_LDRS_SB_G1 #define R_ARM_LDRS_SB_G1 79 #endif /* R_ARM_LDRS_SB_G1 */ #ifndef R_ARM_LDRS_SB_G2 #define R_ARM_LDRS_SB_G2 80 #endif /* R_ARM_LDRS_SB_G2 */ #ifndef R_ARM_LDC_SB_G0 #define R_ARM_LDC_SB_G0 81 #endif /* R_ARM_LDC_SB_G0 */ #ifndef R_ARM_LDC_SB_G1 #define R_ARM_LDC_SB_G1 82 #endif /* R_ARM_LDC_SB_G1 */ #ifndef R_ARM_LDC_SB_G2 #define R_ARM_LDC_SB_G2 83 #endif /* R_ARM_LDC_SB_G2 */ #ifndef R_ARM_MOVW_BREL_NC #define R_ARM_MOVW_BREL_NC 84 #endif /* R_ARM_MOVW_BREL_NC */ #ifndef R_ARM_MOVT_BREL #define R_ARM_MOVT_BREL 85 #endif /* R_ARM_MOVT_BREL */ #ifndef R_ARM_MOVW_BREL #define R_ARM_MOVW_BREL 86 #endif /* R_ARM_MOVW_BREL */ #ifndef R_ARM_THM_MOVW_BREL_NC #define R_ARM_THM_MOVW_BREL_NC 87 #endif /* R_ARM_THM_MOVW_BREL_NC */ #ifndef R_ARM_THM_MOVT_BREL #define R_ARM_THM_MOVT_BREL 88 #endif /* R_ARM_THM_MOVT_BREL */ #ifndef R_ARM_THM_MOVW_BREL #define R_ARM_THM_MOVW_BREL 89 #endif /* R_ARM_THM_MOVW_BREL */ #ifndef R_ARM_TLS_GOTDESC #define R_ARM_TLS_GOTDESC 90 #endif /* R_ARM_TLS_GOTDESC */ #ifndef R_ARM_TLS_CALL #define R_ARM_TLS_CALL 91 #endif /* R_ARM_TLS_CALL */ #ifndef R_ARM_TLS_DESCSEQ #define R_ARM_TLS_DESCSEQ 92 #endif /* R_ARM_TLS_DESCSEQ */ #ifndef R_ARM_THM_TLS_CALL #define R_ARM_THM_TLS_CALL 93 #endif /* R_ARM_THM_TLS_CALL */ #ifndef R_ARM_PLT32_ABS #define R_ARM_PLT32_ABS 94 #endif /* R_ARM_PLT32_ABS */ #ifndef R_ARM_GOT_ABS #define R_ARM_GOT_ABS 95 #endif /* R_ARM_GOT_ABS */ #ifndef R_ARM_GOT_PREL #define R_ARM_GOT_PREL 96 #endif /* R_ARM_GOT_PREL */ #ifndef R_ARM_GOT_BREL12 #define R_ARM_GOT_BREL12 97 #endif /* R_ARM_GOT_BREL12 */ #ifndef R_ARM_GOTOFF12 #define R_ARM_GOTOFF12 98 #endif /* R_ARM_GOTOFF12 */ #ifndef R_ARM_GOTRELAX #define R_ARM_GOTRELAX 99 #endif /* R_ARM_GOTRELAX */ #ifndef R_ARM_GNU_VTENTRY #define R_ARM_GNU_VTENTRY 100 #endif /* R_ARM_GNU_VTENTRY */ #ifndef R_ARM_GNU_VTINHERIT #define R_ARM_GNU_VTINHERIT 101 #endif /* R_ARM_GNU_VTINHERIT */ #ifndef R_ARM_THM_JUMP11 #define R_ARM_THM_JUMP11 102 #endif /* R_ARM_THM_JUMP11 */ #ifndef R_ARM_THM_JUMP8 #define R_ARM_THM_JUMP8 103 #endif /* R_ARM_THM_JUMP8 */ #ifndef R_ARM_TLS_GD32 #define R_ARM_TLS_GD32 104 #endif /* R_ARM_TLS_GD32 */ #ifndef R_ARM_TLS_LDM32 #define R_ARM_TLS_LDM32 105 #endif /* R_ARM_TLS_LDM32 */ #ifndef R_ARM_TLS_LDO32 #define R_ARM_TLS_LDO32 106 #endif /* R_ARM_TLS_LDO32 */ #ifndef R_ARM_TLS_IE32 #define R_ARM_TLS_IE32 107 #endif /* R_ARM_TLS_IE32 */ #ifndef R_ARM_TLS_LE32 #define R_ARM_TLS_LE32 108 #endif /* R_ARM_TLS_LE32 */ #ifndef R_ARM_TLS_LDO12 #define R_ARM_TLS_LDO12 109 #endif /* R_ARM_TLS_LDO12 */ #ifndef R_ARM_TLS_LE12 #define R_ARM_TLS_LE12 110 #endif /* R_ARM_TLS_LE12 */ #ifndef R_ARM_TLS_IE12GP #define R_ARM_TLS_IE12GP 111 #endif /* R_ARM_TLS_IE12GP */ #ifndef R_ARM_ME_TOO #define R_ARM_ME_TOO 128 #endif /* R_ARM_ME_TOO */ #ifndef R_ARM_THM_TLS_DESCSEQ16 #define R_ARM_THM_TLS_DESCSEQ16 129 #endif /* R_ARM_THM_TLS_DESCSEQ16 */ #ifndef R_ARM_THM_TLS_DESCSEQ32 #define R_ARM_THM_TLS_DESCSEQ32 130 #endif /* R_ARM_THM_TLS_DESCSEQ32 */ #ifndef R_ARM_RXPC25 #define R_ARM_RXPC25 249 #endif /* R_ARM_RXPC25 */ #ifndef R_ARM_RSBREL32 #define R_ARM_RSBREL32 250 #endif /* R_ARM_RSBREL32 */ #ifndef R_ARM_THM_RPC22 #define R_ARM_THM_RPC22 251 #endif /* R_ARM_THM_RPC22 */ #ifndef R_ARM_RREL32 #define R_ARM_RREL32 252 #endif /* R_ARM_RREL32 */ #ifndef R_ARM_RABS32 #define R_ARM_RABS32 253 #endif /* R_ARM_RABS32 */ #ifndef R_ARM_RPC24 #define R_ARM_RPC24 254 #endif /* R_ARM_RPC24 */ #ifndef R_ARM_RBASE #define R_ARM_RBASE 255 #endif /* R_ARM_RBASE */ #ifndef R_ARM_NUM #define R_ARM_NUM 256 #endif /* R_ARM_NUM */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 0x101 #endif /* R_AARCH64_ABS64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 0x102 #endif /* R_AARCH64_ABS32 */ libdwarf-20210528/libdwarf/pro_reloc_stream.h0000664000175000017500000000346214012266121015776 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); libdwarf-20210528/libdwarf/dwarf_loclists.c0000664000175000017500000011564613764007262015475 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_loc.h" #define SIZEOFT8 1 #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 #define TRUE 1 #define FALSE 0 #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ /* Used in case of error reading the loclists headers (not referring to Dwarf_Loc_Head_c here), to clean up. */ static void free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head) { Dwarf_Chain cur = head; Dwarf_Chain next = 0; if (!head) { return; } for ( ;cur; cur = next) { next = cur->ch_next; if (cur->ch_item) { free(cur->ch_item); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); } } } static int counted_loc_descr(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Small *enddata, Dwarf_Unsigned offset, Dwarf_Unsigned *loc_ops_overall_size, Dwarf_Unsigned *loc_ops_count_len, Dwarf_Unsigned *loc_ops_len, Dwarf_Small **opsdata, Dwarf_Unsigned *opsoffset, Dwarf_Error * err) { Dwarf_Unsigned ops_len = 0; Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(data,ops_len,leblen, dbg,err,enddata); *loc_ops_count_len = leblen; *loc_ops_overall_size = ops_len+leblen; *loc_ops_len = ops_len; *opsdata = data; *opsoffset = offset +leblen; return DW_DLV_OK; } static int read_single_lle_entry(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Unsigned dataoffset, Dwarf_Small *enddata, unsigned address_size, unsigned *bytes_count_out, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Unsigned *opsblocksize, /* Just the expr data */ Dwarf_Unsigned *opsoffset, /* Just the expr ops data */ Dwarf_Small **ops, /* pointer to expr ops ops */ Dwarf_Error* err) { Dwarf_Unsigned count = 0; unsigned int leblen = 0; unsigned int code = 0; Dwarf_Unsigned val1 = 0; Dwarf_Unsigned val2 = 0; Dwarf_Unsigned loc_ops_overall_size = 0; Dwarf_Unsigned loc_ops_count_len = 0; Dwarf_Unsigned loc_ops_len = 0; Dwarf_Small *lopsdata = 0; Dwarf_Unsigned lopsoffset = 0; /* Some of these have a Counted Location Description in them. */ code = *data; ++data; ++count; switch(code) { case DW_LLE_end_of_list: break; case DW_LLE_base_addressx:{ DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen, dbg,err,enddata); count += leblen; } break; case DW_LLE_startx_endx: case DW_LLE_startx_length: case DW_LLE_offset_pair: { int res = 0; DECODE_LEB128_UWORD_LEN_CK(data,val1,leblen, dbg,err,enddata); count += leblen; DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen, dbg,err,enddata); count += leblen; res = counted_loc_descr(dbg,data,enddata, dataoffset, &loc_ops_overall_size, &loc_ops_count_len, &loc_ops_len, &lopsdata, &lopsoffset, err); if (res != DW_DLV_OK) { return res; } count += loc_ops_overall_size; data += loc_ops_overall_size; } break; case DW_LLE_default_location: { int res = 0; res = counted_loc_descr(dbg,data,enddata, dataoffset, &loc_ops_overall_size, &loc_ops_count_len, &loc_ops_len, &lopsdata, &lopsoffset, err); if (res != DW_DLV_OK) { return res; } data += loc_ops_overall_size; count += loc_ops_overall_size; } break; case DW_LLE_base_address: { READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; } break; case DW_LLE_start_end: { int res = 0; READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; READ_UNALIGNED_CK(dbg,val2, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; res = counted_loc_descr(dbg,data,enddata, dataoffset, &loc_ops_overall_size, &loc_ops_count_len, &loc_ops_len, &lopsdata, &lopsoffset, err); if (res != DW_DLV_OK) { return res; } count += loc_ops_overall_size; data += loc_ops_overall_size; } break; case DW_LLE_start_length: { int res = 0; READ_UNALIGNED_CK(dbg,val1, Dwarf_Unsigned, data,address_size,err,enddata); data += address_size; count += address_size; DECODE_LEB128_UWORD_LEN_CK(data,val2,leblen, dbg,err,enddata); count += leblen; res = counted_loc_descr(dbg,data,enddata, dataoffset, &loc_ops_overall_size, &loc_ops_count_len, &loc_ops_len, &lopsdata, &lopsoffset, err); if (res != DW_DLV_OK) { return res; } count += loc_ops_overall_size; data += loc_ops_overall_size; } break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: " "The loclists entry at .debug_loclists" " offset 0x%x" ,dataoffset); dwarfstring_append_printf_u(&m, " has code 0x%x which is unknown",code); _dwarf_error_string(dbg,err,DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } break; } *bytes_count_out = count; *entry_kind = code; *entry_operand1 = val1; *entry_operand2 = val2; *opsblocksize = loc_ops_len; *opsoffset = lopsoffset; *ops = lopsdata; return DW_DLV_OK; } /* Reads the header. Determines the various offsets, including offset of the next header. Does no memory allocations here. */ int _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, Dwarf_Small *end_data, Dwarf_Unsigned offset, Dwarf_Loclists_Context buildhere, Dwarf_Unsigned *next_offset, Dwarf_Error *error) { Dwarf_Small *startdata = data; Dwarf_Unsigned arealen = 0; int offset_size = 0; int exten_size = 0; Dwarf_Unsigned version = 0; unsigned address_size = 0; unsigned segment_selector_size= 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned localoff = 0; Dwarf_Unsigned lists_len = 0; READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, data,offset_size,exten_size, error, sectionlength,end_data); if (arealen > sectionlength) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_SECTION_SIZE_ERROR: A .debug_loclists " "area size of 0x%x ",arealen); dwarfstring_append_printf_u(&m, "at offset 0x%x ",offset); dwarfstring_append_printf_u(&m, "is larger than the entire section size of " "0x%x. Corrupt DWARF.",sectionlength); _dwarf_error_string(dbg,error,DW_DLE_SECTION_SIZE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->lc_length = arealen +offset_size+exten_size; buildhere->lc_dbg = dbg; buildhere->lc_index = contextnum; buildhere->lc_header_offset = offset; buildhere->lc_offset_size = offset_size; buildhere->lc_extension_size = exten_size; READ_UNALIGNED_CK(dbg,version,Dwarf_Unsigned,data, SIZEOFT16,error,end_data); if (version != DW_CU_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 " "but we find %u instead.",version); _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->lc_version = version; data += SIZEOFT16; READ_UNALIGNED_CK(dbg,address_size,unsigned,data, SIZEOFT8,error,end_data); if (version != DW_CU_VERSION5) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_VERSION_STAMP_ERROR: The version should be 5 " "but we find %u instead.",version); _dwarf_error_string(dbg,error,DW_DLE_VERSION_STAMP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if (address_size != 4 && address_size != 8 && address_size != 2) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, " DW_DLE_ADDRESS_SIZE_ERROR: The address size " "of %u is not supported.",address_size); _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } buildhere->lc_address_size = address_size; data++; READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data, SIZEOFT8,error,end_data); buildhere->lc_segment_selector_size = segment_selector_size; data++; READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data, SIZEOFT32,error,end_data); buildhere->lc_offset_entry_count = offset_entry_count; data += SIZEOFT32; if (offset_entry_count ){ buildhere->lc_offsets_array = data; } localoff = data - startdata; lists_len = offset_size *offset_entry_count; data += lists_len; buildhere->lc_offsets_off_in_sect = offset+localoff; buildhere->lc_first_loclist_offset = offset+localoff+ lists_len; buildhere->lc_loclists_header = startdata; buildhere->lc_endaddr = startdata +buildhere->lc_length; buildhere->lc_past_last_loclist_offset = buildhere->lc_header_offset +buildhere->lc_length; *next_offset = buildhere->lc_past_last_loclist_offset; return DW_DLV_OK; } /* We return a pointer to an array of contexts (not context pointers through *cxt if we succeed and are returning DW_DLV_OK. We never return DW_DLV_NO_ENTRY here. */ static int internal_load_loclists_contexts(Dwarf_Debug dbg, Dwarf_Loclists_Context **cxt, Dwarf_Unsigned *count, Dwarf_Error *error) { Dwarf_Unsigned offset = 0; Dwarf_Unsigned nextoffset = 0; Dwarf_Small * data = dbg->de_debug_loclists.dss_data; Dwarf_Unsigned section_size = dbg->de_debug_loclists.dss_size; Dwarf_Small * startdata = data; Dwarf_Small * end_data = data +section_size; Dwarf_Chain curr_chain = 0; Dwarf_Chain prev_chain = 0; Dwarf_Chain head_chain = 0; int res = 0; Dwarf_Unsigned chainlength = 0; Dwarf_Loclists_Context *fullarray = 0; Dwarf_Unsigned i = 0; for ( ; data < end_data ; ) { Dwarf_Loclists_Context newcontext = 0; /* sizeof the context struct, not sizeof a pointer */ newcontext = malloc(sizeof(*newcontext)); if (!newcontext) { free_loclists_chain(dbg,head_chain); _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Allocation of " "Loclists_Context failed"); return DW_DLV_ERROR; } memset(newcontext,0,sizeof(*newcontext)); res = _dwarf_internal_read_loclists_header(dbg, chainlength, section_size, data,end_data,offset, newcontext,&nextoffset,error); if (res == DW_DLV_ERROR) { free(newcontext); free_loclists_chain(dbg,head_chain); return DW_DLV_ERROR; } curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { free_loclists_chain(dbg,head_chain); _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: allocating Loclists_Context" " chain entry"); return DW_DLV_ERROR; } curr_chain->ch_item = newcontext; ++chainlength; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } data = startdata+nextoffset; offset = nextoffset; } fullarray= (Dwarf_Loclists_Context *)malloc( chainlength *sizeof(Dwarf_Loclists_Context /*pointer*/)); if (!fullarray) { free_loclists_chain(dbg,head_chain); _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL,"Allocation of " "Loclists_Context pointer array failed"); return DW_DLV_ERROR; } curr_chain = head_chain; for (i = 0; i < chainlength; ++i) { fullarray[i] = (Dwarf_Loclists_Context)curr_chain->ch_item; curr_chain->ch_item = 0; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } /* ASSERT: the chain is entirely dealloc'd and the array of pointers points to individually malloc'd Dwarf_Loclists_Context_s */ *cxt = fullarray; *count = chainlength; return DW_DLV_OK; } /* Used by dwarfdump to print raw loclists data. Loads all the .debug_loclists[.dwo] headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and done exactly once. Harmless to do more than once. With DW_DLV_OK it returns the number of loclists headers in the section through loclists_count. */ int dwarf_load_loclists( Dwarf_Debug dbg, Dwarf_Unsigned *loclists_count, Dwarf_Error *error) { int res = DW_DLV_ERROR; Dwarf_Loclists_Context *cxt = 0; Dwarf_Unsigned count = 0; if (dbg->de_loclists_context) { if (loclists_count) { *loclists_count = dbg->de_loclists_context_count; } } if (!dbg->de_debug_loclists.dss_size) { /* nothing there. */ return DW_DLV_NO_ENTRY; } if (!dbg->de_debug_loclists.dss_data) { res = _dwarf_load_section(dbg, &dbg->de_debug_loclists, error); if (res != DW_DLV_OK) { return res; } } res = internal_load_loclists_contexts(dbg,&cxt,&count,error); if (res == DW_DLV_ERROR) { return res; } dbg->de_loclists_context = cxt; dbg->de_loclists_context_count = count; if (loclists_count) { *loclists_count = count; } return DW_DLV_OK; } /* Frees the memory in use in all loclists contexts. Done by dwarf_finish() */ void _dwarf_dealloc_loclists_context(Dwarf_Debug dbg) { Dwarf_Unsigned i = 0; Dwarf_Loclists_Context * loccon = 0; if (!dbg->de_loclists_context) { return; } loccon = dbg->de_loclists_context; for ( ; i < dbg->de_loclists_context_count; ++i,++loccon) { Dwarf_Loclists_Context con = *loccon; con->lc_offsets_array = 0; con->lc_offset_entry_count = 0; free(con); } free(dbg->de_loclists_context); dbg->de_loclists_context = 0; dbg->de_loclists_context_count = 0; } /* Used by dwarfdump to print raw loclists data. */ int dwarf_get_loclist_offset_index_value( Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned offsetentry_index, Dwarf_Unsigned * offset_value_out, Dwarf_Unsigned * global_offset_value_out, Dwarf_Error *error) { Dwarf_Loclists_Context con = 0; unsigned offset_len = 0; Dwarf_Small *offsetptr = 0; Dwarf_Unsigned targetoffset = 0; if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } if (context_index >= dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_loclists_context[context_index]; if (offsetentry_index >= con->lc_offset_entry_count) { return DW_DLV_NO_ENTRY; } offset_len = con->lc_offset_size; offsetptr = con->lc_offsets_array + (offsetentry_index*offset_len); READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned, offsetptr, offset_len,error,con->lc_endaddr); if (offset_value_out) { *offset_value_out = targetoffset; } if (global_offset_value_out) { *global_offset_value_out = targetoffset + con->lc_offsets_off_in_sect; } return DW_DLV_OK; } /* Used by dwarfdump to print basic data from the data generated to look at a specific loclist as returned by dwarf_loclists_index_get_rle_head() or dwarf_loclists_offset_get_rle_head. */ int dwarf_get_loclist_head_basics( Dwarf_Loc_Head_c head, Dwarf_Small * lkind, Dwarf_Unsigned * lle_count, Dwarf_Unsigned * lle_version, Dwarf_Unsigned * loclists_index_returned, Dwarf_Unsigned * bytes_total_in_lle, Dwarf_Half * offset_size, Dwarf_Half * address_size, Dwarf_Half * segment_selector_size, Dwarf_Unsigned * overall_offset_of_this_context, Dwarf_Unsigned * total_length_of_this_context, Dwarf_Unsigned * offset_table_offset, Dwarf_Unsigned * offset_table_entrycount, Dwarf_Bool * loclists_base_present, Dwarf_Unsigned * loclists_base, Dwarf_Bool * loclists_base_address_present, Dwarf_Unsigned * loclists_base_address, Dwarf_Bool * loclists_debug_addr_base_present, Dwarf_Unsigned * loclists_debug_addr_base, Dwarf_Unsigned * loclists_offset_lle_set, UNUSEDARG Dwarf_Error *error) { Dwarf_Loclists_Context loccontext = 0; *lkind = head->ll_kind; *lle_count = head->ll_locdesc_count; *lle_version = head->ll_cuversion; *loclists_index_returned = head->ll_index; *bytes_total_in_lle = head->ll_bytes_total; *offset_size = head->ll_offset_size; *address_size = head->ll_address_size; *segment_selector_size = head->ll_segment_selector_size; /* If a dwarf_expression, no ll_loccontext */ loccontext = head->ll_localcontext; if (loccontext) { *overall_offset_of_this_context = loccontext->lc_header_offset; *total_length_of_this_context = loccontext->lc_length; *offset_table_offset = loccontext->lc_offsets_off_in_sect; *offset_table_entrycount = loccontext->lc_offset_entry_count; } *loclists_base_present = head->ll_at_loclists_base_present; *loclists_base= head->ll_at_loclists_base; *loclists_base_address_present = head->ll_cu_base_address_present; *loclists_base_address= head->ll_cu_base_address; *loclists_debug_addr_base_present = head->ll_cu_addr_base_present; *loclists_debug_addr_base = head->ll_cu_addr_base; *loclists_offset_lle_set = head->ll_llearea_offset; return DW_DLV_OK; } /* Used by dwarfdump to print raw loclists data. Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_loclists section may contain any number of Range List Table Headers with their details. */ int dwarf_get_loclist_context_basics( Dwarf_Debug dbg, Dwarf_Unsigned context_index, Dwarf_Unsigned * header_offset, Dwarf_Small * offset_size, Dwarf_Small * extension_size, unsigned * version, /* 5 */ Dwarf_Small * address_size, Dwarf_Small * segment_selector_size, Dwarf_Unsigned * offset_entry_count, Dwarf_Unsigned * offset_of_offset_array, Dwarf_Unsigned * offset_of_first_loclistentry, Dwarf_Unsigned * offset_past_last_loclistentry, UNUSEDARG Dwarf_Error *error) { Dwarf_Loclists_Context con = 0; if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } if (context_index >= dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_loclists_context[context_index]; if (header_offset) { *header_offset = con->lc_header_offset; } if (offset_size) { *offset_size = con->lc_offset_size; } if (offset_size) { *extension_size = con->lc_extension_size; } if (version) { *version = con->lc_version; } if (address_size) { *address_size = con->lc_address_size; } if (segment_selector_size) { *segment_selector_size = con->lc_segment_selector_size; } if (offset_entry_count) { *offset_entry_count = con->lc_offset_entry_count; } if (offset_of_offset_array) { *offset_of_offset_array = con->lc_offsets_off_in_sect; } if (offset_of_first_loclistentry) { *offset_of_first_loclistentry = con->lc_first_loclist_offset; } if (offset_past_last_loclistentry) { *offset_past_last_loclistentry = con->lc_past_last_loclist_offset; } return DW_DLV_OK; } /* Used by dwarfdump to print raw loclists data. entry offset is offset_of_first_loclistentry. Stop when the returned *next_entry_offset is == offset_past_last_loclistentry (from dwarf_get_loclist_context_plus). This only makes sense within those loclists This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single loclist header, meaning a a single Dwarf_Loclists_Context. */ int dwarf_get_loclist_lle( Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned entry_offset, Dwarf_Unsigned endoffset, unsigned *entrylen, unsigned *entry_kind, Dwarf_Unsigned *entry_operand1, Dwarf_Unsigned *entry_operand2, Dwarf_Unsigned *expr_ops_blocksize, Dwarf_Unsigned *expr_ops_offset, Dwarf_Small **expr_opsdata, Dwarf_Error *err) { Dwarf_Loclists_Context con = 0; Dwarf_Small *data = 0; Dwarf_Small *enddata = 0; int res = 0; unsigned address_size = 0; if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } data = dbg->de_debug_loclists.dss_data + entry_offset; enddata = dbg->de_debug_loclists.dss_data + endoffset; if (contextnumber >= dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } con = dbg->de_loclists_context[contextnumber]; address_size = con->lc_address_size; res = read_single_lle_entry(dbg, data,entry_offset,enddata, address_size, entrylen, entry_kind, entry_operand1, entry_operand2, expr_ops_blocksize, expr_ops_offset, expr_opsdata, err); return res; } static int _dwarf_which_loclists_context(Dwarf_Debug dbg, Dwarf_CU_Context ctx, Dwarf_Unsigned loclist_offset, Dwarf_Unsigned *index, Dwarf_Error *error) { Dwarf_Unsigned count = 0; Dwarf_Loclists_Context *array = 0; Dwarf_Unsigned i = 0; Dwarf_Loclists_Context rcx = 0; Dwarf_Unsigned rcxoff = 0; Dwarf_Unsigned rcxend = 0; array = dbg->de_loclists_context; count = dbg->de_loclists_context_count; if (!array) { return DW_DLV_NO_ENTRY; } rcx = array[i]; rcxoff = rcx->lc_header_offset; rcxend = rcxoff + rcx->lc_length; if (!ctx->cc_loclists_base_present) { /* We look at the location of each loclist context to find one with the offset the DIE gave us. */ for ( i = 0 ; i < count; ++i) { rcx = array[i]; rcxoff = rcx->lc_header_offset; rcxend = rcxoff + rcx->lc_length; rcxend = rcxoff + rcx->lc_length; if (loclist_offset < rcxoff){ continue; } if (loclist_offset < rcxend ){ *index = i; return DW_DLV_OK; } } { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: loclist ran off end " " finding target offset of" " 0x%" DW_PR_XZEROS DW_PR_DUx ,loclist_offset); dwarfstring_append(&m, " Not found anywhere in .debug_loclists " "data. Corrupted data?"); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } else { /* We have a DW_AT_loclists_base (lc_loclists_base), let's use it. */ Dwarf_Unsigned lookfor = 0;; lookfor = ctx->cc_loclists_base; for ( i = 0 ; i < count; ++i) { dwarfstring m; rcx = array[i]; if (rcx->lc_offsets_off_in_sect == lookfor){ *index = i; return DW_DLV_OK; } if (rcx->lc_offsets_off_in_sect < lookfor){ continue; } dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: loclists base of " " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor); dwarfstring_append_printf_u(&m, " was not found though we are now at base " " 0x%" DW_PR_XZEROS DW_PR_DUx , rcx->lc_offsets_off_in_sect); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: loclist base of " " 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor); dwarfstring_append(&m, " was not found anywhere in .debug_loclists " "data. Corrupted data?"); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } return DW_DLV_ERROR; } /* Caller will eventually free as appropriate. */ static int alloc_rle_and_append_to_list(Dwarf_Debug dbg, Dwarf_Loc_Head_c rctx, Dwarf_Locdesc_c *e_out, Dwarf_Error *error) { Dwarf_Locdesc_c e = 0; e = malloc(sizeof(struct Dwarf_Locdesc_c_s)); if (!e) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Out of memory in " "building list of loclists entries on a DIE."); return DW_DLV_ERROR; } memset(e,0,sizeof(struct Dwarf_Locdesc_c_s)); _dwarf_locdesc_c_constructor(dbg,e); if (rctx->ll_first) { rctx->ll_last->ld_next = e; rctx->ll_last = e; } else { rctx->ll_first = e; rctx->ll_last = e; } rctx->ll_locdesc_count++; *e_out = e; return DW_DLV_OK; } /* Read the group of loclists entries, and finally build an array of Dwarf_Locdesc_c records. Attach to rctx here. Since on error the caller will destruct the rctx and we ensure to attach allocations there the caller will destruct the allocations here in case we return DW_DLV_ERROR*/ static int build_array_of_lle(Dwarf_Debug dbg, Dwarf_Loc_Head_c rctx, Dwarf_Error *error) { int res = 0; Dwarf_Small *data = rctx->ll_llepointer; Dwarf_Unsigned dataoffset = rctx->ll_llearea_offset; Dwarf_Small *enddata = rctx->ll_end_data_area; unsigned int offset_size = rctx->ll_offset_size; unsigned int address_size = rctx->ll_address_size; Dwarf_Unsigned bytescounttotal= 0; int done = FALSE; Dwarf_Unsigned locdesc_index = 0; Dwarf_Unsigned i = 0; for ( ; !done ;++locdesc_index ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned val1 = 0; Dwarf_Unsigned val2 = 0; Dwarf_Locdesc_c e = 0; Dwarf_Unsigned opsblocksize = 0; Dwarf_Unsigned opsoffset = 0; Dwarf_Small *ops = 0; Dwarf_Block_c eops; memset(&eops,0,sizeof(eops)); res = read_single_lle_entry(dbg, data,dataoffset, enddata, address_size,&entrylen, &code,&val1, &val2, &opsblocksize,&opsoffset,&ops, error); if (res != DW_DLV_OK) { return res; } res = alloc_rle_and_append_to_list(dbg,rctx,&e,error); if (res != DW_DLV_OK) { return res; } eops.bl_len =opsblocksize; eops.bl_data = ops; eops.bl_kind = rctx->ll_kind; eops.bl_section_offset = opsoffset; eops.bl_locdesc_offset = dataoffset; e->ld_kind = rctx->ll_kind; e->ld_lle_value = code, e->ld_entrylen = entrylen; e->ld_rawlow = val1; e->ld_rawhigh = val2; e->ld_opsblock = eops; bytescounttotal += entrylen; data += entrylen; if (code == DW_LLE_end_of_list) { done = TRUE; break; } } if (rctx->ll_locdesc_count > 0) { Dwarf_Locdesc_c array = 0; Dwarf_Locdesc_c cur = 0; Dwarf_Locdesc_c prev = 0; /* array of structs. Here we copy the previous malloc set of Dwarf_Locdesc_c into a dwarf_get_alloc set and free the malloc set */ array = (Dwarf_Locdesc_c)_dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, rctx->ll_locdesc_count); if (!array) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Out of memory in " "copying list of locdescs into array "); return DW_DLV_ERROR; } rctx->ll_locdesc = array; cur = rctx->ll_first; for (i = 0 ; i < rctx->ll_locdesc_count; ++i) { prev = cur; array[i] = *cur; cur = cur->ld_next; free(prev); } rctx->ll_first = 0; rctx->ll_last = 0; } for (i = 0; i < rctx->ll_locdesc_count; ++i) { Dwarf_Locdesc_c ldc = rctx->ll_locdesc + i; res = _dwarf_fill_in_locdesc_op_c(dbg, i, rctx, &ldc->ld_opsblock, address_size, offset_size, rctx->ll_cuversion, ldc->ld_rawlow, ldc->ld_rawhigh, ldc->ld_lle_value, error); if (res != DW_DLV_OK) { return res; } } rctx->ll_bytes_total = bytescounttotal; return DW_DLV_OK; } /* Build a head with all the relevent Entries attached, all the locdescs and for each such, all its expression operators. */ int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Loc_Head_c llhead, Dwarf_Error *error) { int res = 0; Dwarf_Unsigned loclists_contextnum = 0; Dwarf_Small *table_base = 0; Dwarf_Small *table_entry = 0; Dwarf_Small *enddata = 0; Dwarf_Loclists_Context *array = 0; Dwarf_Loclists_Context rctx = 0; Dwarf_Unsigned entrycount = 0; unsigned offsetsize = 0; Dwarf_Unsigned lle_global_offset = 0; Dwarf_CU_Context ctx = 0; Dwarf_Unsigned offset_in_loclists = 0; Dwarf_Bool is_loclistx = FALSE; int theform = llhead->ll_attrform; Dwarf_Unsigned attr_val = 0; ctx = attr->ar_cu_context; array = dbg->de_loclists_context; if ( theform == DW_FORM_sec_offset) { /* DW_FORM_sec_offset is not formudata , often seen in in DW5 DW_AT_location etc */ res = dwarf_global_formref(attr, &attr_val,error); if (res != DW_DLV_OK) { return res; } offset_in_loclists = attr_val; } else { if (theform == DW_FORM_loclistx) { is_loclistx = TRUE; } res = dwarf_formudata(attr,&attr_val,error); if (res != DW_DLV_OK) { return res; } /* the context cc_loclists_base gives the offset of the array. of offsets (if cc_loclists_base_present) */ offset_in_loclists = attr_val; if (is_loclistx) { if (ctx->cc_loclists_base_present) { offset_in_loclists = ctx->cc_loclists_base; } else if (dbg->de_loclists_context_count == 1) { /* missing a DW_AT_loclists_base! */ offset_in_loclists = 0; } else { /* FIXME: check in tied file for a cc_loclists_base possibly? Make any sense? */ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: loclists table index of" " %u" ,attr_val); dwarfstring_append(&m, " is unusable without a tied file." ); _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } else { offset_in_loclists = attr_val; } } res = _dwarf_which_loclists_context(dbg,ctx, offset_in_loclists, &loclists_contextnum,error); if (res != DW_DLV_OK) { return res; } rctx = array[loclists_contextnum]; table_base = rctx->lc_offsets_array; entrycount = rctx->lc_offset_entry_count; offsetsize = rctx->lc_offset_size; enddata = rctx->lc_endaddr; if (is_loclistx && attr_val >= entrycount) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: loclists table index of" " %u" ,attr_val); dwarfstring_append_printf_u(&m, " too large for table of %u " "entries.",entrycount); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } llhead->ll_localcontext = rctx; llhead->ll_index = loclists_contextnum; llhead->ll_cuversion = rctx->lc_version; llhead->ll_offset_size = offsetsize; llhead->ll_address_size = rctx->lc_address_size; llhead->ll_segment_selector_size = rctx->lc_segment_selector_size; if (is_loclistx) { Dwarf_Unsigned table_entryval = 0; table_entry = attr_val*offsetsize + table_base; /* No malloc here yet so no leak if the macro returns DW_DLV_ERROR */ READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned, table_entry,offsetsize,error,enddata); lle_global_offset = rctx->lc_offsets_off_in_sect + table_entryval; } else { lle_global_offset = attr_val; } llhead->ll_end_data_area = enddata; llhead->ll_llearea_offset = lle_global_offset; llhead->ll_llepointer = lle_global_offset + dbg->de_debug_loclists.dss_data; res = build_array_of_lle(dbg,llhead,error); if (res != DW_DLV_OK) { return res; } return DW_DLV_OK; } int dwarf_get_loclists_entry_fields( Dwarf_Loc_Head_c head, Dwarf_Unsigned entrynum, unsigned *entrylen, unsigned *code, Dwarf_Unsigned *raw1, Dwarf_Unsigned *raw2, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, /* FIXME not right for loclists or their loc exprs */ UNUSEDARG Dwarf_Error *err) { Dwarf_Locdesc_c e = 0; if (entrynum >= head->ll_locdesc_count) { return DW_DLV_NO_ENTRY; } e = head->ll_locdesc + entrynum; *entrylen = e->ld_entrylen; *code = e->ld_lle_value; *raw1 = e->ld_rawlow; *raw2 = e->ld_rawhigh; *cooked1 = e->ld_lopc; *cooked2 = e->ld_highpc; return DW_DLV_OK; } /* Deals with both fully and partially build head */ void _dwarf_free_loclists_head_content(Dwarf_Loc_Head_c head) { Dwarf_Debug dbg = head->ll_dbg; if (head->ll_first) { /* partially built head. */ /* ASSERT: ll_loclists is NULL */ Dwarf_Locdesc_c cur = head->ll_first; Dwarf_Locdesc_c next = 0; for ( ; cur ; cur = next) { next = cur->ld_next; cur->ld_next = 0; free(cur); } head->ll_first = 0; head->ll_last = 0; head->ll_locdesc_count = 0; } else if (head->ll_locdesc) { Dwarf_Locdesc_c desc = head->ll_locdesc; /* ASSERT: ll_first and ll_last are NULL */ /* fully built head. */ Dwarf_Unsigned listlen = head->ll_locdesc_count; Dwarf_Unsigned i = 0; for ( ; i < listlen; ++i) { Dwarf_Loc_Expr_Op loc = desc[i].ld_s; if (loc) { dwarf_dealloc(dbg,loc,DW_DLA_LOC_BLOCK_C); desc[i].ld_s = 0; } } dwarf_dealloc(dbg,head->ll_locdesc,DW_DLA_LOCDESC_C); head->ll_locdesc = 0; head->ll_locdesc_count = 0; } } /* dwarf_alloc calls this on dealloc. head is freed there after this returns. */ void _dwarf_loclists_head_destructor(void *head) { Dwarf_Loc_Head_c h = head; _dwarf_free_loclists_head_content(h); } libdwarf-20210528/libdwarf/dwarf_macro.h0000644000175000017500000000222513743575426014742 00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dwarf_macro.h $Revision: 1.4 $ $Date: 2004/10/28 22:19:14 $ */ libdwarf-20210528/libdwarf/dwarf_dsc.c0000664000175000017500000002316613764007262014405 00000000000000/* Copyright (C) 2016-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_dsc.h" #define FALSE 0 #define TRUE 1 /* When called with ary and *arraycount 0 this just counts the elements found. Otherwise it records the values in ary and recounts. The arraycount pointer must be passed-in non-null always. */ static int get_dsc_leb_entries(Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, int dounsigned, struct Dwarf_Dsc_Entry_s *ary, size_t * arraycount, Dwarf_Error * error) { Dwarf_Small *p = blockpointer; Dwarf_Small *endp = blockpointer + blocklen; size_t larraycount = 0; size_t iarraycount = *arraycount; if (!ary) { if (iarraycount) { /* Internal botch calling this static function. */ _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } else { if (!iarraycount) { /* Internal botch calling this static function. */ _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } if (dounsigned) { while (p < endp) { Dwarf_Unsigned dsc = 0; Dwarf_Unsigned low = 0; Dwarf_Unsigned high = 0; UNUSEDARG Dwarf_Unsigned leblen = 0; if (ary && (larraycount >= iarraycount)) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_LEN_CK(p,dsc, leblen,dbg,error,endp); if (!dsc) { DECODE_LEB128_UWORD_LEN_CK(p,low, leblen, dbg,error,endp); } else { DECODE_LEB128_UWORD_LEN_CK(p,low, leblen, dbg,error,endp); DECODE_LEB128_UWORD_LEN_CK(p,high, leblen, dbg,error,endp); } if (ary) { struct Dwarf_Dsc_Entry_s *arye = ary+larraycount; /* type reads the same as uleb and leb because it is only zero or one. */ arye->dsc_type = dsc; arye->dsc_low_u = low; arye->dsc_high_u = high; } larraycount++; } } else { while (p < endp) { Dwarf_Signed dsc = 0; Dwarf_Signed low = 0; Dwarf_Signed high = 0; UNUSEDARG Dwarf_Unsigned leblen = 0; if (ary && (larraycount >= iarraycount)) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } DECODE_LEB128_SWORD_LEN_CK(p,dsc, leblen,dbg,error,endp); if (!dsc) { DECODE_LEB128_SWORD_LEN_CK(p,low, leblen,dbg,error,endp); } else { DECODE_LEB128_SWORD_LEN_CK(p,low, leblen,dbg,error,endp); DECODE_LEB128_SWORD_LEN_CK(p,high, leblen,dbg,error,endp); } if (ary) { struct Dwarf_Dsc_Entry_s *arye = ary+larraycount; /* type reads the same as uleb and leb because it is only zero or one. */ arye->dsc_type = (Dwarf_Unsigned)dsc; arye->dsc_low_s = low; arye->dsc_high_s = high; } larraycount++; } } if (ary) { /* Just verify this recount matches original */ if (iarraycount != larraycount) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } else { /* This matters for first call with ary 0 and iarraycount 0 as we are generating the count. */ *arraycount = larraycount; } return DW_DLV_OK; } int dwarf_discr_list(Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, Dwarf_Dsc_Head * dsc_head_out, Dwarf_Unsigned * dsc_array_length_out, Dwarf_Error * error) { Dwarf_Dsc_Head h = 0; int res = 0; size_t arraycount = 0; struct Dwarf_Dsc_Entry_s *ary = 0; Dwarf_Small * dscblockp = 0; Dwarf_Unsigned dscblocklen = 0; if (!dbg){ _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ return DW_DLV_ERROR; } if (blocklen == 0) { return DW_DLV_NO_ENTRY; } dscblockp = (Dwarf_Small *)calloc(blocklen,sizeof(Dwarf_Small)); if (!dscblockp) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dscblocklen = blocklen; memcpy(dscblockp,blockpointer,blocklen); res = get_dsc_leb_entries(dbg,dscblockp,dscblocklen, /* TRUE or FALSE here is not important, the arraycount returned to us will be identical either way. */ FALSE, 0, &arraycount,error); if (res != DW_DLV_OK) { free(dscblockp); return res; } h = (Dwarf_Dsc_Head)_dwarf_get_alloc(dbg,DW_DLA_DSC_HEAD,1); if (!h) { free(dscblockp); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } h->dsh_block = dscblockp; h->dsh_block_len = dscblocklen; h->dsh_debug = dbg; /* Now the destructor for h will deal with block malloc space. */ ary = (struct Dwarf_Dsc_Entry_s *)calloc(arraycount, sizeof(struct Dwarf_Dsc_Entry_s)); if (!ary) { dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } h->dsh_count = arraycount; h->dsh_array = ary; h->dsh_set_unsigned = 0; h->dsh_set_signed = 0; *dsc_head_out = h; *dsc_array_length_out = arraycount; return DW_DLV_OK; } /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head dsh , Dwarf_Unsigned entrynum, Dwarf_Half * out_type, Dwarf_Unsigned * out_discr_low, Dwarf_Unsigned * out_discr_high, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Dsc_Entry_s *dse = 0; if (entrynum >= dsh->dsh_count) { return DW_DLV_NO_ENTRY; } if (!dsh->dsh_set_unsigned) { int res =0; int dounsigned = 1; size_t count = dsh->dsh_count; res = get_dsc_leb_entries(dsh->dsh_debug, dsh->dsh_block, dsh->dsh_block_len, dounsigned, dsh->dsh_array, &count, error); if (res != DW_DLV_OK) { return res; } dsh->dsh_set_unsigned = TRUE; } if (!dsh->dsh_array) { _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } dse = dsh->dsh_array + entrynum; *out_type = dse->dsc_type; *out_discr_low = dse->dsc_low_u; *out_discr_high = dse->dsc_high_u; return DW_DLV_OK; } /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head dsh, Dwarf_Unsigned entrynum, Dwarf_Half * out_type, Dwarf_Signed * out_discr_low, Dwarf_Signed * out_discr_high, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Dsc_Entry_s *dse = 0; if (entrynum >= dsh->dsh_count) { return DW_DLV_NO_ENTRY; } if (!dsh->dsh_set_signed) { int res =0; int dounsigned = 0; size_t count = dsh->dsh_count; res = get_dsc_leb_entries(dsh->dsh_debug, dsh->dsh_block, dsh->dsh_block_len, dounsigned, dsh->dsh_array, &count, error); if (res != DW_DLV_OK) { return res; } dsh->dsh_set_signed = TRUE; } if (!dsh->dsh_array) { _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } dse = dsh->dsh_array + entrynum; *out_type = dse->dsc_type; *out_discr_low = dse->dsc_low_s; *out_discr_high = dse->dsc_high_s; return DW_DLV_OK; } void _dwarf_dsc_destructor(void *m) { Dwarf_Dsc_Head h = (Dwarf_Dsc_Head) m; free(h->dsh_array); h->dsh_array = 0; free(h->dsh_block); h->dsh_block = 0; h->dsh_count = 0; } libdwarf-20210528/libdwarf/dwarf_leb.c0000664000175000017500000002231114053207326014360 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_util.h" /* Note that with 'make check') many of the test items only make sense if Dwarf_Unsigned (and Dwarf_Signed) are 64 bits. The encode/decode logic should be fine whether those types are 64 or 32 bits. See runtests.sh */ /* 10 bytes of leb, 7 bits each part of the number, gives room for a 64bit number. While any number of leading zeroes would be legal, so no max is really truly required here, why would a compiler generate leading zeros (for unsigned leb)? That would seem strange except in rare circumstances a compiler may want, for overall alignment, to add extra bytes.. So we allow more than 10 as it is legal for a compiler to generate an leb with correct but useless trailing zero bytes (note the interaction with sign in the signed case). The value of BYTESLEBMAX is arbitrary but allows catching corrupt data before dark. Before April 2021 BYTESLEBMAX was 10. */ #define BYTESLEBMAX 24 #define BITSPERBYTE 8 #define TRUE 1 #define FALSE 0 /* Decode ULEB with checking */ int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Unsigned *outval, Dwarf_Byte_Ptr endptr) { unsigned byte = 0; Dwarf_Unsigned word_number = 0; Dwarf_Unsigned number = 0; size_t shift = 0; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 0; if (leb128 >=endptr) { return DW_DLV_ERROR; } /* The following unrolls-the-loop for the first two bytes and unpacks into 32 bits to make this as fast as possible. word_number is assumed big enough that the shift has a defined result. */ byte = *leb128; if ((byte & 0x80) == 0) { if (leb128_length) { *leb128_length = 1; } *outval = byte; return DW_DLV_OK; } else { unsigned byte2 = 0; if ((leb128+1) >=endptr) { return DW_DLV_ERROR; } byte2 = *(leb128 + 1); if ((byte2 & 0x80) == 0) { if (leb128_length) { *leb128_length = 2; } word_number = byte & 0x7f; word_number |= (byte2 & 0x7f) << 7; *outval = word_number; return DW_DLV_OK; } /* Gets messy to hand-inline more byte checking. */ } /* The rest handles long numbers. Because the 'number' may be larger than the default int/unsigned, we must cast the 'byte' before the shift for the shift to have a defined result. */ number = 0; shift = 0; byte_length = 1; for (;;) { unsigned b = byte & 0x7f; if (shift >= (sizeof(number)*BITSPERBYTE)) { /* Shift is large. Maybe corrupt value, maybe some padding high-end byte zeroes that we can ignore. */ if (!b) { ++byte_length; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { *leb128_length = BYTESLEBMAX; } return DW_DLV_ERROR; } ++leb128; /* shift cannot overflow as BYTESLEBMAX is not a large value */ shift += 7; if (leb128 >=endptr) { return DW_DLV_ERROR; } byte = *leb128; continue; } /* Too big, corrupt data given the non-zero byte content */ return DW_DLV_ERROR; } number |= ((Dwarf_Unsigned)b << shift); if ((byte & 0x80) == 0) { if (leb128_length) { *leb128_length = byte_length; } *outval = number; return DW_DLV_OK; } shift += 7; byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { *leb128_length = BYTESLEBMAX; } break; } ++leb128; if (leb128 >=endptr) { return DW_DLV_ERROR; } byte = *leb128; } return DW_DLV_ERROR; } /* Public Interface: Decode an unsigned LEB128 value. */ int dwarf_decode_leb128(char* leb, Dwarf_Unsigned* leblen, Dwarf_Unsigned* outval, char* endptr) { return _dwarf_decode_u_leb128_chk((Dwarf_Small*)leb, leblen, outval, (Dwarf_Small*)endptr); } int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval,Dwarf_Byte_Ptr endptr) { Dwarf_Unsigned byte = 0; unsigned int b = 0; Dwarf_Signed number = 0; size_t shift = 0; int sign = FALSE; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 1; /* byte_length being the number of bytes of data absorbed so far in turning the leb into a Dwarf_Signed. */ if (!outval) { return DW_DLV_ERROR; } if (leb128 >= endptr) { return DW_DLV_ERROR; } byte = *leb128; for (;;) { b = byte & 0x7f; if (shift >= (sizeof(number)*BITSPERBYTE)) { /* Shift is large. Maybe corrupt value, maybe some padding high-end byte zeroes that we can ignore (but notice sign bit from the last usable byte). */ sign = b & 0x40; if (!byte || byte == 0x40) { /* The value is complete. */ break; } if (b == 0) { ++byte_length; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { *leb128_length = BYTESLEBMAX; } return DW_DLV_ERROR; } ++leb128; /* shift cannot overflow as BYTESLEBMAX is not a large value */ shift += 7; if (leb128 >=endptr) { return DW_DLV_ERROR; } byte = *leb128; continue; } /* Too big, corrupt data given the non-zero byte content */ return DW_DLV_ERROR; } /* This bit of the last (most-significant useful) byte indicates sign */ sign = b & 0x40; number |= ((Dwarf_Unsigned)b) << shift; shift += 7; if ((byte & 0x80) == 0) { break; } ++leb128; if (leb128 >= endptr) { return DW_DLV_ERROR; } byte = *leb128; byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { *leb128_length = BYTESLEBMAX; } return DW_DLV_ERROR; } } if (sign) { /* The following avoids undefined behavior. */ unsigned shiftlim = sizeof(Dwarf_Signed) * BITSPERBYTE -1; if (shift < shiftlim) { Dwarf_Signed y = (Dwarf_Signed) (((Dwarf_Unsigned)1) << shift); Dwarf_Signed x = -y; number |= x; } else if (shift == shiftlim) { Dwarf_Signed x= (((Dwarf_Unsigned)1) << shift); number |= x; } else { /* trailing zeroes case */ Dwarf_Signed x= (((Dwarf_Unsigned)1) << shiftlim); number |= x; } } if (leb128_length) { *leb128_length = byte_length; } *outval = number; return DW_DLV_OK; } /* Public Interface: Decode a signed LEB128 value. */ int dwarf_decode_signed_leb128(char* leb, Dwarf_Unsigned* leblen, Dwarf_Signed* outval, char* endptr) { return _dwarf_decode_s_leb128_chk((Dwarf_Small *)leb, leblen, outval, (Dwarf_Small*)endptr); } libdwarf-20210528/libdwarf/ChangeLog20120000664000175000017500000001622013644370703014355 000000000000002012-11-30 David Anderson * dwarf.h: defines for some added DW_OP_GNU operators * dwarf_loc.c: Added support for some DW_OP_GNU operators. 2012-11-29 David Anderson * dwarf_elf_access.c,dwarf_init_finish.c,dwarf_loc.c, dwarf_reloc_arm.h,dwarf_reloc_x86_64.h,libdwarf.h: Fix indents so dicheck gives no warnings. 2012-11-29 David Anderson * dwarf_addr_finder.c: Add const to a couple const arrays. * gennames.c: Add const to a couple const variables. * dwarf_form.c: dwarf_formflag() was incorrectly returning 1 instead of the actual flag value when non-zero flag value. Now returns the real flag byte value. * dwarf_opaque.h: Moved debug_section area info into a new array in Dwarf_Debug struct. * dwarf_init_finish.c: Instead of a file-static array, the array is moved to the Dwarf_Debug struct and accesses are adjusted to match. * pro_section.c: Add const to an array declaration. * libdwarf2.1.mm: Updated dwarf_formflag() documentation. Now version is 2.06. * libdwarf2.1.pdf: Regenerated. 2012-11-22 David Anderson * dwarf_loc.c: Removed the last dbg->de_length_size instances from _dwarf_get_locdesc() to reflect the incoming argument with the offset size (length size). 2012-11-21 David Anderson * dwarf_loc.c: Updated argument list and implementation for dwarf_loclist_from_expr_b(), adding offset size (length size). * libdwarf.h: Updated argument list for dwarf_loclist_from_expr_b(). * libdwarf2.1.mm: Updated dwarf_loclist_from_expr_b() documentation. Now version is 2.05. * libdwarf2.1.pdf: Regenerated. 2012-11-20 David Anderson * dwarf_line.h: Fixing two small formatting inconsistencies. 2012-11-17 David Anderson * dwarf_original_elf_init.c: Expanded comment about HAVE_ELF_C_READ_MMAP (which is not settable by configure and is not really needed). * configure regenerated with autoconf 2.69 * libdwarf2.1.mm: Document dwarf_encode_leb128() and and dwarf_encode_signed_leb128(). * libdwarf2.1.pdf: Regenerated. 2012-11-17 David Anderson * dwarf_arange.c,dwarf_base_types.h,dwarf_die_deliv.c, dwarf_elf_access.c,dwarf_form.c,dwarf_frame.c, dwarf_frame2.c,dwarf_harmless.c,dwarf_init_finish.c, dwarf_line.c,dwarf_line.h,dwarf_loc.c,dwarf_macro.c, dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_query.c dwarf_ranges.c,dwarf_reloc_arm.h,dwarf_reloc_mips.h, dwarf_reloc_ppc.h,dwarf_reloc_ppc64.h,dwarf_reloc_x86_64.h, dwarf_util.c,dwarf_util.h,pro_forms.c,pro_frame.c, pro_incl.h,pro_init.c,pro_section.c: Update copyright on files changed recently. 2012-11-15 CarlosAlbertoEnciso * dwarf.h: Incorrect comments for registers (64 to 108). * dwarf_arange.c: Consistent layout for if statements. * dwarf_base_type.h: Minor comment type. * dwarf_die_deliv.c: Consistent layout for if and while statements. * dwarf_elf_access.c: Consistent layout for if statements. For Windows, include header files with relocation definitions. Populate new fields 'type' (section type) and 'info' (target section for relocation) in data structure 'Dwarf_Obj_Access_Section_s'. Minor typo error in function 'is_32bit_abs_reloc' for the case 'EM_PPC64', to use the correct symbol 'R_PPC64_DTPREL32' and 'R_PPC64_DTPREL32'. * dwarf_form.c: Consistent layout for if statements. * dwarf_frame.c: Consistent layout for if, for and while statements. * dwarf_frame2.c: Consistent layout for if statements. * dwarf_harmless.c: Consistent layout for if and for statements. * dwarf_init_finish.c: Consistent layout for if statements. Use HAVE_ELF_H, HAVE_LIBELF_H, HAVE_LIBELF_LIBELF_H to control the inclusion of the libelf symbols. New function 'add_debug_section_info' and new data structure 'dbg_sect_s' to deal properly with .rel and .rela section types independently of the section name. The new algorithm to setup the debug sections is implemented in '_dwarf_setup'. * dwarf_line.c: Consistent layout for if statements. * dwarf_line.h: Consistent layout for if statements. * dwarf_loc.c: Consistent layout for if and switch statements. * dwarf_macro.c: Consistent layout for if statements. * dwarf_original_elf_init.c: Consistent layout for if statements. * dwarf_print_lines.c: Consistent layout for if statements. * dwarf_query.c: Consistent layout for if and switch statements. * dwarf_ranges.c: Consistent layout for if and for statements. * dwarf_reloc_arm.h: New file; relocations definitions for ARM. * dwarf_reloc_mips.h: New file; relocations definitions for MIPS. * dwarf_reloc_ppc.h: New file; relocations definitions for PPC. * dwarf_reloc_ppc64.h: New file; relocations definitions for PPC64. * dwarf_reloc_x86_64.h: New file; relocations definitions for X86_64. * dwarf_sort_line.c: Consistent layout for while statements. * dwarf_util.c: Consistent layout for if, for and while statements. New functions 'dwarf_encode_leb128', 'dwarf_encode_signed_leb128' to encode a value as unsiged LEB128 and signed LEB128. * dwarf_util.h: Consistent layout for the macros DECODE_LEB128_UWORD, DECODE_LEB128_SWORD, SKIP_LEB128_WORD, CHECK_DIE, READ_UNALIGNED, SIGN_EXTEND, READ_AREA_LENGTH to include proper tabbing. * libdwarf.h: Consistent layout for some typedef definitions. New fields 'type' (section type) and 'info' (target section for relocation) in data structure 'Dwarf_Obj_Access_Section_s'. Prototypes for new functions 'dwarf_encode_leb128' and 'dwarf_encode_signed_leb128', defined in dwarf_util.c. * pro_forms.c: Consistent layout for if statements. * pro_frame.c: Consistent layout for if statements. * pro_incl.h: For Windows, include the stdafx.h header file. * pro_init.c: Consistent layout for if statements. * pro_section.c: Consistent layout for if statements. 2012-11-14 DavidAnderson * dwarf_loc.c: DW_OP_GNU_implicit_pointer requires a version stamp to work correctly. Created a new function dwarf_loclist_from_expr_b() to allow clients to expicitly pass the version stamp. Most clients can continue to use the old interface. * libdwarf.h: Declaring new function dwarf_loclist_from_expr_b() * libdwarf2.1.mm: Documenting dwarf_loclist_from_expr_b() * libdwarf2.1.pdf: Regenerated. 2012-10-31 DavidAnderson * CODINGSTYLE: Added some small details here. 2012-04-04 DavidAnderson * libdwarf.h: A pointer "*" was right next to a "/*" so a space introduced between them for clarity. Fixed comments on DW_DLC_SIZE_64 and DW_DLC_SIZE_32. * dwarf_die_deliv.c: Two local variables were declared in the middle of code, accidentally creating C99 dependencies. Both trivially fixed with no change in logic. 2012-01-01 DavidAnderson * A new year starts. libdwarf-20210528/libdwarf/dwarf_elf_reloc_mips.h0000664000175000017500000001104213644370703016611 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_mips(unsigned long); #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif /* R_MIPS_NONE */ #ifndef R_MIPS_16 #define R_MIPS_16 1 #endif /* R_MIPS_16 */ #ifndef R_MIPS_32 #define R_MIPS_32 2 #endif /* R_MIPS_32 */ #ifndef R_MIPS_REL #define R_MIPS_REL 3 #endif /* R_MIPS_REL */ #ifndef R_MIPS_26 #define R_MIPS_26 4 #endif /* R_MIPS_26 */ #ifndef R_MIPS_HI16 #define R_MIPS_HI16 5 #endif /* R_MIPS_HI16 */ #ifndef R_MIPS_LO16 #define R_MIPS_LO16 6 #endif /* R_MIPS_LO16 */ #ifndef R_MIPS_GPREL #define R_MIPS_GPREL 7 #endif /* R_MIPS_GPREL */ #ifndef R_MIPS_LITERAL #define R_MIPS_LITERAL 8 #endif /* R_MIPS_LITERAL */ #ifndef R_MIPS_GOT #define R_MIPS_GOT 9 #endif /* R_MIPS_GOT */ #ifndef R_MIPS_PC16 #define R_MIPS_PC16 10 #endif /* R_MIPS_PC16 */ #ifndef R_MIPS_CALL #define R_MIPS_CALL 11 #endif /* R_MIPS_CALL */ #ifndef R_MIPS_GPREL32 #define R_MIPS_GPREL32 12 #endif /* R_MIPS_GPREL32 */ #ifndef R_MIPS_UNUSED1 #define R_MIPS_UNUSED1 13 #endif /* R_MIPS_UNUSED1 */ #ifndef R_MIPS_UNUSED2 #define R_MIPS_UNUSED2 14 #endif /* R_MIPS_UNUSED2 */ #ifndef R_MIPS_UNUSED3 #define R_MIPS_UNUSED3 15 #endif /* R_MIPS_UNUSED3 */ #ifndef R_MIPS_SHIFT5 #define R_MIPS_SHIFT5 16 #endif /* R_MIPS_SHIFT5 */ #ifndef R_MIPS_SHIFT6 #define R_MIPS_SHIFT6 17 #endif /* R_MIPS_SHIFT6 */ #ifndef R_MIPS_64 #define R_MIPS_64 18 #endif /* R_MIPS_64 */ #ifndef R_MIPS_GOT_DISP #define R_MIPS_GOT_DISP 19 #endif /* R_MIPS_GOT_DISP */ #ifndef R_MIPS_GOT_PAGE #define R_MIPS_GOT_PAGE 20 #endif /* R_MIPS_GOT_PAGE */ #ifndef R_MIPS_GOT_OFST #define R_MIPS_GOT_OFST 21 #endif /* R_MIPS_GOT_OFST */ #ifndef R_MIPS_GOT_HI16 #define R_MIPS_GOT_HI16 22 #endif /* R_MIPS_GOT_HI16 */ #ifndef R_MIPS_GOT_LO16 #define R_MIPS_GOT_LO16 23 #endif /* R_MIPS_GOT_LO16 */ #ifndef R_MIPS_SUB #define R_MIPS_SUB 24 #endif /* R_MIPS_SUB */ #ifndef R_MIPS_INSERT_A #define R_MIPS_INSERT_A 25 #endif /* R_MIPS_INSERT_A */ #ifndef R_MIPS_INSERT_B #define R_MIPS_INSERT_B 26 #endif /* R_MIPS_INSERT_B */ #ifndef R_MIPS_DELETE #define R_MIPS_DELETE 27 #endif /* R_MIPS_DELETE */ #ifndef R_MIPS_HIGHER #define R_MIPS_HIGHER 28 #endif /* R_MIPS_HIGHER */ #ifndef R_MIPS_HIGHEST #define R_MIPS_HIGHEST 29 #endif /* R_MIPS_HIGHEST */ #ifndef R_MIPS_CALL_HI16 #define R_MIPS_CALL_HI16 30 #endif /* R_MIPS_CALL_HI16 */ #ifndef R_MIPS_CALL_LO16 #define R_MIPS_CALL_LO16 31 #endif /* R_MIPS_CALL_LO16 */ #ifndef R_MIPS_SCN_DISP #define R_MIPS_SCN_DISP 32 #endif /* R_MIPS_SCN_DISP */ #ifndef R_MIPS_REL16 #define R_MIPS_REL16 33 #endif /* R_MIPS_REL16 */ #ifndef R_MIPS_ADD_IMMEDIATE #define R_MIPS_ADD_IMMEDIATE 34 #endif /* R_MIPS_ADD_IMMEDIATE */ #ifndef R_MIPS_PJUMP #define R_MIPS_PJUMP 35 #endif /* R_MIPS_PJUMP */ #ifndef R_MIPS_RELGOT #define R_MIPS_RELGOT 36 #endif /* R_MIPS_RELGOT */ #ifndef R_MIPS_JALR #define R_MIPS_JALR 37 #endif /* R_MIPS_JALR */ #ifndef R_MIPS_TLS_DTPMOD32 #define R_MIPS_TLS_DTPMOD32 38 #endif /* R_MIPS_TLS_DTPMOD32 */ #ifndef R_MIPS_TLS_DTPREL32 #define R_MIPS_TLS_DTPREL32 39 #endif /* R_MIPS_TLS_DTPREL32 */ #ifndef R_MIPS_TLS_DTPMOD64 #define R_MIPS_TLS_DTPMOD64 40 #endif /* R_MIPS_TLS_DTPMOD64 */ #ifndef R_MIPS_TLS_DTPREL64 #define R_MIPS_TLS_DTPREL64 41 #endif /* R_MIPS_TLS_DTPREL64 */ #ifndef R_MIPS_TLS_GD #define R_MIPS_TLS_GD 42 #endif /* R_MIPS_TLS_GD */ #ifndef R_MIPS_TLS_LDM #define R_MIPS_TLS_LDM 43 #endif /* R_MIPS_TLS_LDM */ #ifndef R_MIPS_TLS_DTPREL_HI16 #define R_MIPS_TLS_DTPREL_HI16 44 #endif /* R_MIPS_TLS_DTPREL_HI16 */ #ifndef R_MIPS_TLS_DTPREL_LO16 #define R_MIPS_TLS_DTPREL_LO16 45 #endif /* R_MIPS_TLS_DTPREL_LO16 */ #ifndef R_MIPS_TLS_GOTTPREL #define R_MIPS_TLS_GOTTPREL 46 #endif /* R_MIPS_TLS_GOTTPREL */ #ifndef R_MIPS_TLS_TPREL32 #define R_MIPS_TLS_TPREL32 47 #endif /* R_MIPS_TLS_TPREL32 */ #ifndef R_MIPS_TLS_TPREL_HI16 #define R_MIPS_TLS_TPREL_HI16 49 #endif /* R_MIPS_TLS_TPREL_HI16 */ #ifndef R_MIPS_TLS_TPREL_LO16 #define R_MIPS_TLS_TPREL_LO16 50 #endif /* R_MIPS_TLS_TPREL_LO16 */ #ifndef R_MIPS_GLOB_DAT #define R_MIPS_GLOB_DAT 51 #endif /* R_MIPS_GLOB_DAT */ #ifndef R_MIPS_COPY #define R_MIPS_COPY 126 #endif /* R_MIPS_COPY */ #ifndef R_MIPS_JUMP_SLOT #define R_MIPS_JUMP_SLOT 127 #endif /* R_MIPS_JUMP_SLOT */ #ifndef R_MIPS_NUM #define R_MIPS_NUM 128 #endif /* R_MIPS_NUM */ libdwarf-20210528/libdwarf/dwarf_loc.c0000664000175000017500000024712414051756467014423 00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include /* for debugging only. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef HAVE_STDLIB_H #include /* For uintptr_t */ #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_loc.h" #include "dwarfstring.h" #define TRUE 1 #define FALSE 0 static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, Dwarf_Block_c * return_block, Dwarf_Addr * lowpc, Dwarf_Addr * highpc, Dwarf_Bool * at_end, Dwarf_Half * lle_op, Dwarf_Off sec_offset, Dwarf_Half address_size, Dwarf_Half lkind, Dwarf_Error *error); /* Used to enable sanity checking of these data items before we return to caller. */ int _dwarf_locdesc_c_constructor(Dwarf_Debug dbg, void *locd) { Dwarf_Locdesc_c ldp = (Dwarf_Locdesc_c)locd; if (!dbg) { return DW_DLV_ERROR; } ldp->ld_lle_value = DW_LLE_VALUE_BOGUS; ldp->ld_kind = DW_LKIND_unknown; return DW_DLV_OK; } static void _dwarf_lkind_name(unsigned lkind, dwarfstring *m) { switch(lkind) { case DW_LKIND_expression: dwarfstring_append(m,"DW_LKIND_expression"); return; case DW_LKIND_loclist: dwarfstring_append(m,"DW_LKIND_loclist"); return; case DW_LKIND_GNU_exp_list: dwarfstring_append(m,"DW_LKIND_GNU_exp_list"); return; case DW_LKIND_loclists: dwarfstring_append(m,"DW_LKIND_loclists"); return; case DW_LKIND_unknown: dwarfstring_append(m,"DW_LKIND_unknown"); return; } dwarfstring_append_printf_u(m, ".", lkind); } static int determine_location_lkind(unsigned int version, unsigned int form, UNUSEDARG unsigned int attribute, Dwarf_Bool is_dwo) { switch(form) { case DW_FORM_exprloc: /* only defined for DW_CFA_def_cfa_expression */ case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: return DW_LKIND_expression; break; case DW_FORM_data4: case DW_FORM_data8: if (version > 1 && version < 4) { return DW_LKIND_loclist; } break; case DW_FORM_sec_offset: if (version == 5 ) { return DW_LKIND_loclists; } if (version == 4 && is_dwo ) { return DW_LKIND_GNU_exp_list; } return DW_LKIND_loclist; break; case DW_FORM_loclistx: if (version == 5 ) { return DW_LKIND_loclists; } break; default: break; } return DW_LKIND_unknown; } static void _dwarf_free_op_chain(Dwarf_Debug dbg, Dwarf_Loc_Chain headloc) { Dwarf_Loc_Chain cur = headloc; while (cur) { Dwarf_Loc_Chain next = cur->lc_next; dwarf_dealloc(dbg, cur, DW_DLA_LOC_CHAIN); cur = next; } } /* Given a Dwarf_Block that represents a location expression, this function returns a pointer to a Dwarf_Locdesc struct that has its ld_cents field set to the number of location operators in the block, and its ld_s field pointing to a contiguous block of Dwarf_Loc structs. However, the ld_lopc and ld_hipc values are uninitialized. Returns DW_DLV_ERROR on error. Created for DWARF2 this really does not work well as later DWARF needs the newer interface. You want Dwarf_Locdesc_c opaque struct, not what this function provides. This function assumes that the length of the block is greater than 0. Zero length location expressions to represent variables that have been optimized away are handled in the calling function. address_size, offset_size, and version_stamp are per-CU, not per-object or per dbg. We cannot use dbg directly to get those values. Use for DWARF 2,3,4 only to avoid updating to later interfaces. Not for experimental dwarf4 dwo either. Better to switch to a newer interface. */ static int _dwarf_get_locdesc(Dwarf_Debug dbg, Dwarf_Block_c * loc_block, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small version_stamp, Dwarf_Addr lowpc, Dwarf_Addr highpc, Dwarf_Small * section_end, Dwarf_Locdesc ** locdesc_out, Dwarf_Error * error) { /* Offset of current operator from start of block. */ Dwarf_Unsigned offset = 0; /* Used to chain the Dwarf_Loc_Chain_s structs. */ Dwarf_Loc_Chain new_loc = NULL; Dwarf_Loc_Chain prev_loc = NULL; Dwarf_Loc_Chain head_loc = NULL; /* Count of the number of location operators. */ Dwarf_Unsigned op_count = 0; /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ Dwarf_Loc *block_loc = 0; /* Dwarf_Locdesc pointer to be returned. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Unsigned i = 0; int res = 0; /* ***** BEGIN CODE ***** */ offset = 0; op_count = 0; res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); if (res != DW_DLV_OK) { return res; } /* OLD loop getting Loc operators. No DWARF5 */ while (offset <= loc_block->bl_len) { Dwarf_Unsigned nextoffset = 0; struct Dwarf_Loc_Expr_Op_s temp_loc; res = _dwarf_read_loc_expr_op(dbg,loc_block, op_count, version_stamp, offset_size, address_size, offset, section_end, &nextoffset, &temp_loc, error); if (res == DW_DLV_ERROR) { _dwarf_free_op_chain(dbg, head_loc); return res; } if (res == DW_DLV_NO_ENTRY) { /* Normal end. */ break; } op_count++; new_loc = (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1); if (new_loc == NULL) { dwarfstring m; _dwarf_free_op_chain(dbg, head_loc); dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, " DW_DLE_ALLOC_FAIL: out of memory" " allocating location" " expression operator chain entry %u.", op_count); _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* Copying only the fields needed by DWARF 2,3,4 */ new_loc->lc_atom = temp_loc.lr_atom; new_loc->lc_opnumber= temp_loc.lr_opnumber; new_loc->lc_number = temp_loc.lr_number; new_loc->lc_number2 = temp_loc.lr_number2; new_loc->lc_number3 = temp_loc.lr_number3; new_loc->lc_raw1 = temp_loc.lr_raw1; new_loc->lc_raw2 = temp_loc.lr_raw2; new_loc->lc_raw3 = temp_loc.lr_raw3; new_loc->lc_offset = temp_loc.lr_offset; offset = nextoffset; if (head_loc == NULL) head_loc = prev_loc = new_loc; else { prev_loc->lc_next = new_loc; prev_loc = new_loc; } } block_loc = (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count); if (block_loc == NULL) { _dwarf_free_op_chain(dbg, head_loc); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_loc = head_loc; for (i = 0; i < op_count; i++) { /* Copying only the fields needed by DWARF 2,3,4 the struct is public and must never be changed. */ (block_loc + i)->lr_atom = new_loc->lc_atom; (block_loc + i)->lr_number = new_loc->lc_number; (block_loc + i)->lr_number2 = new_loc->lc_number2; (block_loc + i)->lr_offset = new_loc->lc_offset; prev_loc = new_loc; new_loc = prev_loc->lc_next; dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); } locdesc = (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1); if (locdesc == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } locdesc->ld_cents = op_count; locdesc->ld_s = block_loc; locdesc->ld_section_offset = loc_block->bl_section_offset; locdesc->ld_lopc = lowpc; locdesc->ld_hipc = highpc; locdesc->ld_from_loclist = 1; *locdesc_out = locdesc; return DW_DLV_OK; } /* Using a loclist offset to get the in-memory address of .debug_loc data to read, returns the loclist 'header' info in return_block. */ #define MAX_ADDR \ ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) static int _dwarf_read_loc_section(Dwarf_Debug dbg, Dwarf_Block_c * return_block, Dwarf_Addr * lowpc, Dwarf_Addr * hipc, Dwarf_Half * lle_val, Dwarf_Off sec_offset, Dwarf_Half address_size, UNUSEDARG unsigned lkind, Dwarf_Error * error) { Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; Dwarf_Small *loc_section_end = dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; /* start_addr and end_addr are actually offsets of the applicable base address of the CU. They are address-size. */ Dwarf_Addr start_addr = 0; Dwarf_Addr end_addr = 0; Dwarf_Half exprblock_size = 0; Dwarf_Unsigned exprblock_off = 2 * address_size + DWARF_HALF_SIZE; if (sec_offset >= dbg->de_debug_loc.dss_size) { /* We're at the end. No more present. */ return DW_DLV_NO_ENTRY; } /* If it goes past end, error */ if (exprblock_off > dbg->de_debug_loc.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, start_addr, Dwarf_Addr, beg, address_size, error,loc_section_end); READ_UNALIGNED_CK(dbg, end_addr, Dwarf_Addr, beg + address_size, address_size, error,loc_section_end); if (start_addr == 0 && end_addr == 0) { /* If start_addr and end_addr are 0, it's the end and no exprblock_size field follows. */ exprblock_size = 0; exprblock_off -= DWARF_HALF_SIZE; *lle_val = DW_LLE_end_of_list; } else if (start_addr == MAX_ADDR) { /* End address is a base address, no exprblock_size field here either */ exprblock_size = 0; exprblock_off -= DWARF_HALF_SIZE; *lle_val = DW_LLE_base_address; } else { /* Here we note the address and length of the expression operators, DW_OP_reg0 etc */ READ_UNALIGNED_CK(dbg, exprblock_size, Dwarf_Half, beg + 2 * address_size, DWARF_HALF_SIZE, error,loc_section_end); /* exprblock_size can be zero, means no expression */ if ( exprblock_size >= dbg->de_debug_loc.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } if ((sec_offset +exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } *lle_val = DW_LLE_start_end; } *lowpc = start_addr; *hipc = end_addr; return_block->bl_len = exprblock_size; return_block->bl_kind = DW_LKIND_loclist; return_block->bl_data = beg + exprblock_off; return_block->bl_section_offset = ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data; return DW_DLV_OK; } static int _dwarf_get_loclist_lle_count_dwo(Dwarf_Debug dbg, Dwarf_Off loclist_offset, Dwarf_Half address_size, unsigned lkind, int *loclist_count, Dwarf_Error * error) { int count = 0; Dwarf_Off offset = loclist_offset; for (;;) { Dwarf_Block_c b; Dwarf_Bool at_end = FALSE; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Half lle_op = 0; int res = _dwarf_read_loc_section_dwo(dbg, &b, &lowpc, &highpc, &at_end, &lle_op, offset, address_size, lkind, error); if (res != DW_DLV_OK) { return res; } if (at_end) { count++; break; } offset = b.bl_len + b.bl_section_offset; count++; } *loclist_count = count; return DW_DLV_OK; } static int _dwarf_get_loclist_lle_count(Dwarf_Debug dbg, Dwarf_Off loclist_offset, Dwarf_Half address_size, unsigned lkind, int *loclist_count, Dwarf_Error * error) { int count = 0; Dwarf_Off offset = loclist_offset; for (;;) { Dwarf_Block_c b; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Half lle_val = DW_LLE_VALUE_BOGUS; int res = _dwarf_read_loc_section(dbg, &b, &lowpc, &highpc, &lle_val, offset, address_size,lkind,error); if (res != DW_DLV_OK) { return res; } offset = b.bl_len + b.bl_section_offset; if (lowpc == 0 && highpc == 0) { break; } count++; } *loclist_count = count; return DW_DLV_OK; } /* Helper routine to avoid code duplication. */ static int _dwarf_setup_loc(Dwarf_Attribute attr, Dwarf_Debug * dbg_ret, Dwarf_CU_Context *cucontext_ret, Dwarf_Half *form_ret, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Half form = 0; int blkres = DW_DLV_ERROR; /* Creating an error with NULL dbg is not a good thing. These won't be freed if we later call dealloc with a non-NULL dbg. */ if (!attr) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } if (attr->ar_cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return DW_DLV_ERROR; } *cucontext_ret = attr->ar_cu_context; dbg = attr->ar_cu_context->cc_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return DW_DLV_ERROR; } *dbg_ret = dbg; blkres = dwarf_whatform(attr, &form, error); if (blkres != DW_DLV_OK) { return blkres; } *form_ret = form; return DW_DLV_OK; } /* Helper routine to avoid code duplication. */ static int _dwarf_get_loclist_header_start(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Unsigned * loclist_offset_out, Dwarf_Error * error) { Dwarf_Unsigned loc_sec_size = 0; Dwarf_Unsigned loclist_offset = 0; int blkres = dwarf_global_formref(attr, &loclist_offset, error); if (blkres != DW_DLV_OK) { return blkres; } if (!dbg->de_debug_loc.dss_data) { int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error); if (secload != DW_DLV_OK) { return secload; } if (!dbg->de_debug_loc.dss_size) { return DW_DLV_NO_ENTRY; } } loc_sec_size = dbg->de_debug_loc.dss_size; if (loclist_offset >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } { int fisres = 0; Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; fisres = _dwarf_get_fission_addition_die(attr->ar_die, DW_SECT_LOCLISTS, &fissoff, &size,error); if (fisres != DW_DLV_OK) { return fisres; } if (fissoff >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } loclist_offset += fissoff; if (loclist_offset >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } } *loclist_offset_out = loclist_offset; return DW_DLV_OK; } /* When llbuf (see dwarf_loclist_n) is partially set up and an error is encountered, tear it down as it won't be used. */ static void _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count) { int i; for (i = 0; i < count; ++i) { dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); } static int context_is_cu_not_tu(Dwarf_CU_Context context, Dwarf_Bool *r) { int ut = context->cc_unit_type; if (ut == DW_UT_type || ut == DW_UT_split_type ) { *r =FALSE; return DW_DLV_OK; } *r = TRUE; return DW_DLV_OK; } /* Handles simple location entries and loclists. Returns all the Locdesc's thru llbuf. Will not work properly for DWARF5 and may not work for some recent versions of gcc or llvm emitting DWARF4 with location extensions. Does not work for .debug_loc.dwo */ int dwarf_loclist_n(Dwarf_Attribute attr, Dwarf_Locdesc *** llbuf_out, Dwarf_Signed * listlen_out, Dwarf_Error * error) { Dwarf_Debug dbg = 0; /* Dwarf_Attribute that describes the DW_AT_location in die, if present. */ Dwarf_Attribute loc_attr = attr; /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Half form = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed listlen = 0; Dwarf_Locdesc **llbuf = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; int cuvstamp = 0; Dwarf_Bool is_cu = FALSE; Dwarf_Half attrnum = 0; int is_dwo = FALSE; unsigned lkind = 0; int blkres = DW_DLV_ERROR; int setup_res = DW_DLV_ERROR; Dwarf_Small * info_section_end = 0; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } info_section_end = _dwarf_calculate_info_section_end_ptr( cucontext); cuvstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3 (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */ if (cuvstamp == DW_CU_VERSION5) { /* Use a newer interface. */ _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR); return DW_DLV_ERROR; } attrnum = attr->ar_attribute; lkind = determine_location_lkind(cuvstamp,form, attrnum, is_dwo); if (lkind == DW_LKIND_unknown || lkind == DW_LKIND_GNU_exp_list || lkind == DW_LKIND_loclists ) { /* We cannot handle this here. */ _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR); return DW_DLV_ERROR; } if (lkind == DW_LKIND_loclist ) { /* A reference to .debug_loc, with an offset in .debug_loc of a loclist */ Dwarf_Small *loc_section_end = 0; Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; int loclist_count = 0; int lli = 0; setup_res = context_is_cu_not_tu(cucontext,&is_cu); if (setup_res != DW_DLV_OK) { return setup_res; } off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } count_res = _dwarf_get_loclist_lle_count(dbg, loclist_offset, address_size,lkind, &loclist_count, error); listlen = loclist_count; if (count_res != DW_DLV_OK) { return count_res; } if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } llbuf = (Dwarf_Locdesc **) _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count); if (!llbuf) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } for (lli = 0; lli < loclist_count; ++lli) { int lres = 0; Dwarf_Half ll_op = 0; blkres = _dwarf_read_loc_section(dbg, &loc_block, &lowpc, &highpc, &ll_op, loclist_offset, address_size,lkind, error); if (blkres != DW_DLV_OK) { _dwarf_cleanup_llbuf(dbg, llbuf, lli); return (blkres); } loc_section_end = dbg->de_debug_loc.dss_data+ dbg->de_debug_loc.dss_size; lres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, loc_section_end, &locdesc, error); if (lres != DW_DLV_OK) { _dwarf_cleanup_llbuf(dbg, llbuf, lli); /* Low level error already set: let it be passed back */ return lres; } llbuf[lli] = locdesc; /* Now get to next loclist entry offset. */ loclist_offset = loc_block.bl_section_offset + loc_block.bl_len; } } else { /* DW_LKIND_expression */ if (form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len, &loc_block.bl_data,error); if (blkres != DW_DLV_OK) { return blkres; } loc_block.bl_kind = lkind; loc_block.bl_section_offset = (char *)loc_block.bl_data - (char *)dbg->de_debug_info.dss_data; } else { Dwarf_Block *tblock = 0; blkres = dwarf_formblock(loc_attr, &tblock, error); if (blkres != DW_DLV_OK) { return (blkres); } loc_block.bl_len = tblock->bl_len; loc_block.bl_data = tblock->bl_data; loc_block.bl_kind = lkind; loc_block.bl_section_offset = tblock->bl_section_offset; loc_block.bl_locdesc_offset = 0; /* not relevent */ /* We copied tblock contents to the stack var, so can dealloc tblock now. Avoids leaks. */ dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); } listlen = 1; /* One by definition of a location entry. */ lowpc = 0; /* HACK, but with bl_kind we do not need */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ blkres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, info_section_end, &locdesc, error); if (blkres != DW_DLV_OK) { /* low level error already set: let it be passed back */ return blkres; } llbuf = (Dwarf_Locdesc **) _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen); if (!llbuf) { /* Free the locdesc we allocated but won't use. */ dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } llbuf[0] = locdesc; } *llbuf_out = llbuf; *listlen_out = listlen; return DW_DLV_OK; } /* Handles only a location expression. If called on a loclist, just returns one of those. Cannot not handle a real loclist. It returns the location expression as a loclist with a single entry. See dwarf_loclist_n() which handles any number of location list entries. This is the original definition, and it simply does not work for loclists. Nor does it work on DWARF4 nor on some versions of gcc generating DWARF4. Kept for compatibility. */ int dwarf_loclist(Dwarf_Attribute attr, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { Dwarf_Debug dbg = 0; /* Dwarf_Attribute that describes the DW_AT_location in die, if present. */ Dwarf_Attribute loc_attr = attr; /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; int is_dwo = FALSE; Dwarf_Small *info_section_end = 0; Dwarf_Half form = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; unsigned lkind = 0; int blkres = DW_DLV_ERROR; int setup_res = DW_DLV_ERROR; int cuvstamp = 0; unsigned attrnum = 0; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } info_section_end = _dwarf_calculate_info_section_end_ptr( cucontext); memset(&loc_block,0,sizeof(loc_block)); cuvstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; attrnum = attr->ar_attribute; lkind = determine_location_lkind(cuvstamp,form, attrnum, is_dwo); if (lkind == DW_LKIND_unknown || lkind == DW_LKIND_GNU_exp_list || lkind == DW_LKIND_loclists ) { /* We cannot handle this here. */ _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR); return DW_DLV_ERROR; } /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ if (lkind == DW_LKIND_loclist) { /* A reference to .debug_loc, with an offset in .debug_loc of a loclist. */ Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; Dwarf_Half ll_op = 0; off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } /* With dwarf_loclist, just read a single entry */ blkres = _dwarf_read_loc_section(dbg, &loc_block, &lowpc, &highpc, &ll_op, loclist_offset, address_size, lkind, error); if (blkres != DW_DLV_OK) { return (blkres); } } else { /* DW_LKIND_expression */ if (form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len, &loc_block.bl_data,error); if (blkres != DW_DLV_OK) { return blkres; } loc_block.bl_kind = lkind; loc_block.bl_section_offset = (char *)loc_block.bl_data - (char *)dbg->de_debug_info.dss_data; } else { Dwarf_Block *tblock = 0; /* If DWARF5 this will surely fail, get an error. */ blkres = dwarf_formblock(loc_attr, &tblock, error); if (blkres != DW_DLV_OK) { return (blkres); } loc_block.bl_len = tblock->bl_len; loc_block.bl_data = tblock->bl_data; loc_block.bl_kind = tblock->bl_from_loclist; /* ASSERT: lkind == loc_block.bl_kind */ loc_block.bl_section_offset = tblock->bl_section_offset; /* We copied tblock contents to the stack var, so can dealloc tblock now. Avoids leaks. */ dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); } /* Because we set bl_kind we don't really need this hack any more */ lowpc = 0; /* HACK */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ } /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. See *dwarf_loclist_n() which handles the general case, this case handles only a single location expression. */ blkres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, info_section_end, &locdesc, error); if (blkres != DW_DLV_OK) { /* low level error already set: let it be passed back */ return blkres; } *llbuf = locdesc; *listlen = 1; return DW_DLV_OK; } /* Handles only a location expression. It returns the location expression as a loclist with a single entry. Usable to access dwarf expressions from any source, but specifically from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression_in must point to a valid dwarf expression set of bytes of length expression_length. Not a DW_FORM_block*, just the expression bytes. If the address_size != de_pointer_size this will not work right. See dwarf_loclist_from_expr_b() for a better interface. */ int dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { int res = 0; Dwarf_Half addr_size = dbg->de_pointer_size; res = dwarf_loclist_from_expr_a(dbg,expression_in, expression_length, addr_size,llbuf,listlen,error); return res; } /* New April 27 2009. Adding addr_size argument for the rare cases where an object has CUs with a different address_size. As of 2012 we have yet another version, dwarf_loclist_from_expr_b() with the version_stamp and offset size (length size) passed in. And later, dwarf_loclist_from_expr_c() */ int dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half addr_size, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { int res; Dwarf_Debug_InfoTypes info_reading = &dbg->de_info_reading; Dwarf_CU_Context current_cu_context = info_reading->de_cu_context; Dwarf_Small version_stamp = DW_CU_VERSION2; Dwarf_Half offset_size = dbg->de_length_size; if (current_cu_context) { /* This is ugly. It is not necessarily right. Due to oddity in DW_OP_GNU_implicit_pointer, see its implementation above. For correctness, use dwarf_loclist_from_expr_b() instead of dwarf_loclist_from_expr_a(). */ version_stamp = current_cu_context->cc_version_stamp; offset_size = current_cu_context->cc_length_size; if (version_stamp < 2) { /* This is probably totally silly. */ version_stamp = DW_CU_VERSION2; } } res = dwarf_loclist_from_expr_b(dbg, expression_in, expression_length, addr_size, offset_size, version_stamp, /* CU context DWARF version */ llbuf, listlen, error); return res; } /* New November 13 2012. Adding DWARF version number argument. */ int dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL); Dwarf_Small version_stamp = dwarf_version; int res = 0; /* We do not know what the end is in this interface. */ Dwarf_Small *section_start = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_end = 0; const char *section_name = 0; res = _dwarf_what_section_are_we(dbg, expression_in,§ion_name,§ion_start, §ion_size,§ion_end,error); if (res != DW_DLV_OK) { _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); return DW_DLV_ERROR; } memset(&loc_block,0,sizeof(loc_block)); loc_block.bl_len = expression_length; loc_block.bl_data = expression_in; loc_block.bl_kind = DW_LKIND_expression; loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */ /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* We need the DWARF version to get a locdesc! */ res = _dwarf_get_locdesc(dbg, &loc_block, addr_size, offset_size, version_stamp, lowpc, highpc, section_end, &locdesc, error); if (res != DW_DLV_OK) { /* low level error already set: let it be passed back */ return res; } *llbuf = locdesc; *listlen = 1; return DW_DLV_OK; } /* Usable to read a single loclist or to read a block of them or to read an entire section's loclists. It's BROKEN because it's not safe to read a loclist entry when we do not know the address size (in any object where address size can vary by compilation unit). It also does not recognize split dwarf or DWARF4 or DWARF5 adequately. Use get_locdesc_entry_c() instead. */ /*ARGSUSED*/ int dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr * hipc_offset, Dwarf_Addr * lopc_offset, Dwarf_Ptr * data, Dwarf_Unsigned * entry_len, Dwarf_Unsigned * next_entry, Dwarf_Error * error) { Dwarf_Block_c b; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Half address_size = 0; int res = DW_DLV_ERROR; Dwarf_Half ll_op = 0; if (!dbg->de_debug_loc.dss_data) { int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error); if (secload != DW_DLV_OK) { return secload; } } /* FIXME: DO NOT USE the call. address_size is not necessarily the same in every frame. */ address_size = dbg->de_pointer_size; res = _dwarf_read_loc_section(dbg, &b, &lowpc, &highpc, &ll_op,offset, address_size,DW_LKIND_loclist,error); if (res != DW_DLV_OK) { return res; } *hipc_offset = highpc; *lopc_offset = lowpc; *entry_len = b.bl_len; *data = b.bl_data; *next_entry = b.bl_len + b.bl_section_offset; return DW_DLV_OK; } /* ============== the October 2015 interfaces. */ int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error* error) { unsigned lkind = loc_block->bl_kind; if (lkind == DW_LKIND_loclist) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Small *end_ptr = 0; loc_ptr = loc_block->bl_data; loc_len = loc_block->bl_len; end_ptr = dbg->de_debug_loc.dss_size + dbg->de_debug_loc.dss_data; if ((loc_ptr +loc_len) > end_ptr) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_LOC_SECTION_SHORT kind: "); _dwarf_lkind_name(lkind, &m); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_LOC_SECTION_SHORT, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } return DW_DLV_OK; } if (lkind == DW_LKIND_loclists) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Small *end_ptr = 0; loc_ptr = loc_block->bl_data; loc_len = loc_block->bl_len; end_ptr = dbg->de_debug_loclists.dss_size + dbg->de_debug_loclists.dss_data; if ((loc_ptr +loc_len) > end_ptr) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_LOC_SECTION_SHORT " "(the .debug_loclists section is short), kind: "); _dwarf_lkind_name(lkind, &m); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_LOC_SECTION_SHORT, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } return DW_DLV_OK; } /* ld_kind was checked before calling this, so we know its value is an intended value. */ static const char *kindset[] = { "DW_LKIND_expression", "DW_LKIND_loclist", "DW_LKIND_GNU_exp_list", "DW_LKIND_unknown3", "DW_LKIND_unknown4", "DW_LKIND_loclists" }; static const char * get_loc_kind_str(Dwarf_Small lkind) { if (lkind <= DW_LKIND_loclists) { return kindset[lkind]; } if (lkind == DW_LKIND_unknown) { return "DW_LKIND_unknown"; } return "UNKNOWN DW_LKIND!"; } static int validate_lle_value(Dwarf_Debug dbg, Dwarf_Locdesc_c locdesc, Dwarf_Error *error) { dwarfstring m; if (locdesc->ld_kind != DW_LKIND_GNU_exp_list) { switch(locdesc->ld_lle_value) { case DW_LLE_end_of_list: case DW_LLE_base_addressx: case DW_LLE_startx_endx: case DW_LLE_startx_length: case DW_LLE_offset_pair: case DW_LLE_default_location: case DW_LLE_base_address: case DW_LLE_start_end: case DW_LLE_start_length: return DW_DLV_OK; } dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_LOCATION_ERROR: For location kind %s (", (char *)get_loc_kind_str(locdesc->ld_kind)); dwarfstring_append_printf_u(&m,"%u) the DW_LLE value is " "not properly set", locdesc->ld_kind); dwarfstring_append_printf_u(&m," but is %u " " which is a libdwarf bug", locdesc->ld_lle_value); _dwarf_error_string(dbg,error,DW_DLE_LOCATION_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } switch(locdesc->ld_lle_value) { case DW_LLEX_end_of_list_entry: case DW_LLEX_base_address_selection_entry: case DW_LLEX_start_end_entry: case DW_LLEX_start_length_entry: case DW_LLEX_offset_pair_entry: return DW_DLV_OK; } { dwarfstring_constructor(&m); dwarfstring_append_printf_s(&m, "DW_DLE_LOCATION_ERROR: For location kind %s (", (char *)get_loc_kind_str(locdesc->ld_kind)); dwarfstring_append_printf_u(&m,"%u) the DW_LLEX value is " "not properly set", locdesc->ld_kind); dwarfstring_append_printf_u(&m," but is %u " " which is a libdwarf bug", locdesc->ld_lle_value); _dwarf_error_string(dbg,error,DW_DLE_LOCATION_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); } return DW_DLV_ERROR; } /* Sets locdesc operator list information in locdesc. Sets the locdesc values (rawlow, rawhigh etc). This synthesizes the ld_lle_value of the locdesc if it's not already provided. Not passing in locdesc pointer, the locdesc_index suffices to index to the relevant locdesc pointer. See also dwarf_loclists.c: build_array_of_lle*/ int _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, Dwarf_Unsigned locdesc_index, Dwarf_Loc_Head_c loc_head, Dwarf_Block_c * loc_block, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small version_stamp, Dwarf_Addr lowpc, Dwarf_Addr highpc, Dwarf_Half lle_op, Dwarf_Error * error) { /* Offset of current operator from start of block. */ Dwarf_Unsigned offset = 0; /* Chain the DW_OPerator structs. */ Dwarf_Loc_Chain new_loc = NULL; Dwarf_Loc_Chain prev_loc = NULL; Dwarf_Loc_Chain head_loc = NULL; Dwarf_Unsigned op_count = 0; /* Contiguous block of Dwarf_Loc_Expr_Op_s for Dwarf_Locdesc. */ Dwarf_Loc_Expr_Op block_loc = 0; Dwarf_Locdesc_c locdesc = loc_head->ll_locdesc + locdesc_index; Dwarf_Unsigned i = 0; int res = 0; Dwarf_Small *section_start = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_end = 0; const char *section_name = 0; Dwarf_Small *blockdataptr = 0; unsigned lkind = loc_head->ll_kind; /* ***** BEGIN CODE ***** */ blockdataptr = loc_block->bl_data; if (!blockdataptr || !loc_block->bl_len) { /* an empty block has no operations so no section or tests need be done.. */ } else { res = _dwarf_what_section_are_we(dbg, blockdataptr,§ion_name,§ion_start, §ion_size,§ion_end,error); if (res != DW_DLV_OK) { _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); return DW_DLV_ERROR; } res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); if (res != DW_DLV_OK) { return res; } } /* New loop getting Loc operators. Non DWO */ while (offset <= loc_block->bl_len) { Dwarf_Unsigned nextoffset = 0; struct Dwarf_Loc_Expr_Op_s temp_loc; /* This call is ok even if bl_data NULL and bl_len 0 */ res = _dwarf_read_loc_expr_op(dbg,loc_block, op_count, version_stamp, offset_size, address_size, offset, section_end, &nextoffset, &temp_loc, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { /* Normal end. Also the end for an empty loc_block. */ break; } op_count++; new_loc = (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1); if (new_loc == NULL) { _dwarf_free_op_chain(dbg,head_loc); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Copying all the fields. DWARF 2,3,4,5. */ new_loc->lc_atom = temp_loc.lr_atom; new_loc->lc_opnumber= temp_loc.lr_opnumber; new_loc->lc_raw1 = temp_loc.lr_number; new_loc->lc_raw2 = temp_loc.lr_number2; new_loc->lc_raw3 = temp_loc.lr_number3; new_loc->lc_number = temp_loc.lr_number; new_loc->lc_number2 = temp_loc.lr_number2; new_loc->lc_number3 = temp_loc.lr_number3; new_loc->lc_offset = temp_loc.lr_offset; if (head_loc == NULL) head_loc = prev_loc = new_loc; else { prev_loc->lc_next = new_loc; prev_loc = new_loc; } offset = nextoffset; } block_loc = (Dwarf_Loc_Expr_Op ) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK_C, op_count); new_loc = head_loc; if (!block_loc) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); for (i = 0; i < op_count; i++) { prev_loc = new_loc; new_loc = prev_loc->lc_next; dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); } return DW_DLV_ERROR; } /* op_count could be zero. */ new_loc = head_loc; for (i = 0; i < op_count; i++) { /* Copying only the fields needed by DWARF 2,3,4 */ (block_loc + i)->lr_atom = new_loc->lc_atom; (block_loc + i)->lr_raw1 = new_loc->lc_raw1; (block_loc + i)->lr_raw2 = new_loc->lc_raw2; (block_loc + i)->lr_raw3 = new_loc->lc_raw3; (block_loc + i)->lr_number = new_loc->lc_number; (block_loc + i)->lr_number2 = new_loc->lc_number2; (block_loc + i)->lr_number3 = new_loc->lc_number3; (block_loc + i)->lr_offset = new_loc->lc_offset; (block_loc + i)->lr_opnumber = new_loc->lc_opnumber; prev_loc = new_loc; new_loc = prev_loc->lc_next; dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); } /* Synthesizing the DW_LLE values for the old loclist versions. */ switch(loc_head->ll_kind) { case DW_LKIND_loclist: { if (highpc == 0 && lowpc == 0) { locdesc->ld_lle_value = DW_LLE_end_of_list; } else if (lowpc == MAX_ADDR) { locdesc->ld_lle_value = DW_LLE_base_address; } else { locdesc->ld_lle_value = DW_LLE_offset_pair; } } break; case DW_LKIND_GNU_exp_list: /* DW_LKIND_GNU_exp_list */ locdesc->ld_lle_value = lle_op; break; case DW_LKIND_expression: /* This is a kind of fake, but better than 0 */ locdesc->ld_lle_value = DW_LLE_start_end; break; case DW_LKIND_loclists: /* ld_lle_value already set */ break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCATION_ERROR: An impossible DW_LKIND" " value of %u encountered, likely internal " "libdwarf error or data corruption", (unsigned)loc_head->ll_kind); _dwarf_error_string(dbg,error, DW_DLE_LOCATION_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); dwarf_dealloc(dbg,block_loc,DW_DLA_LOC_BLOCK_C); return DW_DLV_ERROR; } } locdesc->ld_cents = op_count; locdesc->ld_s = block_loc; locdesc->ld_kind = lkind; locdesc->ld_section_offset = loc_block->bl_section_offset; locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset; locdesc->ld_rawlow = lowpc; locdesc->ld_rawhigh = highpc; res = validate_lle_value(dbg,locdesc,error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg,block_loc,DW_DLA_LOC_BLOCK_C); return res; } /* Leaving the cooked values zero. Filled in later. */ /* We have not yet looked for debug_addr, so we'll set it as not-missing. */ locdesc->ld_index_failed = FALSE; return DW_DLV_OK; } /* Non-standard DWARF4 dwo loclist */ static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, Dwarf_Block_c * return_block, Dwarf_Addr * lowpc, Dwarf_Addr * highpc, Dwarf_Bool *at_end, Dwarf_Half * lle_op, Dwarf_Off sec_offset, Dwarf_Half address_size, Dwarf_Half lkind, Dwarf_Error * error) { Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; Dwarf_Small *locptr = 0; Dwarf_Small llecode = 0; Dwarf_Unsigned expr_offset = sec_offset; Dwarf_Byte_Ptr section_end = dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; if (sec_offset >= dbg->de_debug_loc.dss_size) { /* We're at the end. No more present. */ return DW_DLV_NO_ENTRY; } memset(return_block,0,sizeof(*return_block)); /* not the same as non-split loclist, but still a list. */ return_block->bl_kind = lkind; /* This is non-standard GNU Dwarf4 loclist */ return_block->bl_locdesc_offset = sec_offset; llecode = *beg; locptr = beg +1; expr_offset++; switch(llecode) { case DW_LLEX_end_of_list_entry: *at_end = TRUE; return_block->bl_section_offset = expr_offset; expr_offset++; break; case DW_LLEX_base_address_selection_entry: { Dwarf_Unsigned addr_index = 0; DECODE_LEB128_UWORD_CK(locptr,addr_index, dbg,error,section_end); return_block->bl_section_offset = expr_offset; /* So this behaves much like non-dwo loclist */ *lowpc=MAX_ADDR; *highpc=addr_index; } break; case DW_LLEX_start_end_entry: { Dwarf_Unsigned addr_indexs = 0; Dwarf_Unsigned addr_indexe= 0; Dwarf_Unsigned exprlen = 0; Dwarf_Unsigned leb128_length = 0; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexs, leb128_length, dbg,error,section_end); expr_offset += leb128_length; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexe, leb128_length, dbg,error,section_end); expr_offset +=leb128_length; *lowpc=addr_indexs; *highpc=addr_indexe; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_LOC_SECTION_SHORT:"); dwarfstring_append_printf_u(&m, " in DW_LLEX_start_end_entry " "The expression offset is 0x%x", expr_offset); dwarfstring_append_printf_u(&m, " which is greater than the section size" " of 0x%x. Corrupt Dwarf.", dbg->de_debug_loc.dss_size); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_LOC_SECTION_SHORT, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } break; case DW_LLEX_start_length_entry: { Dwarf_Unsigned addr_index = 0; Dwarf_Unsigned range_length = 0; Dwarf_Unsigned exprlen = 0; Dwarf_Unsigned leb128_length = 0; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_index, leb128_length, dbg,error,section_end); expr_offset +=leb128_length; READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; *lowpc = addr_index; *highpc = range_length; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; /* exprblock_size can be zero, means no expression */ expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_LOC_SECTION_SHORT:"); dwarfstring_append_printf_u(&m, " in DW_LLEX_start_length_entry " "The expression offset is 0x%x", expr_offset); dwarfstring_append_printf_u(&m, " which is greater than the section size" " of 0x%x. Corrupt Dwarf.", dbg->de_debug_loc.dss_size); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_LOC_SECTION_SHORT, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } break; case DW_LLEX_offset_pair_entry: { Dwarf_Unsigned startoffset = 0; Dwarf_Unsigned endoffset = 0; Dwarf_Unsigned exprlen = 0; READ_UNALIGNED_CK(dbg, startoffset, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; READ_UNALIGNED_CK(dbg, endoffset, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; *lowpc= startoffset; *highpc = endoffset; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_DEBUG_LOC_SECTION_SHORT:"); dwarfstring_append_printf_u(&m, " in DW_LLEX_offset_pair_entry " "The expression offset is 0x%x", expr_offset); dwarfstring_append_printf_u(&m, " which is greater than the section size" " of 0x%x. Corrupt Dwarf.", dbg->de_debug_loc.dss_size); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_LOC_SECTION_SHORT, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append(&m, "DW_DLE_LLE_CODE_UNKNOWN:"); dwarfstring_append_printf_u(&m, " in DW_LLEX_ code value " " is 0x%x ,not an expected value.", llecode); _dwarf_error_string(dbg,error, DW_DLE_LLE_CODE_UNKNOWN, dwarfstring_string(&m)); dwarfstring_destructor(&m); _dwarf_error(dbg,error,DW_DLE_LLE_CODE_UNKNOWN); return DW_DLV_ERROR; } } *lle_op = llecode; return DW_DLV_OK; } int dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header, unsigned int * kind, UNUSEDARG Dwarf_Error * error) { *kind = ll_header->ll_kind; return DW_DLV_OK; } static int _dwarf_original_loclist_build(Dwarf_Debug dbg, Dwarf_Loc_Head_c llhead, Dwarf_Attribute attr, Dwarf_Error *error) { Dwarf_Unsigned loclist_offset = 0; Dwarf_Unsigned starting_loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; int loclist_count = 0; Dwarf_Unsigned lli = 0; unsigned lkind = llhead->ll_kind; unsigned address_size = llhead->ll_address_size; Dwarf_Unsigned listlen = 0; Dwarf_Locdesc_c llbuf = 0; Dwarf_CU_Context cucontext; off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } starting_loclist_offset = loclist_offset; if (lkind == DW_LKIND_GNU_exp_list) { count_res = _dwarf_get_loclist_lle_count_dwo(dbg, loclist_offset, address_size, llhead->ll_kind, &loclist_count, error); } else { count_res = _dwarf_get_loclist_lle_count(dbg, loclist_offset, address_size, llhead->ll_kind, &loclist_count, error); } if (count_res != DW_DLV_OK) { return count_res; } if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } listlen = loclist_count; llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen); if (!llbuf) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = listlen; cucontext = llhead->ll_context; llhead->ll_llearea_offset = loclist_offset; /* Now get loc ops */ for (lli = 0; lli < listlen; ++lli) { int lres = 0; Dwarf_Half lle_op = 0; Dwarf_Bool at_end = 0; Dwarf_Block_c loc_block; Dwarf_Unsigned rawlowpc = 0; Dwarf_Unsigned rawhighpc = 0; int blkres = 0; memset(&loc_block,0,sizeof(loc_block)); if (lkind == DW_LKIND_GNU_exp_list) { blkres = _dwarf_read_loc_section_dwo(dbg, &loc_block, &rawlowpc, &rawhighpc, &at_end, &lle_op, loclist_offset, address_size, lkind, error); } else { blkres = _dwarf_read_loc_section(dbg, &loc_block, &rawlowpc, &rawhighpc, &lle_op, loclist_offset, address_size, lkind, error); } if (blkres != DW_DLV_OK) { return blkres; } /* Fills in the locdesc and its operators list at index lli */ lres = _dwarf_fill_in_locdesc_op_c(dbg, lli, llhead, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, rawlowpc, rawhighpc, lle_op, error); if (lres != DW_DLV_OK) { return lres; } /* Now get to next loclist entry offset. */ loclist_offset = loc_block.bl_section_offset + loc_block.bl_len; } /* We need to calculate the cooked values for each locldesc entry, that will be done in dwarf_get_loclist_c(). */ llhead->ll_bytes_total = loclist_offset - starting_loclist_offset; return DW_DLV_OK; } static int _dwarf_original_expression_build(Dwarf_Debug dbg, Dwarf_Loc_Head_c llhead, Dwarf_Attribute attr, Dwarf_Error *error) { Dwarf_Block_c loc_blockc; Dwarf_Unsigned rawlowpc = 0; Dwarf_Unsigned rawhighpc = 0; unsigned form = llhead->ll_attrform; int blkres = 0; Dwarf_Locdesc_c llbuf = 0; unsigned listlen = 1; Dwarf_CU_Context cucontext = llhead->ll_context; unsigned address_size = llhead->ll_address_size; memset(&loc_blockc,0,sizeof(loc_blockc)); if (form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(attr,&loc_blockc.bl_len, &loc_blockc.bl_data,error); if (blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return blkres; } loc_blockc.bl_kind = llhead->ll_kind; loc_blockc.bl_section_offset = (char *)loc_blockc.bl_data - (char *)dbg->de_debug_info.dss_data; loc_blockc.bl_locdesc_offset = 0; /* not relevant */ } else { Dwarf_Block loc_block; memset(&loc_block,0,sizeof(loc_block)); blkres = _dwarf_formblock_internal(dbg,attr, llhead->ll_context, &loc_block, error); if (blkres != DW_DLV_OK) { return blkres; } loc_blockc.bl_len = loc_block.bl_len; loc_blockc.bl_data = loc_block.bl_data; loc_blockc.bl_kind = llhead->ll_kind; loc_blockc.bl_section_offset = loc_block.bl_section_offset; loc_blockc.bl_locdesc_offset = 0; /* not relevant */ } /* We will mark the Locdesc_c DW_LLE_start_end shortly. Here we fake the address range as 'all addresses'. */ rawlowpc = 0; rawhighpc = MAX_ADDR; llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen); if (!llbuf) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } llhead->ll_locdesc = llbuf; /* One by definition of a location entry. */ llhead->ll_locdesc_count = listlen; /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* Fills in the locdesc and its operators list at index 0 */ blkres = _dwarf_fill_in_locdesc_op_c(dbg, 0, /* fake locdesc is index 0 */ llhead, &loc_blockc, llhead->ll_address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, rawlowpc, rawhighpc, 0, error); llhead->ll_bytes_total += loc_blockc.bl_len; if (blkres != DW_DLV_OK) { /* low level error already set: let it be passed back */ return blkres; } return DW_DLV_OK; } /* Following the original loclist definition the low value is all one bits, the high value is the base address. */ static int cook_original_loclist_contents(Dwarf_Debug dbg, Dwarf_Loc_Head_c llhead, Dwarf_Error *error) { Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address; Dwarf_Unsigned count = llhead->ll_locdesc_count; Dwarf_Unsigned i = 0; for ( i = 0 ; i < count; ++i) { Dwarf_Locdesc_c llc = 0; llc = llhead->ll_locdesc +i; switch(llc->ld_lle_value) { case DW_LLE_end_of_list: { /* nothing to do */ break; } case DW_LLE_base_address: { llc->ld_lopc = llc->ld_rawhigh; llc->ld_highpc = llc->ld_rawhigh; baseaddress = llc->ld_rawhigh; break; } case DW_LLE_offset_pair: { llc->ld_lopc = llc->ld_rawlow + baseaddress; llc->ld_highpc = llc->ld_rawhigh + baseaddress; break; } default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: " "improper synthesized LLE code " "of 0x%x is unknown. In standard DWARF3/4 loclist", llc->ld_lle_value); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } } return DW_DLV_OK; } static int cook_gnu_loclist_contents(Dwarf_Debug dbg, Dwarf_Loc_Head_c llhead, Dwarf_Error *error) { Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address; Dwarf_Unsigned count = llhead->ll_locdesc_count; Dwarf_Unsigned i = 0; Dwarf_CU_Context cucontext = llhead->ll_context; int res = 0; for (i = 0 ; i < count ; ++i) { Dwarf_Locdesc_c llc = 0; llc = llhead->ll_locdesc +i; switch(llc->ld_lle_value) { case DW_LLEX_base_address_selection_entry:{ Dwarf_Addr targaddr = 0; res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawhigh,&targaddr, error); if (res != DW_DLV_OK) { llc->ld_index_failed = TRUE; llc->ld_lopc = 0; llc->ld_highpc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_lopc = targaddr; llc->ld_highpc = targaddr; } break; } case DW_LLEX_end_of_list_entry:{ /* Nothing to do. */ break; } case DW_LLEX_start_length_entry:{ Dwarf_Addr targaddr = 0; res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); if (res != DW_DLV_OK) { llc->ld_index_failed = TRUE; llc->ld_lopc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_lopc = targaddr; llc->ld_highpc = llc->ld_lopc +llc->ld_rawhigh; } break; } case DW_LLEX_offset_pair_entry:{ llc->ld_lopc = llc->ld_rawlow + baseaddress; llc->ld_highpc = llc->ld_rawhigh + baseaddress; break; } case DW_LLEX_start_end_entry:{ Dwarf_Addr targaddr = 0; res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); if (res != DW_DLV_OK) { llc->ld_index_failed = TRUE; llc->ld_lopc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_lopc = targaddr; } res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); if (res != DW_DLV_OK) { llc->ld_index_failed = TRUE; llc->ld_highpc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_highpc = targaddr; } break; } default:{ dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: improper LLEX code " "of 0x%x is unknown. GNU LLEX dwo loclists error", llc->ld_lle_value); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; break; } } } return DW_DLV_OK; } /* DWARF5 */ static int cook_loclists_contents(Dwarf_Debug dbg, Dwarf_Loc_Head_c llhead, Dwarf_Error *error) { Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address; Dwarf_Unsigned count = llhead->ll_locdesc_count; Dwarf_Unsigned i = 0; Dwarf_CU_Context cucontext = llhead->ll_context; int res = 0; Dwarf_Bool base_address_fail = FALSE; Dwarf_Bool debug_addr_fail = FALSE; if (!llhead->ll_cu_base_address_present) { base_address_fail = TRUE; } for (i = 0 ; i < count ; ++i) { Dwarf_Locdesc_c llc = 0; llc = llhead->ll_locdesc +i; switch(llc->ld_lle_value) { case DW_LLE_base_addressx: { Dwarf_Addr targaddr = 0; if (debug_addr_fail) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); } if (res != DW_DLV_OK) { debug_addr_fail = TRUE; base_address_fail = TRUE; llc->ld_index_failed = TRUE; llc->ld_lopc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { base_address_fail = FALSE; baseaddress = targaddr; llc->ld_lopc = targaddr; } break; } case DW_LLE_startx_endx:{ /* two indexes into debug_addr */ Dwarf_Addr targaddr = 0; if (debug_addr_fail) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); } if (res != DW_DLV_OK) { debug_addr_fail = TRUE; llc->ld_index_failed = TRUE; llc->ld_lopc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_lopc = targaddr; } if (debug_addr_fail) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawhigh,&targaddr, error); } if (res != DW_DLV_OK) { debug_addr_fail = TRUE; llc->ld_index_failed = TRUE; llc->ld_highpc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_highpc = targaddr; } break; } case DW_LLE_startx_length:{ /* one index to debug_addr other a length */ Dwarf_Addr targaddr = 0; if (debug_addr_fail) { res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( dbg,cucontext,llc->ld_rawlow,&targaddr, error); } if (res != DW_DLV_OK) { debug_addr_fail = TRUE; llc->ld_index_failed = TRUE; llc->ld_lopc = 0; if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg, *error); *error = 0; } } else { llc->ld_lopc = targaddr; llc->ld_highpc = targaddr + llc->ld_rawhigh; } break; } case DW_LLE_offset_pair:{ if (base_address_fail) { llc->ld_index_failed = TRUE; llc->ld_lopc = 0; llc->ld_highpc = 0; } else { /*offsets of the current base address*/ llc->ld_lopc = llc->ld_rawlow +baseaddress; llc->ld_highpc = llc->ld_rawhigh +baseaddress; } break; } case DW_LLE_default_location:{ /* nothing to do here, just has a counted location description */ break; } case DW_LLE_base_address:{ llc->ld_lopc = llc->ld_rawlow; llc->ld_highpc = llc->ld_rawlow; baseaddress = llc->ld_rawlow; base_address_fail = FALSE; break; } case DW_LLE_start_end:{ llc->ld_lopc = llc->ld_rawlow; llc->ld_highpc = llc->ld_rawhigh; break; } case DW_LLE_start_length:{ llc->ld_lopc = llc->ld_rawlow; llc->ld_highpc = llc->ld_rawlow + llc->ld_rawhigh; break; } case DW_LLE_end_of_list:{ /* do nothing */ break; } default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_LOCLISTS_ERROR: improper DW_LLE code " "of 0x%x is unknown. DWARF5 loclists error", llc->ld_lle_value); _dwarf_error_string(dbg,error, DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } } return DW_DLV_OK; } /* New October 2015 This interface requires the use of interface functions to get data from Dwarf_Locdesc_c. The structures are not visible to callers. */ int dwarf_get_loclist_c(Dwarf_Attribute attr, Dwarf_Loc_Head_c * ll_header_out, Dwarf_Unsigned * listlen_out, Dwarf_Error * error) { Dwarf_Debug dbg; Dwarf_Half form = 0; Dwarf_Loc_Head_c llhead = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; int cuversionstamp = 0; Dwarf_Bool is_cu = FALSE; Dwarf_Unsigned attrnum = 0; Dwarf_Bool is_dwo = 0; int setup_res = DW_DLV_ERROR; int lkind = 0; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } attrnum = attr->ar_attribute; cuversionstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; is_dwo = cucontext->cc_is_dwo; lkind = determine_location_lkind(cuversionstamp, form, attrnum, is_dwo); if (lkind == DW_LKIND_unknown) { dwarfstring m; const char * formname = ""; const char * attrname = ""; dwarfstring_constructor(&m); dwarf_get_FORM_name(form,&formname); dwarf_get_AT_name(attrnum,&attrname); dwarfstring_append_printf_u(&m, "DW_DLE_LOC_EXPR_BAD: For Compilation Unit " "version %u",cuversionstamp); dwarfstring_append_printf_u(&m, ", attribute 0x%x (",attrnum); dwarfstring_append(&m,(char *)attrname); dwarfstring_append_printf_u(&m, ") form 0x%x (",form); dwarfstring_append(&m,(char *)formname); if (is_dwo) { dwarfstring_append(&m,") (the CU is a .dwo) "); } else { dwarfstring_append(&m,") (the CU is not a .dwo) "); } dwarfstring_append(&m," we don't understand the location"); _dwarf_error_string(dbg,error,DW_DLE_LOC_EXPR_BAD, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } /* Doing this early (first) to avoid repeating the alloc code for each type */ llhead = (Dwarf_Loc_Head_c) _dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } llhead->ll_cuversion = cuversionstamp; llhead->ll_kind = lkind; llhead->ll_attrnum = attrnum; llhead->ll_attrform = form; llhead->ll_dbg = dbg; llhead->ll_address_size = address_size; llhead->ll_offset_size = cucontext->cc_length_size; llhead->ll_context = cucontext; llhead->ll_at_loclists_base_present = cucontext->cc_loclists_base_present; llhead->ll_at_loclists_base = cucontext->cc_loclists_base; llhead->ll_cu_base_address_present = cucontext->cc_low_pc_present; llhead->ll_cu_base_address = cucontext->cc_low_pc; llhead->ll_cu_addr_base = cucontext->cc_addr_base; llhead->ll_cu_addr_base_present = cucontext->cc_addr_base_present; if (lkind == DW_LKIND_loclist || lkind == DW_LKIND_GNU_exp_list) { int ores = 0; /* Here we have a loclist to deal with. */ ores = context_is_cu_not_tu(cucontext,&is_cu); if (ores != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return setup_res; } ores = _dwarf_original_loclist_build(dbg, llhead, attr, error); if (ores != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return ores; } if (lkind == DW_LKIND_loclist) { ores = cook_original_loclist_contents(dbg,llhead, error); } else { ores = cook_gnu_loclist_contents(dbg,llhead,error); } if (ores != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return ores; } } else if (lkind == DW_LKIND_expression) { /* DWARF2,3,4,5 */ int eres = 0; eres = _dwarf_original_expression_build(dbg, llhead, attr, error); if (eres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return eres; } } else if (lkind == DW_LKIND_loclists) { /* DWARF5! */ int leres = 0; leres = _dwarf_loclists_fill_in_lle_head(dbg, attr,llhead,error); if (leres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return leres; } leres = cook_loclists_contents(dbg,llhead,error); if (leres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return leres; } } /* ASSERT else impossible */ *ll_header_out = llhead; *listlen_out = llhead->ll_locdesc_count; return DW_DLV_OK; } /* An interface giving us no cu context! This is not going to be quite right. */ int dwarf_loclist_from_expr_c(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Loc_Head_c *loc_head, Dwarf_Unsigned * listlen, Dwarf_Error * error) { /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; Dwarf_Loc_Head_c llhead = 0; Dwarf_Locdesc_c llbuf = 0; int local_listlen = 1; Dwarf_Addr rawlowpc = 0; Dwarf_Addr rawhighpc = MAX_ADDR; Dwarf_Small version_stamp = dwarf_version; int res = 0; llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memset(&loc_block,0,sizeof(loc_block)); loc_block.bl_len = expression_length; loc_block.bl_data = expression_in; loc_block.bl_kind = DW_LKIND_expression; /* Not from loclist. */ loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */ loc_block.bl_locdesc_offset = 0; /* Fake. Not meaningful. */ llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, local_listlen); if (!llbuf) { dwarf_loc_head_c_dealloc(llhead); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = local_listlen; llhead->ll_context = 0; /* Not available! */ llhead->ll_dbg = dbg; llhead->ll_kind = DW_LKIND_expression; /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* Fills in the locdesc and its operators list at index 0 */ res = _dwarf_fill_in_locdesc_op_c(dbg, 0, llhead, &loc_block, address_size, offset_size, version_stamp, rawlowpc, rawhighpc, DW_LKIND_expression, error); if (res != DW_DLV_OK) { /* low level error already set: let it be passed back */ dwarf_loc_head_c_dealloc(llhead); return DW_DLV_ERROR; } *loc_head = llhead; *listlen = local_listlen; return DW_DLV_OK; } /* New June 2020. */ int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned index, Dwarf_Small * lle_value_out, Dwarf_Unsigned * rawval1, Dwarf_Unsigned * rawval2, Dwarf_Bool * debug_addr_unavailable, Dwarf_Addr * lowpc_out, /* 'cooked' value */ Dwarf_Addr * hipc_out, /* 'cooked' value */ Dwarf_Unsigned * loclist_expr_op_count_out, /* Returns pointer to the specific locdesc of the index; */ Dwarf_Locdesc_c* locdesc_entry_out, Dwarf_Small * loclist_source_out, /* 0,1, or 2 */ Dwarf_Unsigned * expression_offset_out, Dwarf_Unsigned * locdesc_offset_out, Dwarf_Error * error) { Dwarf_Locdesc_c descs_base = 0; Dwarf_Locdesc_c desc = 0; Dwarf_Unsigned desc_count = 0; Dwarf_Debug dbg; desc_count = loclist_head->ll_locdesc_count; descs_base = loclist_head->ll_locdesc; dbg = loclist_head->ll_dbg; if (index >= desc_count) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR); return DW_DLV_ERROR; } desc = descs_base + index; *lle_value_out = desc->ld_lle_value; *rawval1 = desc->ld_rawlow; *rawval2 = desc->ld_rawhigh; *lowpc_out = desc->ld_lopc; *hipc_out = desc->ld_highpc; *debug_addr_unavailable = desc->ld_index_failed; *loclist_expr_op_count_out = desc->ld_cents; *locdesc_entry_out = desc; *loclist_source_out = desc->ld_kind; *expression_offset_out = desc->ld_section_offset; *locdesc_offset_out = desc->ld_locdesc_offset; return DW_DLV_OK; } /* Use dwarf_get_locdesc_entry_d() instead This function is not sufficient for DWARF 5. */ int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned index, Dwarf_Small * lle_value_out, Dwarf_Addr * lowpc_out, Dwarf_Addr * hipc_out, Dwarf_Unsigned * loclist_count_out, /* Returns pointer to the specific locdesc of the index; */ Dwarf_Locdesc_c* locdesc_entry_out, /* 0,1,2 or 5 DW_LKIND_* */ Dwarf_Small * loclist_source_out, Dwarf_Unsigned * expression_offset_out, Dwarf_Unsigned * locdesc_offset_out, Dwarf_Error * error) { int res = 0; Dwarf_Unsigned cookedlow = 0; Dwarf_Unsigned cookedhigh = 0; Dwarf_Bool debug_addr_unavailable = FALSE; res = dwarf_get_locdesc_entry_d(loclist_head, index,lle_value_out, lowpc_out,hipc_out, &debug_addr_unavailable, &cookedlow,&cookedhigh, loclist_count_out, locdesc_entry_out, loclist_source_out, expression_offset_out, locdesc_offset_out, error); return res; } int dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc, Dwarf_Unsigned index, Dwarf_Small * atom_out, Dwarf_Unsigned * operand1, Dwarf_Unsigned * operand2, Dwarf_Unsigned * operand3, Dwarf_Unsigned * rawop1, Dwarf_Unsigned * rawop2, Dwarf_Unsigned * rawop3, Dwarf_Unsigned * offset_for_branch, Dwarf_Error* error) { Dwarf_Loc_Expr_Op op = 0; Dwarf_Unsigned max = locdesc->ld_cents; if (index >= max) { Dwarf_Debug dbg = locdesc->ld_loclist_head->ll_dbg; _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR); return DW_DLV_ERROR; } op = locdesc->ld_s + index; *atom_out = op->lr_atom; *operand1 = op->lr_number; *operand2 = op->lr_number2; *operand3 = op->lr_number3; *rawop1 = op->lr_raw1; *rawop2 = op->lr_raw2; *rawop3 = op->lr_raw3; *offset_for_branch = op->lr_offset; return DW_DLV_OK; } int dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc, Dwarf_Unsigned index, Dwarf_Small * atom_out, Dwarf_Unsigned * operand1, Dwarf_Unsigned * operand2, Dwarf_Unsigned * operand3, Dwarf_Unsigned * offset_for_branch, Dwarf_Error* error) { Dwarf_Unsigned raw1 = 0; Dwarf_Unsigned raw2 = 0; Dwarf_Unsigned raw3 = 0; int res = 0; res = dwarf_get_location_op_value_d(locdesc, index,atom_out, operand1,operand2,operand3, &raw1,&raw2,&raw3, offset_for_branch, error); return res; } void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head) { Dwarf_Debug dbg = loclist_head->ll_dbg; /* destructor will remove content then free head itself */ dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C); } /* ============== End of the October 2015 interfaces. */ libdwarf-20210528/libdwarf/dwarf_reloc_ppc.h0000644000175000017500000002474413763276336015621 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DWARF_RELOC_PPC_H #define DWARF_RELOC_PPC_H /* Definitions for PPC */ #define DWARF_RELOC_PPC /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 #define R_PPC_ADDR32 1 /* 32bit absolute address */ #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ #define R_PPC_ADDR16 3 /* 16bit absolute address */ #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ #define R_PPC_ADDR14_BRTAKEN 8 #define R_PPC_ADDR14_BRNTAKEN 9 #define R_PPC_REL24 10 /* PC relative 26 bit */ #define R_PPC_REL14 11 /* PC relative 16 bit */ #define R_PPC_REL14_BRTAKEN 12 #define R_PPC_REL14_BRNTAKEN 13 #define R_PPC_GOT16 14 #define R_PPC_GOT16_LO 15 #define R_PPC_GOT16_HI 16 #define R_PPC_GOT16_HA 17 #define R_PPC_PLTREL24 18 #define R_PPC_COPY 19 #define R_PPC_GLOB_DAT 20 #define R_PPC_JMP_SLOT 21 #define R_PPC_RELATIVE 22 #define R_PPC_LOCAL24PC 23 #define R_PPC_UADDR32 24 #define R_PPC_UADDR16 25 #define R_PPC_REL32 26 #define R_PPC_PLT32 27 #define R_PPC_PLTREL32 28 #define R_PPC_PLT16_LO 29 #define R_PPC_PLT16_HI 30 #define R_PPC_PLT16_HA 31 #define R_PPC_SDAREL16 32 #define R_PPC_SECTOFF 33 #define R_PPC_SECTOFF_LO 34 #define R_PPC_SECTOFF_HI 35 #define R_PPC_SECTOFF_HA 36 /* Unused types */ #define R_PPC_37 37 #define R_PPC_38 38 #define R_PPC_39 39 #define R_PPC_40 40 #define R_PPC_41 41 #define R_PPC_42 42 #define R_PPC_43 43 #define R_PPC_44 44 #define R_PPC_45 45 #define R_PPC_46 46 #define R_PPC_47 47 #define R_PPC_48 48 #define R_PPC_49 49 #define R_PPC_50 50 #define R_PPC_51 51 #define R_PPC_52 52 #define R_PPC_53 53 #define R_PPC_54 54 #define R_PPC_55 55 /* Unused types */ #define R_PPC_56 56 #define R_PPC_57 57 #define R_PPC_58 58 #define R_PPC_59 59 #define R_PPC_60 60 #define R_PPC_61 61 #define R_PPC_62 62 #define R_PPC_63 63 #define R_PPC_64 64 #define R_PPC_65 65 #define R_PPC_66 66 /* PowerPC relocations defined for the TLS access ABI. */ #define R_PPC_TLS 67 /* none (sym+add)@tls */ #define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ #define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ #define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ #define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ #define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ #define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ #define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ #define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ #define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ #define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ #define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ #define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ #define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ #define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ #define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ #define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ #define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ #define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ #define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ #define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ #define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ #define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ #define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ #define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ #define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ #define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ #define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ /* Keep this the last entry. */ #define R_PPC_NUM 95 #endif /* _WIN32 */ /* PowerPC relocations defined by the ABIs */ static const char *reloc_type_names_PPC[] = { "R_PPC_NONE", /* 00 */ "R_PPC_ADDR32", /* 01 */ "R_PPC_ADDR24", /* 02 */ "R_PPC_ADDR16", /* 03 */ "R_PPC_ADDR16_LO", /* 04 */ "R_PPC_ADDR16_HI", /* 05 */ "R_PPC_ADDR16_HA", /* 06 */ "R_PPC_ADDR14", /* 07 */ "R_PPC_ADDR14_BRTAKEN", /* 08 */ "R_PPC_ADDR14_BRNTAKEN", /* 09 */ "R_PPC_REL24", /* 10 */ "R_PPC_REL14", /* 11 */ "R_PPC_REL14_BRTAKEN", /* 12 */ "R_PPC_REL14_BRNTAKEN", /* 13 */ "R_PPC_GOT16", /* 14 */ "R_PPC_GOT16_LO", /* 15 */ "R_PPC_GOT16_HI", /* 16 */ "R_PPC_GOT16_HA", /* 17 */ "R_PPC_PLTREL24", /* 18 */ "R_PPC_COPY", /* 19 */ "R_PPC_GLOB_DAT", /* 20 */ "R_PPC_JMP_SLOT", /* 21 */ "R_PPC_RELATIVE", /* 22 */ "R_PPC_LOCAL24PC", /* 23 */ "R_PPC_UADDR32", /* 24 */ "R_PPC_UADDR16", /* 25 */ "R_PPC_REL32", /* 26 */ "R_PPC_PLT32", /* 27 */ "R_PPC_PLTREL32", /* 28 */ "R_PPC_PLT16_LO", /* 29 */ "R_PPC_PLT16_HI", /* 30 */ "R_PPC_PLT16_HA", /* 31 */ "R_PPC_SDAREL16", /* 32 */ "R_PPC_SECTOFF", /* 33 */ "R_PPC_SECTOFF_LO", /* 34 */ "R_PPC_SECTOFF_HI", /* 35 */ "R_PPC_SECTOFF_HA", /* 36 */ "R_PPC_37", /* 37 */ "R_PPC_38", /* 38 */ "R_PPC_39", /* 39 */ "R_PPC_40", /* 40 */ "R_PPC_41", /* 41 */ "R_PPC_42", /* 42 */ "R_PPC_43", /* 43 */ "R_PPC_44", /* 44 */ "R_PPC_45", /* 45 */ "R_PPC_46", /* 46 */ "R_PPC_47", /* 47 */ "R_PPC_48", /* 48 */ "R_PPC_49", /* 49 */ "R_PPC_50", /* 50 */ "R_PPC_51", /* 51 */ "R_PPC_52", /* 52 */ "R_PPC_53", /* 53 */ "R_PPC_54", /* 54 */ "R_PPC_55", /* 55 */ "R_PPC_56", /* 56 */ "R_PPC_57", /* 57 */ "R_PPC_58", /* 58 */ "R_PPC_59", /* 59 */ "R_PPC_60", /* 60 */ "R_PPC_61", /* 61 */ "R_PPC_62", /* 62 */ "R_PPC_63", /* 63 */ "R_PPC_64", /* 64 */ "R_PPC_65", /* 65 */ "R_PPC_66", /* 66 */ "R_PPC_TLS", /* 67 */ "R_PPC_DTPMOD32", /* 68 */ "R_PPC_TPREL16", /* 69 */ "R_PPC_TPREL16_LO", /* 70 */ "R_PPC_TPREL16_HI", /* 71 */ "R_PPC_TPREL16_HA", /* 72 */ "R_PPC_TPREL32", /* 73 */ "R_PPC_DTPREL16", /* 74 */ "R_PPC_DTPREL16_LO", /* 75 */ "R_PPC_DTPREL16_HI", /* 76 */ "R_PPC_DTPREL16_HA", /* 77 */ "R_PPC_DTPREL64", /* 78 */ "R_PPC_GOT_TLSGD16", /* 79 */ "R_PPC_GOT_TLSGD16_LO", /* 80 */ "R_PPC_GOT_TLSGD16_HI", /* 81 */ "R_PPC_GOT_TLSGD16_HA", /* 82 */ "R_PPC_GOT_TLSLD16", /* 83 */ "R_PPC_GOT_TLSLD16_LO", /* 84 */ "R_PPC_GOT_TLSLD16_HI", /* 85 */ "R_PPC_GOT_TLSLD16_HA", /* 86 */ "R_PPC_GOT_TPREL16_DS", /* 87 */ "R_PPC_GOT_TPREL16_LO", /* 88 */ "R_PPC_GOT_TPREL16_HI", /* 89 */ "R_PPC_GOT_TPREL16_HA", /* 90 */ "R_PPC_GOT_DTPREL16", /* 91 */ "R_PPC_GOT_DTPREL16_LO", /* 92 */ "R_PPC_GOT_DTPREL16_HI", /* 93 */ "R_PPC_GOT_DTPREL16_HA", /* 94 */ }; #endif /* DWARF_RELOC_PPC_H */ libdwarf-20210528/libdwarf/dwarf_elf_reloc_sparc.h0000664000175000017500000001775613644370703016773 00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_sparc(unsigned long); #ifndef R_SPARC_NONE #define R_SPARC_NONE 0 #endif /* R_SPARC_NONE */ #ifndef R_SPARC_8 #define R_SPARC_8 1 #endif /* R_SPARC_8 */ #ifndef R_SPARC_16 #define R_SPARC_16 2 #endif /* R_SPARC_16 */ #ifndef R_SPARC_32 #define R_SPARC_32 3 #endif /* R_SPARC_32 */ #ifndef R_SPARC_DISP8 #define R_SPARC_DISP8 4 #endif /* R_SPARC_DISP8 */ #ifndef R_SPARC_DISP16 #define R_SPARC_DISP16 5 #endif /* R_SPARC_DISP16 */ #ifndef R_SPARC_DISP32 #define R_SPARC_DISP32 6 #endif /* R_SPARC_DISP32 */ #ifndef R_SPARC_WDISP30 #define R_SPARC_WDISP30 7 #endif /* R_SPARC_WDISP30 */ #ifndef R_SPARC_WDISP22 #define R_SPARC_WDISP22 8 #endif /* R_SPARC_WDISP22 */ #ifndef R_SPARC_HI22 #define R_SPARC_HI22 9 #endif /* R_SPARC_HI22 */ #ifndef R_SPARC_22 #define R_SPARC_22 10 #endif /* R_SPARC_22 */ #ifndef R_SPARC_13 #define R_SPARC_13 11 #endif /* R_SPARC_13 */ #ifndef R_SPARC_LO10 #define R_SPARC_LO10 12 #endif /* R_SPARC_LO10 */ #ifndef R_SPARC_GOT10 #define R_SPARC_GOT10 13 #endif /* R_SPARC_GOT10 */ #ifndef R_SPARC_GOT13 #define R_SPARC_GOT13 14 #endif /* R_SPARC_GOT13 */ #ifndef R_SPARC_GOT22 #define R_SPARC_GOT22 15 #endif /* R_SPARC_GOT22 */ #ifndef R_SPARC_PC10 #define R_SPARC_PC10 16 #endif /* R_SPARC_PC10 */ #ifndef R_SPARC_PC22 #define R_SPARC_PC22 17 #endif /* R_SPARC_PC22 */ #ifndef R_SPARC_WPLT30 #define R_SPARC_WPLT30 18 #endif /* R_SPARC_WPLT30 */ #ifndef R_SPARC_COPY #define R_SPARC_COPY 19 #endif /* R_SPARC_COPY */ #ifndef R_SPARC_GLOB_DAT #define R_SPARC_GLOB_DAT 20 #endif /* R_SPARC_GLOB_DAT */ #ifndef R_SPARC_JMP_SLOT #define R_SPARC_JMP_SLOT 21 #endif /* R_SPARC_JMP_SLOT */ #ifndef R_SPARC_RELATIVE #define R_SPARC_RELATIVE 22 #endif /* R_SPARC_RELATIVE */ #ifndef R_SPARC_UA32 #define R_SPARC_UA32 23 #endif /* R_SPARC_UA32 */ #ifndef R_SPARC_PLT32 #define R_SPARC_PLT32 24 #endif /* R_SPARC_PLT32 */ #ifndef R_SPARC_HIPLT22 #define R_SPARC_HIPLT22 25 #endif /* R_SPARC_HIPLT22 */ #ifndef R_SPARC_LOPLT10 #define R_SPARC_LOPLT10 26 #endif /* R_SPARC_LOPLT10 */ #ifndef R_SPARC_PCPLT32 #define R_SPARC_PCPLT32 27 #endif /* R_SPARC_PCPLT32 */ #ifndef R_SPARC_PCPLT22 #define R_SPARC_PCPLT22 28 #endif /* R_SPARC_PCPLT22 */ #ifndef R_SPARC_PCPLT10 #define R_SPARC_PCPLT10 29 #endif /* R_SPARC_PCPLT10 */ #ifndef R_SPARC_10 #define R_SPARC_10 30 #endif /* R_SPARC_10 */ #ifndef R_SPARC_11 #define R_SPARC_11 31 #endif /* R_SPARC_11 */ #ifndef R_SPARC_64 #define R_SPARC_64 32 #endif /* R_SPARC_64 */ #ifndef R_SPARC_OLO10 #define R_SPARC_OLO10 33 #endif /* R_SPARC_OLO10 */ #ifndef R_SPARC_HH22 #define R_SPARC_HH22 34 #endif /* R_SPARC_HH22 */ #ifndef R_SPARC_HM10 #define R_SPARC_HM10 35 #endif /* R_SPARC_HM10 */ #ifndef R_SPARC_LM22 #define R_SPARC_LM22 36 #endif /* R_SPARC_LM22 */ #ifndef R_SPARC_PC_HH22 #define R_SPARC_PC_HH22 37 #endif /* R_SPARC_PC_HH22 */ #ifndef R_SPARC_PC_HM10 #define R_SPARC_PC_HM10 38 #endif /* R_SPARC_PC_HM10 */ #ifndef R_SPARC_PC_LM22 #define R_SPARC_PC_LM22 39 #endif /* R_SPARC_PC_LM22 */ #ifndef R_SPARC_WDISP16 #define R_SPARC_WDISP16 40 #endif /* R_SPARC_WDISP16 */ #ifndef R_SPARC_WDISP19 #define R_SPARC_WDISP19 41 #endif /* R_SPARC_WDISP19 */ #ifndef R_SPARC_GLOB_JMP #define R_SPARC_GLOB_JMP 42 #endif /* R_SPARC_GLOB_JMP */ #ifndef R_SPARC_7 #define R_SPARC_7 43 #endif /* R_SPARC_7 */ #ifndef R_SPARC_5 #define R_SPARC_5 44 #endif /* R_SPARC_5 */ #ifndef R_SPARC_6 #define R_SPARC_6 45 #endif /* R_SPARC_6 */ #ifndef R_SPARC_DISP64 #define R_SPARC_DISP64 46 #endif /* R_SPARC_DISP64 */ #ifndef R_SPARC_PLT64 #define R_SPARC_PLT64 47 #endif /* R_SPARC_PLT64 */ #ifndef R_SPARC_HIX22 #define R_SPARC_HIX22 48 #endif /* R_SPARC_HIX22 */ #ifndef R_SPARC_LOX10 #define R_SPARC_LOX10 49 #endif /* R_SPARC_LOX10 */ #ifndef R_SPARC_H44 #define R_SPARC_H44 50 #endif /* R_SPARC_H44 */ #ifndef R_SPARC_M44 #define R_SPARC_M44 51 #endif /* R_SPARC_M44 */ #ifndef R_SPARC_L44 #define R_SPARC_L44 52 #endif /* R_SPARC_L44 */ #ifndef R_SPARC_REGISTER #define R_SPARC_REGISTER 53 #endif /* R_SPARC_REGISTER */ #ifndef R_SPARC_UA64 #define R_SPARC_UA64 54 #endif /* R_SPARC_UA64 */ #ifndef R_SPARC_UA16 #define R_SPARC_UA16 55 #endif /* R_SPARC_UA16 */ #ifndef R_SPARC_TLS_GD_HI22 #define R_SPARC_TLS_GD_HI22 56 #endif /* R_SPARC_TLS_GD_HI22 */ #ifndef R_SPARC_TLS_GD_LO10 #define R_SPARC_TLS_GD_LO10 57 #endif /* R_SPARC_TLS_GD_LO10 */ #ifndef R_SPARC_TLS_GD_ADD #define R_SPARC_TLS_GD_ADD 58 #endif /* R_SPARC_TLS_GD_ADD */ #ifndef R_SPARC_TLS_GD_CALL #define R_SPARC_TLS_GD_CALL 59 #endif /* R_SPARC_TLS_GD_CALL */ #ifndef R_SPARC_TLS_LDM_HI22 #define R_SPARC_TLS_LDM_HI22 60 #endif /* R_SPARC_TLS_LDM_HI22 */ #ifndef R_SPARC_TLS_LDM_LO10 #define R_SPARC_TLS_LDM_LO10 61 #endif /* R_SPARC_TLS_LDM_LO10 */ #ifndef R_SPARC_TLS_LDM_ADD #define R_SPARC_TLS_LDM_ADD 62 #endif /* R_SPARC_TLS_LDM_ADD */ #ifndef R_SPARC_TLS_LDM_CALL #define R_SPARC_TLS_LDM_CALL 63 #endif /* R_SPARC_TLS_LDM_CALL */ #ifndef R_SPARC_TLS_LDO_HIX22 #define R_SPARC_TLS_LDO_HIX22 64 #endif /* R_SPARC_TLS_LDO_HIX22 */ #ifndef R_SPARC_TLS_LDO_LOX10 #define R_SPARC_TLS_LDO_LOX10 65 #endif /* R_SPARC_TLS_LDO_LOX10 */ #ifndef R_SPARC_TLS_LDO_ADD #define R_SPARC_TLS_LDO_ADD 66 #endif /* R_SPARC_TLS_LDO_ADD */ #ifndef R_SPARC_TLS_IE_HI22 #define R_SPARC_TLS_IE_HI22 67 #endif /* R_SPARC_TLS_IE_HI22 */ #ifndef R_SPARC_TLS_IE_LO10 #define R_SPARC_TLS_IE_LO10 68 #endif /* R_SPARC_TLS_IE_LO10 */ #ifndef R_SPARC_TLS_IE_LD #define R_SPARC_TLS_IE_LD 69 #endif /* R_SPARC_TLS_IE_LD */ #ifndef R_SPARC_TLS_IE_LDX #define R_SPARC_TLS_IE_LDX 70 #endif /* R_SPARC_TLS_IE_LDX */ #ifndef R_SPARC_TLS_IE_ADD #define R_SPARC_TLS_IE_ADD 71 #endif /* R_SPARC_TLS_IE_ADD */ #ifndef R_SPARC_TLS_LE_HIX22 #define R_SPARC_TLS_LE_HIX22 72 #endif /* R_SPARC_TLS_LE_HIX22 */ #ifndef R_SPARC_TLS_LE_LOX10 #define R_SPARC_TLS_LE_LOX10 73 #endif /* R_SPARC_TLS_LE_LOX10 */ #ifndef R_SPARC_TLS_DTPMOD32 #define R_SPARC_TLS_DTPMOD32 74 #endif /* R_SPARC_TLS_DTPMOD32 */ #ifndef R_SPARC_TLS_DTPMOD64 #define R_SPARC_TLS_DTPMOD64 75 #endif /* R_SPARC_TLS_DTPMOD64 */ #ifndef R_SPARC_TLS_DTPOFF32 #define R_SPARC_TLS_DTPOFF32 76 #endif /* R_SPARC_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF64 #define R_SPARC_TLS_DTPOFF64 77 #endif /* R_SPARC_TLS_DTPOFF64 */ #ifndef R_SPARC_TLS_TPOFF32 #define R_SPARC_TLS_TPOFF32 78 #endif /* R_SPARC_TLS_TPOFF32 */ #ifndef R_SPARC_TLS_TPOFF64 #define R_SPARC_TLS_TPOFF64 79 #endif /* R_SPARC_TLS_TPOFF64 */ #ifndef R_SPARC_GOTDATA_HIX22 #define R_SPARC_GOTDATA_HIX22 80 #endif /* R_SPARC_GOTDATA_HIX22 */ #ifndef R_SPARC_GOTDATA_LOX10 #define R_SPARC_GOTDATA_LOX10 81 #endif /* R_SPARC_GOTDATA_LOX10 */ #ifndef R_SPARC_GOTDATA_OP_HIX22 #define R_SPARC_GOTDATA_OP_HIX22 82 #endif /* R_SPARC_GOTDATA_OP_HIX22 */ #ifndef R_SPARC_GOTDATA_OP_LOX10 #define R_SPARC_GOTDATA_OP_LOX10 83 #endif /* R_SPARC_GOTDATA_OP_LOX10 */ #ifndef R_SPARC_GOTDATA_OP #define R_SPARC_GOTDATA_OP 84 #endif /* R_SPARC_GOTDATA_OP */ #ifndef R_SPARC_H34 #define R_SPARC_H34 85 #endif /* R_SPARC_H34 */ #ifndef R_SPARC_SIZE32 #define R_SPARC_SIZE32 86 #endif /* R_SPARC_SIZE32 */ #ifndef R_SPARC_SIZE64 #define R_SPARC_SIZE64 87 #endif /* R_SPARC_SIZE64 */ #ifndef R_SPARC_WDISP10 #define R_SPARC_WDISP10 88 #endif /* R_SPARC_WDISP10 */ #ifndef R_SPARC_JMP_IREL #define R_SPARC_JMP_IREL 248 #endif /* R_SPARC_JMP_IREL */ #ifndef R_SPARC_IRELATIVE #define R_SPARC_IRELATIVE 249 #endif /* R_SPARC_IRELATIVE */ #ifndef R_SPARC_GNU_VTINHERIT #define R_SPARC_GNU_VTINHERIT 250 #endif /* R_SPARC_GNU_VTINHERIT */ #ifndef R_SPARC_GNU_VTENTRY #define R_SPARC_GNU_VTENTRY 251 #endif /* R_SPARC_GNU_VTENTRY */ #ifndef R_SPARC_REV32 #define R_SPARC_REV32 252 #endif /* R_SPARC_REV32 */ libdwarf-20210528/libdwarf/dwarf_peread.h0000664000175000017500000001264613763277305015110 00000000000000#ifndef PE_GENERIC_H #define PE_GENERIC_H /* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct dwarf_pe_generic_file_header { Dwarf_Unsigned Machine; Dwarf_Unsigned NumberOfSections; Dwarf_Unsigned TimeDateStamp; Dwarf_Unsigned PointerToSymbolTable; Dwarf_Unsigned NumberOfSymbols; Dwarf_Unsigned SizeOfOptionalHeader; /* in object file */ Dwarf_Unsigned Characteristics; }; struct dwarf_pe_generic_data_directory { Dwarf_Unsigned VirtualAddress; Dwarf_Unsigned Size; }; #define DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 struct dwarf_pe_generic_optional_header { Dwarf_Unsigned Magic; unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; Dwarf_Unsigned SizeOfCode; Dwarf_Unsigned SizeOfInitializedData; Dwarf_Unsigned SizeOfUninitializedData; Dwarf_Unsigned AddressOfEntryPoint; Dwarf_Unsigned BaseOfCode; Dwarf_Unsigned BaseOfData; Dwarf_Unsigned ImageBase; Dwarf_Unsigned SectionAlignment; Dwarf_Unsigned FileAlignment; Dwarf_Unsigned MajorOperatingSystemVersion; Dwarf_Unsigned MinorOperatingSystemVersion; Dwarf_Unsigned MajorImageVersion; Dwarf_Unsigned MinorImageVersion; Dwarf_Unsigned MajorSubsystemVersion; Dwarf_Unsigned MinorSubsystemVersion; Dwarf_Unsigned Win32VersionValue; Dwarf_Unsigned SizeOfImage; /* size in object file */ Dwarf_Unsigned SizeOfHeaders; /* size in object file */ Dwarf_Unsigned CheckSum; Dwarf_Unsigned Subsystem; Dwarf_Unsigned DllCharacteristics; Dwarf_Unsigned SizeOfStackReserve; Dwarf_Unsigned SizeOfStackCommit; Dwarf_Unsigned SizeOfHeapReserve; Dwarf_Unsigned SizeOfHeapCommit; Dwarf_Unsigned LoaderFlags; Dwarf_Unsigned NumberOfRvaAndSizes; Dwarf_Unsigned SizeOfDataDirEntry; /* size in object file */ struct dwarf_pe_generic_data_directory DataDirectory[DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; }; struct dwarf_pe_generic_image_section_header { char *name; /* Name must be freed */ char *dwarfsectname; /* Name must be freed */ Dwarf_Unsigned SecHeaderOffset; /* offset in object file */ /* union { */ /* Dwarf_Unsigned PhysicalAddress; */ Dwarf_Unsigned VirtualSize; /* } Misc; */ Dwarf_Unsigned VirtualAddress; Dwarf_Unsigned SizeOfRawData; /* size we need */ Dwarf_Unsigned PointerToRawData; Dwarf_Unsigned PointerToRelocations; Dwarf_Unsigned PointerToLinenumbers; Dwarf_Unsigned NumberOfRelocations; Dwarf_Unsigned NumberOfLinenumbers; Dwarf_Unsigned Characteristics; Dwarf_Small * loaded_data; /* must be freed. */ }; #define DWARF_PE_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define DWARF_PE_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define DWARF_PE_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 /* ident[0] == 'P' means this is a PE header. ident[1] will be 1 indicating version 1. Other bytes in ident not defined, should be zero. */ typedef struct pe_filedata_s { char pe_ident[8]; const char * pe_path; /* must free.*/ int pe_fd; int pe_destruct_close_fd; /*aka: lib owns fd */ int pe_is_64bit; Dwarf_Unsigned pe_filesize; Dwarf_Small pe_offsetsize; /* 32 or 64 section data */ Dwarf_Small pe_pointersize; int pe_ftype; unsigned pe_endian; /*Dwarf_Small pe_machine; */ void (*pe_copy_word) (void *, const void *, unsigned long); Dwarf_Unsigned pe_nt_header_offset; Dwarf_Unsigned pe_optional_header_offset; Dwarf_Unsigned pe_optional_header_size; Dwarf_Unsigned pe_symbol_table_offset; Dwarf_Unsigned pe_string_table_offset; Dwarf_Unsigned pe_section_table_offset; Dwarf_Unsigned pe_signature; struct dwarf_pe_generic_file_header pe_FileHeader; struct dwarf_pe_generic_optional_header pe_OptionalHeader; Dwarf_Unsigned pe_section_count; struct dwarf_pe_generic_image_section_header *pe_sectionptr; Dwarf_Unsigned pe_string_table_size; char *pe_string_table; } dwarf_pe_object_access_internals_t; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PE_GENERIC_H */ libdwarf-20210528/libdwarf/dwarf_abbrev.h0000664000175000017500000000472113771417277015107 00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* In a given CU, one of these is (eventually) set up for every abbreviation we need to find (and for all those earlier in the abbreviations for that CU). So we don't want elements needlessly big. */ struct Dwarf_Abbrev_s { /* No TAG should exceed DW_TAG_hi_user, 0xffff, but we do allow a larger value here. */ Dwarf_Unsigned dab_tag; /* Abbreviations are numbered (normally sequentially from 1 and so 16 bits is not enough! */ Dwarf_Unsigned dab_code; Dwarf_Small dab_has_child; /* dab_abbrev_ptr points to the abbreviations themselves in memory, the list of attr/form integers terminated by 0,0. */ Dwarf_Byte_Ptr dab_abbrev_ptr; Dwarf_Debug dab_dbg; /* Section global offset of the abbrev. */ Dwarf_Off dab_goffset; /* dab_count is the number of attr/form uleb pairs */ Dwarf_Off dab_count; /* When the caller cycles through attr/form pairs by index from zero this lets the code read just one pair to work. */ Dwarf_Byte_Ptr dab_next_ptr; Dwarf_Unsigned dab_next_index; }; int _dwarf_count_abbrev_entries(Dwarf_Debug dbg, Dwarf_Byte_Ptr abbrev_ptr, Dwarf_Byte_Ptr abbrev_section_end, Dwarf_Unsigned *abbrev_count_out, Dwarf_Byte_Ptr *abbrev_ptr_out, Dwarf_Error *error); libdwarf-20210528/libdwarf/pdfbld.sh0000775000175000017500000000354414054013352014063 00000000000000#!/bin/sh # This is meant to be done by hand # when changes made. Not done during build or install. # Just use the built pdf to install. # Run in the libdwarf source directory. # This generates two reader/consumer pdfs with -c or -a: # libdwarf2.1.pdf is standard mm output. # and libdwarf2.1xl.pdf is rearranged to have # TOC first but is...gigantic, so not shipped. c="n" p="n" if [ $# -lt 1 ] then echo "Usage: pdfbld.sh [-a] [-c] [-p]" echo "where: -c formats libdwarf2.1.pdf" echo "where: -p formats libdwarf2p.1.pdf" echo "where: -a formats both" exit 1 fi for i in $* do case $i in -a) c="y" ; p="y" shift ;; -c) c="y" shift ;; -p) p="y" shift ;; *) echo "Giving up: unknown argument use argument -a or -c or -p" exit 1 ;; esac done set -x TROFF=/usr/bin/groff #TROFFDEV="-T ps" PSTOPDF=/usr/bin/ps2pdf if [ $c = "y" ] then rm -f libdwarf2.1.pdf t=junklibdwarfread.pdf pr -t -e libdwarf2.1.mm | tbl | $TROFF -n16 -mm >libdwarf2.1.ps $PSTOPDF libdwarf2.1.ps libdwarf2.1.pdf # The rearrangement bloats the pdf from 600KB to 14MB # and makes the release gigantic. So skip it. #$PSTOPDF libdwarf2.1.ps $t #echo "Now create libdwarf2.1.mm by tranforming $t" #set +x #sh ../scripts/rebuildpdf.sh $t libdwarf2.1xl.pdf #ls -l libdwarf2.1.pdf #ls -l libdwarf2.1xl.pdf #rm $t #if [ -d ~/web4/gweb/pagedata ] #then # echo "Copying libdwarf2.1xl.pdf to ~/web4/gweb/pagedata" # cp libdwarf2.1xl.pdf ~/web4/gweb/pagedata #fi #set -x fi if [ $p = "y" ] then rm -f libdwarf2p.1.pdf pr -t -e libdwarf2p.1.mm | tbl | $TROFF -mm >libdwarf2p.1.ps $PSTOPDF libdwarf2p.1.ps libdwarf2p.1.pdf fi set +x echo "Check libdwarf/libdwarf2.1xl.pdf is correct " echo "Should start with abstract page then follow with" echo "libdwarf2.1.pdf table of contents." rm -f libdwarf2.1.ps rm -f libdwarf2p.1.ps libdwarf-20210528/libdwarf/dwarfstring.h0000664000175000017500000000573314012266121014774 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* A lightly generalized string buffer for libdwarf. The functions that return anything return either TRUE (nonzero int) or FALSE (zero) On return of FALSE the dwarfstring_s struct remains in a usable state. It is expected that most users will not check the return value. */ #ifndef DWARFSTRING_H #define DWARFSTRING_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct dwarfstring_s { char * s_data; unsigned long s_size; unsigned long s_avail; unsigned char s_malloc; }; typedef unsigned long long dwarfstring_u; typedef signed long long dwarfstring_i; typedef struct dwarfstring_s dwarfstring; int dwarfstring_constructor(struct dwarfstring_s *g); int dwarfstring_constructor_fixed(struct dwarfstring_s *g, unsigned long len); int dwarfstring_constructor_static(struct dwarfstring_s *g, char * space, unsigned long len); void dwarfstring_destructor(struct dwarfstring_s *g); int dwarfstring_reset(struct dwarfstring_s *g); int dwarfstring_append(struct dwarfstring_s *g,char *str); /* When one wants the first 'len' characters of str appended. NUL termination is provided by dwarfstrings. */ int dwarfstring_append_length(struct dwarfstring_s *g, char *str,unsigned long len); int dwarfstring_append_printf_s(dwarfstring *data, char *format,char *s); int dwarfstring_append_printf_i(dwarfstring *data, char *format,dwarfstring_i); int dwarfstring_append_printf_u(dwarfstring *data, char *format,dwarfstring_u); char * dwarfstring_string(struct dwarfstring_s *g); unsigned long dwarfstring_strlen(struct dwarfstring_s *g); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARFSTRING_H */ libdwarf-20210528/libdwarf/dwarf_form_class_names.c0000664000175000017500000000734514013007503017132 00000000000000/* Copyright (c) 2021, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "libdwarf.h" /* FORM_CLASS is created by libdwarf, it is not a part of Standard Dwarf. Dwarf_Form_Class attempts to allow convenient processing of FORMs across DWARF2,3,4, and 5 for libdwarf, dwarfdump, and other clients and ensures type-safe referencing. */ int dwarf_get_FORM_CLASS_name (enum Dwarf_Form_Class fc, const char ** s_out) { switch (fc) { case DW_FORM_CLASS_UNKNOWN: *s_out = "DW_FORM_CLASS_UNKNOWN"; return DW_DLV_OK; case DW_FORM_CLASS_ADDRESS: *s_out = "DW_FORM_CLASS_ADDRESS"; return DW_DLV_OK; case DW_FORM_CLASS_BLOCK: *s_out = "DW_FORM_CLASS_BLOCK"; return DW_DLV_OK; case DW_FORM_CLASS_CONSTANT: *s_out = "DW_FORM_CLASS_CONSTANT"; return DW_DLV_OK; case DW_FORM_CLASS_EXPRLOC: *s_out = "DW_FORM_CLASS_EXPRLOC"; return DW_DLV_OK; case DW_FORM_CLASS_FLAG: *s_out = "DW_FORM_CLASS_FLAG"; return DW_DLV_OK; case DW_FORM_CLASS_LINEPTR: *s_out = "DW_FORM_CLASS_LINEPTR"; return DW_DLV_OK; case DW_FORM_CLASS_LOCLISTPTR: *s_out = "DW_FORM_CLASS_LOCLISTPTR"; return DW_DLV_OK; case DW_FORM_CLASS_MACPTR: *s_out = "DW_FORM_CLASS_MACPTR"; return DW_DLV_OK; case DW_FORM_CLASS_RANGELISTPTR: *s_out = "DW_FORM_CLASS_RANGELISTPTR"; return DW_DLV_OK; case DW_FORM_CLASS_REFERENCE: *s_out = "DW_FORM_CLASS_REFERENCE"; return DW_DLV_OK; case DW_FORM_CLASS_STRING: *s_out = "DW_FORM_CLASS_STRING"; return DW_DLV_OK; case DW_FORM_CLASS_FRAMEPTR: *s_out = "DW_FORM_CLASS_FRAMEPTR"; return DW_DLV_OK; case DW_FORM_CLASS_MACROPTR: *s_out = "DW_FORM_CLASS_MAXCROPTR"; return DW_DLV_OK; case DW_FORM_CLASS_ADDRPTR: *s_out = "DW_FORM_CLASS_ADDRPTR"; return DW_DLV_OK; case DW_FORM_CLASS_LOCLIST: *s_out = "DW_FORM_CLASS_LOCLIST"; return DW_DLV_OK; case DW_FORM_CLASS_LOCLISTSPTR: *s_out = "DW_FORM_CLASS_LOCLISTSPTR"; return DW_DLV_OK; case DW_FORM_CLASS_RNGLIST: *s_out = "DW_FORM_CLASS_RNGLIST"; return DW_DLV_OK; case DW_FORM_CLASS_RNGLISTSPTR: *s_out = "DW_FORM_CLASS_RNGLISTSPTR"; return DW_DLV_OK; case DW_FORM_CLASS_STROFFSETSPTR: *s_out = "DW_FORM_CLASS_STROFFSETSPTR"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } libdwarf-20210528/libdwarf/testdebuglink.sh0000755000175000017500000000071013743575426015505 00000000000000#!/bin/sh # Verify the printed output of of test_linkedto top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/libdwarf ./test_linkedtopath >junk.ltp which dos2unix if [ $? -eq 0 ] then dos2unix junk.ltp fi diff $srcdir/baseline.ltp junk.ltp if [ $? -ne 0 ] then echo "FAIL base test " echo "To update baseline: mv junk.ltp $srcdir/baseline.ltp" exit 1 fi exit 0 libdwarf-20210528/libdwarf/dwarf_reading.h0000664000175000017500000000417113644370703015245 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_READING_H #define DWARF_READING_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef DW_DLV_OK /* DW_DLV_OK must match libdwarf.h */ /* DW_DLV_NO_ENTRY must match libdwarf.h */ #define DW_DLV_OK 0 #define DW_DLV_NO_ENTRY -1 #define DW_DLV_ERROR 1 #endif /* DW_DLV_OK */ #define TRUE 1 #define FALSE 0 #define ALIGN4 4 #define ALIGN8 8 #define PREFIX "\t" #define LUFMT "%lu" #define UFMT "%u" #define DFMT "%d" #define XFMT "0x%x" /* even if already seen, values must match, so no #ifdef needed. */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 #define P printf #define F fflush(stdout) #define RRMOA(f,buf,loc,siz,fsiz,errc) _dwarf_object_read_random(f, \ (char *)buf,loc,siz,fsiz,errc); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_READING_H */ libdwarf-20210528/libdwarf/pro_incl.h0000664000175000017500000000531314012266121014241 00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2012 David Anderson. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef DWARF_WITH_LIBELF #ifdef HAVE_ELF_H /* does includes of elf.h libelf.h here. */ #include #elif defined(HAVE_LIBELF_H) /* On one platform without elf.h this gets Elf32_Rel type defined (a required type). */ #include /* Consider the other known directory too */ #elif defined(HAVE_LIBELF_LIBELF_H) #include #endif /* HAVE_ELF_H or HAVE_LIBELF*H */ #endif /* DWARF_WITH_LIBELF */ #if defined(sun) #include #include #endif /* The target address is given: the place in the source integer is to be determined. */ #ifdef WORDS_BIGENDIAN #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((const char *)source) +(srclength)-(len_out),\ (len_out)) ; \ } #else /* LITTLE ENDIAN */ #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((const char *)source) , \ (len_out)) ; \ } #endif /* BIG- LITTLE-ENDIAN */ #if defined(sparc) && defined(sun) #define REL32 Elf32_Rela #define REL64 Elf64_Rela #define REL_SEC_PREFIX ".rela" #else #define REL32 Elf32_Rel #define REL64 Elf64_Rel #define REL_SEC_PREFIX ".rel" #endif libdwarf-20210528/libdwarf/dwarf_tied_test.c0000664000175000017500000001344014004647467015617 00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #ifdef HAVE_STDLIB_H #include /* for free(). */ #endif /* HAVE_STDLIB_H */ #include /* For debugging. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" #define TRUE 1 #define FALSE 0 #define TRUE 1 #define FALSE 0 struct test_data_s { const char action; unsigned long val; } testdata[] = { {'a', 0x33c8}, {'a', 0x34d8}, {'a', 0x35c8}, {'a', 0x3640}, {'a', 0x3820}, {'a', 0x38d0}, {'a', 0x3958}, {'a', 0x39e8}, {'a', 0x3a78}, {'a', 0x3b08}, {'a', 0x3b98}, {'a', 0x3c28}, {'a', 0x3cb8}, {'d', 0x3c28}, {'a', 0x3d48}, {'d', 0x3cb8}, {'a', 0x3dd8}, {'d', 0x3d48}, {'a', 0x3e68}, {'d', 0x3dd8}, {'a', 0x3ef8}, {'a', 0x3f88}, {'d', 0x3e68}, {'a', 0x4018}, {'d', 0x3ef8}, {0,0} }; /* We don't test this here, referenced from dwarf_tied.c. */ int _dwarf_next_cu_header_internal( UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Bool is_info, UNUSEDARG Dwarf_Unsigned * cu_header_length, UNUSEDARG Dwarf_Half * version_stamp, UNUSEDARG Dwarf_Unsigned * abbrev_offset, UNUSEDARG Dwarf_Half * address_size, UNUSEDARG Dwarf_Half * offset_size, UNUSEDARG Dwarf_Half * extension_size, UNUSEDARG Dwarf_Sig8 * signature, UNUSEDARG Dwarf_Bool * has_signature, UNUSEDARG Dwarf_Unsigned *typeoffset, UNUSEDARG Dwarf_Unsigned * next_cu_offset, UNUSEDARG Dwarf_Half * header_cu_type, UNUSEDARG Dwarf_Error * error) { return DW_DLV_NO_ENTRY; } static struct Dwarf_Tied_Entry_s * makeentry(unsigned long instance, unsigned ct) { Dwarf_Sig8 s8; Dwarf_CU_Context context = 0; struct Dwarf_Tied_Entry_s * entry = 0; memset(&s8,0,sizeof(s8)); /* Silly, but just a test...*/ memcpy(&s8,&instance,sizeof(instance)); context = (Dwarf_CU_Context)instance; entry = (struct Dwarf_Tied_Entry_s *) _dwarf_tied_make_entry(&s8,context); if (!entry) { printf("Out of memory in test! %u\n",ct); exit(1); } return entry; } static int insone(void**tree,unsigned long instance, unsigned ct) { struct Dwarf_Tied_Entry_s * entry = 0; void *retval = 0; entry = makeentry(instance, ct); retval = dwarf_tsearch(entry,tree, _dwarf_tied_compare_function); if (!retval) { printf("FAIL ENOMEM in search on rec %u adr 0x%lu," " error in insone\n", ct,(unsigned long)instance); exit(1); } else { struct Dwarf_Tied_Entry_s *re = 0; re = *(struct Dwarf_Tied_Entry_s **)retval; if (re != entry) { /* Found existing, error. */ printf("insertone rec %u addr 0x%lu found record" " preexisting, error\n", ct,(unsigned long)instance); _dwarf_tied_destroy_free_node(entry); exit(1); } else { /* inserted new entry, make sure present. */ struct Dwarf_Tied_Entry_s * entry2 = 0; entry2 = makeentry(instance,ct); retval = dwarf_tfind(entry2,tree, _dwarf_tied_compare_function); _dwarf_tied_destroy_free_node(entry2); if (!retval) { printf("insertonebypointer record %d addr 0x%lu " "failed to add as desired," " error\n", ct,(unsigned long)instance); exit(1); } } } return 0; } static int delone(void**tree,unsigned long instance, unsigned ct) { struct Dwarf_Tied_Entry_s * entry = 0; void *r = 0; entry = makeentry(instance, ct); r = dwarf_tfind(entry,(void *const*)tree, _dwarf_tied_compare_function); if (r) { struct Dwarf_Tied_Entry_s *re3 = *(struct Dwarf_Tied_Entry_s **)r; re3 = *(struct Dwarf_Tied_Entry_s **)r; dwarf_tdelete(entry,tree,_dwarf_tied_compare_function); _dwarf_tied_destroy_free_node(entry); _dwarf_tied_destroy_free_node(re3); } else { printf("delone could not find rec %u ! error! addr" " 0x%lx\n", ct,(unsigned long)instance); exit(1) ; } return 0; } int main() { void *tied_data = 0; unsigned u = 0; INITTREE(tied_data,_dwarf_tied_data_hashfunc); for ( ; testdata[u].action; ++u) { char action = testdata[u].action; unsigned long v = testdata[u].val; if (action == 'a') { insone(&tied_data,v,u); } else if (action == 'd') { delone(&tied_data,v,u); } else { printf("FAIL testtied on action %u, " "not a or d\n",action); exit(1); } } printf("PASS tsearch works for Dwarf_Tied_Entry_s.\n"); return 0; } libdwarf-20210528/libdwarf/memcpy_swap.h0000664000175000017500000000302313763272657015003 00000000000000/* Copyright (C) 2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef MEMCPY_SWAP_H #define MEMCPY_SWAP_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len); /* It's inconvenient to use memcpy directly as it uses size_t and that requires */ void _dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MEMCPY_SWAP_H */ libdwarf-20210528/libdwarf/pro_debug_sup.c0000664000175000017500000000446513764007262015307 00000000000000/* Copyright 2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_encode_nm.h" int dwarf_add_debug_sup(Dwarf_P_Debug dbg, Dwarf_Half version, Dwarf_Small is_supplementary, char * filename, Dwarf_Unsigned checksum_len, Dwarf_Small * checksum, Dwarf_Error * error) { dbg->de_debug_sup.ds_version = version; dbg->de_debug_sup.ds_is_supplementary = is_supplementary; dbg->de_debug_sup.ds_filename = strdup(filename); dbg->de_debug_sup.ds_checksum_len = checksum_len; dbg->de_debug_sup.ds_checksum = malloc(checksum_len); if (!dbg->de_debug_sup.ds_checksum) { free(dbg->de_debug_sup.ds_filename); dbg->de_debug_sup.ds_filename = 0; dbg->de_debug_sup.ds_version = 0; dbg->de_debug_sup.ds_checksum_len = 0; _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(dbg->de_debug_sup.ds_checksum,checksum,checksum_len); return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_alloc.c0000664000175000017500000001461613764007262014423 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2019. David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_alloc.h" #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef HAVE_INTTYPES_H #include #endif /* HAVE_INTTYPES_H */ #include "dwarf_tsearch.h" /* When each block is allocated, there is a two-word structure allocated at the beginning so the block can go on a list. The address returned is the address *after* the two pointers at the start. But this allows us to be given a pointer to a generic block, and go backwards to find the list-node. Then we can remove this block from it's list without the need to search through a linked list in order to remove the node. It also allows us to 'delete' a memory block without needing the dbg structure. We still need the dbg structure on allocation so that we know which linked list to add the block to. Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc. That structure should be set up by hand, and the two list pointers should be initialized to point at the node itself. That initializes the doubly linked list. */ #define LIST_TO_BLOCK(lst) \ ((void*) (((char *)lst) + sizeof(memory_list_t))) #define BLOCK_TO_LIST(blk) \ ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t))) /* dbg should be NULL only when allocating dbg itself. In that case we initialize it to an empty circular doubly-linked list. */ Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size) { void *sp; memory_list_t *lp = NULL; memory_list_t *dbglp = NULL; memory_list_t *nextblock = NULL; /* Alloc control struct and data block together for performance reasons */ lp = (memory_list_t *) malloc(size + sizeof(memory_list_t)); if (lp == NULL) { /* should throw an error */ return NULL; } /* point to 'size' bytes just beyond lp struct */ sp = LIST_TO_BLOCK(lp); memset(sp, 0, size); if (dbg == NULL) { lp->next = lp->prev = lp; } else { /* I always have to draw a picture to understand this part. */ dbglp = BLOCK_TO_LIST(dbg); nextblock = dbglp->next; /* Insert between dbglp and nextblock */ dbglp->next = lp; lp->prev = dbglp; lp->next = nextblock; nextblock->prev = lp; } return sp; } /* This routine is only here in case a caller of an older version of the library is calling this for some reason. This does nothing! No need to remove this block. In theory the user might be depending on the fact that we used to just 'free' this. In theory they might also be passing a block that they got from libdwarf. So we don't know if we should try to remove this block from our global list. Safest just to do nothing at this point. !!! This function is deprecated! Don't call it inside libdwarf or outside of it. Does nothing! !!! */ void dwarf_p_dealloc(UNUSEDARG Dwarf_Small * ptr) { return; } /* The dbg structure is not needed here anymore. */ void _dwarf_p_dealloc(UNUSEDARG Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */ { memory_list_t *lp; lp = BLOCK_TO_LIST(ptr); /* Remove from a doubly linked, circular list. Read carefully, use a white board if necessary. If this is an empty list, the following statements are no-ops, and will write to the same memory location they read from. This should only happen when we deallocate the dbg structure itself. */ if (lp == lp->next) { /* The list has a single item, itself. */ lp->prev = 0; lp->next = 0; } else if (lp->next == lp->prev) { /* List had exactly two entries. Reduce it to one, cutting lp out. */ memory_list_t * remaining = lp->next; remaining->next = remaining; remaining->prev = remaining; } else { /* Multi=entry. Just cut lp out. */ lp->prev->next = lp->next; lp->next->prev = lp->prev; lp->prev = lp->next = 0; } free((void*)lp); } static void _dwarf_str_hashtab_freenode(void * nodep) { free(nodep); } /* This routine deallocates all the nodes on the dbg list, and then deallocates the dbg structure itself. */ void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg) { memory_list_t *dbglp; memory_list_t *base_dbglp; if (dbg == NULL) { /* should throw an error */ return; } base_dbglp = BLOCK_TO_LIST(dbg); dbglp = base_dbglp->next; while (dbglp != base_dbglp) { memory_list_t*next = dbglp->next; _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp)); dbglp = next; } dwarf_tdestroy(dbg->de_debug_str_hashtab, _dwarf_str_hashtab_freenode); dwarf_tdestroy(dbg->de_debug_line_str_hashtab, _dwarf_str_hashtab_freenode); free((void *)base_dbglp); } libdwarf-20210528/libdwarf/pro_arange.h0000644000175000017500000000330613771416606014567 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* If ag_end_symbol_index is zero, ag_length must be known and non-zero. Deals with length being known constant or from assembler output, not known. */ struct Dwarf_P_Arange_s { Dwarf_Addr ag_begin_address; /* known address or for symbolic assem output, offset of symbol */ Dwarf_Addr ag_length; /* zero or address or offset */ Dwarf_Unsigned ag_symbol_index; Dwarf_P_Arange ag_next; Dwarf_Unsigned ag_end_symbol_index; /* zero or index/id of end symbol */ Dwarf_Addr ag_end_symbol_offset; /* known address or for symbolic assem output, offset of end symbol */ }; libdwarf-20210528/libdwarf/dwarfstring.c0000664000175000017500000005631614004647233015002 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* A lighly generalized data buffer. Works for more than just strings, but has features (such as ensuring data always has a NUL byte following the data area used) most useful for C strings. All these return either TRUE (the values altered) or FALSE (something went wrong, quite likely the caller presented a bad format string for the value). Normally a string like DWARFSTRINGERR is stuck in the output in case of error. */ #include "config.h" #include /* for malloc */ #ifdef HAVE_STDLIB_H #include /* for malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include /* for strlen */ #endif /* HAVE_STRING_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarfstring.h" #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* m must be a string, like "DWARFSTRINGERR..." for this to work */ #define DWSERR(m) dwarfstring_append_length(data,m,sizeof(m)-1) static unsigned long minimumnewlen = 30; /* struct dwarfstring_s { char * s_data; unsigned long s_size; unsigned long s_avail; unsigned char s_malloc; }; */ int dwarfstring_constructor(struct dwarfstring_s *g) { g->s_data = ""; g->s_size = 0; g->s_avail = 0; g->s_malloc = FALSE; return TRUE; } static int dwarfstring_resize_to(struct dwarfstring_s *g,unsigned long newlen) { char *b = 0; unsigned long lastpos = g->s_size - g->s_avail; unsigned long malloclen = newlen+1; if (malloclen < minimumnewlen) { malloclen = minimumnewlen; } b = malloc(malloclen); if (!b) { return FALSE; } if (lastpos > 0) { memcpy(b,g->s_data,lastpos); } if (g->s_malloc) { free(g->s_data); g->s_data = 0; } g->s_data = b; g->s_data[lastpos] = 0; g->s_size = newlen; g->s_avail = newlen - lastpos; g->s_malloc = TRUE; return TRUE; } int dwarfstring_reset(struct dwarfstring_s *g) { if (!g->s_size) { /* In initial condition, nothing to do. */ return TRUE; } g->s_avail = g->s_size; g->s_data[0] = 0; return TRUE; } int dwarfstring_constructor_fixed(struct dwarfstring_s *g, unsigned long len) { int r = FALSE; dwarfstring_constructor(g); if (len == 0) { return TRUE; } r = dwarfstring_resize_to(g,len); if (!r) { return FALSE; } return TRUE; } int dwarfstring_constructor_static(struct dwarfstring_s *g, char * space, unsigned long len) { dwarfstring_constructor(g); g->s_data = space; g->s_data[0] = 0; g->s_size = len; g->s_avail = len; g->s_malloc = FALSE; return TRUE; } void dwarfstring_destructor(struct dwarfstring_s *g) { if (g->s_malloc) { free(g->s_data); g->s_data = 0; g->s_malloc = 0; } dwarfstring_constructor(g); } /* For the case where one wants just the first 'len' characters of 'str'. NUL terminator provided for you in s_data. */ int dwarfstring_append_length(struct dwarfstring_s *g,char *str, unsigned long slen) { unsigned long lastpos = g->s_size - g->s_avail; int r = 0; if (!str || slen ==0) { return TRUE; } if (slen >= g->s_avail) { unsigned long newlen = 0; newlen = g->s_size + slen+2; r = dwarfstring_resize_to(g,newlen); if (!r) { /* Unable to resize, dare not do anything. */ return FALSE; } } memcpy(g->s_data + lastpos,str,slen); g->s_avail -= slen; g->s_data[g->s_size - g->s_avail] = 0; return TRUE; } int dwarfstring_append(struct dwarfstring_s *g,char *str) { unsigned long dlen = 0; if (!str) { return TRUE; } dlen = strlen(str); return dwarfstring_append_length(g,str,dlen); } char * dwarfstring_string(struct dwarfstring_s *g) { return g->s_data; } unsigned long dwarfstring_strlen(struct dwarfstring_s *g) { return g->s_size - g->s_avail; } static int _dwarfstring_append_spaces(dwarfstring *data, size_t count) { int res = 0; char spacebuf[] = {" "}; size_t charct = sizeof(spacebuf)-1; size_t l = count; while (l > charct) { res = dwarfstring_append_length(data,spacebuf,charct); l -= charct; if (res != TRUE) { return res; } } /* ASSERT: l > 0 */ res = dwarfstring_append_length(data,spacebuf,l); return res; } static int _dwarfstring_append_zeros(dwarfstring *data, size_t l) { int res = 0; static char zeros[] = { "0000000000000000000000000000000000000000"}; size_t charct = sizeof(zeros)-1; while (l > charct) { res = dwarfstring_append_length(data,zeros,charct); l -= charct; if (res != TRUE) { return res; } } /* ASSERT: l > 0 */ dwarfstring_append_length(data,zeros,l); return res; } int dwarfstring_append_printf_s(dwarfstring *data, char *format,char *s) { size_t stringlen = 0; size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; /* was %[-]fixedlen. Zero means no len provided. */ size_t fixedlen = 0; /* was %-, nonzero means left-justify */ long leftjustify = 0; size_t prefixlen = 0; int res = 0; if (!s) { DWSERR(""); return FALSE; } stringlen = strlen(s); if (!format) { DWSERR(""); return FALSE; } while (format[next] && format[next] != '%') { ++next; ++prefixlen; } if (prefixlen) { dwarfstring_append_length(data,format,prefixlen); } if (format[next] != '%') { /* No % operator found, we are done */ DWSERR(""); return FALSE; } next++; if (!format[next]) { DWSERR(""); return FALSE; } if (format[next] == ' ') { DWSERR(""); return FALSE; } if (format[next] == '-') { leftjustify++; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); if (format[next] != 's') { DWSERR(""); return FALSE; } next++; if (fixedlen && (stringlen >= fixedlen)) { /* Ignore leftjustify (if any) and the stringlen as the actual string overrides those. */ leftjustify = 0; } if (leftjustify) { dwarfstring_append_length(data,s,stringlen); if (fixedlen) { size_t trailingspaces = fixedlen - stringlen; _dwarfstring_append_spaces(data,trailingspaces); } } else { if (fixedlen && fixedlen < stringlen) { /* This lets us have fixedlen < stringlen by taking all the chars from s*/ dwarfstring_append_length(data,s,stringlen); } else { if (fixedlen) { size_t leadingspaces = fixedlen - stringlen; size_t k = 0; for ( ; k < leadingspaces; ++k) { dwarfstring_append_length(data," ",1); } } dwarfstring_append_length(data,s,stringlen); } } if (!format[next]) { return TRUE; } { char * startpt = format+next; size_t suffixlen = strlen(startpt); res = dwarfstring_append_length(data,startpt,suffixlen); } return res; } static char v32m[] = {"-2147483648"}; static char v64m[] = {"-9223372036854775808"}; static char dtable[10] = { '0','1','2','3','4','5','6','7','8','9' }; static char xtable[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; static char Xtable[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; /* We deal with formats like: %d %5d %05d %+d %+5d %-5d (and ld and lld too). */ int dwarfstring_append_printf_i(dwarfstring *data, char *format, dwarfstring_i v) { int res = TRUE; size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int minuscount = 0; /*left justify */ int pluscount = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = dtable; size_t prefixlen = 0; int done = 0; if (!format) { DWSERR(""); return FALSE; } while (format[next] && format[next] != '%') { ++next; ++prefixlen; } dwarfstring_append_length(data,format,prefixlen); if (format[next] != '%') { /* No % operator found, we are done */ DWSERR(""); return FALSE; } next++; if (!format[next]) { DWSERR(""); return FALSE; } if (format[next] == ' ') { DWSERR(""); return FALSE; } if (format[next] == '-') { minuscount++; next++; } if (format[next] == '+') { pluscount++; next++; } if (format[next] == '-') { minuscount++; next++; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { DWSERR( ""); return FALSE; } if (xcount || Xcount) { /* Use the printf_u for %x and the like just copying the entire format makes it easier for coders to understand nothing much was done */ DWSERR(""); return FALSE; } if (!dcount || (lcount >2) || (Xcount+xcount+dcount+ucount) > 1) { /* error */ DWSERR( ""); return FALSE; } if (pluscount && minuscount) { /* We don't allow format +- */ DWSERR(""); return FALSE; } { char digbuf[36]; char *digptr = digbuf+sizeof(digbuf) -1; size_t digcharlen = 0; dwarfstring_i remaining = v; int vissigned = 0; dwarfstring_i divisor = 10; *digptr = 0; --digptr; if (v < 0) { vissigned = 1; /* This test is for twos-complement machines and would be better done via configure with a compile-time check so we do not need a size test at runtime. */ if (sizeof(v) == 8) { dwarfstring_u vm = 0x7fffffffffffffffULL; if (vm == (dwarfstring_u)~v) { memcpy(digbuf,v64m,sizeof(v64m)); digcharlen = sizeof(v64m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } } else if (sizeof(v) == 4) { dwarfstring_u vm = 0x7fffffffL; if (vm == (dwarfstring_u)~v) { memcpy(digbuf,v32m,sizeof(v32m)); digcharlen = sizeof(v32m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } }else { DWSERR(""); return FALSE; } } if (!done) { for ( ;; ) { dwarfstring_u dig = 0; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; digcharlen++; if (!remaining) { break; } --digptr; } if (vissigned) { /* could check minuscount instead */ --digptr; digcharlen++; *digptr = '-'; } else if (pluscount) { --digptr; digcharlen++; *digptr = '+'; } } if (fixedlen > 0) { if (fixedlen <= digcharlen) { dwarfstring_append_length(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; if (!leadingzero) { _dwarfstring_append_spaces(data,prefixcount); dwarfstring_append_length(data,digptr,digcharlen); } else { if (*digptr == '-') { dwarfstring_append_length(data,"-",1); _dwarfstring_append_zeros(data,prefixcount); digptr++; dwarfstring_append_length(data,digptr, digcharlen-1); } else if (*digptr == '+') { dwarfstring_append_length(data,"+",1); _dwarfstring_append_zeros(data,prefixcount); digptr++; dwarfstring_append_length(data,digptr, digcharlen-1); } else { _dwarfstring_append_zeros(data,prefixcount); dwarfstring_append_length(data,digptr, digcharlen); } } } } else { res = dwarfstring_append_length(data,digptr,digcharlen); } } if (format[next]) { size_t trailinglen = strlen(format+next); res = dwarfstring_append_length(data,format+next,trailinglen); } return res; } #if 0 /* Counts hex chars. divide by two to get bytes from input integer. */ static unsigned trimleadingzeros(char *ptr,unsigned digits,unsigned keepcount) { char *cp = ptr; unsigned leadzeroscount = 0; unsigned trimoff = 0; for (; *cp; ++cp) { if (*cp == '0') { leadzeroscount++; continue; } } trimoff = keepcount - digits; if (trimoff&1) { trimoff--; } return trimoff; } #endif /* 0 */ /* With gcc version 5.4.0 20160609 a version using const char *formatp instead of format[next] and deleting the 'next' variable is a few hundredths of a second slower, repeatably. We deal with formats like: %u %5u %05u (and ld and lld too). %x %5x %05x (and ld and lld too). */ int dwarfstring_append_printf_u(dwarfstring *data, char *format, dwarfstring_u v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = 0; size_t divisor = 0; size_t prefixlen = 0; if (!format) { DWSERR(""); return FALSE; } while (format[next] && format[next] != '%') { ++next; ++prefixlen; } dwarfstring_append_length(data,format,prefixlen); if (format[next] != '%') { /* No % operator found, we are done */ DWSERR(""); return FALSE; } next++; if (!format[next]) { DWSERR(""); return FALSE; } if (format[next] == ' ') { DWSERR(""); return FALSE; } if (format[next] == '-') { DWSERR(""); return FALSE; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { DWSERR(""); return FALSE; } if ( (Xcount +xcount+dcount+ucount) > 1) { DWSERR(""); return FALSE; } if ( (Xcount +xcount+dcount+ucount) == 0) { DWSERR(""); return FALSE; } if (lcount > 2) { DWSERR(""); return FALSE; } if (dcount > 0) { DWSERR(""); return FALSE; } if (ucount) { divisor = 10; ctable = dtable; } else { divisor = 16; if (xcount) { ctable = xtable; } else { ctable = Xtable; } } { char digbuf[36]; char *digptr = 0; unsigned digcharlen = 0; dwarfstring_u remaining = v; if (divisor == 16) { digptr = digbuf+sizeof(digbuf) -1; for ( ;; ) { dwarfstring_u dig; dig = remaining & 0xf; remaining = remaining >> 4; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } else { digptr = digbuf+sizeof(digbuf) -1; *digptr = 0; --digptr; for ( ;; ) { dwarfstring_u dig; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } if (fixedlen <= digcharlen) { dwarfstring_append_length(data,digptr,digcharlen); } else { if (!leadingzero) { size_t justcount = fixedlen - digcharlen; _dwarfstring_append_spaces(data,justcount); dwarfstring_append_length(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; _dwarfstring_append_zeros(data,prefixcount); dwarfstring_append_length(data,digptr,digcharlen); } } } if (format[next]) { size_t trailinglen = strlen(format+next); dwarfstring_append_length(data,format+next,trailinglen); } return FALSE; } libdwarf-20210528/libdwarf/pro_encode_nm.h0000644000175000017500000000264113763272471015263 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Bytes needed to encode a number. Not a tight bound, just a reasonable bound. */ #define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, char *space, int splen); int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, char *space, int splen); libdwarf-20210528/libdwarf/libdwarf.h0000664000175000017500000065106414054270754014255 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct Elf Elf; typedef struct Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; /* Dwarf_Bool as int is wasteful, but for compatibility it must stay as int, not unsigned char. */ typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain location information functions, a frame expression function, and also used with DW_FORM_block<> functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* See libdwarf.h DW_LKIND* */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location description */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW July 2020. */ /* This provides access to data from sections .debug_gnu_pubtypes or .debug_gnu_pubnames. These are not standard DWARF, and can appear with gcc -gdwarf-5 */ struct Dwarf_Gnu_Index_Head_s; typedef struct Dwarf_Gnu_Index_Head_s * Dwarf_Gnu_Index_Head; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_number2; Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression( struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { /* Offset of string attribute data */ Dwarf_Unsigned sa_offset; Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s *Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s *Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ /* Dwarf_Frame Block (not used) */ #define DW_DLA_FRAME_BLOCK 0x17 #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x34 (52) reserved for internal to libdwarf types. */ /* .debug_gnu_typenames/pubnames, 2020 */ #define DW_DLA_GNU_INDEX_HEAD 0x35 #define DW_DLA_RNGLISTS_HEAD 0x36 /* .debug_rnglists DW5 */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ /* struct Dwarf_Str_Offsets_Table_s */ #define DW_DLA_STR_OFFSETS 0x40 /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() 'access' argument values. Used for reading/consuming DWARF, not relevant to the producer portion of libdwarf. None of the following three arguments do anything. The following short set is useless. Only DW_DLC_READ has a documented effect but... it is useless and irrelevant as it means 'do the default'. In the 1990's there was an option DW_DLC_MMAP (deleted from libdwarf.h many years ago). The old option libdwarf told IRIX libelf to mmap the object file. */ #define DW_DLC_READ 0 /* Pointless. Ok to use. */ #define DW_DLC_WRITE 1 /* DO NOT USE */ #define DW_DLC_RDWR 2 /* DO NOT USE */ /* ===== the following DW_DLC options are for producing DWARF, not used for reading/consuming DWARF. */ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so. See the Dwarf_Rel_Type enum relocation indicators. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* old spelling */ #define DW_DLC_POINTER64 0x40000000 /* correct spelling */ /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* old spelling */ #define DW_DLC_POINTER32 0x20000000 /* correct spelling */ /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* DO NOT USE */ /* DW_DLC_OFFSET32 is the default, the bit is not checked. */ #define DW_DLC_OFFSET32 0x00010000 /* default offset size */ /* 64-bit offset-size DWARF offsets */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* old spelling */ #define DW_DLC_OFFSET64 0x10000000 /* correct spelling */ /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* DO NOT USE. */ /* Special for IRIX only. For producing DWARF with Elf 64bit offset headers and non-standard IRIX 64bit offset DWARF .debug_info etc compilation unit headers. */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Old style Elf binary relocation (.rel) records. The default. For producing DWARF */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* ===== END DW_DLC options LIBDWARF */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 #define DW_DLE_ELF_RELOC_SECTION_ERROR 466 #define DW_DLE_USER_DECLARED_ERROR 467 #define DW_DLE_RNGLISTS_ERROR 468 #define DW_DLE_LOCLISTS_ERROR 469 #define DW_DLE_SECTION_SIZE_OR_OFFSET_LARGE 470 #define DW_DLE_GDBINDEX_STRING_ERROR 471 #define DW_DLE_GNU_PUBNAMES_ERROR 472 #define DW_DLE_GNU_PUBTYPES_ERROR 473 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBNAMES 474 #define DW_DLE_DUPLICATE_GNU_DEBUG_PUBTYPES 475 #define DW_DLE_DEBUG_SUP_STRING_ERROR 476 #define DW_DLE_DEBUG_SUP_ERROR 477 #define DW_DLE_LOCATION_ERROR 478 #define DW_DLE_DEBUGLINK_PATH_SHORT 479 #define DW_DLE_SIGNATURE_MISMATCH 480 #define DW_DLE_MACRO_VERSION_ERROR 481 #define DW_DLE_NEGATIVE_SIZE 482 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 482 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the separation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN = 0, DW_FORM_CLASS_ADDRESS = 1, DW_FORM_CLASS_BLOCK = 2, DW_FORM_CLASS_CONSTANT =3, DW_FORM_CLASS_EXPRLOC = 4, DW_FORM_CLASS_FLAG = 5, DW_FORM_CLASS_LINEPTR = 6, DW_FORM_CLASS_LOCLISTPTR=7, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR = 8, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR=9, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE=10, DW_FORM_CLASS_STRING = 11, DW_FORM_CLASS_FRAMEPTR= 12, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR= 13, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR = 14, /* DWARF5 */ DW_FORM_CLASS_LOCLIST = 15, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR=16, /* DWARF5 */ DW_FORM_CLASS_RNGLIST =17, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR=18, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR=19 /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects and Elf SHT_GROUP blocks of DWARF sections. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*==================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur, nor will the GNU_debuglink processing occur. In case GNU debuglink data was followed or MacOS dSYM applies the true_path_out will not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* New October 2020. Following GNU debuglink to the true-path with DWARF if there is appropriate debuglink data available. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. In case GNU debuglink data was followed the true_path_out will not match path. If debuglink missing from the Elf executable or shared-object (ie, it is a normal object!) or unusable by libdwarf or true_path_buffer len is zero or true_path_out_buffer is zero the accepts the path given as the object to report on. Passing dl_path_array and dl_path_array size zero suffices unless one has unusual locations for debuglink objects. If true_path_buffer len is zero or true_path_out_buffer is zero then the Special MacOS processing will not occur either. */ int dwarf_init_path_dl(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned int /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, char ** /* dl_path array */, unsigned int /* dl_path array size */, unsigned char * /* path_source */, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned int /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned int /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned int /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* New 4 February 2021. returns DIE and is_info flag if it finds the referenced DW_UT_split_type or DW_UT_type CU. */ int dwarf_find_die_given_sig8(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*ref*/, Dwarf_Die * /*die_out*/, Dwarf_Bool * /*is_info*/, Dwarf_Error * /*error*/); /* Returns the is_info flag. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New December 2020. Any Dwarf_Die will work. The values returned are about the CU itself, not a DIE. */ int dwarf_cu_header_basics(Dwarf_Die die, Dwarf_Half * /*version*/, Dwarf_Bool * /*is_info*/, Dwarf_Bool * /*is_dwo*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*extension_size*/, Dwarf_Sig8 ** /*signature*/, Dwarf_Off * /*offset_of_length*/, Dwarf_Unsigned * /*total_byte_length*/, Dwarf_Error * /*error*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* Reading a CU DIE with DW_AT_low_pc an indexed value can be problematic as that interacts with DW_AT_addr_base in that DIE. Here is a test readers may find useful */ Dwarf_Bool dwarf_addr_form_is_indexed(int form); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/, Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: debug_gnu_pubnames/typenames access, calling these Gnu_Index as a general reference. */ int dwarf_get_gnu_index_head(Dwarf_Debug /*dbg*/, /* The following arg false to select gnu_pubtypes */ Dwarf_Bool /*for_gdb_pubnames*/ , Dwarf_Gnu_Index_Head * /*index_head_out*/, Dwarf_Unsigned * /*index_block_count_out*/, Dwarf_Error * /*error*/); /* Frees all resources used for the indexes. */ void dwarf_gnu_index_dealloc(Dwarf_Gnu_Index_Head /*head*/); int dwarf_get_gnu_index_block(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*number*/, Dwarf_Unsigned * /*block_length */, Dwarf_Half * /*version */, Dwarf_Unsigned * /*offset_into_debug_info*/, Dwarf_Unsigned * /*size_of_debug_info_area*/, Dwarf_Unsigned * /*count_of_index_entries*/, Dwarf_Error * /*error*/); int dwarf_get_gnu_index_block_entry(Dwarf_Gnu_Index_Head /*head*/, Dwarf_Unsigned /*blocknumber*/, Dwarf_Unsigned /*entrynumber*/, Dwarf_Unsigned * /*offset_in_debug_info*/, const char ** /*name_string*/, unsigned char * /*flagbyte*/, unsigned char * /*staticorglobal*/, unsigned char * /*typeofentry*/, Dwarf_Error * /*error*/); /* END: debug_gnu_pubnames/typenames access, */ /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); #define DW_LKIND_expression 0 /* DWARF2,3,4*/ #define DW_LKIND_loclist 1 /* DWARF 2,3,4 */ #define DW_LKIND_GNU_exp_list 2 /* GNU DWARF4 .dwo extension */ #define DW_LKIND_loclists 5 /* DWARF5 loclists */ #define DW_LKIND_unknown 99 /* DWARF2 kind is 2. DWARF3/4 kind is 3, DWARF5 kind is 5 */ int dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c /*ll_header*/, unsigned int * /*lkind*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Unsigned * /*rawlowpc*/, Dwarf_Unsigned * /*rawhipc*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); /* New June 2020 for DWARF5 (and all earlier). */ int dwarf_get_location_op_value_d(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*rawop1*/, Dwarf_Unsigned * /*rawop2*/, Dwarf_Unsigned * /*rawop3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count( Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data( Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/ Separate-Debug-Files.html If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. Caller frees space returned by debuglink_fullpath_returned. See libdwarf2.1.mm revision 3.13 or later for additional important details. */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*debuglink_path_returned */, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_fullpath_returned free this*/, unsigned int * /*debuglink_path_count_returned */, unsigned int * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned int * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned int * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* Only useful inside dwarfexample/dwdebuglink.c so we can show all that is going on. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* crc32 used for debuglink crc calculation. Caller passes pointer to array of 4 unsigned char provided by the caller and if this returns DW_DLV_OK that is filled in. */ int dwarf_crc32 (Dwarf_Debug /*dbg*/,unsigned char * /*crcbuf*/, Dwarf_Error * /*error*/); /* Public interface to the real crc calculation just in case some find it useful. */ unsigned int dwarf_basic_crc32 (const unsigned char * /*buf*/, unsigned long /*len*/, unsigned int /*init*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Special for dwarfdump. Sets a flag in the dbg. Always returns DW_DLV_OK and (as of March 2020) never touches error */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* jUser-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) DO NOT USE, it cannot deal with recent dwarf or CUs with different address sizes. Use dwarf_get_locdesc_entry_c() instead. */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned /*indx*/, Dwarf_Bool /*filter_outliers*/, Dwarf_Unsigned * /*returned_attr_num*/, Dwarf_Unsigned * /*returned_form*/, Dwarf_Signed * /*returned_implicit_const*/, Dwarf_Off * /*offset*/, Dwarf_Error * /*error*/); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable3* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); /* New December 2020. Sometimes its necessary to know a context total length including macro 5 header */ int dwarf_macro_context_total_length(Dwarf_Macro_Context /*head*/, Dwarf_Unsigned * /*mac_total_len*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned int * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. The last op has 0 as opcode_number,operand_count and operand_array */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file( Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. Use dwarf_check_lineheader_b() (new 14 April 2020) in place of dwarf_check_lineheader(). */ int dwarf_check_lineheader_b(Dwarf_Die /*cu_die*/, int * /*errcount_out*/, Dwarf_Error * /*error*/); void dwarf_check_lineheader(Dwarf_Die /*cu_die*/, int * /*errcount_out*/); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. Completely different than .debug_gnu_pubnames or .debug_gnu_pubtypes sections. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); void dwarf_error_creation(Dwarf_Debug /*dbg*/ , Dwarf_Error * /*error*/, char * /*errmsg*/); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Never Implemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* These convenience functions allow type checking at the call, whereas dwarf_dealloc itself uses void * so ... easy to misuse. */ void dwarf_dealloc_error(Dwarf_Debug /*dbg*/, Dwarf_Error /*err*/); void dwarf_dealloc_die( Dwarf_Die /*die*/); void dwarf_dealloc_attribute(Dwarf_Attribute /*attr*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New July 2020 for testing DWARF5 */ int dwarf_add_debug_sup(Dwarf_P_Debug /*dbg*/, Dwarf_Half /*version*/, Dwarf_Small /*is_supplementary*/, char * /*filename*/, Dwarf_Unsigned /*checksum_len*/, Dwarf_Small * /*checksum*/, Dwarf_Error * /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb( Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* Adds return of the final offset to accommodate DWARF4 GNU split-dwarf. Other than for split-dwarf the realoffset will be set by the function to be the same as rangesoffset. New September 10, 2020. */ int dwarf_get_ranges_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /*diepointer */, Dwarf_Off * /*realoffset */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New July 2020 for DWARF5 */ int dwarf_get_debug_sup(Dwarf_Debug /*dbg*/, Dwarf_Half * /*version*/, Dwarf_Small * /*is_supplementary*/, char ** /*filename*/, Dwarf_Unsigned * /*checksum_len*/, Dwarf_Small ** /*checksum*/, Dwarf_Error * /*error*/); /* ======= START .debug_rnglists interfaces. New May 2020 */ struct Dwarf_Rnglists_Entry_s; typedef struct Dwarf_Rnglists_Entry_s * Dwarf_Rnglists_Entry; struct Dwarf_Rnglists_Head_s; typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; /* For DWARF5 DW_AT_ranges: DW_FORM_sec_offset DW_FORM_rnglistx */ int dwarf_rnglists_get_rle_head(Dwarf_Attribute /*attr*/, Dwarf_Half /*theform*/, Dwarf_Unsigned /*index_or_offset_value*/, Dwarf_Rnglists_Head * /*head_out*/, Dwarf_Unsigned * /*count_of_entries_in_head*/, Dwarf_Unsigned * /*global_offset_of_rle_set*/, Dwarf_Error * /*error*/); /* Get the rnglist entries details */ int dwarf_get_rnglists_entry_fields_a( Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned * /*entrylen*/, unsigned * /*rle_value_out*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Bool * /*debug_addr_unavailable*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*err*/); /* The following is not complete. DO NOT USE. Use dwarf_get_rnglists_entry_fields_a() instead. */ int dwarf_get_rnglists_entry_fields(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); int dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head ); /* Loads all the rnglists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of rnglists headers in the section through rnglists_count. */ int dwarf_load_rnglists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*rnglists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th rangelists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_rnglists section offset of the range list. */ int dwarf_get_rnglist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_rnglists_index_get_rle_head() or dwarf_rnglists_offset_get_rle_head. */ int dwarf_get_rnglist_head_basics(Dwarf_Rnglists_Head /*head*/, Dwarf_Unsigned * /*rle_count*/, Dwarf_Unsigned * /*rnglists_version*/, Dwarf_Unsigned * /*rnglists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*rnglists_base_present*/, Dwarf_Unsigned * /*rnglists_base*/, Dwarf_Bool * /*rnglists_base_address_present*/, Dwarf_Unsigned * /*rnglists_base_address*/, Dwarf_Bool * /*rnglists_debug_addr_base_present*/, Dwarf_Unsigned * /*rnglists_debug_addr_base*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_rnglists section may contain any number of Range List Table Headers with their details. */ int dwarf_get_rnglist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_rangeentry*/, Dwarf_Unsigned * /*offset_past_last_rangeentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_rangeentry. Stop when the returned *next_entry_offset is == offset_past_last_rangentry (from dwarf_get_rnglist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single rnglist header, meaning a a single Dwarf_Rnglists_Context. This interface assumes there is no segment selector. */ int dwarf_get_rnglist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_rnglist_rle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Error * /*err*/); /* ======= END .debug_rnglists interfaces. */ /* ======= START .debug_loclists interfaces. New May 2020 */ /* These interfaces allow reading the .debug_loclists section. Normal use of .debug_loclists uses dwarf_get_loclist_c() to open access to any kind of location or loclist and uses dwarf_loc_head_c_dealloc() to deallocate that memory once one is finished with that data. So for most purposes you do not need to use these functions */ struct Dwarf_Loclists_Entry_s; typedef struct Dwarf_Loclists_Entry_s * Dwarf_Loclists_Entry; /* See dwarf_get_loclist_c() to open a Dwarf_Loc_Head_c on any type of location list or expression. */ /* Get the loclists entries details */ int dwarf_get_loclists_entry_fields(Dwarf_Loc_Head_c /*head*/, Dwarf_Unsigned /*entrynum*/, unsigned int * /*entrylen*/, unsigned int * /*code*/, Dwarf_Unsigned * /*raw1*/, Dwarf_Unsigned * /*raw2*/, Dwarf_Unsigned * /*cooked1*/, Dwarf_Unsigned * /*cooked2*/, Dwarf_Error * /*error*/); /* Loads all the loclists headers and returns DW_DLV_NO_ENTRY if the section is missing or empty. Intended to be done quite early and it is automatically done if .debug_info is loaded. Doing it more than once is never necessary or harmful. There is no deallocation call made visible, deallocation happens when dwarf_finish() is called. With DW_DLV_OK it returns the number of loclists headers in the section through loclists_count. */ int dwarf_load_loclists(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*loclists_count*/, Dwarf_Error * /*err*/); /* Retrieve the offset from the context-index'th loclists context and the offsetentry_index element of the array of offsets. If an index is too large to be correct this returns DW_DLV_NO_ENTRY. If all is correct it returns DW_DLV_OK and sets *offset_value_out to the offset of the range list from the base of the offset array, and *global_offset_value_out is set to the .debug_loclists section offset of the range list. */ int dwarf_get_loclist_offset_index_value(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*context_index*/, Dwarf_Unsigned /*offsetentry_index*/, Dwarf_Unsigned * /*offset_value_out*/, Dwarf_Unsigned * /*global_offset_value_out*/, Dwarf_Error * /*error*/); /* Used by dwarfdump to print basic data from the data generated to look at a specific rangelist as returned by dwarf_loclists_index_get_lle_head() or dwarf_loclists_offset_get_lle_head. */ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c /*head*/, Dwarf_Small * /*lkind*/, Dwarf_Unsigned * /*lle_count*/, Dwarf_Unsigned * /*loclists_version*/, Dwarf_Unsigned * /*loclists_index_returned*/, Dwarf_Unsigned * /*bytes_total_in_rle*/, Dwarf_Half * /*offset_size*/, Dwarf_Half * /*address_size*/, Dwarf_Half * /*segment_selector_size*/, Dwarf_Unsigned * /*overall offset_of_this_context*/, Dwarf_Unsigned * /*total_length of this context*/, Dwarf_Unsigned * /*offset_table_offset*/, Dwarf_Unsigned * /*offset_table_entrycount*/, Dwarf_Bool * /*loclists_base_present*/, Dwarf_Unsigned * /*loclists_base*/, Dwarf_Bool * /*loclists_base_address_present*/, Dwarf_Unsigned * /*loclists_base_address*/, Dwarf_Bool * /*loclists_debug_addr_base_present*/, Dwarf_Unsigned * /*loclists_debug_addr_base*/, Dwarf_Unsigned * /*offset_this_lle_area*/, Dwarf_Error * /*error*/); /* Enables printing of details about the Range List Table Headers, one header per call. Index starting at 0. Returns DW_DLV_NO_ENTRY if index is too high for the table. A .debug_loclists section may contain any number of Location List Table Headers with their details. */ int dwarf_get_loclist_context_basics(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*index*/, Dwarf_Unsigned * /*header_offset*/, Dwarf_Small * /*offset_size*/, Dwarf_Small * /*extension_size*/, unsigned int * /*version*/, /* 5 */ Dwarf_Small * /*address_size*/, Dwarf_Small * /*segment_selector_size*/, Dwarf_Unsigned * /*offset_entry_count*/, Dwarf_Unsigned * /*offset_of_offset_array*/, Dwarf_Unsigned * /*offset_of_first_locentry*/, Dwarf_Unsigned * /*offset_past_last_locentry*/, Dwarf_Error * /*err*/); /* entry offset is offset_of_first_locentry. Stop when the returned *next_entry_offset is == offset_past_last_locentry (from dwarf_get_loclist_context_plus). This only makes sense within those ranges. This retrieves raw detail from the section, no base values or anything are added. So this returns raw individual entries for a single loclist header, meaning a a single Dwarf_Loclists_Context. This interface assumes there is no segment selector. */ int dwarf_get_loclist_raw_entry_detail(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*next_entry_offset*/, Dwarf_Error * /*err*/); /* If no error, returns DW_DLV_OK and sets the entry length,kind, and operands through the pointers. If any missing operands assign zero back through tye operand pointers. */ int dwarf_get_loclist_lle( Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*contextnumber*/, Dwarf_Unsigned /*entry_offset*/, Dwarf_Unsigned /*endoffset*/, unsigned int * /*entrylen*/, unsigned int * /*entry_kind*/, Dwarf_Unsigned * /*entry_operand1*/, Dwarf_Unsigned * /*entry_operand2*/, Dwarf_Unsigned * /*expr_ops_blocksize*/, Dwarf_Unsigned * /*expr_ops_offset*/, Dwarf_Small ** /*expr_opsdata*/, Dwarf_Error * /*err*/); /* ======= END .debug_loclists interfaces. */ /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned int /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned int * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned int dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned int /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIKIND_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIVIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is for a GNU extension. Not defined by the GNU folks nor a DWARF standard but it seemed essential. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ extern int dwarf_get_FORM_CLASS_name(enum Dwarf_Form_Class /*fc*/, const char ** /*s_out*/); /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* New May 2017. So users can find out what groups (dwo or COMDAT) are in the object and how much to allocate so one can get the group-section map data. */ int dwarf_sec_group_sizes(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' values and this function fills in the array entries. Output ordered by group number and section number. */ int dwarf_sec_group_map(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/)) (void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Same for LEB decoding routines. caller sets endptr to an address one past the last valid address the library should be allowed to access. */ int dwarf_decode_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Unsigned * /*outval*/, char * /*endptr*/); int dwarf_decode_signed_leb128(char * /*leb*/, Dwarf_Unsigned * /*leblen*/, Dwarf_Signed * /*outval*/, char * /*endptr*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ /* Defined March 7 2020. Allows a caller to avoid most tracking by the de_alloc_tree hash table if called with v of zero. Returns the value the flag was before this call. */ int dwarf_set_de_alloc_flag(int v); /* Solely looks for debuglink */ int dwarf_object_detector_path(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); /* Solely looks for debuglink */ int dwarf_object_detector_path_b(const char * /*path*/, char * /*outpath_buffer*/, unsigned long /*outpathlen*/, char ** /* gl_pathnames*/, unsigned /* gl_pathcount*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, unsigned char * /*pathsource*/, int * /*errcode*/); /* Solely looks for dSYM */ int dwarf_object_detector_path_dSYM( const char *path, char *outpath, unsigned long outpath_len, char ** gl_pathnames, unsigned gl_pathcount, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, unsigned char *pathsource, int *errcode); #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 #define DW_PATHSOURCE_dsym 2 /* MacOS dSYM */ #define DW_PATHSOURCE_debuglink 3 /* GNU debuglink */ /* Returns the pathsource value set up at init time*/ int dwarf_get_path_source_type(Dwarf_Debug /* dbg*/, unsigned char * /*path_source*/, Dwarf_Error * /*error*/); int dwarf_object_detector_fd(int /*fd*/, unsigned int * /*ftype*/, unsigned int * /*endian*/, unsigned int * /*offsetsize*/, Dwarf_Unsigned * /*filesize*/, int * /*errcode*/); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ libdwarf-20210528/libdwarf/Makefile.in0000664000175000017500000055266114054252021014345 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = test_dwarfstring$(EXEEXT) \ test_extra_flag_strings$(EXEEXT) test_linkedtopath$(EXEEXT) \ test_headersok$(EXEEXT) subdir = libdwarf ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdwarfdevdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libdwarf_la_DEPENDENCIES = am_libdwarf_la_OBJECTS = libdwarf_la-dwarf_abbrev.lo \ libdwarf_la-dwarf_alloc.lo libdwarf_la-dwarf_arange.lo \ libdwarf_la-dwarf_crc32.lo libdwarf_la-dwarf_debuglink.lo \ libdwarf_la-dwarf_die_deliv.lo \ libdwarf_la-dwarf_debug_names.lo \ libdwarf_la-dwarf_debug_sup.lo libdwarf_la-dwarf_dsc.lo \ libdwarf_la-dwarf_elf_access.lo \ libdwarf_la-dwarf_elf_load_headers.lo \ libdwarf_la-dwarf_elfread.lo \ libdwarf_la-dwarf_elf_rel_detector.lo \ libdwarf_la-dwarf_error.lo libdwarf_la-dwarf_find_sigref.lo \ libdwarf_la-dwarf_fission_to_cu.lo libdwarf_la-dwarf_form.lo \ libdwarf_la-dwarf_form_class_names.lo \ libdwarf_la-dwarf_frame.lo libdwarf_la-dwarf_frame2.lo \ libdwarf_la-dwarf_funcs.lo libdwarf_la-dwarf_gdbindex.lo \ libdwarf_la-dwarf_generic_init.lo libdwarf_la-dwarf_global.lo \ libdwarf_la-dwarf_gnu_index.lo libdwarf_la-dwarf_groups.lo \ libdwarf_la-dwarf_harmless.lo libdwarf_la-dwarf_init_finish.lo \ libdwarf_la-dwarf_leb.lo libdwarf_la-dwarf_line.lo \ libdwarf_la-dwarf_loc.lo libdwarf_la-dwarf_locationop_read.lo \ libdwarf_la-dwarf_loclists.lo libdwarf_la-dwarf_machoread.lo \ libdwarf_la-dwarf_macro.lo libdwarf_la-dwarf_macro5.lo \ libdwarf_la-dwarf_names.lo \ libdwarf_la-dwarf_object_detector.lo \ libdwarf_la-dwarf_object_read_common.lo \ libdwarf_la-dwarf_original_elf_init.lo \ libdwarf_la-dwarf_peread.lo libdwarf_la-dwarf_print_lines.lo \ libdwarf_la-dwarf_pubtypes.lo libdwarf_la-dwarf_query.lo \ libdwarf_la-dwarf_ranges.lo libdwarf_la-dwarf_rnglists.lo \ libdwarf_la-dwarf_str_offsets.lo libdwarf_la-dwarfstring.lo \ libdwarf_la-dwarf_stringsection.lo libdwarf_la-dwarf_tied.lo \ libdwarf_la-dwarf_tsearchhash.lo libdwarf_la-dwarf_types.lo \ libdwarf_la-dwarf_util.lo libdwarf_la-dwarf_vars.lo \ libdwarf_la-dwarf_weaks.lo libdwarf_la-dwarf_xu_index.lo \ libdwarf_la-crc32.lo libdwarf_la-malloc_check.lo \ libdwarf_la-pro_alloc.lo libdwarf_la-pro_arange.lo \ libdwarf_la-pro_debug_sup.lo libdwarf_la-pro_die.lo \ libdwarf_la-pro_dnames.lo libdwarf_la-pro_encode_nm.lo \ libdwarf_la-pro_error.lo libdwarf_la-pro_expr.lo \ libdwarf_la-pro_finish.lo libdwarf_la-pro_forms.lo \ libdwarf_la-pro_frame.lo libdwarf_la-pro_funcs.lo \ libdwarf_la-pro_init.lo libdwarf_la-pro_line.lo \ libdwarf_la-pro_log_extra_flag_strings.lo \ libdwarf_la-pro_macinfo.lo libdwarf_la-pro_pubnames.lo \ libdwarf_la-pro_reloc.lo libdwarf_la-pro_reloc_stream.lo \ libdwarf_la-pro_reloc_symbolic.lo libdwarf_la-pro_section.lo \ libdwarf_la-pro_types.lo libdwarf_la-pro_vars.lo \ libdwarf_la-pro_weaks.lo libdwarf_la_OBJECTS = $(am_libdwarf_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libdwarf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libdwarf_la_CFLAGS) \ $(CFLAGS) $(libdwarf_la_LDFLAGS) $(LDFLAGS) -o $@ am_test_dwarfstring_OBJECTS = \ test_dwarfstring-test_dwarfstring.$(OBJEXT) \ test_dwarfstring-dwarfstring.$(OBJEXT) test_dwarfstring_OBJECTS = $(am_test_dwarfstring_OBJECTS) test_dwarfstring_LDADD = $(LDADD) test_dwarfstring_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_dwarfstring_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am_test_extra_flag_strings_OBJECTS = \ test_extra_flag_strings-test_extra_flag_strings.$(OBJEXT) \ test_extra_flag_strings-pro_log_extra_flag_strings.$(OBJEXT) \ test_extra_flag_strings-dwarfstring.$(OBJEXT) test_extra_flag_strings_OBJECTS = \ $(am_test_extra_flag_strings_OBJECTS) test_extra_flag_strings_LDADD = $(LDADD) test_extra_flag_strings_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_extra_flag_strings_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_test_headersok_OBJECTS = test_headersok-test_headersok.$(OBJEXT) test_headersok_OBJECTS = $(am_test_headersok_OBJECTS) test_headersok_LDADD = $(LDADD) test_headersok_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_headersok_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am_test_linkedtopath_OBJECTS = \ test_linkedtopath-test_linkedtopath.$(OBJEXT) \ test_linkedtopath-dwarfstring.$(OBJEXT) \ test_linkedtopath-dwarf_debuglink.$(OBJEXT) test_linkedtopath_OBJECTS = $(am_test_linkedtopath_OBJECTS) test_linkedtopath_LDADD = $(LDADD) test_linkedtopath_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_linkedtopath_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libdwarf_la-crc32.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_alloc.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_arange.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_crc32.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_debug_names.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_debug_sup.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_dsc.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_elfread.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_error.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_find_sigref.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_form.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_form_class_names.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_frame.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_frame2.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_funcs.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_global.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_gnu_index.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_groups.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_harmless.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_leb.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_line.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_loc.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_locationop_read.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_loclists.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_machoread.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_macro.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_macro5.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_names.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_peread.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_query.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_ranges.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_rnglists.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_tied.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_types.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_util.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_vars.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_weaks.Plo \ ./$(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo \ ./$(DEPDIR)/libdwarf_la-dwarfstring.Plo \ ./$(DEPDIR)/libdwarf_la-malloc_check.Plo \ ./$(DEPDIR)/libdwarf_la-pro_alloc.Plo \ ./$(DEPDIR)/libdwarf_la-pro_arange.Plo \ ./$(DEPDIR)/libdwarf_la-pro_debug_sup.Plo \ ./$(DEPDIR)/libdwarf_la-pro_die.Plo \ ./$(DEPDIR)/libdwarf_la-pro_dnames.Plo \ ./$(DEPDIR)/libdwarf_la-pro_encode_nm.Plo \ ./$(DEPDIR)/libdwarf_la-pro_error.Plo \ ./$(DEPDIR)/libdwarf_la-pro_expr.Plo \ ./$(DEPDIR)/libdwarf_la-pro_finish.Plo \ ./$(DEPDIR)/libdwarf_la-pro_forms.Plo \ ./$(DEPDIR)/libdwarf_la-pro_frame.Plo \ ./$(DEPDIR)/libdwarf_la-pro_funcs.Plo \ ./$(DEPDIR)/libdwarf_la-pro_init.Plo \ ./$(DEPDIR)/libdwarf_la-pro_line.Plo \ ./$(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo \ ./$(DEPDIR)/libdwarf_la-pro_macinfo.Plo \ ./$(DEPDIR)/libdwarf_la-pro_pubnames.Plo \ ./$(DEPDIR)/libdwarf_la-pro_reloc.Plo \ ./$(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo \ ./$(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo \ ./$(DEPDIR)/libdwarf_la-pro_section.Plo \ ./$(DEPDIR)/libdwarf_la-pro_types.Plo \ ./$(DEPDIR)/libdwarf_la-pro_vars.Plo \ ./$(DEPDIR)/libdwarf_la-pro_weaks.Plo \ ./$(DEPDIR)/test_dwarfstring-dwarfstring.Po \ ./$(DEPDIR)/test_dwarfstring-test_dwarfstring.Po \ ./$(DEPDIR)/test_extra_flag_strings-dwarfstring.Po \ ./$(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po \ ./$(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po \ ./$(DEPDIR)/test_headersok-test_headersok.Po \ ./$(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po \ ./$(DEPDIR)/test_linkedtopath-dwarfstring.Po \ ./$(DEPDIR)/test_linkedtopath-test_linkedtopath.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdwarf_la_SOURCES) $(test_dwarfstring_SOURCES) \ $(test_extra_flag_strings_SOURCES) $(test_headersok_SOURCES) \ $(test_linkedtopath_SOURCES) DIST_SOURCES = $(libdwarf_la_SOURCES) $(test_dwarfstring_SOURCES) \ $(test_extra_flag_strings_SOURCES) $(test_headersok_SOURCES) \ $(test_linkedtopath_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(libdwarfdev_DATA) HEADERS = $(include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver COPYING ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_BIGENDIAN = @DWARF_BIGENDIAN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in ### libdwarf lib_LTLIBRARIES = libdwarf.la libdwarf_la_SOURCES = \ dwarf.h \ dwarf_abbrev.c \ dwarf_abbrev.h \ dwarf_alloc.c \ dwarf_alloc.h \ dwarf_arange.c \ dwarf_arange.h \ dwarf_base_types.h \ dwarf_crc32.c \ dwarf_debuglink.c \ dwarf_debuglink.h \ dwarf_die_deliv.c \ dwarf_die_deliv.h \ dwarf_debug_names.c \ dwarf_debug_names.h \ dwarf_debug_sup.c \ dwarf_dsc.c \ dwarf_dsc.h \ dwarf_elf_access.c \ dwarf_elf_access.h \ dwarf_elf_defines.h \ dwarf_elf_load_headers.c \ dwarf_elfread.c \ dwarf_elfread.h \ dwarf_elf_rel_detector.c \ dwarf_elf_rel_detector.h \ dwarf_elf_reloc_386.h \ dwarf_elf_reloc_aarch64.h \ dwarf_elf_reloc_arm.h \ dwarf_elf_reloc_mips.h \ dwarf_elf_reloc_ppc64.h \ dwarf_elf_reloc_ppc.h \ dwarf_elf_reloc_sparc.h \ dwarf_elf_reloc_x86_64.h \ dwarf_elfstructs.h \ dwarf_errmsg_list.h \ dwarf_error.c \ dwarf_error.h \ dwarf_find_sigref.c \ dwarf_fission_to_cu.c \ dwarf_form.c \ dwarf_form_class_names.c \ dwarf_frame.c \ dwarf_frame.h \ dwarf_frame2.c \ dwarf_funcs.c \ dwarf_funcs.h \ dwarf_gdbindex.c \ dwarf_gdbindex.h \ dwarf_generic_init.c \ dwarf_global.c \ dwarf_global.h \ dwarf_gnu_index.h \ dwarf_gnu_index.c \ dwarf_groups.c \ dwarf_harmless.c \ dwarf_harmless.h \ dwarf_incl.h \ dwarf_init_finish.c \ dwarf_leb.c \ dwarf_line.c \ dwarf_line.h \ dwarf_line_table_reader_common.h \ dwarf_loc.c \ dwarf_loc.h \ dwarf_locationop_read.c \ dwarf_loclists.c \ dwarf_macho_loader.h \ dwarf_machoread.c \ dwarf_machoread.h \ dwarf_macro.c \ dwarf_macro.h \ dwarf_macro5.c \ dwarf_macro5.h \ dwarf_names.c \ dwarf_names.h \ dwarf_object_detector.c \ dwarf_object_detector.h \ dwarf_object_read_common.c \ dwarf_object_read_common.h \ dwarf_opaque.h \ dwarf_original_elf_init.c \ dwarf_pe_descr.h \ dwarf_peread.c \ dwarf_peread.h \ dwarf_print_lines.c \ dwarf_pubtypes.c \ dwarf_query.c \ dwarf_ranges.c \ dwarf_rnglists.c \ dwarf_rnglists.h \ dwarf_reading.h \ dwarf_reloc_386.h \ dwarf_reloc_arm.h \ dwarf_reloc_mips.h \ dwarf_reloc_ppc.h \ dwarf_reloc_ppc64.h \ dwarf_reloc_x86_64.h \ dwarf_str_offsets.c \ dwarf_str_offsets.h \ dwarfstring.c \ dwarfstring.h \ dwarf_stringsection.c \ dwarf_tied.c \ dwarf_tied_decls.h \ dwarf_tsearchhash.c \ dwarf_tsearch.h \ dwarf_types.c \ dwarf_types.h \ dwarf_util.c \ dwarf_util.h \ dwarf_vars.c \ dwarf_vars.h \ dwarf_weaks.c \ dwarf_weaks.h \ dwarf_xu_index.c \ dwarf_xu_index.h \ crc32.c \ libdwarf.h \ libdwarf_version.h \ libdwarfdefs.h \ malloc_check.c \ malloc_check.h \ memcpy_swap.h \ pro_alloc.c \ pro_alloc.h \ pro_arange.c \ pro_arange.h \ pro_debug_sup.c \ pro_die.c \ pro_die.h \ pro_dnames.h \ pro_dnames.c \ pro_encode_nm.c \ pro_encode_nm.h \ pro_error.c \ pro_error.h \ pro_expr.c \ pro_expr.h \ pro_finish.c \ pro_forms.c \ pro_frame.c \ pro_frame.h \ pro_funcs.c \ pro_incl.h \ pro_init.c \ pro_line.c \ pro_line.h \ pro_log_extra_flag_strings.c \ pro_macinfo.c \ pro_macinfo.h \ pro_opaque.h \ pro_pubnames.c \ pro_reloc.c \ pro_reloc.h \ pro_reloc_stream.c \ pro_reloc_stream.h \ pro_reloc_symbolic.c \ pro_reloc_symbolic.h \ pro_section.c \ pro_section.h \ pro_types.c \ pro_types.h \ pro_util.h \ pro_vars.c \ pro_weaks.c libdwarf_la_CFLAGS = $(DWARF_CFLAGS_WARN) libdwarf_la_LIBADD = @DWARF_LIBS@ libdwarf_la_LDFLAGS = -fPIC -no-undefined -version-info @version_info@ @release_info@ TESTS = $(check_PROGRAMS) $(check_TESTS) AM_TESTS_ENVIRONMENT = DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR; include_HEADERS = $(top_srcdir)/libdwarf/dwarf.h libdwarf.h libdwarfdevdir = $(datadir)/libdwarf/libdwarf-devel libdwarfdev_DATA = \ libdwarf2.1.pdf \ libdwarf2p.1.pdf test_dwarfstring_SOURCES = test_dwarfstring.c \ dwarfstring.h dwarfstring.c test_dwarfstring_CFLAGS = $(CFLAGS_WARN) test_dwarfstring_CPPFLAGS = \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src test_extra_flag_strings_SOURCES = test_extra_flag_strings.c \ pro_log_extra_flag_strings.c \ dwarfstring.h dwarfstring.c test_extra_flag_strings_CFLAGS = $(CFLAGS_WARN) test_extra_flag_strings_CPPFLAGS = -DTESTING \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src test_linkedtopath_SOURCES = test_linkedtopath.c \ dwarfstring.h dwarfstring.c \ dwarf_debuglink.h dwarf_debuglink.c \ dwarf_error.h test_linkedtopath_CFLAGS = $(RO_CFLAGS_WARN) -DTESTING test_linkedtopath_CPPFLAGS = -DTESTING \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src # Just ensures the headers usable, no C source errors. test_headersok_SOURCES = test_headersok.c \ dwarf_reloc_386.h dwarf_reloc_mips.h \ dwarf_reloc_ppc.h dwarf_reloc_arm.h \ dwarf_reloc_ppc64.h dwarf_reloc_x86_64.h test_headersok_CFLAGS = $(RO_CFLAGS_WARN) test_headersok_CPPFLAGS = -DTESTING \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src check_TESTS = testdebuglink.sh runtests.sh EXTRA_DIST = \ COPYING \ LGPL.txt \ LIBDWARFCOPYRIGHT \ CHANGES \ ChangeLog \ ChangeLog2006 \ ChangeLog2007 \ ChangeLog2008 \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CODINGSTYLE \ baseline.ltp \ dwarf_leb_test.c \ dwarf_tied_test.c \ dwarf_names_new.h \ dwarf_names_enum.h \ gennames.c \ dwarf_test_errmsg_list.c \ libdwarf2.1.mm \ libdwarf2p.1.mm \ mips_extensions.mm \ mips_extensions.pdf \ dwgetopt.h \ dwgetopt.c \ CMakeLists.txt \ cmake/libdwarf-config.cmake \ libdwarf.h.in \ testdebuglink.sh \ generated_libdwarf.h.in \ pdfbld.sh \ NEWS \ README \ CODINGSTYLE \ $(libdwarf_DATA) \ $(libdwarfdev_DATA) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libdwarf/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libdwarf/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdwarf.la: $(libdwarf_la_OBJECTS) $(libdwarf_la_DEPENDENCIES) $(EXTRA_libdwarf_la_DEPENDENCIES) $(AM_V_CCLD)$(libdwarf_la_LINK) -rpath $(libdir) $(libdwarf_la_OBJECTS) $(libdwarf_la_LIBADD) $(LIBS) test_dwarfstring$(EXEEXT): $(test_dwarfstring_OBJECTS) $(test_dwarfstring_DEPENDENCIES) $(EXTRA_test_dwarfstring_DEPENDENCIES) @rm -f test_dwarfstring$(EXEEXT) $(AM_V_CCLD)$(test_dwarfstring_LINK) $(test_dwarfstring_OBJECTS) $(test_dwarfstring_LDADD) $(LIBS) test_extra_flag_strings$(EXEEXT): $(test_extra_flag_strings_OBJECTS) $(test_extra_flag_strings_DEPENDENCIES) $(EXTRA_test_extra_flag_strings_DEPENDENCIES) @rm -f test_extra_flag_strings$(EXEEXT) $(AM_V_CCLD)$(test_extra_flag_strings_LINK) $(test_extra_flag_strings_OBJECTS) $(test_extra_flag_strings_LDADD) $(LIBS) test_headersok$(EXEEXT): $(test_headersok_OBJECTS) $(test_headersok_DEPENDENCIES) $(EXTRA_test_headersok_DEPENDENCIES) @rm -f test_headersok$(EXEEXT) $(AM_V_CCLD)$(test_headersok_LINK) $(test_headersok_OBJECTS) $(test_headersok_LDADD) $(LIBS) test_linkedtopath$(EXEEXT): $(test_linkedtopath_OBJECTS) $(test_linkedtopath_DEPENDENCIES) $(EXTRA_test_linkedtopath_DEPENDENCIES) @rm -f test_linkedtopath$(EXEEXT) $(AM_V_CCLD)$(test_linkedtopath_LINK) $(test_linkedtopath_OBJECTS) $(test_linkedtopath_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-crc32.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_alloc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_arange.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_crc32.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_debug_names.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_debug_sup.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_dsc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elfread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_find_sigref.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_form.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_form_class_names.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_frame.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_frame2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_funcs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_global.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_gnu_index.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_groups.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_harmless.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_leb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_line.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_loc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_locationop_read.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_loclists.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_machoread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_macro.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_macro5.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_names.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_peread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_query.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_ranges.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_rnglists.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_tied.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_vars.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_weaks.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarfstring.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-malloc_check.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_alloc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_arange.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_debug_sup.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_die.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_dnames.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_encode_nm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_expr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_finish.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_forms.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_frame.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_funcs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_line.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_macinfo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_pubnames.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_section.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_vars.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_weaks.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dwarfstring-dwarfstring.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dwarfstring-test_dwarfstring.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-dwarfstring.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_headersok-test_headersok.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-dwarfstring.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-test_linkedtopath.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libdwarf_la-dwarf_abbrev.lo: dwarf_abbrev.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_abbrev.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_abbrev.Tpo -c -o libdwarf_la-dwarf_abbrev.lo `test -f 'dwarf_abbrev.c' || echo '$(srcdir)/'`dwarf_abbrev.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_abbrev.Tpo $(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_abbrev.c' object='libdwarf_la-dwarf_abbrev.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_abbrev.lo `test -f 'dwarf_abbrev.c' || echo '$(srcdir)/'`dwarf_abbrev.c libdwarf_la-dwarf_alloc.lo: dwarf_alloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_alloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_alloc.Tpo -c -o libdwarf_la-dwarf_alloc.lo `test -f 'dwarf_alloc.c' || echo '$(srcdir)/'`dwarf_alloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_alloc.Tpo $(DEPDIR)/libdwarf_la-dwarf_alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_alloc.c' object='libdwarf_la-dwarf_alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_alloc.lo `test -f 'dwarf_alloc.c' || echo '$(srcdir)/'`dwarf_alloc.c libdwarf_la-dwarf_arange.lo: dwarf_arange.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_arange.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_arange.Tpo -c -o libdwarf_la-dwarf_arange.lo `test -f 'dwarf_arange.c' || echo '$(srcdir)/'`dwarf_arange.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_arange.Tpo $(DEPDIR)/libdwarf_la-dwarf_arange.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_arange.c' object='libdwarf_la-dwarf_arange.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_arange.lo `test -f 'dwarf_arange.c' || echo '$(srcdir)/'`dwarf_arange.c libdwarf_la-dwarf_crc32.lo: dwarf_crc32.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_crc32.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_crc32.Tpo -c -o libdwarf_la-dwarf_crc32.lo `test -f 'dwarf_crc32.c' || echo '$(srcdir)/'`dwarf_crc32.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_crc32.Tpo $(DEPDIR)/libdwarf_la-dwarf_crc32.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_crc32.c' object='libdwarf_la-dwarf_crc32.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_crc32.lo `test -f 'dwarf_crc32.c' || echo '$(srcdir)/'`dwarf_crc32.c libdwarf_la-dwarf_debuglink.lo: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_debuglink.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_debuglink.Tpo -c -o libdwarf_la-dwarf_debuglink.lo `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_debuglink.Tpo $(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='libdwarf_la-dwarf_debuglink.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_debuglink.lo `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c libdwarf_la-dwarf_die_deliv.lo: dwarf_die_deliv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_die_deliv.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Tpo -c -o libdwarf_la-dwarf_die_deliv.lo `test -f 'dwarf_die_deliv.c' || echo '$(srcdir)/'`dwarf_die_deliv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Tpo $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_die_deliv.c' object='libdwarf_la-dwarf_die_deliv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_die_deliv.lo `test -f 'dwarf_die_deliv.c' || echo '$(srcdir)/'`dwarf_die_deliv.c libdwarf_la-dwarf_debug_names.lo: dwarf_debug_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_debug_names.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_debug_names.Tpo -c -o libdwarf_la-dwarf_debug_names.lo `test -f 'dwarf_debug_names.c' || echo '$(srcdir)/'`dwarf_debug_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_debug_names.Tpo $(DEPDIR)/libdwarf_la-dwarf_debug_names.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debug_names.c' object='libdwarf_la-dwarf_debug_names.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_debug_names.lo `test -f 'dwarf_debug_names.c' || echo '$(srcdir)/'`dwarf_debug_names.c libdwarf_la-dwarf_debug_sup.lo: dwarf_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_debug_sup.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_debug_sup.Tpo -c -o libdwarf_la-dwarf_debug_sup.lo `test -f 'dwarf_debug_sup.c' || echo '$(srcdir)/'`dwarf_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_debug_sup.Tpo $(DEPDIR)/libdwarf_la-dwarf_debug_sup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debug_sup.c' object='libdwarf_la-dwarf_debug_sup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_debug_sup.lo `test -f 'dwarf_debug_sup.c' || echo '$(srcdir)/'`dwarf_debug_sup.c libdwarf_la-dwarf_dsc.lo: dwarf_dsc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_dsc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_dsc.Tpo -c -o libdwarf_la-dwarf_dsc.lo `test -f 'dwarf_dsc.c' || echo '$(srcdir)/'`dwarf_dsc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_dsc.Tpo $(DEPDIR)/libdwarf_la-dwarf_dsc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_dsc.c' object='libdwarf_la-dwarf_dsc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_dsc.lo `test -f 'dwarf_dsc.c' || echo '$(srcdir)/'`dwarf_dsc.c libdwarf_la-dwarf_elf_access.lo: dwarf_elf_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_access.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_access.Tpo -c -o libdwarf_la-dwarf_elf_access.lo `test -f 'dwarf_elf_access.c' || echo '$(srcdir)/'`dwarf_elf_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_access.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_access.c' object='libdwarf_la-dwarf_elf_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_access.lo `test -f 'dwarf_elf_access.c' || echo '$(srcdir)/'`dwarf_elf_access.c libdwarf_la-dwarf_elf_load_headers.lo: dwarf_elf_load_headers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_load_headers.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Tpo -c -o libdwarf_la-dwarf_elf_load_headers.lo `test -f 'dwarf_elf_load_headers.c' || echo '$(srcdir)/'`dwarf_elf_load_headers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_load_headers.c' object='libdwarf_la-dwarf_elf_load_headers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_load_headers.lo `test -f 'dwarf_elf_load_headers.c' || echo '$(srcdir)/'`dwarf_elf_load_headers.c libdwarf_la-dwarf_elfread.lo: dwarf_elfread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elfread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elfread.Tpo -c -o libdwarf_la-dwarf_elfread.lo `test -f 'dwarf_elfread.c' || echo '$(srcdir)/'`dwarf_elfread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elfread.Tpo $(DEPDIR)/libdwarf_la-dwarf_elfread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elfread.c' object='libdwarf_la-dwarf_elfread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elfread.lo `test -f 'dwarf_elfread.c' || echo '$(srcdir)/'`dwarf_elfread.c libdwarf_la-dwarf_elf_rel_detector.lo: dwarf_elf_rel_detector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_rel_detector.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Tpo -c -o libdwarf_la-dwarf_elf_rel_detector.lo `test -f 'dwarf_elf_rel_detector.c' || echo '$(srcdir)/'`dwarf_elf_rel_detector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_rel_detector.c' object='libdwarf_la-dwarf_elf_rel_detector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_rel_detector.lo `test -f 'dwarf_elf_rel_detector.c' || echo '$(srcdir)/'`dwarf_elf_rel_detector.c libdwarf_la-dwarf_error.lo: dwarf_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_error.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_error.Tpo -c -o libdwarf_la-dwarf_error.lo `test -f 'dwarf_error.c' || echo '$(srcdir)/'`dwarf_error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_error.Tpo $(DEPDIR)/libdwarf_la-dwarf_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_error.c' object='libdwarf_la-dwarf_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_error.lo `test -f 'dwarf_error.c' || echo '$(srcdir)/'`dwarf_error.c libdwarf_la-dwarf_find_sigref.lo: dwarf_find_sigref.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_find_sigref.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_find_sigref.Tpo -c -o libdwarf_la-dwarf_find_sigref.lo `test -f 'dwarf_find_sigref.c' || echo '$(srcdir)/'`dwarf_find_sigref.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_find_sigref.Tpo $(DEPDIR)/libdwarf_la-dwarf_find_sigref.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_find_sigref.c' object='libdwarf_la-dwarf_find_sigref.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_find_sigref.lo `test -f 'dwarf_find_sigref.c' || echo '$(srcdir)/'`dwarf_find_sigref.c libdwarf_la-dwarf_fission_to_cu.lo: dwarf_fission_to_cu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_fission_to_cu.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Tpo -c -o libdwarf_la-dwarf_fission_to_cu.lo `test -f 'dwarf_fission_to_cu.c' || echo '$(srcdir)/'`dwarf_fission_to_cu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Tpo $(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_fission_to_cu.c' object='libdwarf_la-dwarf_fission_to_cu.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_fission_to_cu.lo `test -f 'dwarf_fission_to_cu.c' || echo '$(srcdir)/'`dwarf_fission_to_cu.c libdwarf_la-dwarf_form.lo: dwarf_form.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_form.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_form.Tpo -c -o libdwarf_la-dwarf_form.lo `test -f 'dwarf_form.c' || echo '$(srcdir)/'`dwarf_form.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_form.Tpo $(DEPDIR)/libdwarf_la-dwarf_form.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_form.c' object='libdwarf_la-dwarf_form.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_form.lo `test -f 'dwarf_form.c' || echo '$(srcdir)/'`dwarf_form.c libdwarf_la-dwarf_form_class_names.lo: dwarf_form_class_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_form_class_names.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_form_class_names.Tpo -c -o libdwarf_la-dwarf_form_class_names.lo `test -f 'dwarf_form_class_names.c' || echo '$(srcdir)/'`dwarf_form_class_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_form_class_names.Tpo $(DEPDIR)/libdwarf_la-dwarf_form_class_names.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_form_class_names.c' object='libdwarf_la-dwarf_form_class_names.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_form_class_names.lo `test -f 'dwarf_form_class_names.c' || echo '$(srcdir)/'`dwarf_form_class_names.c libdwarf_la-dwarf_frame.lo: dwarf_frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_frame.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_frame.Tpo -c -o libdwarf_la-dwarf_frame.lo `test -f 'dwarf_frame.c' || echo '$(srcdir)/'`dwarf_frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_frame.Tpo $(DEPDIR)/libdwarf_la-dwarf_frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_frame.c' object='libdwarf_la-dwarf_frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_frame.lo `test -f 'dwarf_frame.c' || echo '$(srcdir)/'`dwarf_frame.c libdwarf_la-dwarf_frame2.lo: dwarf_frame2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_frame2.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_frame2.Tpo -c -o libdwarf_la-dwarf_frame2.lo `test -f 'dwarf_frame2.c' || echo '$(srcdir)/'`dwarf_frame2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_frame2.Tpo $(DEPDIR)/libdwarf_la-dwarf_frame2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_frame2.c' object='libdwarf_la-dwarf_frame2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_frame2.lo `test -f 'dwarf_frame2.c' || echo '$(srcdir)/'`dwarf_frame2.c libdwarf_la-dwarf_funcs.lo: dwarf_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_funcs.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_funcs.Tpo -c -o libdwarf_la-dwarf_funcs.lo `test -f 'dwarf_funcs.c' || echo '$(srcdir)/'`dwarf_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_funcs.Tpo $(DEPDIR)/libdwarf_la-dwarf_funcs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_funcs.c' object='libdwarf_la-dwarf_funcs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_funcs.lo `test -f 'dwarf_funcs.c' || echo '$(srcdir)/'`dwarf_funcs.c libdwarf_la-dwarf_gdbindex.lo: dwarf_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_gdbindex.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Tpo -c -o libdwarf_la-dwarf_gdbindex.lo `test -f 'dwarf_gdbindex.c' || echo '$(srcdir)/'`dwarf_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Tpo $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_gdbindex.c' object='libdwarf_la-dwarf_gdbindex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_gdbindex.lo `test -f 'dwarf_gdbindex.c' || echo '$(srcdir)/'`dwarf_gdbindex.c libdwarf_la-dwarf_generic_init.lo: dwarf_generic_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_generic_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_generic_init.Tpo -c -o libdwarf_la-dwarf_generic_init.lo `test -f 'dwarf_generic_init.c' || echo '$(srcdir)/'`dwarf_generic_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_generic_init.Tpo $(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_generic_init.c' object='libdwarf_la-dwarf_generic_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_generic_init.lo `test -f 'dwarf_generic_init.c' || echo '$(srcdir)/'`dwarf_generic_init.c libdwarf_la-dwarf_global.lo: dwarf_global.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_global.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_global.Tpo -c -o libdwarf_la-dwarf_global.lo `test -f 'dwarf_global.c' || echo '$(srcdir)/'`dwarf_global.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_global.Tpo $(DEPDIR)/libdwarf_la-dwarf_global.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_global.c' object='libdwarf_la-dwarf_global.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_global.lo `test -f 'dwarf_global.c' || echo '$(srcdir)/'`dwarf_global.c libdwarf_la-dwarf_gnu_index.lo: dwarf_gnu_index.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_gnu_index.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_gnu_index.Tpo -c -o libdwarf_la-dwarf_gnu_index.lo `test -f 'dwarf_gnu_index.c' || echo '$(srcdir)/'`dwarf_gnu_index.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_gnu_index.Tpo $(DEPDIR)/libdwarf_la-dwarf_gnu_index.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_gnu_index.c' object='libdwarf_la-dwarf_gnu_index.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_gnu_index.lo `test -f 'dwarf_gnu_index.c' || echo '$(srcdir)/'`dwarf_gnu_index.c libdwarf_la-dwarf_groups.lo: dwarf_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_groups.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_groups.Tpo -c -o libdwarf_la-dwarf_groups.lo `test -f 'dwarf_groups.c' || echo '$(srcdir)/'`dwarf_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_groups.Tpo $(DEPDIR)/libdwarf_la-dwarf_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_groups.c' object='libdwarf_la-dwarf_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_groups.lo `test -f 'dwarf_groups.c' || echo '$(srcdir)/'`dwarf_groups.c libdwarf_la-dwarf_harmless.lo: dwarf_harmless.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_harmless.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_harmless.Tpo -c -o libdwarf_la-dwarf_harmless.lo `test -f 'dwarf_harmless.c' || echo '$(srcdir)/'`dwarf_harmless.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_harmless.Tpo $(DEPDIR)/libdwarf_la-dwarf_harmless.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_harmless.c' object='libdwarf_la-dwarf_harmless.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_harmless.lo `test -f 'dwarf_harmless.c' || echo '$(srcdir)/'`dwarf_harmless.c libdwarf_la-dwarf_init_finish.lo: dwarf_init_finish.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_init_finish.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_init_finish.Tpo -c -o libdwarf_la-dwarf_init_finish.lo `test -f 'dwarf_init_finish.c' || echo '$(srcdir)/'`dwarf_init_finish.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_init_finish.Tpo $(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_init_finish.c' object='libdwarf_la-dwarf_init_finish.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_init_finish.lo `test -f 'dwarf_init_finish.c' || echo '$(srcdir)/'`dwarf_init_finish.c libdwarf_la-dwarf_leb.lo: dwarf_leb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_leb.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_leb.Tpo -c -o libdwarf_la-dwarf_leb.lo `test -f 'dwarf_leb.c' || echo '$(srcdir)/'`dwarf_leb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_leb.Tpo $(DEPDIR)/libdwarf_la-dwarf_leb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_leb.c' object='libdwarf_la-dwarf_leb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_leb.lo `test -f 'dwarf_leb.c' || echo '$(srcdir)/'`dwarf_leb.c libdwarf_la-dwarf_line.lo: dwarf_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_line.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_line.Tpo -c -o libdwarf_la-dwarf_line.lo `test -f 'dwarf_line.c' || echo '$(srcdir)/'`dwarf_line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_line.Tpo $(DEPDIR)/libdwarf_la-dwarf_line.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_line.c' object='libdwarf_la-dwarf_line.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_line.lo `test -f 'dwarf_line.c' || echo '$(srcdir)/'`dwarf_line.c libdwarf_la-dwarf_loc.lo: dwarf_loc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_loc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_loc.Tpo -c -o libdwarf_la-dwarf_loc.lo `test -f 'dwarf_loc.c' || echo '$(srcdir)/'`dwarf_loc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_loc.Tpo $(DEPDIR)/libdwarf_la-dwarf_loc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_loc.c' object='libdwarf_la-dwarf_loc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_loc.lo `test -f 'dwarf_loc.c' || echo '$(srcdir)/'`dwarf_loc.c libdwarf_la-dwarf_locationop_read.lo: dwarf_locationop_read.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_locationop_read.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_locationop_read.Tpo -c -o libdwarf_la-dwarf_locationop_read.lo `test -f 'dwarf_locationop_read.c' || echo '$(srcdir)/'`dwarf_locationop_read.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_locationop_read.Tpo $(DEPDIR)/libdwarf_la-dwarf_locationop_read.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_locationop_read.c' object='libdwarf_la-dwarf_locationop_read.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_locationop_read.lo `test -f 'dwarf_locationop_read.c' || echo '$(srcdir)/'`dwarf_locationop_read.c libdwarf_la-dwarf_loclists.lo: dwarf_loclists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_loclists.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_loclists.Tpo -c -o libdwarf_la-dwarf_loclists.lo `test -f 'dwarf_loclists.c' || echo '$(srcdir)/'`dwarf_loclists.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_loclists.Tpo $(DEPDIR)/libdwarf_la-dwarf_loclists.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_loclists.c' object='libdwarf_la-dwarf_loclists.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_loclists.lo `test -f 'dwarf_loclists.c' || echo '$(srcdir)/'`dwarf_loclists.c libdwarf_la-dwarf_machoread.lo: dwarf_machoread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_machoread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_machoread.Tpo -c -o libdwarf_la-dwarf_machoread.lo `test -f 'dwarf_machoread.c' || echo '$(srcdir)/'`dwarf_machoread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_machoread.Tpo $(DEPDIR)/libdwarf_la-dwarf_machoread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_machoread.c' object='libdwarf_la-dwarf_machoread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_machoread.lo `test -f 'dwarf_machoread.c' || echo '$(srcdir)/'`dwarf_machoread.c libdwarf_la-dwarf_macro.lo: dwarf_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_macro.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_macro.Tpo -c -o libdwarf_la-dwarf_macro.lo `test -f 'dwarf_macro.c' || echo '$(srcdir)/'`dwarf_macro.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_macro.Tpo $(DEPDIR)/libdwarf_la-dwarf_macro.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_macro.c' object='libdwarf_la-dwarf_macro.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_macro.lo `test -f 'dwarf_macro.c' || echo '$(srcdir)/'`dwarf_macro.c libdwarf_la-dwarf_macro5.lo: dwarf_macro5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_macro5.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_macro5.Tpo -c -o libdwarf_la-dwarf_macro5.lo `test -f 'dwarf_macro5.c' || echo '$(srcdir)/'`dwarf_macro5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_macro5.Tpo $(DEPDIR)/libdwarf_la-dwarf_macro5.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_macro5.c' object='libdwarf_la-dwarf_macro5.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_macro5.lo `test -f 'dwarf_macro5.c' || echo '$(srcdir)/'`dwarf_macro5.c libdwarf_la-dwarf_names.lo: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_names.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_names.Tpo -c -o libdwarf_la-dwarf_names.lo `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_names.Tpo $(DEPDIR)/libdwarf_la-dwarf_names.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='libdwarf_la-dwarf_names.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_names.lo `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c libdwarf_la-dwarf_object_detector.lo: dwarf_object_detector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_object_detector.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_object_detector.Tpo -c -o libdwarf_la-dwarf_object_detector.lo `test -f 'dwarf_object_detector.c' || echo '$(srcdir)/'`dwarf_object_detector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_object_detector.Tpo $(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_object_detector.c' object='libdwarf_la-dwarf_object_detector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_object_detector.lo `test -f 'dwarf_object_detector.c' || echo '$(srcdir)/'`dwarf_object_detector.c libdwarf_la-dwarf_object_read_common.lo: dwarf_object_read_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_object_read_common.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Tpo -c -o libdwarf_la-dwarf_object_read_common.lo `test -f 'dwarf_object_read_common.c' || echo '$(srcdir)/'`dwarf_object_read_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Tpo $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_object_read_common.c' object='libdwarf_la-dwarf_object_read_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_object_read_common.lo `test -f 'dwarf_object_read_common.c' || echo '$(srcdir)/'`dwarf_object_read_common.c libdwarf_la-dwarf_original_elf_init.lo: dwarf_original_elf_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_original_elf_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Tpo -c -o libdwarf_la-dwarf_original_elf_init.lo `test -f 'dwarf_original_elf_init.c' || echo '$(srcdir)/'`dwarf_original_elf_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Tpo $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_original_elf_init.c' object='libdwarf_la-dwarf_original_elf_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_original_elf_init.lo `test -f 'dwarf_original_elf_init.c' || echo '$(srcdir)/'`dwarf_original_elf_init.c libdwarf_la-dwarf_peread.lo: dwarf_peread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_peread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_peread.Tpo -c -o libdwarf_la-dwarf_peread.lo `test -f 'dwarf_peread.c' || echo '$(srcdir)/'`dwarf_peread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_peread.Tpo $(DEPDIR)/libdwarf_la-dwarf_peread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_peread.c' object='libdwarf_la-dwarf_peread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_peread.lo `test -f 'dwarf_peread.c' || echo '$(srcdir)/'`dwarf_peread.c libdwarf_la-dwarf_print_lines.lo: dwarf_print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_print_lines.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_print_lines.Tpo -c -o libdwarf_la-dwarf_print_lines.lo `test -f 'dwarf_print_lines.c' || echo '$(srcdir)/'`dwarf_print_lines.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_print_lines.Tpo $(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_print_lines.c' object='libdwarf_la-dwarf_print_lines.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_print_lines.lo `test -f 'dwarf_print_lines.c' || echo '$(srcdir)/'`dwarf_print_lines.c libdwarf_la-dwarf_pubtypes.lo: dwarf_pubtypes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_pubtypes.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Tpo -c -o libdwarf_la-dwarf_pubtypes.lo `test -f 'dwarf_pubtypes.c' || echo '$(srcdir)/'`dwarf_pubtypes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Tpo $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_pubtypes.c' object='libdwarf_la-dwarf_pubtypes.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_pubtypes.lo `test -f 'dwarf_pubtypes.c' || echo '$(srcdir)/'`dwarf_pubtypes.c libdwarf_la-dwarf_query.lo: dwarf_query.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_query.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_query.Tpo -c -o libdwarf_la-dwarf_query.lo `test -f 'dwarf_query.c' || echo '$(srcdir)/'`dwarf_query.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_query.Tpo $(DEPDIR)/libdwarf_la-dwarf_query.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_query.c' object='libdwarf_la-dwarf_query.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_query.lo `test -f 'dwarf_query.c' || echo '$(srcdir)/'`dwarf_query.c libdwarf_la-dwarf_ranges.lo: dwarf_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_ranges.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_ranges.Tpo -c -o libdwarf_la-dwarf_ranges.lo `test -f 'dwarf_ranges.c' || echo '$(srcdir)/'`dwarf_ranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_ranges.Tpo $(DEPDIR)/libdwarf_la-dwarf_ranges.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_ranges.c' object='libdwarf_la-dwarf_ranges.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_ranges.lo `test -f 'dwarf_ranges.c' || echo '$(srcdir)/'`dwarf_ranges.c libdwarf_la-dwarf_rnglists.lo: dwarf_rnglists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_rnglists.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_rnglists.Tpo -c -o libdwarf_la-dwarf_rnglists.lo `test -f 'dwarf_rnglists.c' || echo '$(srcdir)/'`dwarf_rnglists.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_rnglists.Tpo $(DEPDIR)/libdwarf_la-dwarf_rnglists.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_rnglists.c' object='libdwarf_la-dwarf_rnglists.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_rnglists.lo `test -f 'dwarf_rnglists.c' || echo '$(srcdir)/'`dwarf_rnglists.c libdwarf_la-dwarf_str_offsets.lo: dwarf_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_str_offsets.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Tpo -c -o libdwarf_la-dwarf_str_offsets.lo `test -f 'dwarf_str_offsets.c' || echo '$(srcdir)/'`dwarf_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Tpo $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_str_offsets.c' object='libdwarf_la-dwarf_str_offsets.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_str_offsets.lo `test -f 'dwarf_str_offsets.c' || echo '$(srcdir)/'`dwarf_str_offsets.c libdwarf_la-dwarfstring.lo: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarfstring.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarfstring.Tpo -c -o libdwarf_la-dwarfstring.lo `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarfstring.Tpo $(DEPDIR)/libdwarf_la-dwarfstring.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='libdwarf_la-dwarfstring.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarfstring.lo `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c libdwarf_la-dwarf_stringsection.lo: dwarf_stringsection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_stringsection.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_stringsection.Tpo -c -o libdwarf_la-dwarf_stringsection.lo `test -f 'dwarf_stringsection.c' || echo '$(srcdir)/'`dwarf_stringsection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_stringsection.Tpo $(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_stringsection.c' object='libdwarf_la-dwarf_stringsection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_stringsection.lo `test -f 'dwarf_stringsection.c' || echo '$(srcdir)/'`dwarf_stringsection.c libdwarf_la-dwarf_tied.lo: dwarf_tied.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_tied.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_tied.Tpo -c -o libdwarf_la-dwarf_tied.lo `test -f 'dwarf_tied.c' || echo '$(srcdir)/'`dwarf_tied.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_tied.Tpo $(DEPDIR)/libdwarf_la-dwarf_tied.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tied.c' object='libdwarf_la-dwarf_tied.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_tied.lo `test -f 'dwarf_tied.c' || echo '$(srcdir)/'`dwarf_tied.c libdwarf_la-dwarf_tsearchhash.lo: dwarf_tsearchhash.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_tsearchhash.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Tpo -c -o libdwarf_la-dwarf_tsearchhash.lo `test -f 'dwarf_tsearchhash.c' || echo '$(srcdir)/'`dwarf_tsearchhash.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Tpo $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchhash.c' object='libdwarf_la-dwarf_tsearchhash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_tsearchhash.lo `test -f 'dwarf_tsearchhash.c' || echo '$(srcdir)/'`dwarf_tsearchhash.c libdwarf_la-dwarf_types.lo: dwarf_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_types.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_types.Tpo -c -o libdwarf_la-dwarf_types.lo `test -f 'dwarf_types.c' || echo '$(srcdir)/'`dwarf_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_types.Tpo $(DEPDIR)/libdwarf_la-dwarf_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_types.c' object='libdwarf_la-dwarf_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_types.lo `test -f 'dwarf_types.c' || echo '$(srcdir)/'`dwarf_types.c libdwarf_la-dwarf_util.lo: dwarf_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_util.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_util.Tpo -c -o libdwarf_la-dwarf_util.lo `test -f 'dwarf_util.c' || echo '$(srcdir)/'`dwarf_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_util.Tpo $(DEPDIR)/libdwarf_la-dwarf_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_util.c' object='libdwarf_la-dwarf_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_util.lo `test -f 'dwarf_util.c' || echo '$(srcdir)/'`dwarf_util.c libdwarf_la-dwarf_vars.lo: dwarf_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_vars.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_vars.Tpo -c -o libdwarf_la-dwarf_vars.lo `test -f 'dwarf_vars.c' || echo '$(srcdir)/'`dwarf_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_vars.Tpo $(DEPDIR)/libdwarf_la-dwarf_vars.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_vars.c' object='libdwarf_la-dwarf_vars.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_vars.lo `test -f 'dwarf_vars.c' || echo '$(srcdir)/'`dwarf_vars.c libdwarf_la-dwarf_weaks.lo: dwarf_weaks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_weaks.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_weaks.Tpo -c -o libdwarf_la-dwarf_weaks.lo `test -f 'dwarf_weaks.c' || echo '$(srcdir)/'`dwarf_weaks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_weaks.Tpo $(DEPDIR)/libdwarf_la-dwarf_weaks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_weaks.c' object='libdwarf_la-dwarf_weaks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_weaks.lo `test -f 'dwarf_weaks.c' || echo '$(srcdir)/'`dwarf_weaks.c libdwarf_la-dwarf_xu_index.lo: dwarf_xu_index.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_xu_index.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_xu_index.Tpo -c -o libdwarf_la-dwarf_xu_index.lo `test -f 'dwarf_xu_index.c' || echo '$(srcdir)/'`dwarf_xu_index.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_xu_index.Tpo $(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_xu_index.c' object='libdwarf_la-dwarf_xu_index.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_xu_index.lo `test -f 'dwarf_xu_index.c' || echo '$(srcdir)/'`dwarf_xu_index.c libdwarf_la-crc32.lo: crc32.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-crc32.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-crc32.Tpo -c -o libdwarf_la-crc32.lo `test -f 'crc32.c' || echo '$(srcdir)/'`crc32.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-crc32.Tpo $(DEPDIR)/libdwarf_la-crc32.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crc32.c' object='libdwarf_la-crc32.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-crc32.lo `test -f 'crc32.c' || echo '$(srcdir)/'`crc32.c libdwarf_la-malloc_check.lo: malloc_check.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-malloc_check.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-malloc_check.Tpo -c -o libdwarf_la-malloc_check.lo `test -f 'malloc_check.c' || echo '$(srcdir)/'`malloc_check.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-malloc_check.Tpo $(DEPDIR)/libdwarf_la-malloc_check.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc_check.c' object='libdwarf_la-malloc_check.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-malloc_check.lo `test -f 'malloc_check.c' || echo '$(srcdir)/'`malloc_check.c libdwarf_la-pro_alloc.lo: pro_alloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_alloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_alloc.Tpo -c -o libdwarf_la-pro_alloc.lo `test -f 'pro_alloc.c' || echo '$(srcdir)/'`pro_alloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_alloc.Tpo $(DEPDIR)/libdwarf_la-pro_alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_alloc.c' object='libdwarf_la-pro_alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_alloc.lo `test -f 'pro_alloc.c' || echo '$(srcdir)/'`pro_alloc.c libdwarf_la-pro_arange.lo: pro_arange.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_arange.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_arange.Tpo -c -o libdwarf_la-pro_arange.lo `test -f 'pro_arange.c' || echo '$(srcdir)/'`pro_arange.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_arange.Tpo $(DEPDIR)/libdwarf_la-pro_arange.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_arange.c' object='libdwarf_la-pro_arange.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_arange.lo `test -f 'pro_arange.c' || echo '$(srcdir)/'`pro_arange.c libdwarf_la-pro_debug_sup.lo: pro_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_debug_sup.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_debug_sup.Tpo -c -o libdwarf_la-pro_debug_sup.lo `test -f 'pro_debug_sup.c' || echo '$(srcdir)/'`pro_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_debug_sup.Tpo $(DEPDIR)/libdwarf_la-pro_debug_sup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_debug_sup.c' object='libdwarf_la-pro_debug_sup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_debug_sup.lo `test -f 'pro_debug_sup.c' || echo '$(srcdir)/'`pro_debug_sup.c libdwarf_la-pro_die.lo: pro_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_die.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_die.Tpo -c -o libdwarf_la-pro_die.lo `test -f 'pro_die.c' || echo '$(srcdir)/'`pro_die.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_die.Tpo $(DEPDIR)/libdwarf_la-pro_die.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_die.c' object='libdwarf_la-pro_die.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_die.lo `test -f 'pro_die.c' || echo '$(srcdir)/'`pro_die.c libdwarf_la-pro_dnames.lo: pro_dnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_dnames.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_dnames.Tpo -c -o libdwarf_la-pro_dnames.lo `test -f 'pro_dnames.c' || echo '$(srcdir)/'`pro_dnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_dnames.Tpo $(DEPDIR)/libdwarf_la-pro_dnames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_dnames.c' object='libdwarf_la-pro_dnames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_dnames.lo `test -f 'pro_dnames.c' || echo '$(srcdir)/'`pro_dnames.c libdwarf_la-pro_encode_nm.lo: pro_encode_nm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_encode_nm.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_encode_nm.Tpo -c -o libdwarf_la-pro_encode_nm.lo `test -f 'pro_encode_nm.c' || echo '$(srcdir)/'`pro_encode_nm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_encode_nm.Tpo $(DEPDIR)/libdwarf_la-pro_encode_nm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_encode_nm.c' object='libdwarf_la-pro_encode_nm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_encode_nm.lo `test -f 'pro_encode_nm.c' || echo '$(srcdir)/'`pro_encode_nm.c libdwarf_la-pro_error.lo: pro_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_error.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_error.Tpo -c -o libdwarf_la-pro_error.lo `test -f 'pro_error.c' || echo '$(srcdir)/'`pro_error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_error.Tpo $(DEPDIR)/libdwarf_la-pro_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_error.c' object='libdwarf_la-pro_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_error.lo `test -f 'pro_error.c' || echo '$(srcdir)/'`pro_error.c libdwarf_la-pro_expr.lo: pro_expr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_expr.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_expr.Tpo -c -o libdwarf_la-pro_expr.lo `test -f 'pro_expr.c' || echo '$(srcdir)/'`pro_expr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_expr.Tpo $(DEPDIR)/libdwarf_la-pro_expr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_expr.c' object='libdwarf_la-pro_expr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_expr.lo `test -f 'pro_expr.c' || echo '$(srcdir)/'`pro_expr.c libdwarf_la-pro_finish.lo: pro_finish.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_finish.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_finish.Tpo -c -o libdwarf_la-pro_finish.lo `test -f 'pro_finish.c' || echo '$(srcdir)/'`pro_finish.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_finish.Tpo $(DEPDIR)/libdwarf_la-pro_finish.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_finish.c' object='libdwarf_la-pro_finish.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_finish.lo `test -f 'pro_finish.c' || echo '$(srcdir)/'`pro_finish.c libdwarf_la-pro_forms.lo: pro_forms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_forms.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_forms.Tpo -c -o libdwarf_la-pro_forms.lo `test -f 'pro_forms.c' || echo '$(srcdir)/'`pro_forms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_forms.Tpo $(DEPDIR)/libdwarf_la-pro_forms.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_forms.c' object='libdwarf_la-pro_forms.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_forms.lo `test -f 'pro_forms.c' || echo '$(srcdir)/'`pro_forms.c libdwarf_la-pro_frame.lo: pro_frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_frame.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_frame.Tpo -c -o libdwarf_la-pro_frame.lo `test -f 'pro_frame.c' || echo '$(srcdir)/'`pro_frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_frame.Tpo $(DEPDIR)/libdwarf_la-pro_frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_frame.c' object='libdwarf_la-pro_frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_frame.lo `test -f 'pro_frame.c' || echo '$(srcdir)/'`pro_frame.c libdwarf_la-pro_funcs.lo: pro_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_funcs.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_funcs.Tpo -c -o libdwarf_la-pro_funcs.lo `test -f 'pro_funcs.c' || echo '$(srcdir)/'`pro_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_funcs.Tpo $(DEPDIR)/libdwarf_la-pro_funcs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_funcs.c' object='libdwarf_la-pro_funcs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_funcs.lo `test -f 'pro_funcs.c' || echo '$(srcdir)/'`pro_funcs.c libdwarf_la-pro_init.lo: pro_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_init.Tpo -c -o libdwarf_la-pro_init.lo `test -f 'pro_init.c' || echo '$(srcdir)/'`pro_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_init.Tpo $(DEPDIR)/libdwarf_la-pro_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_init.c' object='libdwarf_la-pro_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_init.lo `test -f 'pro_init.c' || echo '$(srcdir)/'`pro_init.c libdwarf_la-pro_line.lo: pro_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_line.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_line.Tpo -c -o libdwarf_la-pro_line.lo `test -f 'pro_line.c' || echo '$(srcdir)/'`pro_line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_line.Tpo $(DEPDIR)/libdwarf_la-pro_line.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_line.c' object='libdwarf_la-pro_line.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_line.lo `test -f 'pro_line.c' || echo '$(srcdir)/'`pro_line.c libdwarf_la-pro_log_extra_flag_strings.lo: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_log_extra_flag_strings.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Tpo -c -o libdwarf_la-pro_log_extra_flag_strings.lo `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Tpo $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='libdwarf_la-pro_log_extra_flag_strings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_log_extra_flag_strings.lo `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c libdwarf_la-pro_macinfo.lo: pro_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_macinfo.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_macinfo.Tpo -c -o libdwarf_la-pro_macinfo.lo `test -f 'pro_macinfo.c' || echo '$(srcdir)/'`pro_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_macinfo.Tpo $(DEPDIR)/libdwarf_la-pro_macinfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_macinfo.c' object='libdwarf_la-pro_macinfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_macinfo.lo `test -f 'pro_macinfo.c' || echo '$(srcdir)/'`pro_macinfo.c libdwarf_la-pro_pubnames.lo: pro_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_pubnames.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_pubnames.Tpo -c -o libdwarf_la-pro_pubnames.lo `test -f 'pro_pubnames.c' || echo '$(srcdir)/'`pro_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_pubnames.Tpo $(DEPDIR)/libdwarf_la-pro_pubnames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_pubnames.c' object='libdwarf_la-pro_pubnames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_pubnames.lo `test -f 'pro_pubnames.c' || echo '$(srcdir)/'`pro_pubnames.c libdwarf_la-pro_reloc.lo: pro_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc.Tpo -c -o libdwarf_la-pro_reloc.lo `test -f 'pro_reloc.c' || echo '$(srcdir)/'`pro_reloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc.Tpo $(DEPDIR)/libdwarf_la-pro_reloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc.c' object='libdwarf_la-pro_reloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc.lo `test -f 'pro_reloc.c' || echo '$(srcdir)/'`pro_reloc.c libdwarf_la-pro_reloc_stream.lo: pro_reloc_stream.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc_stream.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc_stream.Tpo -c -o libdwarf_la-pro_reloc_stream.lo `test -f 'pro_reloc_stream.c' || echo '$(srcdir)/'`pro_reloc_stream.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc_stream.Tpo $(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc_stream.c' object='libdwarf_la-pro_reloc_stream.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc_stream.lo `test -f 'pro_reloc_stream.c' || echo '$(srcdir)/'`pro_reloc_stream.c libdwarf_la-pro_reloc_symbolic.lo: pro_reloc_symbolic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc_symbolic.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Tpo -c -o libdwarf_la-pro_reloc_symbolic.lo `test -f 'pro_reloc_symbolic.c' || echo '$(srcdir)/'`pro_reloc_symbolic.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Tpo $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc_symbolic.c' object='libdwarf_la-pro_reloc_symbolic.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc_symbolic.lo `test -f 'pro_reloc_symbolic.c' || echo '$(srcdir)/'`pro_reloc_symbolic.c libdwarf_la-pro_section.lo: pro_section.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_section.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_section.Tpo -c -o libdwarf_la-pro_section.lo `test -f 'pro_section.c' || echo '$(srcdir)/'`pro_section.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_section.Tpo $(DEPDIR)/libdwarf_la-pro_section.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_section.c' object='libdwarf_la-pro_section.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_section.lo `test -f 'pro_section.c' || echo '$(srcdir)/'`pro_section.c libdwarf_la-pro_types.lo: pro_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_types.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_types.Tpo -c -o libdwarf_la-pro_types.lo `test -f 'pro_types.c' || echo '$(srcdir)/'`pro_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_types.Tpo $(DEPDIR)/libdwarf_la-pro_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_types.c' object='libdwarf_la-pro_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_types.lo `test -f 'pro_types.c' || echo '$(srcdir)/'`pro_types.c libdwarf_la-pro_vars.lo: pro_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_vars.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_vars.Tpo -c -o libdwarf_la-pro_vars.lo `test -f 'pro_vars.c' || echo '$(srcdir)/'`pro_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_vars.Tpo $(DEPDIR)/libdwarf_la-pro_vars.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_vars.c' object='libdwarf_la-pro_vars.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_vars.lo `test -f 'pro_vars.c' || echo '$(srcdir)/'`pro_vars.c libdwarf_la-pro_weaks.lo: pro_weaks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_weaks.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_weaks.Tpo -c -o libdwarf_la-pro_weaks.lo `test -f 'pro_weaks.c' || echo '$(srcdir)/'`pro_weaks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_weaks.Tpo $(DEPDIR)/libdwarf_la-pro_weaks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_weaks.c' object='libdwarf_la-pro_weaks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_weaks.lo `test -f 'pro_weaks.c' || echo '$(srcdir)/'`pro_weaks.c test_dwarfstring-test_dwarfstring.o: test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-test_dwarfstring.o -MD -MP -MF $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo -c -o test_dwarfstring-test_dwarfstring.o `test -f 'test_dwarfstring.c' || echo '$(srcdir)/'`test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-test_dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_dwarfstring.c' object='test_dwarfstring-test_dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-test_dwarfstring.o `test -f 'test_dwarfstring.c' || echo '$(srcdir)/'`test_dwarfstring.c test_dwarfstring-test_dwarfstring.obj: test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-test_dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo -c -o test_dwarfstring-test_dwarfstring.obj `if test -f 'test_dwarfstring.c'; then $(CYGPATH_W) 'test_dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/test_dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-test_dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_dwarfstring.c' object='test_dwarfstring-test_dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-test_dwarfstring.obj `if test -f 'test_dwarfstring.c'; then $(CYGPATH_W) 'test_dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/test_dwarfstring.c'; fi` test_dwarfstring-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo -c -o test_dwarfstring-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_dwarfstring-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_dwarfstring-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo -c -o test_dwarfstring-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_dwarfstring-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_extra_flag_strings-test_extra_flag_strings.o: test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-test_extra_flag_strings.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo -c -o test_extra_flag_strings-test_extra_flag_strings.o `test -f 'test_extra_flag_strings.c' || echo '$(srcdir)/'`test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_extra_flag_strings.c' object='test_extra_flag_strings-test_extra_flag_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-test_extra_flag_strings.o `test -f 'test_extra_flag_strings.c' || echo '$(srcdir)/'`test_extra_flag_strings.c test_extra_flag_strings-test_extra_flag_strings.obj: test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-test_extra_flag_strings.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo -c -o test_extra_flag_strings-test_extra_flag_strings.obj `if test -f 'test_extra_flag_strings.c'; then $(CYGPATH_W) 'test_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/test_extra_flag_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_extra_flag_strings.c' object='test_extra_flag_strings-test_extra_flag_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-test_extra_flag_strings.obj `if test -f 'test_extra_flag_strings.c'; then $(CYGPATH_W) 'test_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/test_extra_flag_strings.c'; fi` test_extra_flag_strings-pro_log_extra_flag_strings.o: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-pro_log_extra_flag_strings.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo -c -o test_extra_flag_strings-pro_log_extra_flag_strings.o `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='test_extra_flag_strings-pro_log_extra_flag_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-pro_log_extra_flag_strings.o `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c test_extra_flag_strings-pro_log_extra_flag_strings.obj: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-pro_log_extra_flag_strings.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo -c -o test_extra_flag_strings-pro_log_extra_flag_strings.obj `if test -f 'pro_log_extra_flag_strings.c'; then $(CYGPATH_W) 'pro_log_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/pro_log_extra_flag_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='test_extra_flag_strings-pro_log_extra_flag_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-pro_log_extra_flag_strings.obj `if test -f 'pro_log_extra_flag_strings.c'; then $(CYGPATH_W) 'pro_log_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/pro_log_extra_flag_strings.c'; fi` test_extra_flag_strings-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo -c -o test_extra_flag_strings-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo $(DEPDIR)/test_extra_flag_strings-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_extra_flag_strings-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_extra_flag_strings-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo -c -o test_extra_flag_strings-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo $(DEPDIR)/test_extra_flag_strings-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_extra_flag_strings-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_headersok-test_headersok.o: test_headersok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_headersok_CPPFLAGS) $(CPPFLAGS) $(test_headersok_CFLAGS) $(CFLAGS) -MT test_headersok-test_headersok.o -MD -MP -MF $(DEPDIR)/test_headersok-test_headersok.Tpo -c -o test_headersok-test_headersok.o `test -f 'test_headersok.c' || echo '$(srcdir)/'`test_headersok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_headersok-test_headersok.Tpo $(DEPDIR)/test_headersok-test_headersok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_headersok.c' object='test_headersok-test_headersok.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_headersok_CPPFLAGS) $(CPPFLAGS) $(test_headersok_CFLAGS) $(CFLAGS) -c -o test_headersok-test_headersok.o `test -f 'test_headersok.c' || echo '$(srcdir)/'`test_headersok.c test_headersok-test_headersok.obj: test_headersok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_headersok_CPPFLAGS) $(CPPFLAGS) $(test_headersok_CFLAGS) $(CFLAGS) -MT test_headersok-test_headersok.obj -MD -MP -MF $(DEPDIR)/test_headersok-test_headersok.Tpo -c -o test_headersok-test_headersok.obj `if test -f 'test_headersok.c'; then $(CYGPATH_W) 'test_headersok.c'; else $(CYGPATH_W) '$(srcdir)/test_headersok.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_headersok-test_headersok.Tpo $(DEPDIR)/test_headersok-test_headersok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_headersok.c' object='test_headersok-test_headersok.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_headersok_CPPFLAGS) $(CPPFLAGS) $(test_headersok_CFLAGS) $(CFLAGS) -c -o test_headersok-test_headersok.obj `if test -f 'test_headersok.c'; then $(CYGPATH_W) 'test_headersok.c'; else $(CYGPATH_W) '$(srcdir)/test_headersok.c'; fi` test_linkedtopath-test_linkedtopath.o: test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-test_linkedtopath.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo -c -o test_linkedtopath-test_linkedtopath.o `test -f 'test_linkedtopath.c' || echo '$(srcdir)/'`test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo $(DEPDIR)/test_linkedtopath-test_linkedtopath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_linkedtopath.c' object='test_linkedtopath-test_linkedtopath.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-test_linkedtopath.o `test -f 'test_linkedtopath.c' || echo '$(srcdir)/'`test_linkedtopath.c test_linkedtopath-test_linkedtopath.obj: test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-test_linkedtopath.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo -c -o test_linkedtopath-test_linkedtopath.obj `if test -f 'test_linkedtopath.c'; then $(CYGPATH_W) 'test_linkedtopath.c'; else $(CYGPATH_W) '$(srcdir)/test_linkedtopath.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo $(DEPDIR)/test_linkedtopath-test_linkedtopath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_linkedtopath.c' object='test_linkedtopath-test_linkedtopath.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-test_linkedtopath.obj `if test -f 'test_linkedtopath.c'; then $(CYGPATH_W) 'test_linkedtopath.c'; else $(CYGPATH_W) '$(srcdir)/test_linkedtopath.c'; fi` test_linkedtopath-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo -c -o test_linkedtopath-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo $(DEPDIR)/test_linkedtopath-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_linkedtopath-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_linkedtopath-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo -c -o test_linkedtopath-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo $(DEPDIR)/test_linkedtopath-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_linkedtopath-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_linkedtopath-dwarf_debuglink.o: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarf_debuglink.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo -c -o test_linkedtopath-dwarf_debuglink.o `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='test_linkedtopath-dwarf_debuglink.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarf_debuglink.o `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c test_linkedtopath-dwarf_debuglink.obj: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarf_debuglink.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo -c -o test_linkedtopath-dwarf_debuglink.obj `if test -f 'dwarf_debuglink.c'; then $(CYGPATH_W) 'dwarf_debuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_debuglink.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='test_linkedtopath-dwarf_debuglink.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarf_debuglink.obj `if test -f 'dwarf_debuglink.c'; then $(CYGPATH_W) 'dwarf_debuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_debuglink.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-libdwarfdevDATA: $(libdwarfdev_DATA) @$(NORMAL_INSTALL) @list='$(libdwarfdev_DATA)'; test -n "$(libdwarfdevdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libdwarfdevdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdwarfdevdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libdwarfdevdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(libdwarfdevdir)" || exit $$?; \ done uninstall-libdwarfdevDATA: @$(NORMAL_UNINSTALL) @list='$(libdwarfdev_DATA)'; test -n "$(libdwarfdevdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libdwarfdevdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test_dwarfstring.log: test_dwarfstring$(EXEEXT) @p='test_dwarfstring$(EXEEXT)'; \ b='test_dwarfstring'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_extra_flag_strings.log: test_extra_flag_strings$(EXEEXT) @p='test_extra_flag_strings$(EXEEXT)'; \ b='test_extra_flag_strings'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_linkedtopath.log: test_linkedtopath$(EXEEXT) @p='test_linkedtopath$(EXEEXT)'; \ b='test_linkedtopath'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_headersok.log: test_headersok$(EXEEXT) @p='test_headersok$(EXEEXT)'; \ b='test_headersok'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testdebuglink.sh.log: testdebuglink.sh @p='testdebuglink.sh'; \ b='testdebuglink.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) runtests.sh.log: runtests.sh @p='runtests.sh'; \ b='runtests.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdwarfdevdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libdwarf_la-crc32.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_alloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_arange.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_crc32.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debug_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debug_sup.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_dsc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elfread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_error.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_find_sigref.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_form.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_form_class_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_frame.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_frame2.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_funcs.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_global.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_gnu_index.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_groups.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_harmless.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_leb.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_line.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_loc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_locationop_read.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_loclists.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_machoread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_macro.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_macro5.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_peread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_query.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_ranges.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_rnglists.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_tied.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_types.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_util.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_vars.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_weaks.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarfstring.Plo -rm -f ./$(DEPDIR)/libdwarf_la-malloc_check.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_alloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_arange.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_debug_sup.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_die.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_dnames.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_encode_nm.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_error.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_expr.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_finish.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_forms.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_frame.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_funcs.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_line.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_macinfo.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_pubnames.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_section.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_types.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_vars.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_weaks.Plo -rm -f ./$(DEPDIR)/test_dwarfstring-dwarfstring.Po -rm -f ./$(DEPDIR)/test_dwarfstring-test_dwarfstring.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-dwarfstring.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po -rm -f ./$(DEPDIR)/test_headersok-test_headersok.Po -rm -f ./$(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po -rm -f ./$(DEPDIR)/test_linkedtopath-dwarfstring.Po -rm -f ./$(DEPDIR)/test_linkedtopath-test_linkedtopath.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-includeHEADERS install-libdwarfdevDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libdwarf_la-crc32.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_alloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_arange.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_crc32.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debug_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debug_sup.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_dsc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_elfread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_error.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_find_sigref.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_fission_to_cu.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_form.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_form_class_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_frame.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_frame2.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_funcs.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_global.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_gnu_index.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_groups.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_harmless.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_leb.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_line.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_loc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_locationop_read.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_loclists.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_machoread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_macro.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_macro5.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_names.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_peread.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_query.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_ranges.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_rnglists.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_tied.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_types.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_util.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_vars.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_weaks.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo -rm -f ./$(DEPDIR)/libdwarf_la-dwarfstring.Plo -rm -f ./$(DEPDIR)/libdwarf_la-malloc_check.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_alloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_arange.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_debug_sup.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_die.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_dnames.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_encode_nm.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_error.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_expr.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_finish.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_forms.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_frame.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_funcs.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_init.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_line.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_macinfo.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_pubnames.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_section.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_types.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_vars.Plo -rm -f ./$(DEPDIR)/libdwarf_la-pro_weaks.Plo -rm -f ./$(DEPDIR)/test_dwarfstring-dwarfstring.Po -rm -f ./$(DEPDIR)/test_dwarfstring-test_dwarfstring.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-dwarfstring.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po -rm -f ./$(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po -rm -f ./$(DEPDIR)/test_headersok-test_headersok.Po -rm -f ./$(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po -rm -f ./$(DEPDIR)/test_linkedtopath-dwarfstring.Po -rm -f ./$(DEPDIR)/test_linkedtopath-test_linkedtopath.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-libdwarfdevDATA .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-libdwarfdevDATA install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am recheck tags tags-am uninstall \ uninstall-am uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-libdwarfdevDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libdwarf-20210528/libdwarf/dwarf_weaks.h0000644000175000017500000000226013743575426014752 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Weak_Context_s *Dwarf_Weak_Context; /* struct never completed: see dwarf_global.h */ libdwarf-20210528/libdwarf/pro_vars.c0000664000175000017500000000427313764007262014302 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_section.h" /* This function adds another variable name to the list of variable names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_varname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, var_name, dwarf_snk_varname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_varname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, var_name, dwarf_snk_varname, error); return res; } libdwarf-20210528/libdwarf/libdwarf2p.1.pdf0000664000175000017500000061333414004644006015164 00000000000000%PDF-1.4 %Çì¢ %%Invocation: path/gs -P- -dSAFER -dCompatibilityLevel=1.4 -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=? -sOutputFile=? -P- -dSAFER -dCompatibilityLevel=1.4 ? 5 0 obj <> stream xœW]oÛ6}÷¯ ö2yˆY‘õ=¹MÚ¹H“ÌVPÍd‰±µZ’+Ju³_¿{IJ–=À‰EÞÏsνúJ\ʈ‹?ö3+'¯–!Ù¨‰K6“¯¦û‘•äu2ñ¨ Iç"Â|’Œ©Û«?†fDåõâv‘|BÈ¿]$w7«•Á'TPxa_×úíý’ÌÉØ HSTÂIooçKòð¸|¸_Ýгiìi4ˆ“‡®âú]72·¯•×p[žOãþ‚ÆœòÐ «бï}ûœrˆ53q˜—¥žxòlöxqDÃ0øéì±Ã4þG¨ì„oÝ(ŒûâÇ?€ZÙëé `8mR\Ê4ÇãOðQu%üý4ÅT—mûÉiy•uJ2È}Ú@^&+Ž3§¯‘vÜ“–kz¬&渪Û:8À™1 ÙÀN£g€kR—Øwü¾Ûƒ—Zµ»à/È¢Y¢m˜.=Ãe±Oý¹.H)3í0i˜¨ «w ¹$YIÈ nw!æÓ8 ôБzEÁ)ÅÛ1§ÜœU]Ž«ñä`0DUuû}Ý´l…w¬zÇ󽕎2m;À(‚‰}-¡&öUW‘EÖÔêEµ²Tc=åxïéæ{Šõ2Iª­UnÊYÔ•VD+ÿCäé®q(S¬8ÄØUƒâæFe}&˜°¨†…ªgIè$4GNŽõ\  nBô¿mÝxý…©õÛ¨Ò­—&£3CÌÅ—‹,Xê…ÁMºéËÌÚøäØD.ŒvH8´Ñë)Þ¡IÃf÷„ÍVÓ] õÅAMôÖ®ßB"aµž¦¦]žÌuï8þ°à@ÌËútÒ£“õLêý‘¤J³ýêHS€ `tjØËâs–¨ßMuh»2~€xŦ‚Í!§Àe´½5U»i1¬9¬Õ›+"õÿ7e¢W¿6-*¸:î+ ©a®ÝŽ^kÆØ€Þ ÑPmQ‡v¢\X’_ޝƒ 0zß³çÿ 1¼oÎ<÷6”f3[µHÁ„õzÉþÆFs{<‚`ô].Èû´êpLà²z4ÂÚ0¼¶ÍØ ŸÜ$“?áç_CM?:endstream endobj 6 0 obj 1789 endobj 19 0 obj <> stream xœ¥Y[“ÓF}Ÿ_Ñ;/‘·ÆºÕºí0PÌf·˜-J#·= ¶d$gþýž¯o’–lÕLP_¾ë9çë|f1,¦_îïzñä&gÛá"fÛ‹ÏÂ|dî¯zÏž­.¶ª±JH†ß«Í…Ý)˜ÌSž(–'[í/¢¥\.V¿ã»:v«—2Îx+¶L±n}‘p™ ¶:]DÏ»v8îuÏ^7w=mͱ°(éx·NšuUÿÀ^µ£î7U­ÙرkZ¼Œy.é®2噥Ýýö4!2žÅyá>ܼ¤s7Ï2ån‹.¯Øé¾©ïÙpßwkv§Y¯+ú{Óõöç¦Ý²ñ¾Ìí2–¼,¶Êì_w5|iGN_%Î|}!yš”äÁꯢgöœk]ëý|–±(Ø—…H›2‹4|ÜèÅ¿W?_¤vìO . å w4IRgç‡è¬^(rBeߪº!”‡Hcäùÿ­“Öe3Ó¬`KéJTÄ&ÁÑÓu›GÉÕ®Jñ#]'3îOû¢'+ªð•¯²WW»»G4+*ÅËR&(—)Gº«‘ ÇáëÇÁü—õ]$9—8ÖeFq)s›³ž›B·H“ˆ‹ˆbXµkæ³hƒ)%ŠG¸ ~¼~mJBr!Á||û ëzÛœ™â¹Ê„÷Ëì1Ý!±ðÅÍ96+y¦rìÛv¡€m¤‹’+•zODb"ýU|(4mÇŽƒ6) Ý"˹ʋoÜ®pû›·_¼YY è_³Ì­Tá’Ý.8[YSTŠÂ÷®LvŒÕÝÎÜXwˆ`;šè Qq)Ckp…>1 ð8ÁvÍ`r¦Ù®õ0z0ÈRŸ]¨+ ÒÆu8g?u6†$ôÿéQ¡%<+¥<+5|TÅãrƒ/™1*ê¯X5UdjJ'>³;B ’©ºêw ‚ィÈ.‹‡e˜gÞc‰Ã]É5;ôz Ÿï5 °ÙïõºÏ;M’ª:-£“EX}~¼ ¬Ó•)O¸4éõ•M£"¼ƘZþâEî)Áæ …ÍÙÓÝΤ4AK÷ÙÁÖÜ»fê‰Xd´ÝË]§Y 3&Ù\ ÜÇ2â¶ýP×¢&Ð;YjoyÎÎÏs{þmt÷ †¸]P²­nu_íØ0>Ø¢Ûз!5æ˜ËcNtl9çà{ÅÙÉŠ¾ÂÊž=_Ž=ÎÀ¹§f¼GýI‚ÔXR›îˆÚ|8hƒã Ü‚X‰¨Úɟ͈l5s5jû=Ô"?È % ÷ÁÕ1»­ªMßíM kKÁR"×Ì©oÑ,l¥ Íº4¼L.øÙˆ¹ø\lÿ…¨ú.¥,Måô)r‹ó]ßlŠ˜• E=ŠIC_‘LÁÓTz ºy)Œ€ŸHÍ¡PIì­w[¤I3™¿EÆÀK‘ÿÇd9/<ä!%ü·°€.û ³øD„ß~ƒg ¸.›à¬L¥g{ãN¨h[Ì'ò¤„MÜ«ï«v Oo#ôœBE»æYŸ,˜áh)•œ2Nôm|¬n#öNk³çòÚÃçO€Ï®¸´àãÎà“&.ýºörù”}üâ4ÿoaW‚çÉÿÜKøFFNÉ,UÚˆ˜6=ÑmçHZf1—åTc±U»>\ˆ\r×h‰¶ød€ mdœ\æ>åz&à$Ï òj–SÝvl• •KZ¡7控ó£S£ |º3bHTæEãá°kêÊbÐHusz¥DzÑË㩟ϰ"ËÂEé/ì‘© Ýt…+ˆ\g¸ Pâj¶È± å°×ûª™ñéžOµmQŒþb¡Hr|ëj¬\ É™z¬q-2ÎPsÍÛhèöÚB)ÄΉZÓ¾¡`Q¸¨‘½®Z#švmbœ VÍîØkË$vŽHƒè8˜D„DŠ} 61 (yR:IMÈ€šŒ¥ƒtÝ6°ª)! áÇïŠ<§)(15i54H,B®¯'˜Y"ψ–Î-©7D餠"Ï“Œ 2V±¡Ùv¦ŸºSÂJ‹¢•ŸP ÛõŽYwkýˆžÙ¾zðž:¿+—sRDf$\«;p;_,SôP vXÍN€ºìgJCRÆm·¼åˆxBšÓŠ8¿40¨šRd4;YØÙ˜|j£õ±ÆøDµdGÒS@(3šVDafŠ*ÐK©'„“Ê n1q-ñ’µt·ƒ°´JÉ“Ü|M=oF_ºù`’g±G˜fÍH|™JE¨lÌýŒÐX}F1šÜÔ¶×WIæYY¨ÒÆä†ô² 9Ñøb™g’+”„CzãÆ1å_’¸ày*§yû†øècø±i›ñ6º]<žâ`À¼ü¢µê¾9ï´‹Í0šgsÙ<¶SL!0zO*m­G4êÀí}#«è­Ce†ÐÖe£û"Hm晋vÐpãÛ"rLöÈò¥[FMe9 e  S„$6ˆÅSv;âg#u[ƒ:.ß¿yõOËtmåPCÔ¶¯öX¾5~òØaìk0ñÚ$ÞtÝ`©ÙHãÉ}w<°K寯߽ú‘’˜A)Ÿ^ȳ¸H·a&yàv¿àÜ‚1ªŸjsV™B{8Ú4!!9MVá½gG“ÄÚÉL]2“™Y™ú™Ñ»ËþÔÃÊd×Ô1|5Ákhøîµ}!¢two Ò{w»û$R.]±ý€úOùæ¼wØ·‡)(ÿ ¹oôp3jˆ‚\‘C°÷(käðÝH³‰Tg`¬îŽíHû( —x^(¯ûß`ùªíD)UôG­uü(á˜ÂìÍR®2å©4/’‰J-[Rêñhʬ×Ä9kJUk$²$z°7÷³i®¥5ASû[ΙÔÔ’™ûçUmôc‘'%éÇîu1tÇžªÙp.Pym%¦}ÚxÀß§ 2㩙Ȳ(h¢R;?Î\ÞãáoOžœN'ÔrAX‡7 n¯( E7 ãšw–ÒŠÀâöÒbÓâϽW[V{~M "EˆïëH2ÐíÍK¯úµÉ¼ÓáÿêÅ­îPÚ㇤&h™/нNz$¹r“ÂS8´Öw AyËDtÜn©bæ‘Ó¶¦Qׯ^ s¦Í<¢m¡Afm÷þ±e¾ó°«j3–»Zs&x²pªtÆ'XQ9ì:n?ÒP¸œ‹é½Ä©iû@fÛÀM»{@Wî ‘ìÔû¥æ~&Ö´Ÿ€:LC‰‚Úm]Ðkâ4³%œÎ­Æ+ªhˆÆß=ººo1?t±º21j¡ ‡Á¾õölxØßuPç®i–»ó"E¼âOÞ"£]xâÍÒrb]$¤"0˜Fb§áóÄZnSÊÙ ±™BÑòiÀ·Ê‚ÂÔì—g/T³Gáÿ&Â3¯0ôQ d:Øj1ª°kk hX§†å¹3ìFñ½š•›áÓX™ov82wœµEÆ?KD—3½Þ™3=p¼å"Å̆„'6–7:ˆAäžìÄL{̵ ¦Ú+&SösÕ)×2–b:àR†`¹ÿóbuñwüúî9ïendstream endobj 20 0 obj 2843 endobj 24 0 obj <> stream xœ­XÛ’ÛÆ}çWLé%`j9ÂÌàš·u$År­Gb¢mJCи4ÿÞ§ç€ëU.U)mÕ®HLO÷éîsºñ ¹`!ýs¿·õâõ‡”íûEÈö‹_Â|Éܯm;[/[oñ” ?ëÝžL¦1WKUÂÖõ"X©Õrý3ìàé• †[Åø²\?=||ÿ¶k;V°ºí4Û¶õé¨ÍJÝo»ê4TmÃÚº×L7CWéž“A\±~X“l}YëCÕ³²Ýžk<ÅŠ²= =+ŽG:ÊÝÕø_SÂînù‡…1iáÙˆª©èžU {E—¬Be.ÎÐÅg<‰UnÏo>щ”GI(Ý÷Þ±7zCßF1Ïc%Üç=}&ϲж¯š={߈º ÌÝð+1¨©(çBÆl%"óô»vºSò0Þ:m°y–)y’¸hƒWOÓiÅS‘ØÏCBàs »ž —|¹ŠÃ0 ÈÀWË­íz(òK>¸ÿód7ãJÅΫÏEV:öPmº%E”EwEÄHÌ®Ø"A-{c®â©46âN;ÛŸî'Û OBŸºàÃ;úb^…NE×W¦TVJe Ý- ”DÊà©Ògb,ˆ•{ÜcMÁ?6 9® 4=š¯×. C6ó:°LDγSמÚþãò¼…ÿ1Vu¤P:Ó×.ÙYfhiýGJ\¯ë y\‚X¨âÑR-}ï²o+!4JÕf]S^ ‚õØÚ½iî(BCùF¹ÛÍ©!‰¤ôu”eŽã¨t6WÅNx:w…ï¢w^Oº·d”‚Ýr5re›ÂE7gÎS…2KlU˜üoLñøQ=a˜¥òò}<¶K¡Zâ<¸Ø‡g”ïÒÌ}‰ê‘YÎ'†}*æ%ÊLL~¤6ÖcÜj¹3´j•#ǵ±³A½hâ‹ÑMäãCÍd™±1IJO,Ö³k{fEGmÛvíy@e(d(yžx¸ef](êêX»TÃÁÁ1²<Ô® ƒ‡í’³r¶=øß(Fj‹{®>\9JÄ£>Ìj®¸Ì}ý­×–Yå)8©éêø°;£·FF#ûåMLXiË™v Å"ü´ÃVȬ~CN ©ÕôU,òüÿ#*1ˆ2ߎ¢bãÿlˆeêó<ÓçÞê¾/:¢Â¯Më¤|”9`!ÊãÌ*„a@ñn*”Þ¦=¦znøìs9TÛ‰‰­NbVۮΰÃ-aË45{\r‡KnØ$‚^팭Ÿ4«G„MI>]ÅWú<1FMóÉ<ðq±Œ˜ˆeÐØöµ"ÜɱE­?ôó4Ô“QAϧ ¬©üô0å*9Æ3CN‰´ W—£.÷  ÖÕXð'è­¯@üV5©µÒñžÛÑ*šè`öD%³ƒ¬ëHýë‹r‹öÇ8{çÊÉ—¾J!BB¾ÀïsZϹÊr1Ž©rÝ jZÈRk âҫѾàKWe1(}[VýW“j™¤ êd²&G ôZf'¥$¦4ÝöžØwEÍÌÝ45pëë·d:ÁüMs f%;xõ¦Aê¢û ç°±’wîÌlÿæýÛgÉDà€lZLZCaÆ69Ol8K,ad &E“NZ<ÌÄã1Q›wê›xBˆ^µXšiKÍM<¶Ã¢9@œž@™ýt©ædG|!ØÂ!“<ß:еŽ;\‹½q/U"CǘÞfê>3ûé“ sûBPj¨°ö5öR1-@ô6Äî{À¡c`ÝtUÕšö›Š^HÙ%Œ¥’qmr§ö6{|„–6ñì™éQÀ nçÞ.Ó혳ÇlOxÉIêO÷òcrÓ> stream xœXÛ’Û¸}×Wà-Tj„%@ðöèÍØ©8Þõf¢ŠÆ)ER#®9¤–¤Fž¿Ïé@]l')»<®aèËéÓøC„R‰þ¸Ÿåó⧇T<‹P<-þX(þ(ÜòYü¼^Db]ÂJi¿ëÝ®TB§±ŒŒH£D¬ŸÁʬ–ëß±¬W:Ld±Šñ±Zÿ¬Sý¼­l}'t¨ñsMæJiiÒ ^Ñf§EðÔt]Ó=‰i_‹ÃЗõ8Š~'Ê¡.&ú}Ç‹#k_.T¢e’ÙM‚S3û¡bXĹûÐMõ°£oZËxþ5ó¡ŽcC‹I”ûºüBGíúÖ¬4Ve:+eì²Ä^VC?ˆfeßÍ8ÕÝ$ŠrèárѶ¢Ä?£ø#ÙT}W‹¦ãÀÈþøŒœ´Ív(†×ÏKÉ)Á¶[ˆˆ°ÿúÏÁÖ}[a!‡ B$7M­ÃÅP‹/öWq Ï¢è*1‡~˜êŠ:Õb_,ÿ½~¿X!ÚŒ2£ÓP¦‘¶)ˆ¤Ñ)ÇòR‹íœ=I­LæmÂÄÚ4|¥ClZòHæ&™ÓÂ&cJ ðù€zm›¶™^Å©™öEÙW5GºÊC¨pqîëÒ$T L¼i[N‡VpÃ:Ë8a€<»cWNMß]åD%6']ÏÑf0OBk=Jm|˜QèаÒÒFY¼ÆØ¼‡62 #ç>ŸA–ËtNSlÍ#¹Ç`êé8t€p×¾º³-pWH°Œ”òé î?]î›ø ›ûŒ\T-O”GnñQÿÚ|ü»ïÉ$NdîC} >ÑB"9ÊÀîíÃg&ÁÞ&M½ÕÇÍ¡çdòÿ{ t/K„ç*ŠöhÁfq¤’T†çn€¯y–³36VoÚýñiÞ•ûHe¹Œ2w2Z*·«žÐÝ4JñŽŒÒDªØšÐÎÖÚ®ÏбÆååkñ|hë;NjF2IϹ¬N¶dlÌ€ŒP1ì6EUmvCñ\ošn×oÊÏÁç%u)uç HãËRQ"2ãêz'Nû¦õÉpGü—ƒ•’ùÎ¥Sï©ð{^mÙ+jóºÚ¦®;ù›Ó_ê3„”œ‘i;“':‚ûåžw§45†c¡• íbß ïí«P†šS‡Ä9ƒ8]5A#šOY÷âìõo¨=dãКtŶ­ÅTÌçàvP{å)ÿÞz 7¨2FšØÓû§7çðМñÅÎÊføá],ÆÚ²ƒ¬êí’1¤‚ãÓQò­œ2¹TÚcédQEè«™Ð"aÇÃÌ8¶¼‰’anülñu£ã¨ Á çÁcöà‚Y]Y¦©Ìý{¨¡Ãí@ÄþOu‡aÒñ@AÍhù×0—œ§’N®¼½ƒ)·¡Ý>Góèl&DÇ3*iÿÃPèCTš¨JìlêR44Äú#†‹ØöOÇÑ&–r¨Ãõ®Buí˜"‘êf2¸ºL@ˆ…ÀØP{$ÜÎ…Çà}Ñià蘡§–«Ä„”,¢ô£Ïü[ÑùóAÌ›mÛ—_6㙿–‹ÅšsœŠ3r1 ÂÈW±Å$u]2~¥`ŸÔ+™¡”± Eñ|3@Š:3ÿk <›w~ÙÔK̳P…Iðõ0 .É¡ÿô Z¿£Þµ«VÆc˜³ ¥XóIp°Ÿ©¡Àë(o·Ô1 7ƒ)ßP¡FK6~Å7*ñ׺«‡¢u´­•ÏÀ}=–Cs MèÛ…€\9;Ï,P7Î"tÉ&3>hÈ£êTÐŒ¹w±Î»¡à‘Ž;(H4Çï{ð ØÛB8K`V\SÑ€ÿ&„[ջю½¡v#¦¢иŒã9DO´‚ÍmBÒj ½Pƒ©ûãëó¶o›Rt ðQGš„=ØmWuQÔoGО·A#ê3|ðAÕØÝ¯TxŒ#IŽZk¹>ƒá“œZ×)0G„ çíëœWãÙÃ9sH¹²òÂe­&ýyãs’ÈLeÿg¡PT¥g‰!9^»~°#-ÅÄ0‰·üÁ<ƒœ'"AiÐý`ŽÏ2-ÃTù¦¾'·678sÆÙÜ™ÐçA3n4i™&sG#ÍWªeÓUMYLµe9¡Ÿ½Bß±lXøMÚÆþ¶\D)èWùÈ^‡sddb<ˆ“ÈJ è1ÃhBá<-ƒ(säkæu­îÎN¥ŽÓ¹F!ã ¾ú"ù´E¸·ÅñuÚ~»MZ.1Ñ­³óôæ¶BžÃ<¾Q¹rJÑõ„ã7,Ì“ðv\H’«ÉUð4mI¿ V¬g™,ù²´&JÏ©3˜ó™ª–܆ûÍ åsnæ]$y!·=ø@œ''¿ûÛÖþ–`c0.n ÓÅy ^Ùï4W9v ¿¡ÐiôkÕyš¢2moŸ?bz¹ ò¥ÉçëíáRz¨y„ÖœE–ŽTcæ(rÖÝyl°@Á‡¦£NË)˜2ãg÷Váz#θ›gò£«¬ãàr ÷Š=XçÙë?ß*¯Žq^`ô–*yˆ¯ó"÷jâB•!¨è|¶ÍDyÅ?RÁ·µE³ÓÙÐW@;®‘3×H‰ªç—ƒIœ†fš:+Ç1‹ÒùŽar—ÁWpº¬ôÄ_8G0ŒòàoÝ8Ayˆf¢ P ½4)‡’±æç%Ä‹›$ z‡´]©åÊZs)“Ið@ÔÁOr*’áü>ð¢.½¼(ˆ#HæXÌ šÔ3áÆÊ ÓæïÞ®ÿÀŸÿè¿V´endstream endobj 30 0 obj 2276 endobj 34 0 obj <> stream xœXÛn7}×WèƒWE–]^öÖ7'qNƒ:ŒÂ.Œ½PÒ&«]e/Vô÷!¹)v6bG$‡3sfÎú+ñ(#~ÙŸÙnñÛMH6íÂ#›Å×Ó‹ÄþÈväõj!È*ƒ]Œø^­æ$#<ô©$YíŽë»ËÕg°£wG„IÜìr/ ž'‰ÀJ¾Ô'«ÃÂà@ZTIsÄCAHƒ0àDoñô†º!IÛª]Zª†Ô}·ï;ÜézTFg¹Ãq¸ 8·Åè “”EÒvº-~'加^Ä#»üööáíõ›‡O«›«Ë7W×ß\®Þ}üó“=5& 4”¡õVÿŠß;­R$Ueû¥ Rxñ´)Ò›÷KRt¤h1º~§rÒm“þQ$Kʲ¨6$Ùïu¤Ü—TJŸ¸˜É|ÁÁ36в$m±Û—GrhŠNéãmרdv«œ4àD–tE]µ$/•u°µ¨ºVÉU¹&k¼AHN™°q ym½(Õ+r(º-$ljðH{3l¶Þhî £MÝo¶hvDkéû€x;tùÏêý„äyu­Á¹ø)lÀ ;‡æï¯?^¿{óp¸ç!¦CPüŠQ%˜ìú¶# ¢„êºL6ªRMÒ)“ySž™0ñš’å÷$탹œä*]rp‰ éôa]7»ïÂ!-¼ñº„…1Þ¸úõÎyâ2ƒ)1x*'‹iÉá#Ð;¯g1}×H¤3—‰Hâ!b;“™ýÖ‘5v_ep·{NqŸ,‚àS®ƒØ7uÞg ªÓÏèáZÇî1Ž~½¤¹8°Èp­ÒajË"Íèf ü éØ0KÒ¬ÝÒeas§ï[ƒÏ,§sD:ݺ.§# 53£,0—m“j£Èº¢kI½&*ɶ–Ç,8¦ÍµVª2Õb‚Úã.­ÁR%;ÕRÝ{ÓzæLßij¨l-7ºÃÖÑ›(2Þ JÌ ©"È=–G–©}§Á«aNhbæëº©w:µº =›Ï´è 0=Âé´î«SeØ8ô°Ä¦ˆ$ “œìŽeä¼tCÿäx2%à™“ªÊõQâÆIÓ™ÿÌM¤m]öœRU 243>#n,O§×u¬ /Éç³ïÎ9@“fÉ"G•©m±G<»­õiú ìôƒ;bSL·[UéÉë FMÕ™"&T`60hÂh ÚC3A484š5³¥ËúÂ’O ކ«~—ªæÂÎ7h†¦N]•¦ŒY(©7òHDCϘËÕ ÞÁV(ҮÌÞ;E2NÅ4ɾu_™köXï9€>®#±­ÏƇ“c,%5EUt÷ÎýŠ684>£CÒdŠ>¤‚Gì˜V}í±R°Ø ÑÕ8+޹p6˜í罃ÃôQÒ¾ª—)T„ÎAµÝýÒÒ "êC…Û*‰à‹ŸM˜H—´ {¶€JèG»pÎ~ÃFà~®›†:å|*¾4Sà Ç9LfHÆÐ"LLCÒ÷LqÏî0Ñê" Å9D *×çþ‹Õ—¯¯2§’%–Ì8r i v£sÈ'Oi4ŸÆ¾°¡Ãh”ÜêTû4 ‡ pŠï%JDã±u_€¾Ê;qÌN6ͳt Æ…-¯ó Çb)§1ÀÍ|œÓ¹UgÙÖÃÂYGÚúÉ]xÚgKÉè(”‡ƒ ¶`Ê Ì÷(Óܲø²d8é¡Ê jkòlâKþ2Â+òÏÓûßÅ!ç±¢=bU‘Ç%Gu1'){Ê’ ôê¼-¬×v´ù(ÊqP)Ó„Xì°£[ÌÙfS °Ñ+M°‹5˜´ ÇútŒØ’ÔGÙwföXÌÍÆÓBeä*$QIdÆÜ„w¨•}8™p|H ‡¬>ªç/®ösJñÃh ”?ƼÖ2>ð͈z™|_Â3E¿nŒdÃú`~ŒÍ>~Z,u½ã:\ƒc™Ò€Ím¹2¿ÂQ¡!3âúªBÖêÙ ÂôDó!ØÀb'8ŒA6 òHðÌ Hæ‰Î7zwØOÙfoÌ_dq4¯Y󾞽70[IÓ$Gmí™GI®Ú¬)R­èÝáq0Û¯a“ÀBéZm-ÓØO] >¿Q“4Ç9›•àü1Ô¯Lé÷IÕã­Üãl2†4ÉÄþ èjµø ¾þÃ$endstream endobj 35 0 obj 1917 endobj 39 0 obj <> stream xœ¥XÛŽÛÈ}×Wô›©@dÈæ=o³¶¼Ç›±€E`B‹lJÌò"óâñì×çT_¨ËN€À<&»»ªO:u8_™ï̧?æß¢]ýõ)eÇqå³ãêë*P/™ù§hÙ/ÛUȶVœáï¶Zéãiì…KÄmÛ•ã&îzûoœƒÕ.÷Ï÷#æÆxY®/å1Û>¯¾8²˜ê¾cÝÜä02Ñ•l|i}syt>K1°®_óÈËó0wžOr¬îØt’ìPwbxaã4HÑŽû<§õ¿¶¿®‚ˆmWÜãANñsNß5/vï ›¾*º«ú¡Õ?Sôú,ÆQ–îAܼ¯†¾e…hšqýfü|u¡í_¾8ƒü:Ëqª»ãOÎ÷Önìg^š„ήÇоi_WÈÚöfÇÀ,w uWÖ…ß fÇù© F<úÀÔy!¸]ú¿K·. zBøÜ×Ý$qçÑë€ô¹sijokŽ AÄÑÌ8sT¡éVxÙÎãÄÄ0ˆî(ñ\Lêe?Oçyb¥ {®§ÓÕýFO¥äú^”QÙyFà;¿×„=@è ‹L¾Ó‰‘"K¤ØKÃ87¯ßý¾÷øvÿyûôþáãþéýã§·ÛŸþþÙìZè—%ž92ô"?Ðenš;ì1èRÖ¸†Ú Ê$KvШñ ñBnsšúP>Ó ž‚9`ª1׊¡"¬nYÇvf_àÒ S«Ñt0­] òµ²í‡Y¨Ï.V!÷½S¿8›Ê<0Å™JµRáÈ/KãÌ Õã讟ØóP£¼t0ɽŒÚíŠÀ[¶lêÁøÇníi3FKªU¨JzŠÄ€4 8nP»4GaüÀÀ` (Ëa¤ R;-2nTËôU5ÊiT¹^Uɵg@ 4˜‘µ&Uß4=åE^”f6–:Ø3õZ·© Å^·¦$µ'yÛ%Èùݤ¥™Î¹£òÛ°"ÚD- ]›ƒÁއžR4¤Z>£¢{¼Øî'1÷&ȾØ9»5»¼ªgöz|G×=¤¦ÀR»k×.°\¼œZ ¢•ûª”:Þ}$±g¥@wiCW¿r©KÕŽV—ÿK?"‘øëǘºçn,d꡹çù3ñ’ÈP—«mÔ¯¤±TFƒ(«G´Ħú€VØ¡»5ôAïlÅÅãÜKòÄÏ-yx–©£©Ü‹˜ïœ®ïÜcÓDƒc/¤Q}êMÈ1 ¼8]ºð;¦N)1® cÔUÂØË€¾8fŠéCIß1ª Αnbé–·ÁË-RßwÎ*ZcË£“Öïó;ׇP¸¨`Ê¡¿§üÿ©Íüª3.üóã/Ÿ?¼ý™:ç©G|QÐ(´ZÄF°™šzè:ÑLµ<Ø`Tér¨å„1ÑÊÝæÂßœ’ÊmVÝ8IQnÌV­§n˜gp%K;ß0~‘5«î¯¹ØŠJ­Ð<Ôe<èFj¸;¦ Èãó<±³Èž§ÀguÃÜ‹yö*ätß 1bô5«'ê€ù ±Ó‚eº: I @’8e'Ì;ž®gàΩ+ùy¨±W‚-À¦i~à¤(¶vP¾—X{ÑrdP‚Èù>™õ8¿R6ƒ­ˆ@³=ÀNÒ'z~aÂDÑÕ” } M?A]M9ŽöÊmÙo’¦LÕ<0Æê„i\ôí¹‘fòý~ÂcMŠ×Wêe‹ÎƒœôæéMÇ»1E×c2òØG=Ã1#¡eTNìGщ£le7Ýõƒk×¹¡æãgi´:Ðb€:›3¾É S´Bf‰Å=±\¥š»BWX E‚b¨GrmÒ$à›¸Ïa'Bã‘ æË]–1É'¿ ˜+9ôå\Hm$±+÷ò,'óÊ–/hk⢶4.}$áR„5–KˆÒ¸O? ”û4¾¿oɶ)>çªFþtêqŸñŒPÆfòÍ”§v’ÄQ¾Š«\˜Vj^˜MKRIª£>YÉy©%Q4¢nõÆ Q7nƒÑ€VwÙÑ×NÙl«)KPÔm:ß yžtaÈ—*ã¡¢ºä?¼‚¡rµÆÓôÍôHýÄz[}!c I)TPcf¯T›û”‚í í$l ÷UÝÕãi/vNy8¾²Þ¥±sxeSÐþ¥Á~|ø2¸ê§¢Ÿƒ®ûzJ<­RL‚‘¨X½aª‹¹÷ÉœúÃöÍ;•Éoûwò0ïBc¥~hF)Çb¨ÏIÖ‡DKõeG]u‰­Ä›û)ÂX?d?·b œ_¬öݧ‡ˆ$Y¤á§é%ÖÂiÁºN°£Ùh¿YAŸ2í^I¿ÕÂ;År¸ú& 3ÝÌVºö„i©Ì[ÄÓìÆÞ¢ï–ßàð3ªrìôg ðåk_o7_x~dZc«¾¿Déªo Ro}šX5Ì }&…‘Sëi«&lnoõ%c­/}1“ âÕjzÌYµ1SÊ~ã# ÒŒkeÔ`~sàA³s_y '‰ŸCc¸üų~ .ú[ºÆá†ñ˜ý*º™Æ$ÔT­Ò»S|-l~ÿñ~»úþü×Ödendstream endobj 40 0 obj 1963 endobj 44 0 obj <> stream xœ­YÛŽãÆ}×Wô›©`Ôa7ïyÜì±³ð&c!A° ZTK¢—"µ¼Ìxüõ9Õ’ÒdŒØ0ÖÀbÅîêêSU§Nµ¿² Ò÷wy^ýñ>cÇ~²ãêëJ˜ÌýUžÙ»í*bÛ«„døo{XÙ‚É,áQ̲(eÛó*Ød›õöGØ1«s&bZ¼‘aÊÃ0f›_ö«ˆ'lû¼ b.ÙCÛ©£¦]YÄó,'ËX¼×ª®ÛR UÛÐ×ÅῆÍÚ?ciÕݲØ-‹ ž9cûgÕ/]»KÝ=ª¦êOê!ØïŽëó2Lx‘Ú‚G©0Î:­{†ƒØpÒ¬¿¨Rß1ÕìYeÜÛ„Ü`$dÆSé/ñ¤&8„࡜nWW{5X{fw”Ç< ¶!Äö´G^Úªt׳Nc×è=;tíùæ–B„¼Èœ»ÁÇjgîzs¥4ä~ÅalJ´gmÃÚŽíu_êfÿ†ñ$¹Gqw¼…JLvÖÜ~œ¢Å91¢å×Q؇®£Å1ÒB8ëöÊpè¯uÍ)èn±‹¹àq\˜-ß6ì¨Ý©á0Ví§r•"7“Ì{ÿ¢çX$<Ë|ntAaÐåv/&¾>UXjÇ?kV³j¯;BŠ,ÉTòÐcOî¨AÕœmOj EÀOJ!ØäsnUý«Võ6øEÆc_ÿsP/mßW»Z³¡õÁ‹®ƒ§¬‡Ë8°Þ`t}Ü,a¼ 'ú¥×úܳ¯£î)ä ¶øú?ÛïV„áGø#%µýÃç`‹K·]u¬à8ÝÞäßa Ã"ó=l¶À'›–L1—¨”NŠÕª[‹²88jc¸Jú7V ë±µëÁøB—þ¸I jªÓ_ÇŠ¦X”(ìÃ¥êü¤ö´þf%2‰ ¸0ÒþܧêÑ@F1íÎU„ö³½G–äB9Œ°û_6‚µj/×iãÕ† R®lü1.:Á³©i[ìÄC¢°|zµ–I4Ö‚É4°A$céWP®­©¦ò" l(6±à¢Hg2{gò¦EâöIžÛÒAtŒ›UÃ~ЗAŸwÀE†"ej¿¯Lˆk3ÊP‰´LâÙˆe2EÕi$µÉš½ §®+ Z"LbÊd¦SbrP£1ÑhØè«á…s Þ`ÞbsÕ³ñh)\tB{pñî¹/œ´ða“è ®Œßê¿RnãŒL¤“ØIÙRq{Cü’Ø wZ•'Ü£lÏ—Z|½I³œgIb’q•”…¹žªžŠx"B›Ç& S"bߎþõøþã??ýÍTµ=÷ª#¦1÷Ls×ÎLžjnèµÀGÊë#>Üߺ¿!¿<åÞá&–s¯C;‚çSUžLpû3õª¾:RߘŠP¤aÿ°6½ë¹Âš“š2>79 V/Òhj€ÒÆüI3›ùø›u!øÌ7´F-ÙURú›ÕäÝœ¢ž/'}Ť"uLúrÑ›^)o" šQp-®àyjÎ¥üõézÛ¡CôÓ©ý[sÔÃc¯ÍêÇÝ d)×2Gd\ú¥×½çô›Cà.Mqð©úý§Çßoïÿ}cY„ùU²Ò¿§¶ —¬WÇÁS ‚YTXx Ú>«Šj9BJP¼ï°¾{1ÙÛ·cgZâù™¸«jOHmMD€Ä{Žm££DÀ÷¹¹áÌBÄ.$•aœ¨÷Ü‚×3±éS^Å$œýÅEDÕhFy“I(}k,Ãà­†q« ˜»ã`2£ÈºjG ²ˆ{o«oÒ™ŠÔóÊ›2³ª©çS¿p”gBOX¿_o鯏àIä™§®v §%¹õ¼\EÐb’»üÃìGNMËþ f¾JßM”"µ#9Óx–Ž#ÌÝ/‡ª)ëqOAz€rXË0€p§ow3¦Sò…(‚g«Ü D¦‰N]NE×Õ§ó¿1Q©/Oë¥Úß|Ž·hJÛH¨iÅ.åÒì±Î³Õ[.V>†tv¿¢M*”yôº²{PË‹QšèÁ¤odáYŸ6dV d~¶ŒÞ²c׎—þO7¡ YâS€Suõ³¹‹©+‹ì¿é–Fo¤9r¯‰Í·þ–0 àSLMîæTà—%{ü(–;„ŒZnŒ¶ i‰¯8)#/kHÓ rÏÖ)t”xi“)Z@ä9ö̓Qø†Oú4üP¦#ɲS¥ri”^<œrâËaNåˆÇyâk횆'Ò_pAäù„뀬°"ˆÇ‘7*¬ €b„ú²÷Úa”ÿÿ½Á 2v¢d”I'ú§ùJhÝSߺXœ±]F¹‹…sˆdáe組Ǚ_ó+cÈ/€¨I–7£Q{Öv†ñ.I~Å}ß´}€ìܨÒèÆ‡@uîm!œÇre§K4À<ýšDÑ„}œ¦¿¯+–ø2ÔPÍÒ-L-<—qרó p¤L‹ßHJ†ÃI‚…V Þ ó¬Õv}¦ˆbž‰ä7Ÿç¾~ÎÊZŒìáP‹PÂbºN[͹(y /‚,à`Hx‘d¿ƒGuûlyÒ1MŠMY»!U@Rêèp¢/A‚$&úzž@ÞÉxùRƒ1‡}{Õ>,Qºø³™Ù·k(¦ü4X´—O¾‰ö·m¼If¡ô=qÙ2ÁÙÃxyõêeEÃ/¿zI\9š_²0²Þ¢s¢ÆóXÓ°;Å™Âüª‘œ„6nw?¢sÜY.²„Ød®â$tšvìý£‰R¨/²±á3S‹{ž¡©åÕ[“1žZc¨—ð§¾,øvNœÚijïØoŸ2¦'·7°csFjq12ÆÒy ݹoÁÅðeFÜêEÖÒsȬi`×Ìöû¶4ÉòAdÁ§:Ü¿.᣹}~ä‰y˜[Á»Óº±/w‹séÒžáû4M²~Š:ÕôdúÕ)C ¹dG4uœ—®¢ÈÒìÃú¡ÓêÜÛ·Ú“®/d깫ð©cj¹ÎؾØc gEÓÃ2Ë6KL¦Uiâ«Ð¨j~Hƒ[uåêØ½CEY`žKœ;Ðlýêý¡˜ç³÷f°ûûã{½o_F (7é™tK/fN„æFvɬpWl$'a~Lm˜LPØyxÒ f‰¤oÕ Iñ¡*QcÝ«bps9—ÂRNoÄÖû{½|\ #ŸÿObñ¼°É1ŸÜ1$ówªi.”¡³‰,ãEæm¸ÿ9ña»úþüº¹Á”endstream endobj 45 0 obj 2619 endobj 49 0 obj <> stream xœX]sã¸|ׯÀÛR[€ßyÛœ}_¶ÎEÉVÅN© ’x'‘^’²oóëÓ€¢Kj·J²f==M~cÜŒÓ?÷™ŸX'ìÐ.8;,¾-„¹ÈÜG~fÚ,¶É±JH†ÿ›ýÂÞ)˜L"?YÄls^x«tµÜü‚8vuèV¯$}ÎC¶Š°®XxÅ«jöÛç¦..¹n¶eUvOÞÓ’în _bºÃ§k+ûËJ¦ô›ôƒ,a›×Å£·9jÖGcêùùTæª+늽.3?ËD{õåT°K«Yw,Ûå¿6?M”‚ûuؽnMv_¶·zw9ÌrÊRÄKíBJ ¥¼B·yS>wuúš©<¿œ/'Õi“tÀ3GÚØÎ¯wô»H|ž&™ bElB]‡²:°²Ú×ÍÙ±§°ÈšÕ»_tÞ¡ Z±¿T9]nÙ¾©Ï¬îލ½Õî·zo 5¨¹\"ôÃȦ]#Q]u>{¨r“¬à‰…®>!ú…êtB8}•ÕQl§uÅTQè↕ÐF™?è±4!„‰a G$‡è@Ž Iý4àcàïUµ´Û¶«·EÙþº¥?Þa‰™ö)só•¶Ã9äueêÑSb¤Ìü8è õ¢¦"IÑðšÎT:žaqUuYuµ *cPDtY~`÷Ý}ï4k»F«s‹Õ¨n |ÙkÙ)ø ‘…~Æ£ž|_?­œ•‚i)wT‰ñÝ"Úvª*TSølcƒHž¤Â® úuÞ›ŽH³PÚA:•é†U ÐÊqØ’¦»¼F?kÂáôý½ãK%ÐíAµGwÐÝÖqKp´[õÞ¹qá§Ø‚÷»YþٵʖÁs¬2NHˆ^ êÐíÇYd0*Dkfc)–7¦Â˶FÂ9”W\É|DYxEgÆ—¶y(Dè’ý¦Siš2Iíê‹åZ¡:Å P¤;¥)»…¿ˆùNû¸ôÃl GŸJ{¼Ÿ:+Ï5ØycB;ÎŽ»Ñ'­ ‚ÔÐnëK^BÑÊßç¢ð5¸ò>—;sº3¬cÂBôÍ…b8ĉbYŒ!rј¿ëÃ)èÙì #îÇqx>/öíñ]V‰”_M ˜@ã̈mŸ>z÷C‚êÔÖ®mËÝIà–#Lµ­>ã§f)À0óVeõŒ˪QyGZëšÜÈ/>m}&Uú{fvNõüÃB‹Î©Ü5ªù¾ü°Híâ@O{ÐýÍH®Ìdê4À£»÷vi4ÎñÛ¥Äa²öTŽÚ´(Í1‰(ëU–Ŷê½n ø$cg‰±Ç¹ˆ=•÷ŽªÂ­ ˜Q™ ?ñÕ‰=z»²BÎ äþrqnæo¡;Už€(R¢¡Ží4Ð`B^°Uâý†›,ÓR&C´„` ÀƒRäƒS¬*AæG(Úñè9,1ψÒÞÜ=Ìø»êo_…|d*gïÚB,Jü¡\gþ^µå*ÙŸÔ¡½1¸šcu×}w*ÿuû#æ±Ê7ÈÜ]ü3bºin1¹ò¥3¿ªæ@?n>>z/uY°Ë• (Z²Ù’.˜¢]4Åœ €>JÆMl²4Žì×ö9bè'3$u±"¡1ófî¡%Ç 'ÉPÍ›Öd!â¡qàýô•ë 4:Ë®\Ï;yný4“Ùÿ2 fë¬7G©‰•ÖE;»®ÅC»;Ã&Êaë×z:£¸7Åž=ç:Ù“§L¯¼–ð9h0k²ØOã`6ÎŒ×$#¹ë¹à¡GŽrˆÕ&ÓdÆ6>kç¢Ýå§¥edÃ?\=W¾@Ìy ¼çÔ!ÇŒî›äEMç2<%­!ØN ì'ÏÚŇõ ™¹š“ܼž|bP釨¶#܈6Ù±}ÿÈÃpÜTZ~êÓ0ÐkÃ3V¡Ÿ–fè+[›Lð¬?>ÎÁrÔ§S½”ÿ\FÞkûǹt…3Ñúaûu}¿¹›Ëó’¤Pž¸G43@…‘LˆH˜aôböI1Ÿ’YEÀÍè+? ñ &_ZŒ].ë»O·¬ÿ~ûu®Z$ýQÔ?½gva×™٭j0ôòü\7ƒ œ¾¶ÓÎÌkZ†S}& Zi!ïJ‰óxµ8.í¹&†&zÂ%ýåáþçÍÝ:ç™KtÖðÜùäÕó¾&ç;´lío÷ÿ¼ÛÚXôN'š¿â|˜*OËû‘zÁ$V`o$H z.5æÓ'C\LW–é9{Rå£"Õ„Ã'E~òR㉑EÑÐÄlËk#æduãkèæo"<[Gñ»èòwxKaV¯Mú+•¯ÄƒÚ’Öô†Áñþ¤ª ùiÉ¥C$°¸IýU»Û,þŠÿù%L¤endstream endobj 50 0 obj 2122 endobj 54 0 obj <> stream xœX]sÓ8}ϯÐð²Î –dË6o¦´lšv·Ýé8‰’˜Iì`;”î¯ß£;Ž[Zv§0 ±t¥{î¹ç\óø”_ÿ¸ß‹ÝàÕ4"ëjà“õàÛ€™‡ÄýZìÈ›Ù@Ù«'ø3[ ìNFxRHH2Û ¼Q2ξ"VXSßÈ(ÄÃåÀ»ñŠR?E˜  Ñ ŠI?÷åöÝùÛÛ«É_ã[ÁõJAƒ8ìŸìû4v;n†“ö8ÆŽ¡|»ïnpíåËl‘Öª"õF‘:-‡L_Jo­j²I+’ÁÉ<«Éù}­n†$].KUU¤ÊþQtø÷ì#’á B$ƒ»ëtto²"y‘+R¬tøJ‘}‘åµ*ÍÆŠdÙ§U¥–$Ëû‰' •8ø$óÏ—“‹Ùxjs歷;7K!;µ¤zÕHÂF<¶™ë-¸Ú é®¶éZ§Ö;;L¨{G_¾5ž=r2ÓÍÒk/뀙ÖÀMÃV¬†<¤1óV•ªÚ¦8l—d®ÈÁ¥nŒP•ˆ72Ie›«êʬU®J„^’w&-30UõcšÄM½¿œËÓ°Mbú^Ϲ ‰‡‚FLº‡tÖn‚ú@Þ=ø9BÌg4âÁcÉÀÜG²Éäô¹¥¯]Õ2”Tw2§  ={Ê  ©|Rô„“O¡‰f•Œ³§Ñ¼ÖpF M€»çØŸ”É€Y&ô‘ÏÒ,= 'ÓÉ'@v! "ÖoNæ„BO’%4lËö4YFB¢ ø±¡iÌLM<66‡©´ÜÞCö¥ê:‰è4qœ€¢èÄÉNÕ›b©ÕÂeåk”œ¸šk ûE'¹­¦ø®Í¦ÑR{Û²ØÂ3ÉqKˆÂ"­T¯§áñ~§ó}ŽdÓ.v¤ÛªÐ¬kUì%I󥆥wÔˆ%!MÚæ†J¥·yºS½C¤O]Wú–þm`\)…³¶Åhù$öî€Û‘ù/²2ûñÂñÑj|e²ê·/§"‘½ÄggÓhÏ7“ã‹w“³‹~þ' °ÝóШ<ï|2› P$¬ª<ê'VïP­¼¨ÉåÔd^½£b4õQòtsU½À®šH'&:nÔt~NÚ%Ísí^š½ŠÃ0Ÿ7EU“žð ¡!kÊn‘‰H‹VW¼yQo($ÔÜÿÏp))—MnàRŸG äÑ%~µx2î+E·^NG†Z™ÍØ”% ‚^‰/i³{—Ð1³hŽ3`V’ÆÞï ZÒ>ÖR£}©Á­(Žë%®ùM8iÂêý¡&«¢Ü™¹ Ú«EfÐfСP4f•¥ó­zý•Ò(8ÎÕl:>ût;Ÿ_¾=›M./®z¸ˆ(xŠÔ£æy?Þ\žOÞ>™%QÛV¡ì7Î 8ä4q˜¶ˆ¥Z ™ï¥‡­®…¾K&Á:‚ùdrºIÐ ¹/Ì·ý>¢œKÞúýÃüùcl{W† šê óQ×X“®„‚Á®²"¯4÷Rˆ{ž–÷¤ªK•î sieár!N¼Û¹;v}š|¾zeLc¼]‘bþU-ꛡmY |nœwø[7 ä=Õû…Rr ø¤âŸm2­‚t³šÖa;’Œó0zšá˰JÊ#«ÔîŽÎi,>²½q­½µñ´iZ–é½n:`vXÔ<´Ò3IÄ1`éüžl³ùòÎp‰H!Žq#—Âê%¹Ûd‹Éd‘n·º£WxˆA±c[HS¹\Ì fkGͼø=íæáóƧ9åô9:ü/4N]CÓxùŽó·Ó“v¸Ýª¼Té–ÜAqHºß—žÌ0ÞlïõÎØ,Æ‘sGÂ’\Ok‡ZˆK;gôꂱ8dÉsu µýtꢇ”ný¢õè$L¼;k-¸óò°P¥­ÌRt£Ù¹j„Ô¶™BêƒU•a²r[m=0ö‰¦ùA+7ªÍŽ»£ˆ&½7ÿÝ1ž ~ÇÏ¿KyÏendstream endobj 55 0 obj 1735 endobj 59 0 obj <> stream xœ¥YYÛÈ~ׯè7SƒQ§ž9l ‹ Án´ÁL PdKâš"µ$eòëSÕ™ñ l`Æd±»ºŽïûªý;a”†ìÏâ¼úÃ/ 9ö+FŽ«ßW\¿$öGq&Ú®$Ù`Å¿ÛÃÊ|ɉH•!IdL¶çÕS°ák±€mÖÿÞþ뙯BûÕF0I É&ûr ÷‹*ÕTÍ@žƒ‡¿Üòî°ûs^×û¼øºûrmŠçõs°Þþ¶)MÉVÂÏŠSÞ=&?«G|‡Oÿ¶â<¢°Ëmàj}õxùi…ŽÁ#³ò¯M_UÜß.ŸêüØ¿õ¢®š¯o=¯šC‹Ïµ{¯7z ½*†zº«šR½ -CÃíÃSð­­Jò°Þ¤!cÁµWݮ̇üQ‡Ž³Ô娮k»ç5|»¤¥‹\lLlÓ±ùÒbHBÊðäÅŠ fBó²SøR§…K*cf_pc~ƒ æÅI;]µ œŽ 'EÚýoð€Ö<£Y–ˆ ª¼Èíé$¿<Žh–¦v³ºÚ— ÜrânÌi,£Ì5J•=ZRt*Ô#©R@À³SÕ“”º‚klD$i˜Ä® Ü$¼m õƒßUÍ—8tíÙîëc‚ò8´ûjÏvC—7ý¡íλ¡Ý•Uÿu‡ÿx Ös§͇¸)×›>¯É%ï{½£ ”Ûbãä©ÞÙ•/–ÚHx/’©si\||²21žEÎý¸ðî–Ä8ò1Æjÿ?öûÑmtó¼·Œ?Þe™°J7ä¾šš¯º árqN³Ømp¨ü e™àÙ¶D‡MÕå#É›s¶ØSN÷¤ä‹Ž£RÈ¥OméÍB–@\²I•GÒ´æçú0ö¢`€¤‰´½¨zE¾­Eý™y}U=éOíµ.É^‘üréÚKWA\õ÷Iå¥êà;lc)Cš&Üùm75kYÏCFCqß‘p®ë0B•Ë,vùzÉÏ—ÚàóFf’b°ü‘BnV‡n#ªÛ"×ùûÇ7RÃeB³0ý‘rˆ Ù¹Á”€˜þz¹´=’B‹ÁêRÑþ®"÷¼ÆøpSÞÚýb%dD¥t˽´#¶F`2:`Ò ÆXäbÀij³ªã~ò½O̳~ˆGœ‚.ú‹€ƒ®žºöz¡m,$àAs¢fÐ\\ŒFVË Õ½½ÐXˆø fßÖ¾$#c•—†€.–^öcI&ÚÄ<ÇjZ‹6€AGŽ›4iëÈ$Ô“¨ p_—Ow ä¯¨ ï2rÕϽÌ#QSqT¸Ü˜¿¡Ø¶T3twÒ·ZKÌrtÊmØ‘€<™ôZEiô úÓŸà0ÁÇ"©ˆGØá±¡î¼,;ÕkÙÑ©ÔüòL€ßï|·–§–â?/ͤ÷¯t@ÙP§ª‚µŽâ =Ÿ]o³Ü™Ž”`2_×VY ÅhLÅ©¯õ¥WU¬šE y„Èm” ÈÁ8ª×Ä*¢,r‡hGÂ1™1éù4Š3a \5…X•&2Ã:1Ó ¶ÒG–°Ax ^†µÈ„‚ö2Ž •a:®Îí‘:U´]Ù›À0Ü”ÏàICØeØQdÁ R C‡aPÀŠBþ¤:EòÖý€qùGäPºR`)Tè^:zíÔpí&¥±Ä(ý¦At‘ Ì'2rEÌ…ipôƤ¹4DZf3<›,­ËaÁ¸1btSãó+óŠiÍ$ê‰c$BÁÅK‹ ûÝ—‚^Šð} œŽ hè+3ÍL[Þœ§ ªf;>½ÙT“¸é²LA$boßz™wû<–ežÄ´1ì¾YQÎMma¶0Á,éÅL§©ùzî0À4*àñ­N3¨*ÕEAD`ä|Å5æú[ðÀëà›…(óÌÁï,ÉÚ‘_{­ïæô$3Ôî4f–W^ "«¦vÅC S»ÎìÃlƱ P3Xý’лýÚÄtˆ‡˜9A“aê—Ã'ɆOáE7æ7¯ßP04réj‘–j=î@©Å SX7á|R³ÌO3Ÿ¶•ý ÛXâg‘ª+ ã@Zê¬ôíÔjNŠö|©j“Ý+ÄÔ¡­$ xñ‰lçI: <+@FF°q>ÕÕ²‡nÄ2 ŽUÓà0iŠÿÕlÀ8ÄâyœÜš†@P™¤‹¸†Zºo(Ø×1MÒIsÛGIÍ)§%˜ÐdmßI øã§8 Â,4ý¥J¶&Ï!h–”ùv&“F2J¡ZΟVñ!û÷Ýàœë…­8³g²"2Dòó#¸f±!œN-œ‚žÐŽi¡½”(0GG’»ŠN,Œ8je–V3æ“[m a3,OàDyÞl׺9‰‚Ã0ãMîEž+`±åˆA¦×QLcùÖE–g MTP0s¢òÈ.8Pu¶7šâŒGÃ=ÝÂA× >ß'¼&³'±Neú[ Hš ‚Aƒ¼ª¯z›%-‘o¸¾°t¹lBâ…«"}-·pÈ©#°¦·ãH3-Ð!ª`ü±t`*ÒT¯i]ÔÜ<o¡DÍåÒ(®²Phq•Ãb}·üÓ;ö¯î¬ðŠ4¿aqÀ΄ ×K7VãØ±0æ8ž¸”+t"‡å52µ]@%™ySÄ®¯ ¹ÞŽvÓИÖj*•p¯Î8“À:\k‚ÍyTê ``çײškŽrÎçŸÕp­«ïF0è}ŠUˆÒÁ³›§Øw‰åa¶¸¡H’ÑÓ©4™Ü  „…0 &oÄMÜ8è¢9)ÿ%˜aƒûAúƒ²4Ãí­üóæµwIL3ÎüÅŒïÒqÇË\ƒyÉT`ߨ{áVßk¬eÛl¢>®±ÌÃ; 4„V/e6¤JJŽS¶ž¾+›ÎŽ8 [öØ;¹™9![W.Œ›$ä@ÀÐ=Mëf!m4üXüö, 혻-iç—ÉèßžVÚ†Õ¹¨ˆÐ âà:œ:b|¼èx šJÿOÇ¡Ñ?ÚÏ# ‡ûÉ8P@vÖÈB}[ž˜ž²Š­ô@à‚b*2Zð—ÉÖк^´|ã“ÖuèÉGpýSÞ\s JÁ¿é¹»ÊåÿÑ|Þ®~†?ÿ endstream endobj 60 0 obj 2531 endobj 64 0 obj <> stream xœ½YÙrÛÈ}×W ôb°Êì 7—Š&ŠØŒý ¥T‰˜!‹dåësnoiZ㇩”\ZˆF÷]Î9÷Þö× b<ˆèËþ,wgù˜÷ýYÜŸ}=ãúa`”»à—ÕY¬J¬â"À¿ÕÝ™y“",–A«`µ;» —|!’(äËÅV¿b?ó–´o-E³(’Á2ÁúõYXuݦhÖ‹ÕoóÍÉdœä8k8‹hódz°îƒ"Ø·u3T]0´øãnlÊ¡n›`ØCðXo·ÁmŒ}µ Z¼®îhkXÄr)§ýÚï*,ÆíÜ-x›’4,¶ÛåmQþ>m{×vÚe%,΂%<Á‘6‡ ßÖÍ}'Ú®ÇaCU8úöÉúãÜæqÌr•™óÃËúvýXtwÇN§LÙìèý%Ï9K°Á2–.lEw´TL˜ ®(TæÒþkïòÌ8«M ŠnÁ3ñ8 ïÇ]Õ &d·Oú%ï½ õšB —(3›âÇeΧä1brîÒˆËK –ei@èÇïZzž²,Rôœ &sa½ » =ÔXâ´Ä~.ñkjY÷CÛÕe± ºªèÛÆxoœõiBLÊv·ßby…»ívÛ´ˆ‡á#­6]U¹Ä3‘Kî2/às¬³¿/ºâ¾+öJ|_v5€GÛéwº¾¯o·UЗUStuÛ›ª!üvíz,`fƒÀµ!7éœKP`ïÅYÆ’L‡L¦lj]ÐÚÄ=äô› uSLáR,çUÂ,†é`IYô¤ß´CÅ®êûâ¾¢8í;“yX×ëv‚únÒfÜ݃º×IMÆÉ2¢°©l®m.9ãÒáä~fgÂsb¨ð¡Xœr®ˆYþ?TÁu8½Ÿa_Éí½€8çú±Üg㘮^=²%Òéø”™²±2©ÙæzÁ‚RDk”`yªÄlë«ðnìpÇ$Vü¾ÈYžåR„”ÚÞAIâÃ8 {f0$TÄÒT8°#™Ð¿«»~xickN’7ÆÜ”‰(ͯaêÍ[Ïá”åy,‡I}¢4'NvA~ê§à<î }UÖF&c–úLÕå ¨^‡˹H § MNYnS¶nKm©KµÕ$Ï\䨝|¼^X@ÅÐ:¯þÓVMÛ,›éµ±ši‘Ф8^‹$‹ý®ˆ#=ÎGl¹Ã¦ #’¬9Pß7m»k[]J‚–Ý×:œOg*68¡àô&¤‚”šr2”}5•Bž}š² qêªaì e}»;Ød£-´fE’£nÄ W¬Býe8ñô@ÍKÔoœ-7uSƒØ9ûFc# Ê¡/7o.u:ã"v°ø|óáïu Ü@|~û!(nÛs3éôûAçKjŽôàzQÏA:m'ƒ¹IûšôÚ¨²ÍŒÊe  d‘Ý•ÕÌ„”œ'¡!Qîù‰RC¹OUÙ6kϹgè_’8Ï~žtåJ~OºØœQê0JyŠtà×tÔŸB;ÅT6£ÀL;žfžvnåD;AZæ4Ï?ÿïËKW*X—"ÅJð‰u'[’X¹œ†C{ÜQ™WnÝ¢ó9Ú’‘•7Ów†$yƲ95¥­ØÚ•ª0BZ4¶–izWSÐËv]9^êÖ_äÏ“V¹ÉÒ¿Qc1O5 Û[˜ä.ÝÖ K꼦`¹ßÁQþ{‹Ü“Â)13_S]Ú˜ÛnH‹ªPÎócqXº—\µ¶UñX-øÏÊEþœ\xÝù?ÉÆªEú¼Z Nç&=«MÝÍeB)Iß‘þ\mÎâS*¡O ÒÌ™âò„JÈ9­þ• i’S ‹òûC•jRÛ$~á¬6£ÑL]v§žQ‰ a—ó9á„JG‰/ßß«D‚¦ÛËæÏªDŠ=]tm£*ÃÊõÄ—Lä†/};[ûúâ-Öß¡Dâ]„n»Â»Ú% %V;õ4Í@µK¡lð§ì*}Mx¢$Ä´”}{ VŒ÷DscŽá0Yuþßóë…•ÛÜ]pž,û‡ÃÏâ-ô'Gÿ<#?\KÙoÕÇß}9©9ÿ,ˆÀŸcý]“ùsrNX®MÇl0Á1ιà»áÇM]nL׿„6ëHJ oÂ]’…_^Í/æ’ÄßD|‡a„ëÛU÷{;í¹aš¸)§>ÈtÿÑw­G×0(¼»B·Õð±ÚÕÃ`›-K4)Ψ 8§?EÍóT8G`¤¯Lð /ž1±Ï/\ô=õ,"%æúÓB¿½Õ†j2¡k˜ }êôt÷¤eˆ*ºµí àÊÑQìÕÏ„â0)"õêd„¨*bë«»¨Äl-²ç0 £Øü߆î¸M•¨…2~«ôx†U`¡÷{4Õ4Ü–ínW,ûŠn׉}Ûun÷zž9ü_‘*Æs—×VÆó|:Ѱ£×=µBÕdÓN@@•R³ûýÈ”"×éË8`l?<͘^”TQ´ÄCšÖÜ9[+Mù«*A¼N¥6\r“‹Þ«íÖ\X¸Ý„ðqçÀå³r®Z,‰_" ~-š±èž >m‘ÒHç“øÿsoWgÿÂ×ÿ¹'‡_endstream endobj 65 0 obj 2817 endobj 69 0 obj <> stream xœWÙnÛF}×W üb*°&œ…[<8H ¤hÑÖ»(r$3¡H…‹•ôë{f#egiár¨™»œsîÂÏ$¤Œ„úÇ}‡ÅËÛ„ìûEHö‹Ï f¾$î£8×ë… ë§'ø·Þ-ìMFx©$1YwÁŠ-y|µü{ý+ìáÖŠ‡‚†¡$«‡ÊEP·ËõÇEFCeVðLPžÁÅ Nª+ò^‘ö8TmCšü z’wŠtªWÝã’Iše±TI†– ŠÔÕ¶<pMEÍ6¹¶äÝŽT‡c­ªrc¶zUïÈ}ÐUQít@,4“.  *ô³•ä‚ ‘“úqhc|j¬'‡ü+9-3JäÍ C‘DNj•—U³'ãñ¨º%D$‚•I±Và:²k;’—e¥måµK¼¿_R›|þ¶ÖH4_^.VÈP£ÊcšÈÔû˜ë` ڌѧÌgQçÛÚci`4Y‰„&IÌÉŠ›cwÁE©vKùX›ªßôÃa¸¸2þuâðÁ¾ªþQøêUSÆÃ¦jú¡ ícS«f?<øùs Eîª þ:?ï¶Ç¢-Õf TÜ“ºj¾ý—7{û`ýâÎ>t‚+‹4åêzkVÇnNõÊj&L‚½ælæU1´OEŸi¥7ûí}βøYjð·´Ü´¸eaœÊŒs¼:t_0)#wÁ—\‹çJ+¤Wƒp£V&²WƒŠXJhÈXjx!(­ ¯Gð =[’´™ó¾'Uc#ä’Æ"?'÷U8'”Å:̈Æ:3”˺5J3ÁØÈR_PqfOÔýüE + DX¤Èëb¬‘ê@çJl®NQ+#Içèiå%rÖÄfÊ@€ b†^'ßœþµåÇd´c]>AÄú] ®~ü+æ Þ —Ç!c_t}~N1z’/ºã±k]•Jˆ,m‚€/† -O4ÿЉ }ˆÓT&aÝÞèrg-I‘BEÂyøp=»NiyÕÝÞpÒµãþ·µW=IuãÉ~~?‚ûظ¿½‰(¹®k},4 …»Êý‘»ä£‡i\|šˆÌªTëº=¨ál_‘­my‰F+—é;«>–Å4‹’‰wÊb+±RUSöà–¨F‡#Ð0qàës™ ã±êÚF—)9=äZqѵgSCËtûÕ¸†©ë)ŒÏ.éÞK>Žý@ ´§½»·‘y.2†0#7¡ªâŽ>™ò EÀW5sÄ•7 g’J‘xYìª ô„†gRmYšœ ‡_^ë±`ñ}4³2¥©ðìÉé¼)JÞ+Ól¢„¦“g£ãF}0ƒF¡'ZÈÜv¬@£”rÜZ‚Bᢌ't03-§ª®‰¯O´¨î+±¤é2mÚÓwK(,d" ö`âÝûk‚NK®_¿3ŸE{8V5z¶ŸvBúiñcßnßàœò0òPª®k;ôÙF"2IéžwvÇ` yÍDÒ0ìGC}Õ»&f FÇ{l«Æ`ßbÝÆ®!ó~ÀA¯œŒÙR© bÂ!öÔYÌuýWÄS×@4MÛØfˆNHå¼tÐÄJ/hF@®qÓ¿ˆúƵ¼!“ùØžE]KÍøm†®ç‚‡øÒdÂ$q2ÑõaÒ(1R«º·ôn•é¤à›ŸÎ ‚[‡•m3Ðí#¾ <ïQäжô¾¼M &ùDÍfQF9Ñ#X£"xêÇå ËÛæk‰–™ ZŒïaƒ®c:9º6Ô¶Ùf(ì¶;Ü÷Kçl¢bå­®d8‰;@ü¤t¾oט3ä£}vÁsçÏ͵÷äE¹Ý_™Òh7É(Ÿ­«¾êTi ]Ù™zò÷߸_Ôñå¹4VÖŸ 2¶SA/»±1sê™ØXhfãûd—OåÈ©ý¸á¦PéPØ3/Ø´ÞøûP<3ˆÚ£Nÿh”™kë}ÑUÇ¡55f*fj—éT¼æ } Š1tüÔíÚIɘ¨sà ÓÓLÓ9ßNÁü4³Ûyfc‘àó¢\Û— r4lÇ º7ýW«gÞíLÛýå922”ö-Ç#óasóÇíïôo Aì$<ë³÷zžúiŠQÃÍ4½_b@=3xJ£Øïg~ŽÏ¼¤1€mñ1¶'¼…­°I˜}ÁðkW¼£ Ÿá#›Û…ï`¨Ÿ+‚jý5oFÝëyÈÙ|1e ÷Eûô-ðízñ~þΓ÷5endstream endobj 70 0 obj 1694 endobj 74 0 obj <> stream xœ¥XioÛÈþ®_1ßB-¢YÎÁ«ßvð6Yom¡‹Â)ŠÛL$ÒáEÿ¾Ï\"E©Û$…ƒ8!‡Ã÷zŽágRFBýã~»ÙÏw yjg!yš}ž1s“¸_ÅŽüºœ ²,°Šq‚?ËÇ™}’žp*$IDL–»ÙC°`s…XÌÿ½ü ûá© CImfÁŸÏªš/?êí¤ÛN†4 …ÞT/xóçêííÝûUÛ5/n¡o–R.ãÌ.Li*²ÜÏ‚²%­Úª¢SòE?’Ä”ÅÙh]jÖ©æ@ÚçºéH•ïTKöåvKÚNÿÝ·Š<ÖÍnÙ‚3I3N¸2‰­¬ž&Ñ1dšº$¨¾·°WP}…4 cÈòoë«¢+ëJGÔo7d­H‘o·H¡ÜíÔ¦Ì;µ=ü±S ÉIÛ…jÛÇ~kV‘®žDª|7 6û¼y\½4õ¦/T³*«²û|˜Ï_1ÊO5W\ ‚ra¼7Y¶º0“·Å!•qÈ¿¡cœÆ"ô­ÍEªº#›þe[¹îWY‘îYM“eÇ µîŸôî“ÍŒƒ]›uÔÌ„Ý*SØ¿•Ï&=ÇTFÇ6†zÙCÐWåç^ÛK’¿¼¨¼i‰šë–gL_ó¢C êªPÔ ´.j|[ùv²#êú¦jm… „È[¦C}Þ¼ûçêöï:˜x‚¥XCs«°±„Ʊô¨L žœà©¿Ñ4u3bÒ¥˜f©< âúîîönRÇÕÃÏw)aÂÌ¿ˆ8M9Ð+WäÈÔý¡‚lL¼’Ýà!0Ø5yÕ>‚ }žÖª«W›²ý´rW…½š›éÔÅ£Îoé2´(¯08£ÝO6u{éx"”n¬yàÕ=Bd³~z­—8°Ø›÷åS…Aü©xî«O«¢î«nU÷ÝktÔ­¸Öeþ‰(ýkŠ¥…} 4øÝ4*¢œ™^ gÜ£dl"áÉØ5‘›Õz ÕK§vkà‡,¦óEœJÊ¢ø„.¦µbÖ'íÕÑŸ¶ži>ð¨A‹äjh§3LdjÒb4Fp_š!æ®×!Sq™»ÁR»Å¥\y!’8¸éˆc¯ViÁÔï¶ßv$oÏ&%Éh(¢ìë_À§¿¡"räœd‘K`Ý1WlÂÉÀv–†,žØëÒ®Ö2c°h¢7Ó„5uÿôl®Øb2gù×íe€Ù)I½Ô˜{-Íå ÃDOýNUÝ´)b …#Ã`2ÌS¥bì”þ3¦Öhî&2N­b^¦º YcÌå%¦35ô"M|pyµ`wÓdL“oÏ@˜ ]Kj[ÛÞLTýhI_Jª9dTN»i‹ĉÙä]5Õò››DAëÃ4EÔ'æ'{RÝÊí±Z:Õ^„Ë’SjµI çÈlèxdÁææÍÍ5ÑUªñ|¥Ç7·náEåãœešÚ³ D¸¸‰‡Ê3phw&‘3áT¥!`zOê‘k]TùÎégv2š4³Îë!@%Mö&­·Ç®•VU‡å A®3Æ5›Álé§Ü+ZX½^ÏWS*“0Ê ÙˆOž†_ z@OÒ3шû\ê^=C»Ýoêݳa[ýÍ8¯TLF¢´>?Öž2§ÿçÌ<àfP,µ­!›ÁþÃÜ: wl¶÷Þ2¡ilMÛM…ˆP`tÆÖ™OÄîŒÿ°^h£ˆ79ûq‘PP}]ó·Z…¹pDGì,ÝrŒnâP Ûßk¸êiµeÀ|†^.ùÓÀwµbá=~*¹üqcàÓ(ÕÝ1 5²5¦€Àt% e÷c™J§û_Ê Ò8Ô}ÁØ({.)«Vá¤bÁX‘zý[‹ü,bA¹E3Ïf"üæ¾èÛò“QN#lÄ´ði‰¢äÚ™c #X Áó  Ü:«ÀÑ.¿;¼”zød—W—æiøm¤ÆàÐŽgÂ÷NŸdl35?À3‡ièÀìUòì „=M¦,è€Õ|´7Vá¶Ý<²OèTmeµ1À?n¥4‘ÒOÅ×|lÎxŽö1ÐØœlUõÔ=ȽBìøî:…6¤¹ÞÖÅ']4Óx3$StÞ™éIJ|¿žh.°nÆ2åÂÞôVô­!$ifBWZ0xÑF[1ÇiÌ®F¶ºþ|t‘Ч´’DÊÓ ‚fƒkGFÒΩãÖ3ΖÜúXÙ®°tŸVoá”O 3®NP÷ ú:Ta¤$Áøà·ˆp/K3ÃA…{‰´9'ÆÂÀ×Û½ªRƒMGG ,Ò§£ŸY:[«n¯TE®·G#ÒbXöÏ%ʾWØpƒï-í¶ûÆ8³¢ve‡óó@9“ ÿkÓ†óãÌ o•o}¶<‹^OÆKúÉl…æj…Öæ±duàju¿¼»þåýêîúÝíÕ/Ë›Ûßïí¤jɘ´+µWm,ÆÆ[OþÌ>©§öÒ—I£ì¯‡eüR0¢ô/Õ{Kÿ‘i—[Ài«>Œ«H‚0uŸk{–Iàeƒ5j …³q¶Øz¼æBdÁ•·S'o9¾_»F’ FÇH¸tÕe‰ðòà×hŸAOmYÝ\.ôA?•GϽïÆÝÀ¤8ÿš#iŠÏQcšz^ò0Ë ë¢ÆNÚÖD o6²ªièÛ›M—}SÂ~5;rA^±†¼‚Þì²Q›×äcßv†÷ËÎä¬5?¢×ê¤ÿî‰øÜŽ–5 ¼ºÓ.øÕ(÷5 Xzõ-PÂég1›@é_ï½}ws5Ó¸| x§Ä8h[MÔñÃ:9»á>@âÂÙ×O™QÝñs©Fy¥O'öœv¡y’iûœPz{ÔuWúðƒëwjøðq´Í_ØhÆÆ¤E#ñšÀkü–W}Þ9};1ûwN?J_/gÿÀÏE0,âendstream endobj 75 0 obj 2242 endobj 79 0 obj <> stream xœXÛrÛ6}×Wà-”ÇD $ˆ>vìÎ$ÍØ­«¶Ó±;J„$&i“`ÿ}7Þì\ÚI2v„Åb±{ÎÙ…žP„ Šô÷s{ZüpÇѾ]Dh¿xZ³ˆÜí ý´ZÄhµ+Bü]ív'A”S3Äã­N‹û $KšD —ÿ¬Þ?»‹¹]!bE … Ø‹ 8çÍn½—jÝÈc½ÍUYWë²ÚÕÁÃr¹ú0>’Fó$†ca'Ã1üº:/U£Fª¦”Ú<„;eúP¶‘ð¶œXÛO)mfâ¢g1'ƒ?jl ±  ÚËJ6¹’Ú<» †¥ ¦B >n¤š¼jwusZ«z]”íǵþÏk—".ÈÈžW*jÔÖ'©eµGçRP©°¹œ6csÎ}p[¡Ý’D8"4 òòØ5 u.º¦jMúGq ޳Ddö¬àê¯õÕû?××ww·w³€2™³ÒÁ8w(¯lšºAuY)Ù uhên˜¥ƒp†Sê\˜-³XŠ©[Çv)C„˜\²(ÃQè`\¯S(·ÉJ‚ ެ…¶7•%ÎÅ}0J÷’2,²”“¼ÛO) |f™ ½CçPˆ+ã÷÷r_AÕ¿^STÂqÚCÀîýu}%7Ý›ý¥6Ñ‹ïýâµNÌ…M)„ôfœ Ð:sÑ@˜‰hÀÜuÕVÃr–õ4Å$eÉÿæŒþ8›ó²…KT7徬ò#ÚæÇ#R, ³ œ»9ÁiÌÍîºSBA9ÚH¥cp³3©  ޏ+¡Þ”ZðoÁ-êÚ׈ÆSœÐì{î¸Î_¹e¨Õ£/‘©ñ} ÂhSÇ€uú¾m~’èlyE2ÀÌGs‰Cn`ÓË á‹„ú¤¹ Lä…pÌ26&·w’yÜЛ p”§0!zOŒé€~f± œÄÔ³¸×ÎVT¬7ÏJ¶“ë÷ ÷;cC@PT|ÙËwû5®8_—€ìéò…<ö« ô…ü<²ù£jÕQV{uÐK.µîhÕ ‹IœÚdÌØï&ÅŒÐo Ä0‹¦ ûzÂûþ(μJ§®U@C"©EõQªR•“ŽEˆ®xêv|’&Ì×ühx‘Øà·‹ 'I’ùM—ç1ú"žú󡉘³pÝ ÀZ7¶‰Bt5ŒÀF˜qîv~ž <ÑÄ$#.³ ˆ ‹Á²Uy£tCË|¢)µ­+ø ÓŸk ùªî´¡¨wȹlMÔ$YŠ“ yÛ˜^S ¨²ðÄûïBAc ’Q ©Hp¢»uz•Å™ áíÐmg€"ÄtÚkon××7«»¿ç8!Ôø³¶ ¯P…fP’¤ ²m=‡UN5üô™,ÍN¥±våOÕ÷žk`,z.ƒæ3§:fØÁèFÿz´ƒ±pgÝ¥Îú>¨+- ~‚°dþXXÜhu´>”N}$ŸG’(Æ ´Ƚ†€Ñ^{µmÝ.íšúdÓÃl–e3é.LYÆ‚oÕ†©yË'&ÂôËÒ¤¤ó‰—x8×ÃNXßyu6ªéJpCk¶¬Žç¬¾š›e;ŒÍÐ#… >YRVxâ8Œ¡QhЄÅϵU™"®Ø°½‘ãYßH©57Í÷€Ún»•m»ëŽØèÁñ }2Hâa83“¼R¿èzY9êû—k+3_ Ð[°!!¾̱Z‹Š\å––‡–"(/ PeÇ7ïÔ›40bHLœöÝàú8g&‚ O˜©œŽ:8èÚè¡1î¤/gøÄc+203œÙ<›X›ºè¶ ³ùã㱴$©ÚA̵ªÁVB£ò#O”ÚŽù¿Â>7@¶¾ ˜iÚƒù¨–4ÕÎDPoG€fðPòðÐaÙÖcæÊƒlu‚Æàý ½ÛDx@> stream xœXÛŽÛ8}÷Wð-ò ÍI]÷m‚N€ ‚ìlƳû, Ù¦mMÛRG’ÓÝ¿§x“¬\X$Aw$’U¬:uꔾ°˜ Ó÷swYüícÎŽý"fÇÅ—…0/™û±»°×ë…bëV Éðw}XØ‚É\r•°\el}Y|ŠVb)Ó8JWËÿ¬Ãyص’±âqœ°UŠE{,ª›}½«͆“fºëÚn™&¼,ã,âfŸÄÆ÷ Éež³õÓ"ZŸt§Yݳ¦eþr­;}ÑÍ€ýÕ`éõn¨Û†m_ݳj7\«óù…m5{êêaÐ ZV5LŸì°|µP%W®‡RØÉŒú¬9{»\ÿµ%Ï3÷>‚x´B¼ s¡DJ\(c+‘˜÷ú™Þ›Ë ÁEâö)ž–t짨º<žõÛµM_ïug\æ{½]ʘÇB$Ñõ¸©›CîQ5{V=.{n)zä_}Žh÷÷cÛj÷`âµrfC¸[&¬åõ±Ûž–%/‹T¥Q{=ïqp=V`¬ïëcS7GöÊæA摳öŠ5×ËVw½ñˆ Ÿëæ!$«*…!™ÙË’MCãí¡6ùíµ‰_¿&çö AEñ">}5bKTî^ÄX®LT}gÚµ•Åç% êÜ]OÙ¸Ÿ5„hÂn¼’¸-ôÔF v§é„÷#ÉÓ-ßÜ;þ(rð‡k­…IÆ[ßvH õX°{½ÓDöLƨ““‚ A1PÊ6äÜÖXÊO öX”žÇb Ï ƒ¦#O2ã÷­dc-zF2¸&ÀÏ! &D¯O~Xô&L#¢§¾H`¶†T@Ù&È;}€ÈjPèC;ËU•"?7ùƒT9…Ê} ЯVõå`ç .}©l!Þv'½{ Èàµ%G™!†©˜¡ß„»Gêkð:úv,Rq£ `2p™WB6?þjZ@Ëÿãj‰9Ýì#CÊQv?Qâ4©¬G=Ô³æ'H¬IO_õwµct~¡ç‰=y‡¦•¦iá{ÕÝØ&EÆU–û X*p’«DT³@Fvü¢ço U’™ÛüºÌ®]f@B)« «´ú¡êÊH(6 R®.&ÝVIRqg“¼®ŠÊø+$ú¨ þFÛ—yIo<ºªé C›¡ÝìëþaCÿùN®$5cßå-Ÿª‚æA3Îl¼œGýÌ2ÄkZJƇ?ß¿Ÿ™PÉ8.Ðy6,hÚ“QÇŽ*˜c*üà ƒÖªÇP´‡™Mt …‡‰aš™Q0(,ù´Q‡ï.¦ÛÛK*ÍTPHà¼tSÁZImˆ¸†z©m£ „ пYKÒ}6ó6ž‡QžAFydŽ67>u¤qЖ¼`r÷ƒ4ƸvèÚ‹Mu‰ÝE1«è½m_Eý8½–ØXßÎ1,Šz:›¥è{ý\ ÄZ;ÖQ8Ž¢a…~([‰ÊÂ[¶j^¶ò[3ë~€¡dË=Z»ü„qRň±L=£·­-ý̀Η<·wz*1ò0«»ÜÐ+dcÓ6+ ‚ôS¯ô;ûº”4åQu¾j+Ü{"ý9+$)´¡¨k{3b\,Â;|£¾ÍŒb_uŽ‹$ÑTè<‚gÂNVGbµßk;7’þ1³k·>€åœJ4„‘7çyaÀ˜ûÕ-“ù3À™Ä?mýsÊè,á0+p™n¶U|”˜(ÇŠÕ#&9«¿9[[V˜Z”g AS‹)Ɉ>Lxe툲ù6maÛ”0kzª§üÉá£Ä\ÌÌ;tDrÊö‰C!ðäzÚ;ˆÄª7úŸ¾ ˜Ï5X^JšXXXUäL¬ É›“¾} |œ¾ŠInÙd¢â©ºch.¿U͵Â,Jã9ìc=ÿxûf½ø'þü°¶endstream endobj 85 0 obj 2324 endobj 89 0 obj <> stream xœXÛnÛH}÷Wô›©Àêe7ï“Ø<›‰gÍ ñB ¨–ÄD:¼Xñ~ýžê›.öNØ!ûrªêÔ©*~e!,¤û»Ú]üã>cëþ"d닯B¿döWµcog›UX%$ÿÙêÂìLf’G1Ë¢”ÍvŸƒ©˜È$ Òéä_³ŸqvMeñ0ŒÙ4Á¢åEÈÓ8c³=V× 6ŠUmשj`ËýD„XZäAÙ­æ=žÕmÚq·P]ÏìêN}ëN-Y?TS)®ïŠDÄežîf5™ý›Ç±ÐнV]×vv3)*,-ìŠR¿.¸³\Øgëq§šÕ=½šFy Ós6Åd™4íÀÆ^-9-‘xöáBr™i{ T§°5­³B8lÊA›æ,^<ªge5ŒåvûÌŠí»zв²aj»b«É% ãð(7ðO½Uœ½× ž¥…ÃoLž"î¹L Ÿ„ð‰µ Pß轚\Äöàˆ'8‚.w[u…x5}½TÆÌ—jAÛ„Ìx‡-zǸž×ͪõ–•Í’ÕCó·mUêGîÕC ¹‹Ù¢¬¾h¨"Êyšx„°65ÌYÙE” Úq»Ä‘ý¸À ð¤ìûzÝÔÍš]jr8Jd©G§sŒ½ûÒsŒðŒmÝ|‹%Ñ1‹‚Záø~¨½î•>uêŽõð’Øœ;´k…uŒâ0UûˆÎIâ]²Ÿ¼(²$5ð7¥9ÓEGd/òÜA6î|R¬d[¥(äy!¥[cn:°ºÀ$ ϣ“$‰N"ó0áì®ÑÉ’åܯ“nÝç ÒðÔDÄÀ“Êà[¹«í8BâqÈxÄî<¹¿býã¶Œd¼ðÎX–CÉG¼X´c³,»Za³Úa/eë‡N•»ŽE˜-ÃãØ²üÛÃDsÇ==pžÒ,î‰j·Ø"@í8<ŽÃ•<îWeµ9ñØÖÍ`ï/›£}Ëš$«>I¨(x{–%¹pAÛûÉ„‡‘ô^–Ò¬©‡ + ì0ç<èa‹"ÑKúçݢݲ¦Ü)¶jMòy<´57KA$çaaqüæÕ9O¤Ó@GJ#ª>T$PŠˆSØ`¡û/Ú •…$š‡Ÿ!“”/í¸ÞðÉ4ÍÁS‘·Z# 9pF,ŠS‘ÜpòBAÐ:"*ôòL« Á#Q8)^î© ¡\E˜Ð&äGb>uG"¨¥N…ÙNíÚîœ,+ÅÚÕ ñµ4#W¬:MY8|]»+ÕÍWðj¿™—Õå1()pϰ3¶j¦EïúÌLD:Q€ò×+ŸjGWOÝYN»ÿ„å¨<¯á «Œ#_só„¨ñ<.}yà–D®¤„f9¼êj•­å¤Ô¶»öšÚ°|ÜjQÔnר$¬’ø„º-'ÌN]¯µVæI”èÆà×ùµU<ƒ‚p뜜‰ˆìJ `š¼I¸à [êr U“ž»žVÝDdt|œð LÐÎ!Í ÝxwÜT†nC.ذgDu‡iYÎø!z×{o׸fËÅúÊ$ æ—yù{C% T|£™·«ãÓ-y{v;³‚KæÍ²[ÎãjV<¡Äa­1hÍÑ7Ô ½aº):çìÔà”¶zè6\¹|–YJny‘»ßÏYê£È‡§SÃØQå6 ÌdZ1JYªû-ÌнyãóCKów¾ÒrCžÒ³Ä¡àN=¯†ãj›%®Ø ì3üÓ=h!©wè܈´g^™Ê (¶Ÿ&ìÿçQdÜ–7·~ãä¤Ã¶›S³l J’âQÕÿ^¬R”ü(þXAZIìN*vM«HñÓÌàÏùõ-,(d¾U6Óªü1¿û§U8mɉTéâ!R¯V¢ÐÎØéT¢úƒD!åNšåÔñT•êûÕ¸5­æ9mÑÞ¸Ž÷»´9! œ.ÜÆš‚.šªLI7^™‰]5Zvo)œg8¢!IŠ;Ö’TŽ#ÿQõy/‡ÈçÔ&xE)Σ'<“©k% éæ8m5{šPw#B”ÛQ1É)eÑÅBGomº•¢sù«›j[[Ï3Ù]æ¼õ. 6ÑB<‡†zgŽ^fÀ ªMÙ¬u>ÒÐe’t_£™Ú#ÔgÓˆáv¦‡¤)ѳº)ÅdÜ“uP\<ñTW¯žmëV`"ôˆ‘ÒÐÜxƒ÷—yÏé%mIŒOM0,1´ÁøÏ€µ×ÌÅYxº+‡j£¼ãcj§ ãøvåF‰HKÛÔÝáËÍŸÇ-¡ð#DðÓýûùõýõü-½‡8$‰c"¦vÛ?ýþþýÍýü›ûO·whÕµ;ÌK‹¥îêEXH7ºMP¾y˜Ð´aGsBGRCî$èé¨Ï<”¹8»ýs@ XLãHªY?™¡ˆ%µ÷:¥ Vyè;'õê˜tvlÈÇÛ’ÐLOƒ¥i°4#~¹ýõ“µ[µˆ2²¶„ŽH6iÁMPù[ÝtXߎ]¥(3 -e!µ-…uÙ-MCNW/ÉO™W»ÏFWEHÍb ýx7¿ù8»×¥æX‡×iêÌû«>zzY·µ…Pþˆ0azP¦l^TNïÒ˜dÛ ^ !SUùr82Ê–k2úÝüÓ_¿¼½ûpûn~óáîÝO3ÐðÓÿêqeHŸ_NZÜŒúƒ—å£9™’¢Ì¾ˆõj`möHã–ùð¢| XaÄH}ŽE9æ$Ó…µæè̇yE5•½öfñJµ=pý—+÷Ù¨ûÚ¯Õp¤ª<)f ÙoêÊç¨I ”iŠ“Š^&P{ð!&Á"Ž­bGßözý‰Ìñ^סPÒ÷ÁDst|DÓ²»VUx7Ü&уdþ\6c‰‰>‡ÝTÓ]'rþmòfvñ~þ v ¸Yendstream endobj 90 0 obj 2229 endobj 94 0 obj <> stream xœ­WÛRãF}÷WÌÒžÌU#å1‡l¶–„8›JAÊ%ì±Q"K¬.òõé¹I–€ìV%U«§/gNŸn}FSDÌÿÜß\+´oíŸÔ>Dþcs@ß­­6`E‚ßÕnáNRÄÃ\ Å´:,n¢%™$‘ZƬރ?8µd„cBZJ0Ú.(Äghu\D?t¨Ñ]ßT-ºˆW.TTžÁî&úm}ñ!¦„`BEôi}y}m½&N„RÎ*ººFÅu÷ºÑèhœPBá¹wbƒ¥6XÞ¢¼BºiêÆšI÷d³P3.‡¨çEL™ä˜¦QuË%Sõ¾ØÜ£MÞjã p—%W¢'h _ÃMÝWݺޭ]Ö›¼+êjÝêùlýÙ€)#'Î?±-ªêt^Õ~×—ØHå6˜;1ÍŽ™´Ç$ÐÖØò KÎÒPÚ1ovë½îÖMLÎR©¢1«¢ÚÁÝEõmtÛ²'eyGò$¿ªCÛÑçĸ1 H…G,.¬íOë }×ïÑönn/~)ö•Þ¢wºÜ˜ÀÛV?Çg_´Y—Eõ׉á¯UëMOr»ëw;Ý¬í½œØ^y—Û#[øÃÛŸX^½sD¤ÎN¯péêå¶^øXo€ZÝk´ë+›êŒ0@ù4ÔÓê_ЄPsºHÛVîd{_÷åøÒò²|FwèY–ÚÒ`ÉRaÒá&ý »¢+ìCÐÛœã$KB*–Ú–ú”b*óËgó=ú{*ÅRÊÔó6:ß §¸“PÎÀ¨Ó­¨êwºAõ¥¢Ð`‘wóÖJSpŠx,w¹¯A&ȤÃn€ÂÛNGtl²$z*ÚÛXºŸ­K!fº5ËDB 5GFÀ>­¯~œ¥¡ˆ+ÄweW£†­=Æ®T¦Q^Ûð¯2ÿöT ”Î…‡´»û¦î÷÷Ò‡:R7.uÊ@úÒñÊs«z¦D¥>4·Åìûƒ®º#`霜CÓ‡ré<)…g8!ME)½[ä5¬ÕRJ3,ø*@AÕ«Ã@J,³¥Ù0øxµ¾ü¸r;@Txœ$ƒÜý^ÄL%XíºQÉ™ÄYhGÞmU#H¼)éÛÈÀjÙ4#jÞ4ùs ÕÙ¢)ÃŒ X;\ÿÖMoã×p•Àd¸†ÿ×L9Ÿ¬«tì, h(ÆÉŒ­0e¯®gÙPj4"LÜaÜÓ‰Êî!I±Að÷£&(¬²ä ÆÚ¼Ë…™i‰ør—¿*‰KæÉÍwPþ¡nl_U3ÙéŠ\ñ(wÏóT¼»ÿ¢7 î!¡ æ3s×y‹»3øÙž}Œ)ôx–ŠH›Yoµuõ‹9Övá²( ÌÇ™~ÜŒð&Pc!4 ºb«Ý8 ‚¾ô‚¾ôb>)ܨÿ®næÕ‚ôÀΙ~aê$ übk…yžšÝór·š+, ",–§,õó´µÕœÁù0Ì Šz ÷Ó™í=°ÊÂö| ç÷Pÿƒ‡ØG9åD4âv^Š`v›|c9œnk66¨&£k÷$?“¾ÂME.ñ©Žáµ'JN† (äÙðº0º³ü»W‡%Œ›Ã¤Ä“úPþðë\WÏ 5ˆ›BßXmg•šE’P© ê´ÒQíXÆßéqБi“FFaëô`YΣðÖtÒ q¥)?áìlÛ~1~è[Äe™°n–æÞ¿Þ‹É­5©å~š›rÏL·]Óo:tq„u6ì ö®—/ëö 9ÃÔwØmhh¡»ô{YçD¨5ø0k‚\²é벬áÌì7,:¶ßºÕ&³·|­á>¶€èð lt” ’üÁ›àû¼êóæ1Âè¨LÀøL 4}[¿\-~†ŸbnbMendstream endobj 95 0 obj 1594 endobj 99 0 obj <> stream xœ½X]sÛ¸}ׯÀ[¨L„ ø5yê6íLvÚm¢N쎆&!‹ŠÔ’”w§ÿ½çà‡h;ñSÇž±L÷ãÜs.ø;ó¹`>ý¸¿ùqõþsÌÏîW¿¯„ù’¹?ù‘ý´]l›c• ¿ÛýÊîLÆ’ŠÅAĶÇÕ·kú^²Yÿ{û3ìa×Fú÷}Å6!X¤ëó‘}¼¬…çiâeí~÷YW»í:NyšD‘÷xÒìâ²Æ¿iFfEÑö»º©õ;cZ%l#”µg&‰×YŸíZ]5¹]M+ÿ¶Ú¾}nm§×"„#Ry÷G]÷´Ïîz~ý~-á·C¯l»~×ìw•®ïûÃí: —}é}ÏB§ó¦.–;iýf Ëûï‡õö·•×#…Þ³®oÏyOi{³JBžD¾D°¥¹¬†6yÖ—M½ûH èØ[2!dÈ#eßx.ï"LŸÛóÁº!…àáà‰OÜx“‹º-ÎüØj ä\wå}­ –²–J}äÃ9ï‹¶ØQ Ø{ãró pñ¹ã‘²>+ënt Ž_ÎÛ÷6&<Ñ„“kG€Kß7'Û*ÐÙ N”yVUL±¦eÉ`Ì3y1—~œX¿D2&þŸƒa²ÖìMÒE“YÞ¾Ó½9ärЭfýA3Â)ëf ÊÊŽŽÃæB.'×ét²ùšã»Çã]SíʺÐvÚÝiöxß ¦Ly¥PS’šÄÛ4BE¯+×ë€OÉÔ™øx³ŽdÓ¾9-ø1ýÀ“£Œ“¦á®ó¦€Ÿ·ÞC™±<ëúŽ•{Vë\w]Ö>Þ®YY#”š®¬ï+í²pÙÜ,èŸ kæ5ˆIˆ¡GF€{>:¯ù,<šbÜ—´Î°WÌýTŠá ]T.ÂbÛTÖÏS–kvîàň鈳¬ññhº±~%c2 y¬bW;D lfô‰¬·‚4âÜ™·gÍãLÁî{}»æÆZB¥Bec³%c×¹¸*`ŠT„A:K…EüKɈC.¢ôUÉ84UѹzýG#pãeÇš½yh[!’\ ôÉ´qºtɼÓþY¯ nD< §Dàç—ÆäXW{Cs÷›ÙLwìRö†Çweϲө{·Àƒ”P¡àÙ\‡ŽÃ†¶ÅgÛe—²ªÈQÅ]ΨûòUð0Üjï¯ }ØM9h—«Tl›1‹‚–Œå0QX÷mðqÂ?™‚· ù÷O¿~a †°•z_óäÑ L0D”,"’|NôL0ÝŒDk*1¨Ks©]) ƒÏT]¯=U1š¿mê£ ‚uçüà4'„,„c—KÒKqh¨,RË€\‹ñØccÈù‡æTCyÚŽâÕ¡O° å••‚×RA˃Ô7\5гâ&ÒQQá§0n~ËŽ§ ʲº€p`µ­'¢d¼ÓÝÑÒ¡í¹f} _²¢hÁ‚zR±û)À¦-Êâ5C·´CÜI[Çñ ͨµ‰ÄJä´™fÍŽ:(uI8L>ïˆv‘¾šÙƒ@âÁ­g„G³ªüj{ÖXÍW8‰«d¨¼ÞÏ»6ôÇ,¹Ý§¬íËü\e¸¡à8$üé§O|‘ÍØ“¯hÁhÆÞ}yÅ8)XyÂ̓I“¢õÆO$_ `ëúkÖ!»˜ºŠR`˜ôGú/ 5Ó)1Ü\#›=õýs¡ ø¡“í b` ì'\ùÓäf§AÐE ,”'u˜N òYopw"Þ ¼¬:ë¥Ëf8²R Å0@!΀Óõ罉 £Fbò€SãAzoHÊU"PÕÔëªé†&#Lj#”µ‘°èè±›W(“K hàilo1‡~[öfãth 8(ÄDÙȆ6°ßç«I”á0ÈÞzs=ýxdø=Í3+%†Kv¡‰û¦«žð#hPaRj±ïHV*˜ˆþ!Ï ®Ê$k¡e-uûõŒWR³ž(áB)ºG yOYGHµ³“íT±I´¹›] ëbÞj|Wß3wýÊ\µŽÞϳÔ‡Í``AÏ6ª¡ÑdŠ9^ª!ë+Ö”Ét1´bã†1˜‹Ì†®xü¯ƒ®—4€üX‚ˆÜ¿CÌ ­ Mžóþ¹Köµe)ÅtÅ‘æ£i.JKítTAG{{Ýjqûn ›› –øãE>¸¹ÜGË‘CBÊg|÷ÒU~÷$2ví.Ò@7ñÏ-+\U_A? YpPèÍåО"*Ì7zM1÷j/2áÉÞSGÌ'v<¿ñlžh2E*ôüÀ×›8_'‰¹qdz€˜„JAדgÓɘ0Æ´ÝxuÏÞÐte:Q|ó2µÑ0_•hatÜí>¢«D²˜«Ü[–¹)sF1Ê8¼¶°N‡b¤+noׂ‡jÈUyÄÏ\…­¹q>FéAX73a…C'èN7å›M¸ö‚‡°îu­[P<¼¶(Z¬ð15ø¯ï_/±Áwåu>>+«‚޷į“ÖôShk4v¶qÆ—mËvÁE- q—æ3%ÊNDãäóåÏ¿ì>~úò+Ébç(0«fÏΦK÷Ðb:{‚‡Á;Yÿ9«Ï$«Ò—bÚƒ»c9àðúåò_¶«àçµSkendstream endobj 100 0 obj 2226 endobj 104 0 obj <> stream xœXÛrÛ6}×Wà­T'DðþØÖéLÚNÓºjûw44 IL$R%À¨þûÜ(™–ã´ãLd‘v÷ìÙ³ ÿM"ÊH¤Üg}X¼¾ÍÉV."²]ü½`æ%qõ|»ZÄdUcãÿV›…ÝÉÏ9’ÇYïƒ-ye¸ükõÎîG1¢„„)5 ¦¿á·Ó"Xí9ˆC?<y¬jAú Qx&E­Ú¾#÷ _Ô ªi%Ù B4x¨×,W´?‰÷'!«ŸAsª†Íú8ôÍX‹a½i»VîÖÕ]p·\~ué?gœò$C ðˆs%Æ£÷A]í÷ä.èrZ²ˆFŒA?îaVÖxg"»0ú³BíDóy'àuÜùÎ"Æܺœ*½Î>Á:Vä¬t/¥y¹<ÎÝ‹Ëcƒj­Fñ@ê~äÝò©ö}·%§V툎OcÜã¿ÁÂn¼âˆ6N¹"²p´¥°;Õ®Räæ´,iY¤qè(Y߈û%Óò`ÜRNAX¬ãŠs¸™ÏRÊhN¤".ióºþ>0ˆ K`-¤Pk—ÿµÎ¿4¸Í1÷ûÃ$š¼ >õmC,úõstœiNÏ™º9M1Œ[ÒÜoõ G¥9cB»“{)å ´§ðfìŒ'ó”FYÂ\Þ>ã—åÅ%;#N3˜lÙÄ¢Œ†¨ž˜sLÛN‰¡«ö6‰9œÌŠ)‰4f…ÝÚmúáP™ª’½IåÌÛvŠ´|äíö |eeDSvÎd ~Ý‹%CðQ‘[0åÔ_;¥æWãP×¼†H?5•ê”æÅ¿œ™bzhnåÔMJhRt¤ïШ`ßP¦_ªF9´«Ñ”ZäͦVHR5M«m#mÇJJ<9öR¶.CðœæIa´D—5R ™Õ©ä(—,÷bÄJ ®‰˜– !,°"Ÿ€ýtÑ€/ØäNiS¹a}j:d!´èT‹@t•óaZ`Û-Ùâ$9yr>ÑÕg;Heâ2Áä´Œ’à­ÒgWu-ŽÊ“¤¶Í§•®âÓâ²å ‹°ÔUýØhÀ7¾µ˜Ú¢‡UÆ š·Ž•Eò4ï_¢µÚ¬Ý×sæ&z:ˆþ­—©ãnBÓ”ŸEÉÏFWR¦+ƒy~û5bzTZŒR9©²ªŸ¢ºÎõ âÜæZêÂö™_¥–Ç4÷ub¶Ø&có6v§V>α9™ããÏyŒªNjÕY«~Ý´òãZ¹?ϨÈ6ñ]¥-‰Î µëý@Úõ¡ušÇƒEÁBMW&‹#F °²(“ ·¤PÈ„J½0_ð ×€™†»+çXm¥ÅóóÅ«‹þü½“íV×Ù×zÐ]×ýØ©Wâë¯U¯ªýz/º­Ú=»êhOY7Úªvñ3+qÔ­„ž<^poZ†S/½ÑTþšF?™ª,^ܱŸÇ–ýo7¤õ$gŒC+É §AÁ͟뛟þX¿ûqF«¬¤ÑÄ}®%·z~ZËbŒå¤×Ó|EBÐ(aÁn½ðÚ©ó¹2iäúéåÆÃtg¾jÇzç¼&ÍxÜ·Vfý•,-ˆD#|>‡r㆚$ö°ˆ&~nþüæìhaDÖ>¿ýb£ÍÔ¸d*'7a'”iÍçN¹õõKGôC0³Ú@GBaïÕ¨«ý7··ïng@b¡/ Ÿï”G%`ùDWÛmggø;‚¾~Ls­ï¡ËTßc²<ð±¤%Í5câÌòJœ¡¼dû'vF2õ°§ñ+‚FöCÕÕð@0‘°óî†<'æ_y³ZüŠŸÐíÉendstream endobj 105 0 obj 1775 endobj 109 0 obj <> stream xœåXM“ã¶½ëWà¶”k„$Àk¼s{ËãLää°›RQ$$Ñ+‘2 Y5ùõéŠâh&ñÄÎ%5S%•t7ºû½×à/$¦ŒÄø×‡ÙŸžÙv³˜lg¿Ì˜{Húâ@þ¼œ ²,`ãþ—›™ßÉWœ I”HÉò0û-øœ'q/æÿX~öÜ.M˜ÀM  Ç’,’Œ,Ë™ [pžQ™Ê¡¢T ÝgÔÍ©.lÕÔßiJ™ào¹îÛgâ\ gÝïëvÍi_’µ!p¾½)I¾løîR½~¶’´ñAÊŒjrèÔ>Æ2·9Ç­²jWÌ„&iï„Q-ýÊ_Á".sõ挦"É ¦]µŒ©IÑ+¦kPë*©Yt†Jò%ª›öñ=ÌáÁ¹­¬…­¶!eÕ}ý2§óEÊ͘Œ,Ù´î÷¾ÐпÚl(4uêó\燪 Ý»Ö7En!”MÓNòÏ`ø¡/Àzë`î ]q ´_uW LJ‚s¦û¡wü¨.ö§ÒôîÁ©;egÛSaOpÊcƒí^â)×Ï“€8côÒ>žÔ~-ºâa)•, ­ @võ”HP™ºäIKõ¾qêÆŽšÇV}ßÜj ¦qêÍ{θî‰épHJp6j ÈÈ¤Òø6@Ý}So¡{û~e™¤è»4 mÔYJ¬cE ŽCÖZY®»Ib™ óñ﫟þ¶zü~¬TP÷´±!Ý©(L×mN{s–hªôóè±öôJ*Kn»ÖÀV*å׮Ÿ&ÞaaO|regìÔ”ÄîСÀÎïĆ(ÚîÚæ´Ý¹Zú–kç©,K0–×#P?æÕ/ɨBõwsªFêZìô¼«˜ñ[úL>Ò?@;c,ºpçTý‚¥+õó’õSÝUÛºä&þeð·  7¹Ò?L[ÓVÛªÑèõ å´GÆzÐ'¿ €š±Â{ú”,€ôÜ\@*A߂ޠÛ^áÚ¯ ˆÇ¨jˆÅªÞNó¦M”z—\ ¿/°òêY±âØš $ E¤ÃŽ>ä¶ØŸ=hgɾZ—ç9ƒÈãLGCÈ´¹‚÷R œ·%í5gã Eüp%ˆ´ÿíb j«Þ¥‡0‡©l¬‡êm=Tü"ˆê5Aä  b>É —òâŧõJ"1r¡c˜ÚÒ±Bª÷(¤|)oÒD `dÈôwHvC!ßPì©Bê›)þOÒ“m/U䟦mÈ ™ [þK™ûáñÛÇŸ~XNñ w-ý?W:é•NIÊœÒiOáAè8q2§G®{^¸®â·Ð¼Q_¸)¡©¾\¦DÒsuYavïðÀÐùÐ.ð[Ž"³ƒ+ETqá÷m›wþ(0üJ1¹ÛÝ©#Ek÷©Ïwx"Êõè wà‡›/@ ?WeeV¶Y•çÀ@*0ï{ñqmÎ[yÏ›xX¬ª¶³hä›?òËHøú.I¨Yôú^Ž,hcF²º¬P€»—o'Rˆ"K~ÂÙ+÷“èøÚÂišfàa¤ŒBGLLB 8ÍqIçKÀA͕΂D¥Ê3€ï¬éÍ ¾…ݱ©È5¥ïZ|´FÑs¤ ” ùàl§joab"îÄ0Šdñ0æå­—~·´˜i|‹§W˜á!Ãobh\[ÍA¤iX±œc¸zƒ†Ô¥A]PEs8Vžêžæ`ZÅéf€MO.5¢wx1ö+a|,€„;(û.¯O9hŒ ìb„*SÃmëúíåýröøûsœ‘endstream endobj 110 0 obj 1919 endobj 114 0 obj <> stream xœY]sÛ¸}ׯÀÛR ÅIðq»Ig²ÍÄ[WÙ>8 -Q2weÒ!)kýï{ EÉ®“‰gÀÅý>ç"ߣœ0ó§ÿ{ý0ûÛMJv팑ÝìÛŒÛEÒÿµ~ _Î$Y®±‹ ‚ŸåvæNr"RA¥"©LÈòav-Ä\Ä,â‹ù—¿BN-“”1E16mfÑ¡*»ùò#Nõâ§IÊ3ˆ4ÞüЯûë„¢I¿¸­Òݤ¾û£Xw¤)›¢-ª®Ø»ç‰X®™èOnîvf=™˜bîîwÐ¥Ù`µæ •ÒŸÄuM]O•– M&Þ ômT¶¤},Öåv.œ˨t 7dÂL+ojÙ´ÝjSÁ‰¢Úkl–JšÀÁÂ}ühÜÒšªh¬ q7ÿgõþÓï«ëNŧA|]‘ö°^m{Eòj3—¦TòäTZÑ4u3¨3ª¼# Ñm‰cÊ8‡Æ ¡9å©€ ÚJûÇ¡Zw%6¯›"7± qr5áÜúIùi&h“åqÅTP!›ùO3Åiʸð—óf»Ê7ãËUW¯6ÅgitØ}¾Î§qXx ½O™½â½ô¥jË]6äqFÍ8Eðg}c7þ¶zoÖ òðÊl1‹ŸF‹eABį`D¿òÁ¸‹¼³^ƒ¢?=»p×8cÊçŠå=ò ?¶NšrWVùž pH½µ×ù~o½)xJ³Tö1üÒÓÂL¨I¨ ‹¯rëA“ˆB)šfY0¼¬Ú®È7î*fÌuŽ2’'IFúLú|ýËõ—ÏKâ3†ZÓ|iƒŸi’Š!øÂ†^f4–Â'°U¸*ŽVá ç8Ð~ÿI Ëªë£;:û#a]æ;bDtùnRìǼAß:û¼¾/÷›³¯ûbÛ­Úòn_Vç’âû—WßýëC÷#9}¶¡(3ŽF[”4Ʉχ㿇~™Q™°¾µp·ýˆÒ+»âá®hú^Ä:¦Š«è:}Zz¥§˜Qw‡‡![Ó2=:\Û·3ß ¬M¼Æãý§ÐÁáÌ´h —U Túv(›ÂèóŽ@c‡lè[) È&¨Îœ÷¢ž'¨– ñé«/v‡^¬¾;¿)îu5$Ç`„ÙÂ_«Ládm‰^‘’ýâD:è—H=}®ç*ãÓ$Úvu—H²!Œ•dS´ë¦|ìê¦%ù3¹›Î‚zíç/Ÿl¯ÕþÞ±éz ±OM[¸­.[^W&h.£)XŒo9íà ´éÍTèÆrðJgHÒ±Üïa¼YõÞPͳbOá„ ËGáZY/?Ç-9£<~ àåaÏ·&¯ZCÚ\ýlÊöOÇáÎ[®H€$’ûh–©áøÊürA…ɘ{/™ÚÌ®öϤ´éíê#G9š¶Mý`>N¥Ítñ2ÚR£ç`^ò}„>VàY¦ÓÆ¢¸®‡p‘†NiÎøÖ÷••F%Ø"–85–èGO˜]1œ%<Ê÷0ç홚J‘úVÕóºÉ½f®¡$ᾚ–‡ýäx_®ï?w§½Óˆ Oz½rNûým„)5R[è¨Õ«™Ï懾ŽÏlÀò3–‚î-^IËQVOO23ûöð½8ŸÚÃ>Dß…ó€œaƘÂ|B…~Êù,õ-èå5…œ;Cù1¸gT‡Ò^ˆÃ䱯$Q U"‹¶Ëqº½'ñ§ûd{‰FÄÞԿʶ;'s˜RÀ¯ÁlÃèñJœ@´S¡¥äºrä@1t鬯q›ç¸M ïßOß ›%?ÖÓ£çôÍ*ý6ú¦†|¿Dߨ#¯mØ9À‘Ð,t2LG‘;«ºZÈ£äãÔ©iB9“¯K LõäÎqXPÜÃrð¬¹}Êée@ö¯ór.¥iQ»so-ŒZäÂØ4€ûBø§|"ŸD¸F«¾—UWÚ?¸BªãWžðâQ³°b¦ æhûZJ¡í£TMD‘€xmQ8äktWµŠþ…H‡>ȇ:¸C)L¾þ”¨Ì\¸B5@Kû1?/[g¡äÄ i:y÷ Wý¿x^#Ø4݇)ÂV=YvYD-ÍÒ7G6xáb`ÁZô«SìØ¡!®v2š¨$ØM?,0óÔ{B¢×#‰k(Nå«ù:;+<äø‚ƒ2ežÊ{6¿¬ÉÐG j–úÇ/0¾´ÓØlHÞuMygY‹–Yt0½ À\ ÎÔˆŸ.§™Ì&N•HåÕa<›­ýÜP\.GÁCÿÙª -É/棬«)[BÏ÷Üô6Úö¯¯-è~OÍbŽ(Ù"u©&¥™‡ä„Ìõö#¹²Œ¥Ñ_i +É=óº'Àå»[óüÁæ &/÷‡¦˜’­˜cV dæ-ï@ñðÌ<¼þ"¸WÎÌ•*ú}õáæf®ì/it}c_SÚ¢;ŒÂ()”¼»ôº=ÂBÚƒ\cæaézÔ®ûç3þWá‰/!–Wlì×¼:äÍ3Lðát ¿¦áUûôÿZ>,gÿŸÿµo endstream endobj 115 0 obj 2260 endobj 119 0 obj <> stream xœµXMoã6½ûWð¶r±â‡DñZ$vì¶Y·=lŠ@–éX­#¥’²iþ})Q’e'› (lÀ€EÎ ß¼y3Ôß$¢ŒDöÓÿæw‹ï¯¹m¹]ü½`î!éò;òÃj!È*Ç*Æ ¾«í¢ÛÉWœ I”HÈênñ%ù’ÇQÀÃå«°‡]!"I‹6‹àLJ2o‹ª$ym²ÖlHÄȹÉÍÝÚÔ„G,¥ËÕŸp–Ƭ/ç— NULV‹ ¦F6Ëw ɨŠQä ?fõö¦47›Â\×ËÎ “}Ì¡_ˆìúÈ™;w»~¾9/ ÙZ°ûcE†u0¬5ë‡[²YßžÙ%ö᥸Ên‰5ÐfxøîÐü}V›²=ú;ßûÍÑ¿{³mošb½/ÊcKuq»;õô¢®«š|gìÎÿnš²°;Jwö˜¦Jºó¯vECðmw†T°[”Ùžl«úŽT[÷çÖ§++7ä¡1uCš]õ°ßæ±hói+’g{É ðàÏ›Ìåä &&9M¢>LQdßõ%(ʦ5ÙÆÚ†KGi@-aKð¢ekê­£皦iÜYá‘·d¹¡ä³1sV¦jHë©0»-Cœð,É„5ˆlL›û†\ëªÝ 85dS¹€›ìÎF\®—#¥… ¡3ˆH¬IAùHmbc­Ð4<2Û”ÿ:ˆps²Ã9MeºÒ­ æ¾t&qII5MÓãºná§’4ynšæ f¨3SY‹&<:™¦HBQÆú¨‚Ú´uÙ§2EL#?Ï¿9¿üíæÓO3c BOUoŒ¡TG{Ô©  AÅ’,<ŒbïõŸ¢i‹Å ïqÎß_ÌœñÄÖŒ·±1M^kˆ÷úÉt[Øõ!zJjÑ× Ú‚ôÖ¾š!-ŒQ&=­àŒì!…9C¬Ç'îÀ  ’êÖË”j–¼xV ¬©àrDøø¸Œö6мíü4”¬vÎÒ.ïc~t‰XË7][/L>tI,è5ȇô%È‘ãµqù^¾ˆ‰40N7³¾jDNA†Bjq˜gœQÍ:ü@p–åã!4UÚ—U`ëvìSr(ÈWÚßö¨*ôpÎŽÒPÒkÆÌ]̨TÉ[Ü} Î*tt@¡ƒ:› *2B ˆA1fˆ.ñN´ž !Î^¬8ò€¡Zš{“Û'X"eU†½¼0–ôZ¾"U‰ùf;Ož˜ˆÿ›‘¶R>L/oCúpëiÙ…þ¤1ÉHÉžƒ=Ž Zxñ,P­¨ÞeOVS,;¬F¥>eÈXê`µÌ¥äýÓMt é4¦ :ù%Ý@2mETë$:b0+=CE E}½,–hÅ4NÓ ¹uU Iv÷”`«ž5!Ç’n8úJ&â ÌSé;‹s„%å™mnóð /V¼®}a”m:uÖT§ ’uÆXÖˆ{´'’m1ÉÚ)Ò`ª4×Kçr&Ú!—è‰x©c¡åÊio:Ý|_ÙIÙvW#Iy²s”<ð)å}ÎË)aP^ƒ·o¥ðˆy² ï •ZÐÃdjn¯GÉw¢7%Ó#q:™¶W¼,ß#ªC.mKÆ 6Ž¡VÙ (|,+?ˆ+ã³D`f‹$>.m9íñš&9Ôß(•ÁǾ»ôÃ`åaìÆ–`NR¾äŸSêǺh/)èÃbàà¬7¯êÚ4÷U¹±úÝy<12ô]!Þ:a耟ççB!i:>·òµËÜJdÂ7$÷w߯†ì†–p6,ò'Ã-´Ë“;½éæyKãÚÎéìJù«@2t²¾}¹úöÕÉðÞÝÃá¿è&z{EšOÜŠ‹g髜£­)O¯Ó÷D£G-è/!WWŸ®æZMkÈ^?Óέٛþ¸hzˆáš'ô0{EÝtûXàbíîÒnhZ‚Z§<(r’Ýßï‹<[ïM‡É«¡½núWGR½:Ï¿:òˆÀk|w„ë‡ÝpÕÝúi'ÞÐW6R:ž¾1ÀdyFpÏÿ•Yý„ (g£ ‚útÌߢ]¬¿àó/qîô‘endstream endobj 120 0 obj 1707 endobj 124 0 obj <> stream xœWÛnÛF}×Wì[¨ÂÜì…×Çv¤)œjó%®$ÖéðbÅýúž½ð"*yh!²¹»3³gΜ~%ŒrÂôÇýnO‹·1Ù7 Fö‹¯ n‰ûÙžÈÏ«…$«-vqAð]íö$'"T$–Y_<_,EÈ<é/ÿZ}€={*p§|Á$e, ~ˆýù»=gõnýi}[(’›¿óB­Eùôè-W/˜FÄÇù«Í…ºÑôÒÇË¥ç¬Ve{³|sùx{(ŽùÕÓ£Úµ~SlàrµXûC»¾^½«ëª&?)ýó¸Äó 0¾ Y02£‘æ¼ðV‡¢!ø¶E*Ø-ÊìHv]¹m‹ª$mEôõ…&hñ8 q* ³·׸ ½/)h cî6´Õ^Á|­7EpkðeB£(è·Ð•^4YáM£Ô-0»q"¼!ª¼R6à&;)üHÖÌ‚ôE$hÉ!K—i\g ŸQÌY„D.¶M7ÆÆi1a¤‰«¥:½C2³~þÅ+ÕR4MÒÄ;«z X7Åéùˆg@÷¼ä Äã‘WÕOä\´júö!!:nÜC£dù¡0^ihü†T o¸ˆ{¦ÂEõÅû-«Ÿ–)<Çi쩺qö&Dpû8®ÏmÌ0HNîx†B'Ïuµä!e\FÞK‘+’!jm“‹&ŒXÙ+Ù„™>—w[{MµäÀ"ÒûÖÖÙ¶Õ¡“jg’±·kTÛ]]ÌÊ^•ªÎ4\ ß¹r©dÀÃy[CÄAÈMÄyEʪ%E¹;vªÜ*ÕÑ&“[g—&õB¦4f‰ËøçwcÆ Üó‡_Lž­w¬Ióž%7íp¦ÜCGŒá§<è¼6£“€2)zÆËÈfX“ä•dÇcÕ õæ ¥,îkïœ=VDDcÁS·2‚ï8νɗ ˜ò¡*Ô·)»‡ð°?-Ä6a4W›%×(ÇÂëök€[õLÃ´Ï 2>d­²ðö^y lh/ãa†J=Þ‡ë¼guW?WÍä@,x×ÅJ¯(ó†tÚuGòèé(ã˜ð¾eºÚnHfcŒÑ„ñ‘K,uìž´¼ºÒä"ñ²²%M©éÊâkÔjFe º+ŸÊÊâ€Rwš¹ÉÝqŽãõN?Ô»tÒz„•DºTúR#©ä"«<=Ší2×­çòy+m…E4Bá¢h´d AJMŠÑ—”%®"âxF¤s]´­BÇ*§ŠÃƒ$é yÖf“Ö%ÍkºI*†–…Á.— ¶¡ìG–,ÏXlSD9©Úõi×ÃFê8 ýšÀ‹ ¦É>ºË7ô»Õâw|þYj-Ëendstream endobj 125 0 obj 1709 endobj 129 0 obj <> stream xœíW[oÛ6~÷¯à[ä :ãE¤¨ÇmÉCº®éw{HC±hG["µ’œ ýõ;¤HYVœ--  °Ežû9ßGê¡Àµÿ»ºŸ}w™’M;£d3û4cn“øŸÕ=ùa1d±B)Æ ~ëY¯ÉO9ˆ„¤B‘Åýì*ŠùœK%ñü÷Å´×k%^+æT¥ ‰%ʳèô1oÖËU[n*SÂ=æE±,J³¼Ï›?MsÍÌd ŠÄhh§õ~yjn¶RÜlN¬ˆÝ|;Ú, A+'ó£gnz㳦©rlìÏõ×G™Æ½kN­k¦€ÙåÇY´¸-[‚ßY£"š­m1VUÛ´™P¨„8½èÁØMWÆ€%Ú¯7vyT!.€Ñ4ì®FˆJœ÷¡ì·Ej.a1¸’$a~ãÖõ¶Zue]M¼ÇB1t¨ô¡–yaì8Í@dÞƒ‰m‘›²3-éÐåƒÕPt*BzùÝÖLóW 5½Ã‰«$ƒ4xŠºÚŸ)ö€{‰Ó󳉮  Ó®šòcW;7±Ð P Ø”{MÍ€ ™í7U×ìYc«›]Ã%JÐÌo> stream xœíXËrÛF¼ó+öfÐ%nö,p´#ì8åDf’ƒ•bAà’BL J¥|}fö€ dYÉ%I¥ä*ÉÄ>zzzfü0Ê Ãÿ»ØÏ¾¹ÐdÛÎÙÎ~Ÿqûø_Åž¼^Î$Y°Š ÿ–›™ÛɉЂJE´LÈr?û-Ä\Ä,Šó_—ïà<·Kù] Á$eL‘E ë׳èü.o6«VßçÍgÓÌ—¿Ý‹38˜áR‹wÜÍ¢›º¬:Ó´¤«ý†p|¬¨Ð<6ÄvCÛ5‡¢#Çw­ÚémIJSíöú-‡ÆÀ-×M}Ø^Ãoƒ;RhÊtJp-.õp&PTL‰‡íÝ•»²ípWT 5aTgTøåt‰«,y"¦,Žý9©Û!]’7M~Ov¦ÚvפlIcoeÖcÀäap=£™Nú<¾¢>TÝ„–4¡*À²ñÛ"u æ-á²"ßíI]íîÉÞäUYm7‡É7äîùIÒ4õ7¬mŠº&¯ÚMÝìW]½Z—íçþç2ºœO° žYnsn3ºPB8‰¹ØÍRn!"ýÑLј¼³96T\%4–AIY*ž£$Íhœ¨)3†ÀíÄäŵ1e#°,ÓxÓ§èüí²5•iàÚn¢ks5‡ˆ³L‹è°]•Õ¦&—‘û,ÕÑ¡sÌãZØQå¹Î×@}UW‹?LSÌ´-M™[Q,ÜëŠ uk%šRÞëWöóÝÁ\Î)YúbX/d ƃ¢6e/aŒP„ªŒÌn}"ªSÆûRYÕ›Mk¦:N3ž<œ'ަ²²:ïIFýÁf²>4 ¾À`YW¤ÞØ•–EÁz¯î;c YdP^i*CÐ{” Y7ùþ4èDD² ÝgD ä&ØBúˆ÷µ?èGZ)ÞkУy(b¨­ú·#hÛª @靸Ý×s)RƒL6ÝК¡• ž7HG*ò³ZA½I•¡0<ƒðÈ&¡rUܧ|[zvàD8;£LÆY¨‚[K‡Fy@¹~cÁp˜$2´:æ‘€‚ëÍ\(Px’F¨ ê/4FöHúÖø¶ó­°¶dM%“!+翬Îßÿ¼úð£MžôcÈnOßY=²ÊUÇô%Tš EaÚ–’C®¥‡5¦i JËÇ jIEªŽ‘¾¹¸øp1mÎL¸¼ŒJ›¡‡ƒšw-&êî ÓójSËái„³tÃaI5!ø¯3L hîaJ8wBÊ U ¥q… ÚÍæ˜B¨àCl‰(N5 ¬Û.»5̳3ckÇÁê">£Ö{Œå‡ãúäP{–Í”¦Cÿ -þÜ\¶d}µ=sƒ›,ßO] yIFóýlþ",ø©jÝ¥/Çóu´àUÁK+ˆæÅ˜Í…ƒãIh’$ýœÝª[ÚT4Ç@v4J}`„¢ëa‰×0^ãÒâµÅ;˜Û$¯¼é€Šœ ã’Åꄾ/øºxjÓ¾ìë’ÞL=ÇÎñá’d4Á¿`ì’ÿÝ¿ÇØ‰¿jìÔó´d ÝÈ ò‰–uvzììœ1v¨lo!ê‘ü[^×Ç2vÆû¥ÐèÔc§¿ÆØ©ÿ˜±“O»¾“>ÛØ}¯Ää±™Ù’‹ç§ÞÉ‘ §Ù¡rÞ;ÍÝ4Z›¶hÊ›”h‡Acn`2™ª³S0p%0\‡7í¶c2€3´µÝ0­z(îA.®êÙiÕO‚ÃÈXèîÙGøôC>C5L^WÞVd_·ÌöÖ õ@æ­ë JÛÖ{”CkП@$ke_Ât†ZëJµ.ŠCÓ˜µk9ØhÞc5'.oë½ MÑÓö_ƒT&ú9•d¶æîURÒ4Íú¥Â-½5î«• p'Ça~˜cÉ7fWy—_팥‡;ix›ŒüØ’nwÓG óö¾Rã’ðÀt íýþªÞ‘»L&èäÊÆù‹ûo79\—¹™w×eáì箬ÜÛËðýŽÓucëÀ> stream xœ­XÛnÛF}×Wì[©ÀÚì\î£hÒN ¢}° ¢(Y©D*$åËßwf—KR´ì¸ha¸Ë¹œ93g˜„QNþ´³ýäã&›zÂÈfòcÂí!iÿd{ò)™H’dp‹ ¿ÉzâÞäDhA¥"ZF$ÙOnƒ™˜ŠÑlúWòìÁ[3Á$eL‘Y—V“`[¬òiò}"©‰¬]Á¨ŠØÃÓ§-žÙ7¹¤Âı;`p[‘äqMIšûœ\íÖ¤~Þ/ËiÒå.'ë²²åò{ž5ä.(×$+U_Øçíå¡…~¤Ð4êÈúB@ˆö -È2'û²²oÏ¤Ž¨ ™qeãÃØnƒM^äU ÝÃuøµÎ¸¢&VON.á*ù€/,Êc38ºª*¨ñ‡ÿ@®¿ )9sáº4¹ JK›ëuAêc–åumI°>fŠÑp⑦‚y¼ xv/{×BrpçyRåͱ*ê‘(DL#=ôÏÅüë‹ëßFÆ"C…Џ3vU䘕+¹,›ír ÃÁ±vòl»žrƒ\3Á6_‘åó˜\‡4ô|#ßR¢oÓûÖB×p£„¤ ±QmœÁüóÕ”ˆ²ÎV°Êë¬Ú(߯vø ÆOŒM!vÜÛy°n”s È)WmŲïÌñÆŸÇX+ÑãìùhéÊhg™å3D“Î@k:×ʽPö…5¥½%€KããL{ œ†Úƒíê…!ª£6,ܶ&‡´®±^iö7i§[–îv9γªPw7’ž]Xˆ˜ãqÆK--áîËãn…3±,rx ¹Ok’ß0¤|± s ñÜØ65y°Ì±¡Ü´ ‡Þ|îŽ9%‰£\:À¼í AoI*e7‹ƒü©gÊ€AÀHî4¤ dž½uMõ`ë#`tˆþ¾ì"ÂkUŽoæPì®3]Á!\&¥ïŠÁ¨•ÃÀ¨çâe{¼±²QûÔüÀü7Õe€¬v…û¼¶©ºÊ€þ*c‹÷b`~2ôaÂ̺þ†sqì^‡ƒÁXþ–+ ÈvØ=CÍëã>¯-Øc¼”¢ÂËÜOìw›þÓÊXí+0Ç– ŠAÕbÑáµî÷ M™¼ Ò aU7¤<€b[¾âˆ]¦uîèPz•wl¶TÉÜUyŠðm†¼æÐ÷®Ú YÑî“óú`t$z P®nn®oFPÄ0ú†•¶»w“V‰ƒÕÆ~Õƒ­ÂîØÒœjÐŒs‹P— 3^,ήÞÊÉZ1ÔïígÄëBúîãÿ].Þ½Atà%¯/ PØ5Ç[¹¾\˜†¾òJ<’u”\ …Ÿ»Z™ÁÜuBoµ_ËW„~&CÄ'ª0V{,U¦ë*¾¡ö¨œ&~]ínïP{F%7§j/ë7Ô÷põšÚ{è;g(÷‘7üSµ‡}"Ú÷Äé‚Å¥zSï,ô3†ã¨›Ó°=¸•þ6É¡a¯Ê!‡Š„ªíné-Œä®0Ñ}½ËÉ©È <Í9Ms©ð8ÄÕíäË&8«voÔ/3o¨L7õ3©šX›^èߥs˜…¢›´Ÿ»{&ÞH!ûÌ(Þn\|qú¨o‡”öß™Ã%<”–#Àv ¡§;—š*ÐýÅZ($íWŠKKʘJühþoòér~9Ÿ%„3Fã¹iʹiqã³ý gÒ›}àƒ¦ôByA€‡_Òâ˜VÏD0Áû·5°MwjsúÿWÉäwøù™z\fendstream endobj 140 0 obj 1509 endobj 144 0 obj <> stream xœ­XMoÛ8½ûWðV¹ˆ¹ü?Ž)œCÛ Ù Œö. EVRí6R*Ë1òï;$EI¦íMÜ.ÄŽEÎPoÞ¼yòD0EÄþt¯ùÃäk…îׂî'?&Ô]DÝKþ€Þ-&-rXE‚ßÅÝÄ龜)†¹@ŠK´x˜Ü$36e)IÔlú÷âÄs»4¢Ünš1Â1!ÍRƒ« Ç,E‹í$I±À ­¦‹&Üà”3 ÁaÁM²Íš»e¶Z-ϧF`£µLË*{(–Ù×äëÔec‰îX³°RÙÄ…/«­†HC›0UX¢D€åÉÜ­ús9/ To«¢Y•Å™]e¯_N’ü[Ö ·vûÙôͰü¼m›òvÓè-Êàý²Þ´£MSö¾À™ßŒœùüþ¸É§Âa`a£KØ"Ù~²fP2m/2‚á.iw±~rÛÚTb#;ø’‡Û¢AŒP}†2t[´-ü›}‡¿UÖ–;)O1‡"zÔ°-'÷T vˆ¬°Ð"¤´€7Ýç{0»*ùµ=w¸Äá„Ø‚ ƒ%±UÓöSŠ™pùß t·©ò¶¬«(¡TÎ|4mG(±dXŠ5›„Ú,7 ì[£r­¡ŒÕ=Z?yy7¥§’²X¡Ûç˜iT7X¡ÀPÖy¿zÜí?SIÐÕÇØš<*Ý?lT«N ÅŽã‡g!òQÓ§‚¬yAiëৃЊñãÓ)v{žPϧ½±ë ðÀúÿUüÃÜÖ›ü[LA{Š $‰³%<;h˜ù)†9ôèx$ôrÚ›fã p½ó}éŸÑžèèm\m˜(g¦Õ‡¬ÚdÍ3b„Ñ!„‚Ѥúãí~u±˜ü??HÂÂendstream endobj 145 0 obj 1488 endobj 149 0 obj <> stream xœ­˜Koã6Çïú¼U^D,IñyÌÂ9ìv´†Ñ6… ÈŠãv#{e9F¾}‡”¨—Ÿ)°`>føŸ™Gù‰¦ˆØOó½¿ÎZn‚–ÁÏ€ºAÔ|e/èó<ˆÑ<ƒY”!ø›?õJŠ˜b8æHÅÍ_‚ïaÄ&LPG“¿ç_a¿zoVEŒÄ˜Ž"óA8ݧåSò{r[UåêqWåhá~I‹ävždë—M²X•ádþO –(‚Íú+§«­÷E^.VùeÇ¿aöœ–èS¶+˼¨’ýºüwU,í^yV­Ë·›É/~»²\ÃÔÜ~=Là÷Þ1£Ú&#Ö¦ÆJ¡ù>çÏ9zÚYµZÖdaj¤UÇ:¹*ªãjVy3Œ,8j­PgÖlQ¶¶ N±DË•]AØ´Õ• Ò‹ÆÔkîOëÕ™}¢\7ƒÅ£tÑ`±á|¹qÖI|R¼‘÷T ÌHãsàþ÷0­½…Œ€ K¦?v¬'û«KžaJ(&Dµ[ӿΈE‰t9䦂—:j°ÑÌ„Cnï(6à ÈÓœ†`¥kYŸ ÚÖƒáÉc‰õzM¿Ü#$p¬‰iÆù6£ù=¾¹3ŽBc Ë™D†eä‰öøœ¶“díû ]bÖSñ;)ö“¨°7^•ã”ù#äÕ®,¶G„ !|‚èH—(&¦«JR¾VxµEMlÁ„ÆÜÆ­ ´ÝeY¾ÝâI$ ï äJÏEÍa†j¨%}€oV)UÙ!‚-¥œdNÀӴ˧é·?“Ï·ÓÛétvOû½p=¦ëÓÅ1ŽCQ¬ìxŒ™ËíP`Ž9Z8Ý `Ê{ÛUûÄpHI-Ãy²)'Tach®»,/“ô!ÖŒŠ ò{5ÀqrBdSv›\Ïņˆíâ*=ö)üÉF.YïªÿÃIÊ0ijí)5ÖmÁ=Ÿ“hŒ‚¥«³s)©ÆpQ I)Üâ3 T0œ¥€€šV÷‘®c¿¡(5U‘öq„H›+JŸG$ÇÄè"½Õ#ˆ”­¸M bÃXçF-Ÿøq*JÀ¦ŠOc1â”à¸'Äuaø@ùøœêTœÜáâ :ì…¢4tPN6W0áÜö¾ZU¨CÒbáws1-œ‹¼¶›ÙtçJúܧ݉µÓÈóÚ‡ §d»¹ëŒÜ¥³ ìlÊ| ws“i@aŠ r¸Ï`{?ÅÜNÕs¹Þ-Ÿ››5ð%/QÚ *fár÷[Ó&ÐÚôrÊòáR˜„ÛÈH†Žö>8°þãI7›Ý9¯%昧.‹©‚PZ/¹ª+Cõ0]²=‡„"”½ío ÷è@Ï=èbÞï4Àü…V¸ƒâ"ÿz¤CývéШHÂÞÍt(6áW]D¹€'=D9¯;Ãréf\Ñó^ƒq=âç㆚K§­HW`\]ƸºãmÓãü]øyÛ§®Oãù¦K¿ñù^—ÑôºD·wb¿Ù…óøœÔ³÷çš^{Ö6&z^ úsã/ªXv pËf*Ç=rÿµ…_ßshA9ÿx`¾¿5fBÅvÆâúÎ8-ޒ׉ÁÐú1Ùþȇýq÷²áûcJsjÖë( â¶Ç£EMYXƒÀÕ¯i±KË7Ä£Ý üR-á‡ÿ˸›Àç?fåh2endstream endobj 150 0 obj 1311 endobj 154 0 obj <> stream xœíWÛnÛF}çWÌ[©ÀÜî·GrѤ)ܪBò E®T2•ðbÁßÙåòbZ©Ò‡¶/† àîΙ9svŽù(a@õÏ>³çûu‡Ú¡pp¾8Ì,‚}dðvãØd¸‹qÀ¿ÍÞéN2à!'BB(Ø<8[×ã îS7ö¿oÞc¼î”´§C`Äg¦Ý[7íŠ~Dý¡Ä¸«Âi¯_-NÉ‘l[¬Õ'Írv*ëæ" 'h<ÊZ4£fGRºZ${”ð0$rddõîöEïHß”\ÕFEMîž.uK"ù;Ø—Ù_•¼Qj·ƒ0R"%^Qé·ÛbÖòýáný³eðR|n͸Dü¨£¼¨ç °×G²uˆ¤ÎÓ&w6&áØ–{+@ÑÞÞÂki™’M¦7Àä®væ\°{Ù™ˆ„þ ¹k2`œùœ)мûAÏ”{WBÝf™ªk(¨TÓVe=—9å$z…˜«“»ŸfXAHú-ºàZ5ó8’1^§a>}5ÎÖmN¦iY¥ÒYµ4qŠ—EM1ü`ÿc=ЦU™§C›Û޳ÆïƒÞfÜ#ð0î‘ø 賿ÈàÓÜ-·ëõÝz–~Ìgز(rÛ>›¨p^0ªÇ@_"e°R™ÒÊìUD¬"`Ìpj¿à(3}"‰–˜ã,GzCÊx_æ8ޱ™.±kç2Bj™; h3žgJóúxÖ¦.4õ™¿™ûÿŸ~»Ñùxͯù¶Ô÷ãë>wÉåÄ8G¾jr‚È8`¯.÷êr¯.÷¯¸Ü»ÁÚú'`$‚Å ó÷ÌïÁ¶VŸÔW§±¢†I•13EžµvÅ"ä“ÿ×nõv¹Z®Vs¿b”¾m ÿ¯çßlXLÀ²=´u£íJLìJ˜DŒ]a¼Ñ®cV S¼dVZ²QàïìŠ kWFzø f?*¬rÆ‘`{Q7×j Ó£¢Õ#/©%»³<~˜ïû´lÓê Ëâl bváà±Ï¿o7ίøû —ÀÎendstream endobj 155 0 obj 1031 endobj 159 0 obj <> stream xœíWMoã6½ëWðVyqIŠE (…S`·[¤uî!)Y¦µ±´«ù÷R¤d3œº§Àˆ3óÞ›yö7D0EDì³ÜïWÝuAwÁ·€šEdå}X1Z—°‹2ë]0ž¤ˆ †cŽDœ¢õ>¸ £xÁ’hñ×úÜ7žâöTÄHŒ á(J`ÿ6«ºGÛCÑîòb»Í/×yÙÔ]Ÿ?ƒÊ»ê®V[Ø’·ábýwœ¢nÓG—æØoù²R¨9ÔªÝVêBïÒëŸÝúæ4^5Þ{±øa>}Ù÷mµz…ÞðoÞ ýÑúUÛ6-z§ôãvïˆÆlÑÙÌ  C®ïÚ uÙWM­“9*^HLEÊ9¾¦j{‹ÈR‰yjÏÃÉõí®ÒÛ" 3Óh§)fÔmzTzͰ@)¦<³ïýÔ"Î|`GàìÕ>û’`IuQŠã(„enÊñÑ ŽYñj=‰@q¢ß@_ÅXô#¨ „ÄB}5;ýÒ(î(–8TÚXË/Ð^À(&rV±ÑŒ:µÌ8µLv ˆ‚ ùŒÈòã•ÏÇŽ”­êJ¸T¹yz‰A(=ÍødЕé:Á o´:îÀ&sȲa),ÂZÁ?_¯~µ¨"舯C¯ç€B’WðŠ“l}E¾-úâÇú'/J™ 7î½µ2@jƒêa¿QÐj¨¨·f“kº‡ýg¹9Thóœ› ‹dÝ9!PÆ0?Á 2Ä@¯Iê@ ¿T39ØãN®DÆc’ý=TQuÚYµ»%aQ*SÜë….²Õp¢ºA“9#g”Íwq3YŠ'£=ø°W-ôAƒþ©7AŒ`’8¦»9½ ˆHÚfo¨Õ™ ã$ÁñÕßß½ë6à^r鸷ó›|93óöºFÝP–ªƒj{Ôª~hën™“DÃé$a bùùÏüú€T`»H¤:ÕwótÖeëœÊV=¨æH’jŒIEÔ<›¸‚ôÌ×ÁÌ8ãÄÉõ&¼¨ŒkõíìZpašºTm1§-ƒóͳÎVsµZ]¯¼‚²ôTPïW¢Ô  ÚÌ$Ï…^gÀ’!;Á0/ÀžÍæ âqÎÆ±fÊpÒóBwƒHDxj%·!¸—ב»ÖZ˜!ý_!FO >·–ÿSøjüŸ/Ü ˆendstream endobj 160 0 obj 1063 endobj 164 0 obj <> stream xœ¥X[oÛ6~÷¯à[墿x‘D{êk×![¦mÉ`ȲìhpäTù÷;¼J–Ý4ÅBò\>žóù‚¦ˆè÷-g?Ü ´mgmg_fÔ,"÷)ÑOÙŒ£¬€]”!øÍ63{’"&æ1Qb³Ì­m0¬d“.¿«×è)o[È¿ª±IT×Âg[àæíVÎp*…ºC ˜1æ[lp¤j=äíYCÅ)X#44«üIÅ$1N‰ðù帗3"ÃÛ ('%›$XÅPHyâ ÊàHÆàºl p Ьž XÛÊ` T'uêÀ!œ$Þì¡0¡˜Æ>îiÿPbØEÏ z°ŽO˜1¡np6ØÀGÊ;>K—&°z ™Ë5qúªÚ#¶ˆQ… ]yri h[BœÐ°¦ õ5@AÊm)UgLÁ¤«¿—nnОòƒ Xp&;ËŠÁr 1NìHMÖ¾R¡ô›9•«H£mÿmjb]p™b ltÚ'Çj·C+Ȩn˦3=1bMRÈÐó]¾ÚÁš&1G!»r¥i$1b»)TKôaÍ¥Ë,#à8ÔpÔäm¸\ðB8 L“Â)>×··7·çõ‡bXêý¸€¿]xx°ËiÐ)©V5 S€–§:E¾^§äõóò0× ®(5¶ì¡Þ–ùÿ,Ææ‰)3¶4éœê“ *Æ* -cú’ŒyãÜÚµ?k×$}ý!£­,¡Î•Œ2cƒ¶ÙR3©¿¡c@Žpžø‰ö",ÓqÁ@‹øÊÑ ãÒp~á"eß9`~O¡÷¸9ëgÚ™héä£9äc?„I?$žZ ÄG˜®§—2¥æ±Š9ŒÛî6s'œ¨²Ê ºP”IE*Ð BŒfùÅy¯§ïµ‘faJ7™cnÅ0Óí4bžèòÜç ’pÅæ~¦ë7g=8çmª Sþ+ÃÝ’*ƒ¿h^ƒÆµrV0‹´®c=C¸ã©ïò2qšõ «Éî×y7-i%±Ôï¼å`&ÜÔª„Ž32Ôk&@Ã‰é½ 4σJ@e¤„½\ ij®Ã†’ÓÔCÝÔ¨µCUÝ×(ž€håtN<Áà HLȯ-»©J~è¤ÀL_µ*xïUº¹xSwÏ~@œŒnƇ“ Lk‹“$ Ù™¡«-&8ñ>ÞUæqÜ5Ãã`OSŸÌEH@ÆRyiê¥Sü<Uˆíî„ZÑqN‰¦Ÿ"hû«²(uÝ F@Ø'±¯ÚÛð¬ |;Ñm•xç ‡``~Êë>‡#Œ8¨tEx{œþ»à:›ý?ÿÿ YDendstream endobj 165 0 obj 1542 endobj 169 0 obj <> stream xœÕW[OãF~÷¯˜·uVd:7{f¤ªÛPu·T´QZ ŠLâ€[pv}!âß÷ÌÍvœKVª‚”`Ïå;ß9ßñD0EÄ|ü÷ê!ún.Ñmt}‰¨½‰ü×ê}XD-VpŠ2‹M䞤ˆI†¹@’§hñ]ÅS>a ‰Ùtò×âسO)D©yhÊÇ„4M´XG KøÞEq‚VÍz²ø;K^ˆ9rï²j³ÌÖëåéD'ð4Óñb™•OËÇ %ð?§qvßæËö>¿¹Ž¯'Ö1D*|¤Ó`¼‹ÄzœY³¿-O›¦*nÚ&GëÞ‘·?0kâJ$NÑì‚‘îùY‘£í®Ì«u‘Ÿ˜Sæþy$1¸ù9»ß  <•íÃÉäÝ^”uq[ækÔúί9æOœUÕ¶Bïsóé½–aê‚r™1‚™s»¸ËѦ-WM±-MP8(uêÐ_HÚ?<1 ž|Qbx F 8¹-̱)0I™Rk†)O´?õ˜››–”b*”¿>i*ØØ€Š·~À>H‚jüdC?„)êo@*ãì5&‰ô·÷å»ç‚b?Ù«8s‰?N˜ÀZSmɇ¶suL=b-»h<F~¥4°=³|œ@œZÓ˜Öè”´Lð“cÐxaÜîçÈN“®³gãJÂýPþ¼^;`ßÍÓÑzœ*ñÆrÏ¡-Æ ËÎ=¶Îƒ+J‹• T2‡µ¡ñOó_=¼hÛ6ŸÛÆc¯å°/ê1îTJÜå¹4&–í:k²Q(Za)i8yÝý”ê&‡†CY¹(O™Lq á ˰_4!LÑŽ•p,SÂ^&ÁbJ¦i€&þØ *oÚª¬Ô=˜SÝå=pc~³$øºò<øÜŸ§Š ’ÒÔæ´-QÝ®Vy]cGJª46`øè.Jd‡”ñd;Vœ'…†¦ê…L§i`‘KkLe—¾¡”³ó?—Ng§³Ùü _ VûØiŽ™îÀ»Ú›ŠhêašyUåY%§¶·mÝ F(ǾzÊ\7H3ÕÁ^¯WÔê]Ä5N Äcbe8ªR«Õ¶¬› WŒ{¹ò\+Êf™Õ­`zO·àø¾RyãÇl¾U´¾Z‘†²ùÞðd ù_ «^,ɱ GõêÙÔÇO(Å+Ò•Bë%ßBº€õaÞ"]œƒ1öUÚ5ôAœ05¯ä%Ý‚ŽaXIÙgv9Âûùarl$ZCA­FÎ`V ÊèÿF®8l¡0åÃX©Nùkr+eìY¹R â–#Á2zõ}ùÃAi…uÖ§MÃa­¤E{WÜߣ›ÃÒrXÁÅ ËFŠmb±žº[aö_=Ú Y¡ Ài-:ÍÓèмڸa(dœ­r«°¬“Me@Båf´‰ž*ÖÛ³hÇÙ“%” ½}È+ öýSní „;‘ÀFL’Ð2»Mb oX ì®Ä ”˜è‘Ê7wY3Üý„E®h@έz±DE§Únö«8ÃiÇK¯n¿˜ÒÑÔmïÄ-"=G±Î› ìíõ¨Ä©Ä|†&Á2w–Vñîþ©“HO2fߺ¸a™ß˜‚#Óo½œÍçóch©´'í=ZÒÄÚÝçD(šå«Ü¬zFøvŽ»7V ÝDàüà}U¿å}5¬¶?y° €N)»W©mÈó¼6±iŸc2˜Â1ì'V–OYÙfÕ$ÈhoBB² {ÿÅýlýŸ$ª2¢endstream endobj 170 0 obj 1354 endobj 174 0 obj <> stream xœÍWÛnÛF}çWÌ[¨@Úì.—\.Pp HêÀ© Öv@Ðe³µÈ„¢,øï;{)ÚŽí·B$ìe.çÌ™YÿJPýqßÅ&ø°p³ (Ü?f6Á}ø¸ "XxŠqÀ¿å:°7pÉI$@F ,7Áe8‹&<¦a4›|_~A{ö–p·fœF„R³ϯ‚p¾ÏÛuö-;麶ºÞu%¬ÌJ¾Ze'ˬhêm—Ýçw»2ÛÕÛê¦.WUÝ]…“å?A,I3´=44¯JhöuÙ®ªrªOéý3¿ÿ—³Þ˜µ=¼ó'NÛ¶iá}©¿®&¸>Èyf=rª=JÂ1…}.oKXïꢫšZ;¤+a2á`.„¯ÉÌðy¢ˆHÜ}¼¹…½ÝTúØ éK5¾IB8ó‡îK½gpgŒ0‘ºõqh3ÁÇàypœñGŒ3E"îíÝçC?”§Ìm`B#WQD˜â…cäGùù`1‰ñ7b|æ6ó{,®P߃f­L‘ÕWÊI*eŸÙÅì±CaÝQçÉTâQ©P¡.É5VÄΤ$‚qŸ÷üó阼óòD),kG(X-nj:åçÚ²Ûµµ‘œí€ž„Dˆ)_xš÷óâºtøÑaêVOè}@¾b†ü¦†í®(ÊíÖÆ4c©"’Ø:¯Á´fíÉ %(‰½‹iefO×ö³M'‰Íjܸî8¬¯áùÙßÙÇ“ùÉ|¾çC)I‡5õa‘‚ÖV'Sá [j$­¸xlØFRÓTEBè¡»]†ý8˜(¤%M“ðPѶÊxdˆÊ¶S}“åW!ޤ±.¼U7— ç!Öêó“´7§£â)&õÚ1ZÜæ8ñìŽñ÷šÛ µñÚÙjÃp9èòÒpMt?á®õ en¼˜õú&©]3ÒñæØy¥±g.c¿¾/kݼ‡©ƒŸJÉdd̘é»”+ùÁT0žˆåÑúõL\×!8¡@Õ Ö•ïù=þº½äP—û»(Ú2ïpÀ¿ót¢9¶lš>aøt±8_˜³¶W|rÔxË@ÌË¢Ü\—-pÊRbXF•0ûз8¶°6ðª#ø ÂYó”8b-5‡±Šãii8›GÒxÓӛ~ókó—2yõ“E_”Ĺ&ÝXÕ^¥‚g4àlý_$0À%â×…^¶2Ò]Ï¿˜X? ãÁk.$q4ìÄ_òz—·X’œF“Øuå¡âŽÿs9]âç?£úŸäendstream endobj 175 0 obj 1191 endobj 179 0 obj <> stream xœ…–ÝrÛ6…ïù{Êc!)ŠÒ¥m¹S§N•*j;;ÃHPB‡´ã·ï.@Qrã¦#{ôà,öÃY,¿BÄ8Dôêß‹}ð~•Á¶ "Ø_î¡+öp½X8‹Ç€ë*ð+9ÄYÌ’ dÉÖûà!'£8ÂÉxôeýõüªI¿jG ‹¢ ŒSœ_áV=I ͳ–¦T’Ö1.ºæ '<á#mgt v'añ,L•ʯ¬5jÓY ¥l £¶1Pá¿Ý©vô.Àˆ(‘Äúâ!ÃôFCÛ…l[6ó8ŠÂ¥iLc.Ab-þÌ÷ä×W‹«ÅbÅ\2ïW3à ¥‘d¤ž°8u{LÙ„q%ÆLY”Ä3DƒÙ=„n·¢,ó«Ñ|Âæ³Ù4\çV˜Ñ¿¤IniÔŒx†ßç“·•áã¨xwÇNÚe*m¡<ÅpÒ^±"ži†(Çyù-ä¦ÛB¹Ù^ÒOë4¨äp$—˜T?ð³¨+ ’g¿ý®[µÕ²„C‘?‰º“oµ/û\éR~;O`X0w ~€®úªUJmU!j° )Ž{žæ„%ñÿmPH~+äÁöÅÀÑrð½ÓMu B.Fj(Óí1>ù4I–$áµ,D×JgrÚŸ}9Èq+* Ç_UçÌÑZ)Jhªx÷Çnâ 0aäp^cÛ #´•¸#ÛÀFBë%HÝtÛÆ–ê¦úTu,óXŠF[¡084hUiHA˜²F˜(…ð¶Ã‚”kœBp-ÕpÊð¢ð™ „‘x ˆ»Û45xC9\ƒ¢îö‰…Œ¤…ÈþçGÄw:²iæ$6ªVö…fÒ>€‚;ªÜÔvÆx«Ñõ ž…ØÔž•Ý9?ÓUr“þëãõòþî&_ÝÞ/o®ÖwË_?z¬idÆ™G¶®'åhçßKË_¾¿ þœM<7²Ó±.iw‡ÏJ[Ï»•^¹µHvX}4LKpµ¢ï­ ‡Zyx#×M!œˆÒèî½û|ʉ’©„ª;#߸ZoW«åŠ9@ èÆ>%MCW-AãîÔv— P• ï hHš³Ô#ô.5²h •í;LUµÒ¢Û(ú±xÁ…$YÆÞ¨ã®¿¾r´qks•ܘÌ«©B¿xÊyWË›ÚWß—·qüèlâòÓqB'd1•ˆÃB’<qÄgÌ]‹Ø”¸kJ E‰YvÞ”Xß–0ïÂ7ÚVYÏû¶Ä#ñ4ÚÒŒ©+÷¤á>ªŽ§¾¹¬Ü}æžxBíÊÇ Ÿ8ýîžx gý‹¥É%`ý tGG1?IdØ1³aϯ,n×ÁoøúÈÙ¡´endstream endobj 180 0 obj 1089 endobj 184 0 obj <> stream xœÅXÛnÜ6}߯ ò©°X^$Qzt²ê mRgÛ¢°Aµ´ÑÅŽÿ¾CR”´²]'èCá»ÉáÌ™™sFûLQÃg~»úùJ ]»"h·úº¢z ù-z³Yq´Éaeþm¶+s’"&æ>&ç]×”YßITè'iQ$盤K›úÞȶ½qÜÍ—U pˆ<08?½–Y¿CE¶;S[ÔâûÙb)Q}_ɦ(å™ûÚ.ü’¶(…kgÏþ¨ÚrWÉóä.=ôóýŸÌJûp›”U!¿Í–.š¦nÐOR}ܸð|†“gfD9LqàGhs¿r6{‰¶}•we])Ÿg…‹€!}ÀyáИŽÈ×¶õ©k6µ(­t|eæÒÇ1u¼Ý>íP&uµkQWÃÿ¥Î”ÇH¤E–bBcåèµój¸ðÊikÏ µG™—[—ØN ðdÚÚ,GÁM„r_˜KNÊJ£e¶âÚ¤+ˆ ÌÊltpý<°ÀDV¶'Qÿ9‡¸Yè·(C ,Y„ ]OžÏb ÁÄ¢2˜V…¢Î¾È¼3¸*0O“I)Å1‰sëË‹å]¦Q0F6KÌi8„²çÂa™¶^²º!4nž@Ëè“І8¦bp@Eçëè °|ÉÓ.Í·©¥†„C³(²°0ìC½”­†åh܆ܨ>BõV?§=•6Âù3q2æ«""° ªœ‰ÌåßSGÖ¸ÚP¡©³ú PÏ$ê[¸[7CœóˆÍú"ŠLœ<п'! Þ}5Ï”b*¬[#‘¨{|c÷$„ПÊð~ !˜±Ã¾Ì÷h\Ù:1%BøF¨-­oµË}¥:Ûn"g¨ž€{Ñ„EYi«‡­ÁÌéȼD#gaS%‚Õ6)æå8 ´—TQ×7•vÑ£EÜ£‘;c©K~c1P€Å®mÞ”ÇX5¯,EÿŒá ý­|ÚUk«¶Ïs¨ä3`ÇbÑ«‡Î§~4ÉË_ÉúýŸÉ›óõùz}µô:`€˜ŠëZÜ Püãà¡"D©¶oŽx!5õ' ‘ØÇÀ i|™¨n¢7VýÄbGë€K5érÇ‚ • ‹D–d7ˆÐ¢ö×È!öÞiò ÏJ ŽQ¥@ô¨"F8ßÎôÈ;^Võ·™l4r}8×c2%ã˜|V»,q<Ú¤ÇI¹²ès»í¹Hn\ìz¨z1]ªiVÊîAíT ƒ5L;”ŽícX< Y§8í…æ²Út¹D/ä9бˆü©¤ëêðĦG·û²[õ˜€)brÉÝÛäÓß¿¾ùðþòmruñþÃÛóÍå‡ß>=êÛ‹°I“~â)é/tÃ..c*OmóQG YvJ†š˜-Ôc¥U ï­ÔD€ÚŠäÕ}§–‡A|y- ÎÃ'‡­ùÅL¼3.HÇC©›b Š…8zºi4Ö³_4v«¿ÏF gfÔ}]£ªî”Ê€“pƒe3Í~úåãõ)»š±}[‚¼­ìËÝ>9.ÕFÕ-³Ëí0tÃ%q~8ö+a¦Øôn&ÜFæuS@˜¥~I4 ¥&¬ÈŽMζ•fÐ÷)ÿ$3äóÆQqAýæ7.º~JF#ÐÝ1'DÙZž]´]’>RóQHé¼1ó#ÂS šV¦Æ’þ ³Ç¶gýÙ²YñÂ@¯]épô¯ «dîèlŸs† !ïÒªWÁ£“ //bœêN$¹Ø¬~‡¿þ¶èendstream endobj 185 0 obj 1719 endobj 189 0 obj <> stream xœÍVMoã6½ëWÌ-’3üÐY8E±Ý6[WmNaÈí(KYJZ·ýõR’-ËÞ¢E/…‡ó†óÞð3P€š_ÿÍöÎÝ2‚]íPØ9Ÿf¡ÿd{x—8’ £üK¶N·“8>D"„dï¬Ü¹ðx@Ýpîý–¼Ç|vW L˜MsN¡Ô‡y !ÉAxÉÁqâÌ›{ɋ㇄ cvŒX¹‡To×iž¯ï=éÇ¡›¬7¯Uöi>¹OžÅÁÂü¾°ù°ÁLjвü”j”Á@ò˜`<¦Àx‹²[6üãz¡6íòÍîÖ„š N‘ð<¨PPJ¥óBÝz7NècÆSÀ·éëÒ¦Ñfm²ù§}úú ³® ü²~ünQ"8c]”`ii¯£Øxœºx;=iSʤ$±˜ï*cÏ2à`c×MZfÊžSHNÂ(Z™);}=¹y¥j(«2­ÒFM¹EeÑ5pvA-%¹·“,âùòê¸U6®‡Sç«L”õ &LìpH=-9“×€ü‹zÉ¡ÅÒ¦ïAJ¬ç©³ˆ7­jU6O¤e>t¤ðV¡y( M…=¢ ´ÜY;dH[ ¹é©úÐÈ ënŸIs̶@ó¬«v÷löù/%ĉÏuwzžÎJ{ÜèB2†ÇF_™ßzŒŠíï¦Åk«Õy§OQiŒŸ·úÃrù¸œ@χÈJXïfðÉ. åñp‰‡Å‘n¤2,ô>£2µß Íœ²˜ÀG­¶hQèy_<àÌWé-ˆÀ쮯Ç ë,_„æBtâ‹Æc§\7XÐ0‘‡kƒÅ p9 –ëc¥ß}6V.¬÷Êù×#æ1\þãÔøŠ±ÂØ ‘s!¬‰½´ucŒÂ=÷)‰ŽÞxmŒO›“‹Èîè _uö7ÖµQÞ¸’ÈVB,ô\ü½€Šækò‘‰9‘Ï»ûÅýb1ÐØø:ñ2£xh÷å¥wþáõ0óô83 lí›ôd2—¯=f<:Ž]µ==ñ‹×Ì–±ù0k}Í_ØÉî‚‘’]ˆ[Àß§e›ê?PМRDXPtÔàùkñ!q~Äß_R;Å> stream xœíWÛnÛF}×WÌ[ÉÀÜî…×GÇvФNœ:JƒÂ6Š\Ê,(R!—vü÷]Þ$Úh^ ÔIÜÙÙ9gÎÌŽ¾% ¨~ ŸénõëuÛvEa»ú¾bf†to×+ë­|¯óU¿“8.‡õnuc9ÂæµǾ[@ý.wØåp*¥.8Úg+«¨dI“ÇI–ŧë8KTÒHüykÙë¿W^@|pp¿6>7†Ÿãs¹é¶m¶'ÚD/^,êÇJ6Y!Oì_Æ…ß’2‡D©æàÙת-¶•Ì`ŸÆIÙÉ—ÖÚ§]\T™üq°ø9>EOŦSÞh§qÝ©ƒõ‹¦©x#õǭψszHœjHŒp$oýˆÄ­ï‹ðý`3—DaÄ-ÙžÞ;ØtÚÎÅxL¦#Où°¨½H‡ÏwC˜Â:|K¶]©0þ ÈŠ\›û ¹ld¥L,.u eSZiÿÝÕõG¸µšÙÓ¹Í#dÂõ¬o±^5Úp™VBÿp%¼µ‰!‰‡F_[™w%äh\ÕYÖ)ZnJ =Òœd5~)ZÕ’>a#ÑÖ¤€ãDú¡‘Ï&&¢ ‚9ÜvI“TJ¢|T  ˜B›rÀ¬­YÕÝöÔ}¢ P&¤u¥C߾Ƣ:å4›B5Iódp9ã‰#q„k¨È¾†Üµ5º”è®,q¿öºOÚ!)LJXˆfS— élp™ƒŒ´GƒÂúq¸}:ªn·‘F¢·A%ЀxÔëwÞX'µÍýDœYM²Ÿ«_`²©7ÐdMØŒDĈëÎJ ÊB?¬¡éÄ¢y!¼h Õc}¨k„œlвPOš³òDä}£éÖ.ë'ÄËgNqo4ådÁX˜Ùº*Ÿ k„ µtê›*sËúŸ_žÅ_þúøöêòýY|}qyuvº~õéËâ(¹d,F×éŸ8:ÇZ`‘ÛssUAÛ¥©Ô0æUuMÕ.Á1J\1Æm‚ø3¾ú}‰.";*ØJªLËgáÉe$ ǸÆ>¹ôÉ7ûA–öêºR½[™šÚjjpgñÐ%> :€…-Tï{9Œ€ßwÙÏÒpŽ"ÙïË¢/AÇPý:”¢Â®°3ߪE„b˜Èæ ý¾´Îk¨j…)—èæ]ÕÃA‹y„¢Ä~8‘Ž­ø¾ØÞÇûÔTZˆN£EFŽ<é¦&+m:¡]’ḜcQñIeGÝ¿n®[J«ž©,2Q Õ¸„À> stream xœWÛrÛ6}×Wà­dÆDqãí1‰iR§J¥Žá@$$±C‘*/vü÷]€)ÒNÛéX3¢ `»{öìÑ_ˆ`Šˆþ¾ÓÓêÇMˆÍŠ Ãê¯5‹høJOèÍvÅÑ6…]”!øl÷«þ$E,d˜ òmO«;Çã.ó‰yî×í°×ŸÃ)Ž Èóa¶r®O®oß&Ÿÿøøf}ûþm²¹¹]¿}½}¿þå³»ýsæ0X€K} ë5¯ã±È¼ÛÕpÂ:c ÁØpæœ&²èÔÂl@1†=‡ð¸}\9yƒÎ]‹ò²­P{T¨Qi›W%jÚZɪºV/Ë2Ó«K·4Æ<ð·ÍÓ)ÉËL}[ú°‘xrL­cy>¹Ë•‰’‡‡!òÀ¾Þivé+Õª¨Rin•—ûª>™g“‘ÛóqDfÿu…ʪE]£à¾àbß•}$ÞC3ý «ºÕ$Ÿ—šÒ2GÕO¨ÉOy!kMl‹œR p¼Ô²3ؼ{3ñ z¸Eüΰt"7¥@ ±íÓÖS?SìLAûíPKÕtE ÷Ø¡,7m„8ä–­½ªUÙöíO´w0§çwëÍGtïÔ£¡E£EµplCèg}`DÌ’íöî;•—tP€ÙªìÞí!#@õ!Gá—Fí»ÂûܱO¡bÆ#íÓy9C;»`¾-g:Etf!?«zÉÑQŒ0:™ _Û;ÏRÞlW¿Âßß׿’endstream endobj 200 0 obj 1545 endobj 204 0 obj <> stream xœ½WmoÛ6þî_AôKåÂfEê´MŠ¥KçÍU7 É Ð2í¨%W¢êæßïŽ%YN ìËvLñ^ž{îžóWbSFlüëÞÓÃìõ: ûzf“ýìëŒéCÒ½¥ò6ž9$Ná)Æ ¼âݬ½É8u\8>‰³;ké̹g[ÑrþOüìµ·ÜîÖ’Ûµm—,=x~;³®N¢Ú%¿'o”ª²M£$ÙêoÄv›¼‰“Jꕬë{k™yõÉì/_ÉM³'ÛÍ~àáíè0“¤<²Úfr1i~ùŽð:úîsQgûBnÉ1M¾‰¼‘OÕ‡$+¶òûèðºªÊм’øv?‡ïG@-Û²K}Ÿ‘ø@ÅYMàõmÎ\EkÉê‘ÔÙ!ËEET©ñAÇF]aÇÔÏPR¢Ú˜’ͽ!K›rwR5Îü‘‘MƒÏAx>Çç£oóîPUx¨ ¨t»[nûøifɺÉäP¡ý9œ}yì6Ïm¶›s¡gíd% EÞ¯ÖɽUõžÊÕÃ.’«¿¼Ñ“™ÈBj‚ÞȬؓ½„r %·÷sª#ãnDC°·ä¡~ìs-wMNv¥±e{hè~ÜÇ£œx ¼î Ql'¸M²3 ÙáXVjb#ŒhççΚüs¡óÈ‚.¨é’%w"Àg“CÏCSï‘ñˆSÏ5s(sݶ@·}#*Q( LV%ÙHl›³ëí½$²(›ýQB‘L‘T$- %°ÊäXfpµgçÒø1§Žô$ªM¦*ŒÞ % Øu 6%ØËs0€f¢nÉC*)r"¡!§M™LKwEè2ëû‚Àý¢9ld¥ý;­¿tæÚ>õíÐà¹(ç£NhGÎ lç dxl€u…j¹RËTeeAj9²Qx =‡§S·Ð<ŽïOA:©òPq<æ™î„n€Á ÎQÅ@*™—©Ð±d ƒþ¬APlJR”Š4µ„ØÀð®)ÚØqļ<mLˆóóí’c:mb‡úcð_¯CœvðF`"n;œ{:Xº”yD%×§6Œ"Óƒ^Ì#ì¬Ð·â¤éD-¯U"4§ƒÇí`"+õ¥©ÿO®§Z=^'^᥸óßäšwZÇûF7%/€}Æó¢§dùItÏkÌ{$Ûm­g]+ÜF%ÐýLÄEUX¤\o ®¤Óÿ‹¥Íöhäõú&…gÔîe‹‡ô·Vˆ¼,ö(«][¾Ð逆¼ i#oÑ\ ‚m¢ß\OS÷i0We ‹‚î(ê2C|lÎÍãÄ2Ìq NŸ»áK»Í *çië’v90y‚.Ö^ƒœ!ÃróFO«—‰E •ý(±h×k%±²F´`Bt kÍLžk@ؽ‹µîù™¡ŠÕ³²ºUqÇwa'瓽m`ÏD“ÜmƒšGïSÚAI gœV¥; Æz¦pæµç6õ©ˆ=‹0¢gÍSšãøçBæz „¬]KË&y'6§,ÏqI* Ù\ì{XÀ馊«ÃOÅÏ‹ª 5¤nq`cDK—ë£è]“¦W Ê£šª¨§ „Í©ï†c=ÿ3Yý:» G5³–jjÇWÀê'å³vî¬nR¯ôaZ§ü‘¤ Ï°mô:9r¬]c—<€}%Ö†›ç2­ñ‡¡Ðev½^¯Ö?XŸAfõ(Ÿ{ÈfuN™ƒ88}o4Ù„ ¼½’©Äu’p~Ehî:ZŽÖdAó˜9(†Yl ¯£°„.ðQ4¸7r›³¾ ü&‚ÍÚ„zþëø:žýÿˆ¾"Fendstream endobj 205 0 obj 1576 endobj 209 0 obj <> stream xœíW]oÛ6}ׯ ú¹ˆ8~H¤ R8ÅÚeÈæjëC:²D»*)•èý÷»¤(YV¯Ø°í¥p¢îǹ÷Ü{Âψ`Šˆù¹g~ï}·hÓzm¼Ïµ‡È=ò{ô*õ8JsøŠ2éÚë,)b’a"ÉJï½;?g,"> f¤oÁŸµŠ¥Æ(`„cBBDJ a ϽçG8Ä4‚tŠYúÉ %fÂóͿϚõ2+ŠåÕ,‰Àœ%~ºÜUm¹©T±ÌëªÕü32 ]†Aï¢GÄFš[o¿,¯´nÊÕN+Tü?ukÒ‰$(¿àd°Ÿ«ÕnƒŠÕæÒ|boF‡¥Bõ¾RMQªËÙEðc¶]£ Þýæ¢Çl»|Ý4uƒ^*ópãâ]J.Y$-¶ô£Bë]•ë²®LV£bH‰©H’®¤þYȬ³í£1c!\;À¬EYe”«Mp’PßTr_ê({Ò]cLNJØ7Á‚Ÿð‹D8‰„Kø13ŸY6QŠ ‹iwÀ€5Âb‡â¡•ÚÖÕ¦¬6H×HC1^XHY¥_ |›µí¥;˜‡1È@þæzZ<\H¿}Py¹6Ÿ€YHÅ!“ŽË%4sõe" L[̆"ôô0ßIÛ#ü¶Ã]@œÀK,cé2¡„¨õê“Ê5€Ëô „ Å”'ñ9„䀰«ckŠU¶è€7‘¢‹çóGR°žp«MTL€2ú<ФçÑ-––nek©pÁ‚I_Z;çw}›,=ÁÀ%9á¦2ŤÇmB˜ ¦\„>÷¥»<""ˆxçW*u‹aýaØ:Ì7ó<ªŸ›“ÓyPì ¶ƒé¤C|(’&$D‡EÊbûÖŒþëÛÅϨ^[æ×;ý°Ó0‘Û-Œª+åN¦Ô'¦ž1Þ/“e‘éìûê‡I ”ö…Z×Í}Û%±\"Ð ·ŒÞhÔ(½kªöDX)0MzoOVò4.K0ï÷·[Áv¸PmÞ”Ö$$da;’@N„HnYRW¨Ýå¹2ÓŸUÅÓí‹& ãÃvz¿œßü¾|u5¿šÏÓT@¿\±ÍÀ½]ѳȴB{º yÜúïL.»ìÙHð„“;>`Ò)¹ MmÈÝxE/³ÓrçÜÉ]Yéc›:úJû;Òöî´°µ÷%ðÔdÖüÂw¢¦ÿ…ð½;'{ ñã¿=ŽCýsÙã _CiNˆ áyÙ3™„gdDÇò›ì}“½CölîŽ}·Ã–‡tzá™ô†R.0&ã=ûÓ$¢„¡ Öƒb Vé©+صÃøÃ;ë©Û衆•¬š~T+ ˜2˜#Ò{o¡†ðŽóa/ßùc&„¡¡B§5¦7nÝß:5ábœx Ö~º\/·S¥‹áQé)h6—bøãµÛ·(oT¦¡½À§¹ÊÕý ÐÁ½+ÆÇþîǹIóøÆ'ìïâ«.|Ï]÷i®{”X­õj`5åF{žÑ™£‘˜û8â—úmVí²æ  `ôàB‚Ë!Çã{îuêý ¿?tô=endstream endobj 210 0 obj 1188 endobj 214 0 obj <> stream xœWÛrÛ6}×W`òR*c¡¸‘‘;Mê©[WmœŽ†"!™©D*¼XÉßw$EËqÛ‘=À^Îîž}FSḐ{¦‡Ù÷÷1ÚÕ3‚v³Ï3j_¢î‘лՌ£U »(Cð·ÚÎÜIŠXÌ0(æZfÁBÌYHº˜ÿµúöÜ)ÑZ0Â1!-BØŸÍ‚å)©¶ë_Ö×MSå›¶Ñ(³+I–­¯Wë:ß:[§eQ7ƒùêÓ,Œq„`p|z©7íe›Ý•Ùb^ÞŽ^æ•§BWY®¯æßù?&û-JÀíhí7ë=%ûv¼õ¦ªÊ ½Õæñqë#. FL@sãü4 VmÛ"mò²0103)=|#[ðäzWŒ„8¦þ$œ©QRØòÙ †‰õ¡„6ê)oQ2 dÁ# 'ØN‚Ù» xZvŰŒ„ìbx²&m‘)8g²sαˆœsmô¾,vy±CM‰æÍ0)š7(Ý'u}Õ½˜ÄǸÄB©Î×òý͈>òùõQ§ùÖluA£!W‘ »ùú %±Œ|£˜}Ñ$w[iç ¯†Ä#Ì9sëÄz‚ ËÍ'6SÒ\HL†Pœo%&¼£‡ÀW„òuI2C¤„ÏÉLÚ8)*9–!$Ťk²ÍîR>Œ¾–σɥk0ë3â¶&‘PöB$”)L#ß-Æq3í)¨—ßruÖP¼o¨‡ ÈPÞÔè ØƒC˜BVоªó-Øñž@Î{$lãó˜« ÇÊðÔö}ƒ*Ý´UQ_¨ka*ã¾®Sj›¸4àðÐûÍtVù±¢ÙÂ3o1á[Z…q?Ùeê6Mµ™¢¤Èžõ7€Ka^ûÿs½¼ýcýîzy½\ÞO#r–£N~Àºe½yhP§€ŽCV"Ê]«Ù#€—‹Œ¹©±À4F6aQø:|7W+)£`µ®æTz«ÍÓȃt‘êujIpÚÝÞ`ǹnæò¢9WŽÊ˜óVþ¥p|C^”‘îÔëÙ‹AÓÞkë²mþ¨$"~MT(¡8TÑ%U9C₨HÅݹÜv5ª“t_ý¬—(Á,@|ÁËÆ{ù òÙ¬C#ñÎþ2žvêeúBr›pªŽD§¡0£Ë×B¹”0UŘ®ý<'¨ÎǽvÒ2Óxê×îyõ¿y¼vÐ'—`’šïŸ¿½ÊhmvXù›Ø¨aCO9Væ-uÔu{8ú>Yp.pH•»)ˆ 1;k mþ¥=žç\j"`_8=d'}œòýä¥É~o‰µµvÐAsòA)ìË K©fÜLèÑ|Èë.“˜aï/›úhZð¾=—MS½Š;ØìB‡Y''(µ©9“A’ï[À~„Ü„éU ·%Ï¡»¹¿¿›ê–Œ°8sM¥¦êçô‡Ž3QZ養–:Õ‡  É¬3ªFíe€› Çc5ƒßJ°´ˆ1œ`—ä JA˜rrÃm$¦Áɨմ±¢õlïm.”‹÷^÷×$ÊØù‹ ªŽ{‡ü ö~HŠ6©¾BNŒ&Lã>âóh7«Ù¯ðù×®Qendstream endobj 215 0 obj 1366 endobj 219 0 obj <> stream xœ½XÛnÛF}×Wì[¨ÂÜî…·Š ”  Ü›¡6N!P$%1•(…—8ùûÎì…¤)ÉIZ °™âîìÌ™™3gý0Ê Ãû™fßßÅdÛÌÙÎ≯~IìGv /–3I–¬â‚Àïr33;9± 2 ±ŒÈò0»÷ü`.Bæ þ×ò Ø3»»ËLRÆ⇰>Ÿy‹‡´Þ¬~[=oÛº\wmArýMšç«çËU]lŠº¨²â7_¾Ÿ…1ˆÖÆ[źے|½½Á%øòvô²,Èñ¡*ê¼,næÏÜ‹ŸÒý†¤pæè;»¸ÝM¿¬ëcM¾+ðãݾÁà—C—U±"ˇ™·ÜdÓUY[+ôjAшq-Z8ÇlëñŽ#ƒu³ 64$­tå—‚YË„8GôãÞCDÊvGRòƒØs/ÝwiwiKJ°¢åK¦hÅÝ€†JèPz§H{„#5>“84öloñúåÄw¡(WBØ÷eg¤IÉŽ‡S¹O&¿«ÊÏ€—Sû*¡‚G_i¿9Y¹Á%"¡A¿­,r²þ<±ìKÓ8û¢rµ‚ëb„á¤ìuºAºÄEºÂ9Ib›Sn¶tåqý¾ÈZöy`ŠS.ÕÀE”…¡«•u±?VÛ1‚¼ aªN”£Ó#}úÅ€eHÃ8rPAÓ¸@£I ‚_ÔVá=h++(¹X—[ÙØŠŠ$UJ9h™)Hë6®Ç ÖIÜ0îNYÂ\Üxz0¥ H¯ƒî&\äTŠÄí­r]l—ª6b°P>~à¸èËjKt+Ôàñ£ ]Ë+¡ðš.t€;v™5®*|e™Ð@“ÐUø-òÉ«_ï~&lj§kO] ½ß“5ÔiÕàX1Ã3/›¿‘ùÔØ†‘–a`Ü0÷dlØOŒ8&± ¢H:µib PPpÏ`9Wø(¤!›ÄòL‚ò7ð!|Æ4Öú#¦)«–<«+üÒSHÕ4Áü4B#«ÜŸº„Ôüæ2dú › “S}œsDœ ïc™›$7…–¼¦Ù¦0‹tw¯»¯Ô–¤QÄT?ÍÏZ ÒΆWX"»tŸRP\½†Î9jþ}ë/³üôÐØ[ ]…R­&9”TÔ‹»m¡½ó°"}†& (Aݤ«%.'¼_rèš{9GIç:É5jÐ Ý3’ß‹ [vb‡ì'C[7»c·ÏñP«A¹‡Tñ¡–m‚7Èþ¦äÉáš g­v¬Bß ”/›3mà9VéxoÇw¯ÇÞòH¨áL˹»2Û¡ DÀ÷È飑„ùI˜+óW:ÅÒX€—‚í±.†)ÔÊb·ëSz8í‹bîZx/Æ5¾LÜöã£ý°iK*—ÚPYyüŒi{˜s¼1ˆÈKë|TSsÄ*”¡—6ÈÕé\Ð Bôpºƒ*oÊõ~ îAÜá4Â…ô™¬ÁAGCž\yŽÈ Ù0,$‹(høÔöîŠþ6¡²~Fäáx"ÐPÞ`ò7iÕ¥õg"˜àƒ‰{Ÿÿÿèårö;üühnî‡endstream endobj 220 0 obj 1736 endobj 224 0 obj <> stream xœÅX[oÛ6~÷¯ ú2yˆ9Þ)>¦s†µ+–.5Ö‡d0dYvÔ9R*É òïwH‘’,ÛM¶—Á ðz.ßù¾CESDìǧ“Ÿn4ÚÖ‚¶“¯ê&‘ÿJÐÛÅ„£E «(Cð·ØLÚ1Í0Hs…“Ûh&¦L’ˆÏ¦-ÞOf»3F8&D ™„uëIô-™.¾Àu0G)&,¶çÙ‰Ý>³3p“7i¬”óŸçŸ——‹e¯vy±õK;£à–Ø/Lj”4MUì°]5£œaaSì<\j$Z<ÉŸò"ÍPQºõùjJ 6†ÑhßÀèþa•U(M ”<>fI…Ê*CÍ= ”v[ h›oil]â`%Ò[òÍy$àBåý¥"XYÌû8ÄX+ÂPgž²æEï®à¶qL¸€›Dð´uó.º›Žâ1ãJcj4šÁN»´Þo\0fÂÝ)0ïc»É;c4ÜϨi'H§4«QS¢}‘Ýg»g”¯³¢É7Ïèé>Oï‡Ñ‹ ^¹qaØÍ„A³Ëò©ÈªužÌ£C|ì}ë¤qKfÌpÌ™äPÇmTe;*j”å®j¯¦Ÿ¡ù‡?—׿ïq¬;$ÞEÛzŸ‚ÛõÝ•ã3u g†|…3¯nn®oFÇ‚ÅèØ¬ªÊênê)5Š™.ïZ;—~Nváü¼vÎs-!k<äÒ'Å⯱gŠLqü'ˆB6Ž?…øØ”6N>ø¹lTáŠ`å—>¹ju•L¡ÂtFTʘAÕ(ïåm´«²dýŒê¬AymMt.O¥Ä„Já¶`¨¡8V1$4vçýž /R†±pÞs¼Â®ÝFw#—†.®iS®Ú¼»íÌ`iÑÑN^°~ŒÀ m¦bD¹+È”´'B¬íŽ™£ˆHb¨7ƒÖ®Ž&pmgWRm–Éz½¼œÈU´XnvÉv™¸‚%`¶{»,FyÑ uR€Ç‡ê xîV}\γÕ~‹Ö«í…]b'? &s¨=_ZÓÂįÉnã2ûô0CöºÁàÇå¥Ã“…ÑvòÜ7ƒù+›Jô£1Œ)§5·õ×ù·¸ÏÐf_¤M^£*R )žNáˆÖ¨Tš·,®J E?°JŽàÏÖ"À ¾Æ"7ã’…àŸ-@  Ã: ê…VÙ®,¶®tKKÝèuä JwI]_øÁ±Æ±IÊmþîjä1“˜Òæú1KsÇã,Æ‚ªÞˆ– ólVÏcÅàX‡Â°®jwxí2Ø.Å‹Þc…ã hàT¹ú’¥¦e'¥0'}¬Nø¬ÎÅyÈŸ Šƒ©nù­¦àïºSh`ïéQ–%î„4‚iµ'øÉè?%éh<p+å¡«·$Œž±„Ûén{ã'0…Žm‰;É»8@™JécB]‚‹5Ê›}s‡ ÆÁ×ÄwO3lLˆiÅ¡ÙV(N› -éº Þqªzc}oEŽa‡§q[Ðxkéu§ `qè1. Y²íã‹ÚLzÝI PNБ¬’ôohÁK QèÔ|Í­€!´MªÆæ@ÌÚøjÌ:éÚ<[:5EÑ7óa·™oî«r¿½¹zÄÂe‡þŽ5Ç^ˆQäÜ@[™#Öó‹ýZ½¢ñˆU'ö>O`&˜ÚÉí/ž“Q jÝEó,Í\ÏËt¤@Ò–D¬Î0¬‡²ˆ5h€€XÊNé"h>aÆëâiUô›TñXŒŽäáÿRÈW+ °²/j U ­Ó±žR@b%äY Ö¡â{BÈúÕ:³¡/½Ý€}4æ}5P†¶§ýOÒ½» ýÖii4¤k Nk£µ@}G¡±î j(ºÝøy„Q®ÍI<áÕ ²gI¦‡íIÍe'ˆ2V/)";¯ˆ`]|¤ˆîÈ×I¢éº^m3ludh£Wí")åã ³Oq}$’î°×‰¤éÔ·½8BCM‚q¢Æ´xíÓ°‘0ƒë3v*ÀzLè¿E êØîðt˱usô\=†p4<‹jsÀc"€wÁ³x¬³:­òÇXjÿÍaCtûFì¸@ë#ZfDõMך·—óËù|¬6ƒ_ú·éàÕ×?úÜÂo5èæàÉo£À2´Ïpè;±äÞdï“bŸTÏ QŒö»5$\wtøCÔÕbò|þEÌòendstream endobj 225 0 obj 1683 endobj 229 0 obj <> stream xœíWKoÛH ¾ëWÌ­ãÀš—^ÇÎbÛ Övn!ÈÒØQ‘È©$×è¿/ç!Y’¢§ŠÀ H’ßÇ$æ+¢„!ªîY<{­#´o=ŠöÞW™È=Šgô6õJ °bÁ_ºóìI†xĉ(!JŸ½ öå‚Kñ9}þÌ©1¡ùœ B©D~ ´ôáJOˆ$œ¢r‘~ñdH¨à1x‹ >åÍ.ËË2»]$’$qâ4k»¦ª÷Yþ Z˜@™t™ù½ˆ¦]P¡ª;Tž}]è ADBäƒ8€WÆîC¶RÛã•ÛýR›è÷£•B‡S­š²RËÅ›þÃ?ùÓå]טwÅcÞ jdô!»‹j{ìºÑÆÙáØ¾ß5ÍÎ)ý€oÆÄû6U‹“D ƒ/}Thw¬‹®:Ô:Û!%äÜН`X´g†òB®]À¼Eym€UÛ§PE!°ÎÿTu(GßL˜ƒÚÉI“\þtT¨{Ì;TÊ!'1|vœS" DS–jMu8ªf˜I…ÓêÝÝ,RI\ú¸}QEµÓ<&’õ§*U¢í÷™c!ˆ œA_^mÚ'=`*aMIªŒÜYH"î\hXÜÀ‚ò¶_TÑY.Å!‰ã(ù9¢¡Š[õt¨÷-cٌݓÉuƒo‡ž%p^²õ¬i¢€Ä ë%²Ýk¯‘u3ÌÙUÈ@e.7ˆÙà€y$&¤Ì9¥þíõ”´–ææÖŽÌt0Þ§9œÕ2?çÄI S¤.QÕµ R+ŒÄJRy9Àd€ø ²Ë|žpPz÷ýt²(¹ B Ssƒ]­µÐ ³u­‰!TqoÇpz³Ñ<€uéyŒóê騍1!³$‰‡:ö”Ü­×ëè9©‹ —®øo7QѨ\Wœ2´R…zÞXNYL¬CØUÌ5'ÑxCÁÂ,aKhAïÓ€^x‚'£õbA¹ã“u¹®Nêß¿¬^—Ñë2z]FÄ2$ øÝ0p¯T? ø¿˜Kóæä à•öBËw©Ú¢©^:˜;øï¦üÓÈ6ìaXŠKhéò3Þå³[ooW·«Õ|0¸]8’©MÜ›¹µ`.3†‰ 0\Hì_D—×öë×=v²fÊKà V»¬­öñôz2ŒÌázÂ`õjLkC©ég&ô7Çü7vÖO0‚…I –R}Ÿ×ǼùÛ‹³³‹ÒІÝ4½Ý¥ÞGøý%>“iendstream endobj 230 0 obj 1068 endobj 234 0 obj <> stream xœ½WMoã6½ëWÌ­r±")Jä1 'h·[¤uîÁ) Y¢µ¶”•èuóï;$%ÛQœM€…09ßï½a¾@L(ÄöÓÛàûY÷]Ã}ð% îú¯b æ‡y·(ü›¯oIeŒð2žÂ|,Â(™0‡"šü1ÿˆþ¼UÒ[E,æ$ŽˆÞ/ƒ°ª ”û¼]/ó²\^Í—ûÊ<,[½^vÕ½\æwádþg 2’B„^¬ÉÔ]ÿe9­44ûZ·e¥/í-{þi8ÿ!߬!7¦­wÛËÉwAX4ugÀþ†¾áÂE¨jw:8½B‹jµ3.¬ñ²Ù™“óë¶mZ¸m¿ï&xpÒ‘ÈgÉb›eB¸Âùƒ†õ®.LÕÔ6É“fdœÐ,eà —]ðè}—1‰So³‹VçFw×®Öj5axsÚ°d“WuU߃yÐn œ0~èfBbêò”Ñê M0f›]«aµiŠ¿à±Á éL«§Qþ,ŽIF©Ï%B0)ïªï+L?/ong?¦9®$S$¥ú~űrÖ¶tX7ív-âX9gꈃ7ÜSA†Þ{ù_¢„Ùß0u)\ÀÛº]Q讃Ê@«±úº§±Àû}®6òôÓïËÛŸF!SI„Cм.¡Ó¦;"iäTá¨h28ß:ëtâ p–Pë KˆRB…ûÍx”~Äœ3¢2>4jöРŠ(™$ÄÝdÒ&¶]˜_,l#Öj“b2Ì«EÁIG¬Åiö‘BZr=›ÝÎFÈ”$Ïç ;"¼éÙ1ˆÈ©.ôv¥[`1•Ä;”€XCœÛ¬ÉüøAo•¬D:&A‹C³Ž”š(c*f‚~QˆxØ£ç.D>JŒw=©]§ÎHÅëöÿÊ×ûå‰"“Þ’§‹W)ý¦<9—âXØ⤒3â^zℇ–IT9(˻Չ"î„dƒ¼ˆ£‹w‰“T$æ½Îx]œ2áÄì¿'JîTðÇÿœ„&$‰bT ãr“¥DñŠ¥îŠ¶z4¬gдH|ì5– ÷÷n¹}ŽÌì°·üd-~ÉҤNj­€» 쬛ƒÄ^"ÊÍãHbvÚ;«%®¦WÓéXM(> zÑqt\„èÜ~"┆¤§1êwî½ ŽÈáö;Ñ .™$Åa3yN6Pd¥LQ6ÊÜä4=/½ù3™xñ²¼_^Óÿó Âp9uNáâw‡i–_óÍkÏøWp|ÐL=dI leü° >_=ÊqsÍntÇŸ·%‚z­Ûγw/¼ÃÇÇö—™m™D‚1»¯,ªvЯ¾^$ð½!}t‹µž©áW}ŒŽKá°]k³Ë75/q©4k—?O±‚ì0?6ó¢<&ˆJߨ‹]›ö 3Äd‹|³Aþ0í]a]í°È+£«þ6Z×®ø¶:¯½$V«”ÏH"ùûß)”¡è½ñLÉp^r@»{¦œHL¯‡-…Š®øPØ;ñM pÔ7m³»p®½\·¾ù4!R ¤¥Ì\X’rK§a ôRœð>Ä¡_rùc^ïrl<‹=ºÈ·ÇMôüŸ’ëyð+~þÀ|ðendstream endobj 235 0 obj 1247 endobj 239 0 obj <> stream xœ}WÛrÛ6}×Wà­T&B€àå1©“‡4­[Giœ‡"!‰©L*$(Ûß]\xQ<kF8{;{vùƒ„”‘ÿÜwù°zs—C¿ ÉaõcÅÌCâ¾Êòn»d[Â)Æ |¶û•½ÉO8IDL¶«û`­¹ ƒx³þgûðì­ÈÝÚðPÐ0ŒÈFÂùjZwy;èõöû]&4x "µ&ÒC×ôÆòÌh–ÐTf©Ã»ùšß|ú;ww{we5i4·úæ.%L¿YQH†å’lW¤ð³ žŽb îÌÜE·ÏËöáÜ­Y 1Ç"P}Ÿ×VÕå»S[þû-ø¶¾övãq WˆC—¶®^‘j} à)…›79ƒœáåsíÏüF톩v‡×x}ZEËìл¶=‘¡©u^÷y_U½^ÿ²s ÏÅÉ:©æ àH¾«u'“ÌáYëæedxBúÒXîØ„†àná?ÿŠe–7vÏZõùYwxËdaºö¾ëÚîQø ÿe^ó͘Í5£Œá½û`{¬{ò8q¬'e§ m\%®ËáTt`‡Ñ(Â&”f3Gï¯oñ¡éN §”Îâ$çî9wíwUjÔ…” èg™º´£I:¤àt©›8 iì•zè‰nɱpH,µà¿l4ÅÖôEÙ~2 ÀáDJçv4ºW«Š’¯¦ëìoåJH‹Ì¨Ž §™¤™ðQn8µ(Å…¨ÉRHÓH\åá>hZ™XB.u$(lÀŽw7Bf4urõ€æG\£™LÐ4a™/è³6úØ–“>ò˜Æqä<·ín¸6' Å G aŽÇ(ùlJ 2*À‹9ˆI>|@,´~&C¯N €hË¢ë5É\de.Ji„ÙˆÔꜗ9IÞ?’ÁiQ™. Ý£°ÕmC~uR—%ø¿xm›Í_výÆi,#ßpŠìÛÓ©]óˆf€ðˆüÁÎ@ ð$"¨G¥C™ÄCPîÈ+üEÍ9É¢Q’¡UAˆŒgPxSÑHOFLÔ–±Ö¶¦B[Cœ%TfñXß©*P2î˜〻x 4 µ>’‹Dä4Àoj¢¹v%^¸R /ºí êQŒ0pŠTü4:¼3ÞM˜unï~·úëÛø§I‚i1Óf…pAÚzQ ‘šÙFa;} ¤Ý·í¬f‰«§)sn{®0õ€‚¥’M†_¯Î îÚ¹Xw½†ŠNn¡ð‰`;˜D×NïF=æ €Íì_î ÔG‹=T<( Ê5fL“$ö2ëG»ïÎy³‰$1d>QçÔL· R}ÙÕg`—e#rm7µ×ÎnÌ×åpÓŽá¡>Ud8e2yÇ^ÔEÝX±_›#©e‘g‡GÓŠ»\XÍ€’š°E† ñ¤‚êÍpv~Ú'ÞOë$KVeí2ÉpÖ‚QcÒ­¥±ÊlåÇïÈØjŸæ«±„׋ —G`Ò¸‹&È‹YŒ2æ/,6`È ©~ºl4ȼxÉûŸ]wÑ-ä•Á€E7Æù¦O^Ü­çxh›É .7¦®‰%°?}±û‹Û·2âx»v‚ؓưK˜°Ï Œâ<ÎF^ïc~ -iQ åuy8ß©‹•lÃÏ>êéÅYjK2b÷À¼Ž¸MÙ*²»µá© KÛv·¸>—%.$³7·eþXè'€{i»ýí*eqJ™ðã'À™â ÀÓª)r\JM‰'¥%U¢Üg I}AP Þû #ÉÜšÕµÃáèuvsÜçäU[[ÓÔ.ýWŠ[TiϪ+@’Ñu#Âþ=ÂIn±XPÂY×ÛfŒ,Íïv[>á]Òv6ÕRú÷\)^èØE3Ý3¼Úp6­® ˜IÆw‘å«ýûíê/øûÁP]Ëendstream endobj 240 0 obj 1818 endobj 244 0 obj <> stream xœ­X]oÛ6}÷¯à[å"æHJ”¨×"Ð.X·ÌÝÚÁP$ÚÖêHž$'Í¿ß!)J¶j7yÒˆEÞÏsνʿ„QN˜ùé?ó‡ÙOw Ù´3F6³gÜ>$ýGþ@Þ-g!Yæ8ÅÁ¿åzænr"AÈ$aL–³ÏÁ"š É‚d1ÿ{ùöpk!XH‹ÈBâPC+²žsF*ÈÊݡѤìH£»CSµö&\E½«4¡J¦ îp9¸þku}ûçêã/óå?ÇÅõG¨y´à± qLBÙ/>TyWÖÉuº Œ“kë‡{ÝÁ¸¢Î "œ{!2¾ šH²|š’JÊQ¯bþfqš ôÞÛSÖ¬W•~ZéoûæKðeÞæÃ_øã¨ƒ¹À¬½k{í·Õ .‘bbÃX Eð°b“îO_ëûÆ÷›+sÄ<¼õoš¦nÈ[m>ÛãÚ,œ1çY(—Ór«Éº/Ë$è8¡LÄ>Åi|CŽxJCXuÇ]…[’‘J›ƒ‘ó˜Ï¤¢,LR_8ûÐB„'4Mãþ 0²™n[Ó´ &IY‘§m™oaxWç™{+4´<ŠÆ²éo£X”w¥Æþç`°ßvpð@ò¬"÷ÚC„α@ðIð~'ɦðBPé+uÜÖIRF•`\è6oÊ}‡žuÛ¬ë=ÛtBø”Rù,˜ õг]M²¢ õ^7®¶æ‹û¹0LŠ¢àPî rØ•‡h­à’Š>Äð´²”¼ïŒ×XÒP(ÞGç™x Š0Æ™Ðgðë§ÛÛIŠ!÷ìƒ6@Î¥Dˆ!˜éŠ’…˜a¤hœ€abƒ£b¤›Ù`?L©DhÇlC ,W]­²sœó—N8WV]Oµ©‹„³ô4'-áú¯ÿxÈv;4!¯ }¦õ_ªÚrS¡KÙŽ_ø^œûþ­Cßj§«M·]Õ‡îèÔ«y…ÉK¼N Eœòú¸ç¸-™µì®tÙW'=TFQã9v 7¬¯|’v¯órmÊÂ0(‘ìýó”@¿`~¢‡Ð<ÉS/·ú¬Mךá rÔ"=І±o´ƒä¤7àšD/F½¢2u$n´Q]uN‹Ð’í÷Ú´ŽPk3$œWû‹Wá{]¢‡YÛb8ïДµI}^ôÈ¿9§ñ ¢l¢4~ç\ŸÍ‹zHºWïĹԺ<`!†sû៽蛶ó¼"åšôQ\!õ郞%,ý!hdÈÇ, —hâ”ìBšiÈ'ؽ€©žVéØFÃIK)ôÍ”¿Õy]çS9çž§!üO ;³KúLð¾&'n5˜m¢Xý=“,ïÐäg3¼¨ÚtÆ€ÙbŽ'i0¼òÚÀÑ í;¥ä-¯¥~ãLŒRúnÁºÛò0<Þr'î˜4ŠúÒ’«à`˜À¦1­î¦¦",­É°»}?\¦ú†HTú:'ýîyYì‚\¯Ýj|ò8=-¨ã1–³)ÁÛi–ð5¬@úûi\ ‚üÐ4€zбdƉ6£š’lÝi'˜\¥•–z=…>TÌ^;Sh~ 2¥†7†÷—zÅ4–2=íÕÍÝÝÇ»‰ Mñšpº ñ~Zp,UL¯)‚r¿¸œƒ/ñ°Hþ`#2"9Õ/#Kæ•î©ùv<ÒMÒôækkxÜyZ¬•8¦Q|Ëõ¾C3êVÛEÖe%P¢”#!ØfÓÁÄ””%N©ÑQÒ  7ÊœY¬¤ˆ+Qƒú%\¸ 7º3h0RÁ1ì •ÝáAˆX*TÔ¨T ȳƒ w¬°Ù¿«º#æ?(e·h— –“(äñdoô°b7Ŧp[<¬WZP–§­!´yµQò8@³#™ÞÊ9`ÔÈÒUŠ îóxÔäûís°{œs!æÅÕ;Mišü¯/»âòËî ãøÂ«ìRÜYêÙ¿ ðo€Ã6ÅǽþXÿØÝ¯tèCV²æ >šH½d(Çén–³ßñó€ámûendstream endobj 245 0 obj 1635 endobj 249 0 obj <> stream xœXÙrÛ6}×Wà­TÆB‰…Ûc“¸3IÓ¸u”v:NGS̆"’Ší¿ïÀM”Ôd:N,›.îvÎ=ðâSF|óÕ~¦»Ù·ÙÖ3Ÿlg_f̾$íGº#/—3A–)V1Nðo¹™¹ŒðˆS!I$B²ÜÍî¼…œóÀ÷âÅüïå[Øs»d»kÁ}A}_’E€õë™÷úQU›ÕǢζ…^“µýU­×+ý´¯V[]|òæËfADC²€™aÏo«k,!fÝ•Yb^¾ë^~Ø©<'å>-×újþÃÉ9_UÎ.<ç£ç×UUVä…6Ÿæx>JÀÂùÄ}ã“ Èòqæ-4ÙŠ´Éʸ5 >b4b>'v‡w.Tœá¶ôY|kÙmiÔg) ¤d¤?94'ßyº&ª@кR Ü®÷:Í6sî#áBx»¶UùÄdB}·¸„M|‚v>ÛD/$i’$]=õãØÆ®ò²Ø’Ǭy ‡=iJÂ7źî¼1î#¡3h¶&vkëÝq„¤±äÝá¦fft›Žºu1\)³È6ãT²¨Û_¬'æYh,±Á<ÿóéó®Ü `*¶/ ’Ô×Ã.F™ì¬UMM²†d’Õ<艃aLEØÚµä¤6 ‘¨EÜÕÝ’6¡•ÞWºÖE£L'¢1ÖDí÷Ú”!× ÚÅj!uSiµ#÷:C U]ëÝ}Ž¢lÐIfM^¦ªëé>HO?'a¡¬·^js~ïι:3–PÙ¶„gÐ`ÞGÎÈ¥:ÐåшŠXºçwžÁŸkúM_ÕM׃W$ÛÖ‹+„~`-ò“ÿ„BDy Ø¥pÍ‹"NÁÎ*eÈ&½{¡§ZX%C &-¤P7“þZ§%~<ʹãY"pþ¤µCgöbJ_ŽSêsÖæÂxãÈ­²7=ªwꙨ´9€mŸÑ:ÄѨ ‡‹„ò! Ÿ9#9ô|¯MKšŽ;aKÏ.OÊ:C銢oÌ"Ñ-bx“„]Q›jˆÐ§¡àq¡ð]ÃêæP"Åaw¯+RnZ°dÅ XŽ‰× @†ì‡U×Î#oëRîÛ3ÓCU¡È †€!om L5%jÓh?̹̉ÜL ã ô¿—Á©«MœØ=øÁ>}Ó 6ò‰q"˜ Kßë?W¯ßý±zóêæãûåtTa²Çᨚó @ó0kÀ¶0“AØëÓ˜ñoMÍ0¤<ö; ]žš†”¦|Áؘu{Ë¡úãêÛ5v„VŸkËxƒz¨‰ž3„zO©Þ7(GYk|W yP.®žôN9‹ŽH_P3óñÇIAO5ã¡…*Û0 öEqï"kt«Ó †WÁÒýÀ/Ö¶²LpÊD2lmz GÔ@hªÖù!Ý$UEQ6Äü¯a“[¡ŽøžPmLôXn“NªÖ.0^h½¤4€‚X NäØc£P*mتMð蹯vXô¾–ÇiéÓ—u¥à¡§×´åï˜À1+-%d ”ÈBDNq7 PA,)’‚ôÞq+WéHƒÉaƺ]­Ös ÅÈžªÕÎÂw Ö©ölstN–ÖÏ»UV¬õÓ¹—/­r]l›‡Uyhþ‚å!P~ Œ EåqtŒ'ìaN”, ÃAA?7×`¾,U¹ÈÓ¼ƒ¼#À˹ãîÇðŸÎ6™‡²g5t–Xvèv°“`DYxI·_úèð½Ú›š*¦a4ôˆªÇº2I:éÐb-Ûísœ¦e#W1 E§BfÑhKëõísÆM0Öø2Á¤l¬Éö @, `m„"¦{nPÁvÄq:ÑEyØ>´øo ÀN JEö¥q¶êtÖ¢;gª¢½¶¨ê>k*U=“µjùäÕN•¢)r"Ìî¡G‰5‹NωÎ7÷eNLXs°yKæ=]>ì¹ nÏî¼t&ýp—wÞU9ç h$½J WÖE·¬w—ùN q‘cÇ?ÍsH§0x¸ªû,Ïšg³u¨·÷P™lžÈ8ÛÖß.cŒ[¸ßáµ+‹ÜªlôØkÐ#޼µ‚¸·7µÉA4ê=7ð_­>üõëË›wo^­n¯ßݼúiùææý‡ˆK*5F—’~Ö3*G/7©ijØÑ:¯@X¬²ðXÜü29>LŒÌë…¹L¢^=c¦¨IE¯n½SþœÆ†{¨Ÿô—ð²¥*ô´³`“©hbjÊmê ižµÀ•ý­¨•‘í<‹:œ#xÏ\'r,Û[¹‹ v´é¾3iÞÌ™Ñî<öT–*}>ß'€éþ‚Ú&üúööævÚrá´âpC¸W•?÷ Qš‹TÜkj+«9®"vĹù»Í­Æp­d÷ûп²ƒî´@\ ÷·ª8ôq\UzbeÈ ê%ÃñŸ£®—³ßñõ/§! Aendstream endobj 250 0 obj 1858 endobj 254 0 obj <> stream xœ­XmoÛ6þî_Áo• ‹ã‹¨—k’鲸KÝ ƒ3²L;)•ä&ù÷»#EÉ–“¶èð ÉãÝsÏ=wÊgÂ(' _Ý{~?ùé&&ÛfÂÈvòyÂÍ"éÞò{òn>‘džÃ..üÍ7{’ *CˈÌï' /}¡˜—þßó÷`ÏœJçx(LRÆB(Eæë‰ 1¼?N5‹.¤¾Â,„…}š§‡W¨î×»"¿C·1¥héÈÔ’é…÷Tù’§4Š…·ie€;“Îáâ4V/v›îŒ6cÜŒÀ[ÿ†I”\¶†!’r'¨/æv_—ÖÓr¿Ò5RqõÜêÆ]…_HÓÖ:»wi;€N„‚&<|½&$ÔO]Aæûº†ªß=“­.uAýOIAµ- J¥ìÙ`\Ì6-x…ž+ Ã[-'•º†ß–²^Æð~IŒLãÑK“5“YAÓ4r!´õrF¥t²h‘9ÑK‘ðÁ©ó«?–׳³Ù§ëùX¡¨{V bb7ñ•ø$ȉբ¾ÝÊ$¥¡€v p¶[ñ}ív¹ú.ûΖûífÛ/ý§v+"à¦úV¿å<¡"‰^ï·G0õéJ¡'rG&(öb Ä.òl×uÆCH%—ˆiËWšz/rGÝ=‚Šî‰öôb+„:ëª>×-HÖŽÜhy½öȾ\Ê\ý‚¼Ïê ºµ%@Åw™)%}Ñmu×õêÙ êidÕF—Õ~{g\#EKò¬$yU¶(MFª¢4•³J½*Ú:«ŸÉš!¹õšÊ€»ƒxî!kŒBeÐ3r½ÛP@ØÌ|5»ðzÅæÐlS&¼§)Ã}«y¦¸ j0xl”‘Sò…7­|¥TâÕÙàÏRBTL z*lo-ˆ[Ÿú}‹¢È1[»¢}Æ},¶Ë íµ/! £lO캫Ç1%¤÷¤‡½Ä\Ð3¥¢!¹U z¼oÌÔñX´cÃLýT¥E2v¶üø×oïfW—gË›‹«ÙÙÏóËÙõÇ“" ‡IÁ®‚IcÕ®‘ê:Ö _¡U/Ðcâé2aJÆ” 6[E’(àT»¬6›F·ËÌ;ÚgæHÎÈNÃz‹Ç†~PÉÞÚFé UûöÇDj‡§YIš}žãØ~]ÁÂ$9R°Wâ:a0—²~ö©_îbxrÜÄf¿Ž êDŒ 2¶ý»×íØfÓÄÕw Û˜H¸Î´Øù¦Ó&ÙérÛÞa)Ù ¦›ª* ­8rqöO"Ý3LdŸ]»\[o a8ðtÈœ¦@>6>ÎÊ\Àä^ìöµ>J qŽX* :9‚ðâæfv3 <9*˜@@äG;ô~ýÅÝ”ƒøømå\çÚÌn‚Ì@›‡Ú ,³3 <÷£Ê~0µºÛ”œ(Â÷Y¹GѼø0Å Ÿ±p¥xüŸ€‹ùäwxý cQendstream endobj 255 0 obj 1597 endobj 259 0 obj <> stream xœµWÛrÛ6}×Wà-¤ÇBq!@ò1‰Ü™¦ž¸u•øÁîhh ’ÙH”CQvü÷ÝÞL;Ig:öŒl»‹Ý={öð+a”†?õçr7ùå2&›Ã„‘Íäë„Û‡¤þXîÈ»ùD’ùNqAàw¾ž8KND,¨ŒH,5™ï&×ÁT…B±€MÿçÀŸµJçh4LRÆ"2UŠÌWAcø|œŠ*ÁmVáüŸIÄiÌ Ã#×ÁcV®æÛ}¹XË2ä x"0EµØ¯×SÝ7¡׋êëM½‰n˜ 3³¾>‡|S˜Yõ]w=â=TL5™‚K°¯MÿXœÁi‚&§xžû‡ge¹/ɉÁ¸Ñ›n¹¦Î™» ä*"{¡ù!ëc±¬ò}þ:ÄP&SW…à•«B(géc &hœeiªcYH¡ŠãîÖ”d¿&·O•9 ÝTÄ •"ñ‰BxŒw»ê@Û'’ÖÈ¡*M¶#kH¿Ûî—Þž˜G4M… à’æpÀïJƒ‚(öí“=¿Ém«¦€½ÁU¢êfïdQÃ9åQR?,Î4mk®nzÝTƒä¥•9,Ëü¾Ú—aÄ(ãQœ¡£$>ö‘MíQð/ï5 ¿á; \@ 4¯Te› £Rú,]G)Im𦳫ÅìüóâãÅû‹Oç/§Ä\«°þ»P)ÈJ´N OÚzÉà¤aðdŒf’Švð”;™R…@phñ–Õ~q }þ²È:hkZáíz“FÝñêûøÁáŽëÉÖ›êî&Kp°n'ú¯]¶Ý’““lµBèá‰îÀÿð`rii / r8.—àÌ¢ö…åBRÏfô…š5 L"ˆ$ú:ÄCLãD¥}<\ü>ð¤S*´ð¨É ÛÉ)•Ž¥¯/£"JmZ@.!WJdøo˜ÀKét0ÍÄv¢fY”´£2>¼ `U±´‚êú`ÝàAŠ0º r9’&‡P éÈ4ȶGƒédä~q€ål4Ë5¢(­º j#ÜÜìÌn_>‘Ç;SëX 'Hè‹åÒRáÙ®<š>•I¨ºdžw¿Sçž_«¼Øm~»z Sš&i$€P{óÞ˜ X@”~f<؇ÕB8×¼dÛÖÅwÍîuÈ‘ÿDdùöÉçñ8DNc è4éñìòòâr:Ñ4ê…F˜#O9à—¿ÖCD–°Ap%0NffiìN »sèÕ‚”¸\{AYð¦/F¹jŒ©^Ño¡˜ã„õß´Àiý,aƒ¾§4züÑN¨æ5i`¦«jpÕK?++ÿÊ'$쑤‘œ2éZUk„)Li;=¢°b1§"®‰­(úž~è’vàÑOª„¾ôF¯H»55kˆã¹~Pãú!Öú™~€›¾¢!æíÕ5UiÓkEéôø¨Ïr¶05E‘ìþ~›×U®éíKaiW2 /lN&:~.Û»­Á"Š:Þo G =¥‰J,=Ý@÷¥±4˜‘Y›ÐéœûóÀæÃÅÓS”–C i¶‹Ëv772Íž”$«¯c»A´ Û+xxí‹6ˆã{I<®Û"ùL·A­Å&7ÈXßï¯f¡°<®dI X«1ƒÏ‹w¡Ä=¥TðvJ¬—–ðçìr-¬Ô¨#îmײ£“tþ蘤Ó#’®û&U¿F¥<0/½@ʺ‡}Þ{m*Íÿÿ¶t ¸±Øh¶¾[Ò,í.éåR G=+i J*y¡ÄHÓæ…AAv÷ÕS¨U­¥§´¼Þh½utiZÕàiÄýoÁ£<Ø”<%ОYqÌ` á ·Ö1@#n¢÷_ Ïæ“?áç_ù=,Ùendstream endobj 260 0 obj 1442 endobj 264 0 obj <> stream xœ…WmoÛ6þ®_Áo•‡ˆ_DIÛ&ÚeÍ–x†td‰v´Z¢+JMýïw$EYqÝ I`˜äïž{î9æ3Š1A±ù™>«6øñ>E;Äh|ˆÝDÓGÕ¢7뀡u§Eð»ÞÎ’ šRÌ8J™@ë6x £dE“8$Ñêïõ{ðg­2D¸1ŠhÌps Ø©†´~ tÛtrµþ'HLYlÜÃØnÛìÑÝAöåШN›s‹X"oþÇDcù®Ÿ¤–¨ì%R³5Rž$µܬHŽó<¥á¸+öÒ²2‡° Ÿ )™b1¾ÌÅ)xOM^$Ã<ó‘†ÇƒÙ´ ƒO8B§^™gDÄÓw. µ/M-QÓmUßÚàP¹Qã` "F)`e°«‚SF­MÓé¡+—Kãr9ôj×—-*»Ú~×jì+‰LJÚ.,ŒP¥Z‰¶½j±½(ƹ0a³Œã”sŸíñ””8%¹Ûx MUî÷Ç•H –”‡W«ˆå€ >^ o¥LŽídgJ kt¥º¡ÙjÔh³WÕ'}…žŸšê µåÑÜ¡D½„-kQê…… Ì\r ʤs‚ÑzõʯVO±ñx¨Úe…hΦõò“YŸÁ4N³iSKÄ̆Øßü:øW„ã¥Pm|Š|îd¸Üí1ÜB ´Õ²Ë|¡1hc߯¢ÊÂ7²Ž$È&Ø”ßÈè–ëS€GzRâºqú6¢øøBlÎøD$¸Èôy”]%=ÂK`aÆzd3FœÖºšá‰:7&ƒ®V¨S4úá úá<˜ F_æ výgq}û¶xøë—7w·ïÞ÷7·wo_¯ßÝ}x8&çs™±ÛƒùÎì 6#þPÄRW(:xxkÔ–99Nõé\ XQ- ðÁFÞlÊØã? K,5.,Á@ÿg"]Ûƒ¿×r3îP½Ù]™#ÓòïnvrÛìeu•_¯@¹¦Ý×@+dÆX¡¶†q‹­ÙÐÜÞ©Å΃[¯Ô~l»Âg±ýF©=°«p“ºÐC;¹kº g6¥nªÂò»gä¡Ù«Ý(¿{$Ö¶™í;Ý<Ë£Ñå¥ôêFW}Ó6]9(›F¼0¾é{Õ£¤ù€Ò½zù8³EpeƒÂ4¿Ìh0;]Jx”úœŸ4Çókäb•7ž(0EIv®FµÃrã_Oz­Ã=ÿ*yÜèkŽÃØwçqÀ<…w*ç'"™Vù£¸ûù¬1Dê»Ôa£ìˆ­ŒÁ³ìÌkÊJ0y¼¹¿¿»?s MÊýà ZˆWðÞ Ý#5¢ ‰ƒÌzûiTõÒŠŒ®kYI«4}»–˜+à©O)ŠÓE¯Ún}pxuÆ~Ô^lÖÍ½Š¼YÊe-ïÝa{1ó¿SY’%vÐìWÄã}Ùe„°)9¹ðrÿ¾>ÿ—ãfü?ÿ×%•endstream endobj 265 0 obj 1447 endobj 269 0 obj <> stream xœ­XKsÛ6¾ëWàVªc¡xñc3É¡ÚD=Å EB2 tøˆãþú.‚/ÉMÚÉ83rD`¹»ß·ßîú"˜"b†Ïâ²ùé]ŠÎ토óæÓ†º‡hø(.èÕ~ÃѾ€S”!ø·?müMŠXÊ0(å Ú_6¢]¼e1‰ØnûçþW°ço‰áÖŽŽ hÃùr½~Ê›ÓáÓê³Q%*Ýó²UÔMië˸£Î¶6m×ô.õ-0*¨˜n@½{Ê=iðá¨QÊš¨o›@geT“wªÄP‚¶àÞB41‹­ÅýÔo~Æ<½kàä9€Â„çÇi: ²ƒºðÕô©‰~ªŒÈPqÛ¢F·*ÚÜ=ÈÂPN}œÎïzYÐÞñyÅ>žŒü˜ÚóÄÝ\ÖÊJ‘8K1ÄçÁ—0*ccÕC‹"ÙŒ^¹g޻̥<øºªl*f™Þ仂ëHÞìÂSÁ§ªÎ§´r(¢8èß@­7ßM®}²•–¡FméËÒCPa¡E.ºÔª¨¥Ä<fÓØ§æ>Z¸Ò=·Ô9I"è?Eï·è>Ò§þƒã½ùh<ã9PÑ!cOæÎ—%|˹˜Ê2æÜä#~Fä~‹WaA«Iiv“(s~Ä`‹…càŠ'j9Oì…'†B £ð|©·LZ‡¢ÓRwø¨;Äߴɹª3îëÌæʶí¬0-O¤î„Õ ]<@~–ÅíÓ28ñ:ö]¨­Âw¯ºêPÿˆú›‹î…NK)ôæ±\¦NëRWª¢ºÕfc:’vÿˈkðËÜëùfmO@d¿ì¯.hÚ裋Á=UùÙ‹”E«R›ê ÔškLÞ­] ö'¦CóúÚèГEèKÁ‚+.‡ŽÂV6¡þH˜.´Î sƧ^@y”fƒÄ¼ œÄÜðš <ƒ{’‘ š¾,#øýÄ‹“LÒÀ`˜Ýª¼©ž·‰­RžDwkåáJËâzê¼B.sÎ?+9¿¾9?oÅ2žŽ5îîR’ÉÑÁ3“XŒámµQ.®!s³‚‹¹˜ñ:?;šÂ ’ˆ9»—S÷:AÜŠì@maEý;S{°ÿ-Ô†ÁLrï °EòkfK+Þl:"þ/³çb>‚<¾„8dÍíTNDlFߺ!åýDTh ’ñk¢‚I9é·Ûl†Åf€íÈØm|ßè8òóŸÅœ†ìŠX̨òk.þ—$ëÁ‘°ê­õÞ—/·3Wf j'Bßcê¾*íÈù·jjèÕ•¦í{mŒ×‰ If»Ü×K$æíIdf‘¹æhj³k;˜§ó¦ô‘Á6D§• :":“c#­;Êíš6(R2nù¼G– ¯Mƒ ðzh¹y;ì¸0³ÎßoWaxÚ(TªA7(è†qÕŒ 0&׬Û úòX© ìnˆ¿Âb±Q/Q‰+árd áÙWPq]¤Ë•ßZ Øï ÿ÷º}@ù¥VÜ`zv%†ÝK_u<öêçÒRÚAó¤»OÈü2mÜJ)íÜrç<ð‹ñ`'N¡¡d°#íÝhS$Hjÿþãᱫ`ØÀÜ× ‰˜²ò’¹ü/³¸"œ ú?‡Ñ­=7`DkĬš³ª/¼ê¿ósâ0©>n”t¢[ÚqÌï¬E¿æ¦Ï›gÄ£Óí.·ååÃÞì7¿ÃÏ?¯sMendstream endobj 270 0 obj 1825 endobj 274 0 obj <> stream xœWYoÜ6~ß_Á7k ‹I‰¢“Ú’qºÝ4I!èà®Õj¥D‡ßá%i lÀ‹%g8óÍ7ߌ¿£¨û·8¬n61Ú÷«íWßWD"û§8 ×ÛCÛnŠàw»[K‚hL1 QÌ8ÚV_lÏ\2,ÌÅ/ʩ캶[Gñ°NÁ§,ÆIL‘O…¹·}¨z´›b¨À>—r·¦¤È™W5²DYÚº•…<ä²C¼g7Q/3ôýŠâ8BÛ§•aŽ ¤W®¯V!Áq@\ªOY·K³²LkpÊfè^¾z_×')ûÎÀVföz«?5}µWa•})OQŒ9òÁ›FL_û˜ÞÊ|Ü£2ß_«+êðý™Ë]UË´jJù| ‘ÛÓWeÙ¡¢-eÚîv½G“¡Š i'¿™ï‹¶MÚŒ ¹Åñë¶­ë´oÇ®i?†4—ûª¹p'ÏúªHóº-þ:»s§*Œ~Ò…¯–lð AL)×(žÕ{x¨Ïê|RžKw ï4wÕó¡ýÄiWÅ4²öòYÝÓ="¡eªŠÌ°¦ßˆBjëˆö¨îûCç£ë!jý^PÌ‘M EÀöPõ}ÕìuZTWu³ `4K„£á­öApêxœpwöùÕ§ÀQD]GmÞ°›P— Y^K´[+Äx•¬Ë~ÑLãO”9T€ÅÊža:7‡j Y‚#F§–Õ×€-°LÝ­ 4«HB¤!Í4Ôæ¹Sœ‹£N©šÁ¶ÇÒ›uò/;dÉ~EüK´ï_UùüøJËG9ÑñTù“ñïBB“|L¼\»7vpÛ|È:›;áVO! ¦£ØËY—(ÐÓCU< L“„†“ ™ˆ†ÃÀòµm†j?¶ctw*•¬š~èF |«éGb3™ôsÎÚ£·Í®í™Ë\D8äIâÚÂ]ÍòvtGΫFg^®tëú´>Š]¤×.¾x”kh.e®Y+boÜëNF£î—"«kÀ©=e1_ᢠAIˆ…ÃÚÓ ^ê]¯ÿ&‹j§Ž¨À¡v°ñWÒ”°…ÑBËÂSR¬—TjÌ10¬_3úœBÑ0ı“¥ ¥€ó#0D7%> stream xœÅXÛnÛF}×Wì[©ÂÜp/Ü%ѧ¦v¤EÜJûE®$¦4ÙðbÅßÙIÉ’“ô¥p9âî\Μ93ô'a‚"ýã>ó‡Å«;‰vÝ"B»Å§1‘ûÈÐëÕ‚¡U§Eðoµ]Ø›QI1ãH2V‹A/i<\þµz öì-în…4b8Š8 c8_,‚ëCÖn×ïë®ÜÕª@…ùoU«u§úuV­êºû`¹ú¸ˆ%(KÓµßÖ×j3ìP±Ù]é#úá¯þáp5Ûmwµüîé¡,>ϞܴmÓ¢ï•þ¸_Â÷³TCëšFÚ5Ç 8,‚Õ^¡íPç}ÙÔÚù,KÉpJ2çƒ ){inQ†¼šj/¸Ô¡|õY»$I°S=rFP֣þÌ÷(3`‡”KLøˆR„y›Xó¦îËÝÐ ÚTMþ7à‚ʺëÛÁ„ß*ƒŸ´Œ€»l¼»+kŒÞÔÛ¦}È|®IŒ¹HS{tr“mš¡7Á/kóõ\vÚ@HãÇÒGcB-ª”§o.ÔFŸ”3*¨u¥ÏQsnØ­«²VhèÊz‡ò¬ª¥æ¤„Æ8¡|^[ ðb®¯UÝ·OgŠA#Šcê¼d6‡ï…¤#»T^nõ#š`îkˆ$Ü–¯T¶zÍvI9N‘[(©.€Ê r3 ŽqjUpÛºBUÝH”s,'' ·°?9tP³$ÖçˆÄ©H]%ƒÆ<4H(àAÈ¥5N; —‰jŒFDKî-­ö®zœDX@ŒD‹qùv¨h .]–€ŸÒª”뤃 à×¼i (Z ¼ƒ Ú‚7›>sV¨„dAYg•e>¤”2zDÀÔÁcÄ)„’%&õˆ´°MY`"="ó¸}º»I:ôwBšØô"ÆÇžw‰dHjŠÄ˜xâ³F|&Î0N±‰/GÄl9JdótÂeG™§²–5ý\Ø;G Dt¼š*/0ÓĵöÊ–‘ê2¦³2ÿ Ž›¦ ãV&+Ÿ1ä±+ON’ `¤ðQYFZ>%T½™‚ pßž¦›ŽO¬TϬÍrå ™îØÕan–ˆ‘´F !ÜZ XU=9}*ޤó?7ç"Ü:È;¿d0S{ š#ÓMµõߦ`+f<½éÒ~hëÎŽŸ2XıÕ :ј*p¶òÊp…²º8>³qø\ÿ¹¾þõõ»ÛŸnß¿[=3Éh£fø-A˜#BlzëÕ]‚³“›A jécÒjÙc 2Q0¨£Æq€Ù÷iPu®ÖÙLmÇ­À_t3Ö¢ZÖýl85òM+”W›³ÕÀ1ù+‡o^(扗7¡‹È³Uà"$cmR4`t•8LŠR÷¢*`E L†¦ùn‡« Ðrêk&­~Õ$|:5£ËÄ3èòÂ"PIæ«Ý훡*´ ºíËÝ^µzÔóPõ¯UÖnåV ˜W>Z‚¹¤.Y«ª§³q¡×O°¾Êìz­`a±’U«%1£—Ÿû ²|”€cm¦ žî—VÐ ½UØN˜èêzê]ñΗ5–›Mpbiy(ÁÑ>;ÒSÚ4.¢Òɰ7—A¢ÌÆ&Þ,ìˆêaZ¾Ç4äÔcV(­íz™Ëú|9*¥]2Gbî60wTg½¦8x5‡\Žçõ4¯Ð¶©ªÞ‚ƒwÓwж3} öñwk{y³ Œ°K— äâ’ê¶sßísÕ>n—cÙv‚{ûËi³Èq*Oò}N½ùsõ¾¹»»½;±—¤˜¿,Ý!•ºAÇ-&øÙIÊ[R Ð¥k•«‡ 4*€GÖ(>1‰I#XÎt^ ÐDN°Œ}IèÏɼ¿v$óß­ýïzë²$_Ô{ØÒäE¹?ËT©ôSâ‹oIjÛ Mæ¼+ùî|Iã"¦_%ñãË×”x×Y¶¥ Y¤{™Ã*eçÚË›G¯ÆðbpQ㓯Ñxè’ˆžÓøÐ{ ™ÍøÎ.‰FfìÚ‰G2ÛçÓþ Ábô6«‡ Þ3à=’L& ¹S¿ƒŸþ¥äfµø~þ½Ð§endstream endobj 280 0 obj 1614 endobj 284 0 obj <> stream xœÍX]oÛ6}÷¯à[ä"æDRÔÇ㺤@»®Ùw †,ÑŽZEÊ$¹IöëwHŠ’­ÄhŠíaH|˜÷ž{ý‹ø”_õß³ÛÙ—Ù¶3Ÿlg͘ùôß²[òz9d™aãÿ–›™ÝÉ8‰DH–·³+o!ç\úž\Ìÿ\¾ÃyvWÐïZp_PßÈBb}>óòû´Ù¬ÊJ­ZÕ­Òñãò~æÝeInR½xlb}4ä¬_Ê(çvéWE:½NØÍٌŭÎÞÿ¾úpñÓÅÇË'G¢ðC­+¢š‰.Ÿ1ö8Æu24M"N"Ò;åÒä/iHb¢ •‚GPç ŠÝI詬«›ÇU®²r•à'åZ¸CÐ#ÈEÕ‘|ÿ¼É9úvÑЕÆ;3‹]©õnKòõöT/Ñ¢ÙMÚWUz«NQ‚~íǪ-¶¸ôª¨rõ°*ªážBµ{ Ï5Lä•A ñŸìCº°Aô¡S®/DøKð`³« 1&å wÌ—z~¨?OxÆTF¡[ñÑrßöÚ—+;L¢Hê¬b¦e}&õ\°€ÊXx›n&<¤qÌ€€w-¥äÌpÑ Ðe•Ðæ;·ðéÇ‘}hQùä–Ë7’Á”¬ Û;"’”GÉ@ª¼0ʦù¢ßm,™¢Jèék@þ}óö_ÎÍqè#Ÿ åµZµgtgÞ¡Ó鵿üòòâre ‡ûƒÂ ŘÓá¡1(œF{¶ÞX”vÖgüy‹wÇó¦ƒwêPÜeb"ŽOòZ•çMÊwyù"ï1Ôá»Í‡tcàyË¡ÙäÃ7Èh4)Öõ&ä0¼Qü„óoyö¿ö ñqÂ'&äêß¹îvCósô<ÖfbôÑ¿ážyÿ¥ßÐò°óGkp€ÌçpÇ c 8ž[2LúV8¡ù¦8VæéÄ7Š·Tœ0—(„4ä}«8 •Âþ9ÓjÅb¾7a40À[¦=´1~èÈyõ‚Y¿!µÒg{ó/N^6þlÁ#¼Pµiì³HhYð¿w8’#ƒð°=û§Ó±x2€üÀpôS#0‰£¸ŸyL 9f¾›p6/»y!má/G§³?š¼¯lxN‡ðn<%x•¾K«]Šlð€gãî(0Ï×¾@‡ÿ's¾œý†¯ÇZæŠendstream endobj 285 0 obj 1694 endobj 289 0 obj <> stream xœÍX]oÛ6}÷¯à[å fER¥ÇnMv]³î:  Y’m¶äê£IöëwHŠ’­$íö6¤@‹ˆ¼çž{îe¿Ÿ2âëŸþïô0{y£È¶™ùd;û:cæ#éÿJä§åLeŠSŒüYnfö&#\q*¢DH–‡Ù­·s.}/\ÌÿZ¾ƒ={+èo-¸/¨ïd!q>›yÙ]RoVI–­²¢ÎÓ¶ªVYžî?{Ÿçóå—3±O9|êkuÞvuÙô'œuRÁEÔŸyýiõúý«×?_ü°œCýÁ[¯*I^×U=—’úLxÔÄþò&"L˜¨…ðaYGÍô A¹$Ë»™'iH%É´mS)ø`rHk8q$½bŸ›ÔV‰Iκ‘q‘6áEÙ’¢Í© íT*’l˜|͹ßV¯óu·%Ùz{©èïg^ºKjrQ&‡ürþÂýX6ŶÌ3ìWEvÿÔ§¶8ä«C•=õmŸ—Ûv÷Ô— j^¶(gZue»ªºöäà•†›\ÔÅ‹ÓÒ,lVAeXîr²éÊ´-ªrRvŨŒCÖ—ý¸Ó ÄõØ87ø'üÜz¸ÙÞ4X¤Ú„4UW§p?ç¾®"¾&­©ß‚‚†¡jVH¹XBª¤ìíƒ>‚[û]«Q­Œ‹c7‰Të/à>/$Gî’™l}p3g1cfÜ iŽyZèx@-ƽ&×SJ ?¤Œ…=.ÚÜÁ)®¥>{w»"Ý‘C×´úÜBh€t«ÚÜBd*QV-Yç&¬üplHƒ”Ë-AARvû=9Vàm^¨P±£k\0·Þe1ç‘©›×F©@¯¨00S¦&"²65n‰ówW´»ž‚d[ç <êÊv,8‹hñ¡0þç9ÕÐ`h ›éàåÅ­÷¶$iÒäcͯÎ1ßöû‡Å×.Ù;¬…0X“vgz‰­>޲7E–×úSoL>"ð©dÝâ^{)“2rÁi“ƒslQb0*r3*Xd‰ÓSaÐÉ‘ÏÔŸÈäÚ¶ø„2 Šõ¢¥]Ù^sTȪÜBqÈ“R;Ÿ4ÈC£X}‡`T õÙ"ت¶É†¬«tÜÉb4q§<4ã=4Eš  bœ  Õ ÷O ¬ï s×àƒ ±®².Wœš\’»œ4ÅáÓYÞ¤è_Kµ&Ú…íés*ØWã±÷ŸAXÑXöTJ‹pa%¦(3™²Ò™ŒòÐ$÷Õ<ä1Uò6íØ$" A0èÝ%Ðë|ˆqà; Ôñ„–\¨0%&ûݶ¶tWÂëŠ}ÛI׉G3‹G:”ž™æ£3Œ>Y%¸BöQÒWæ”ßŸÒ DAÿ­1óÞ·jBÅ ®žíÝÝÐÜ '„2&4Ö®ø9ymXdz6¢Ði1wø|z5ZŒûýÍÓh—$™@„kÁDŒÿÀyA¢3Q¡›ÿÎë Á\k*@¿P8=’fàÞyÇ÷V‡c±O4yIRšõcáÜ8µ6N4/Ø;ðÌ,q2ÆLe»ûÃiÚB8Poê‚HZUµê~›£qGä0; Ѿyûç¯WØ¡|)·JL ¹æ¤‹g[˜t°šF:¦˜úÉ1à›É¢§mª…‚¹r{vjÙD8•¡?@Þ“\wŠ$-±úf'«QF#Ž”í =mïæ˜¼‘ÒC¢û  …~0hz]š*LÕâ`´ÑÙ95É“Ã<Àl!ëML¡‘÷éx7ÀÝaK±S¾ÔzÔ5¹!CÌ$9¡$aÐ3Vp ‘Ô@$=²QÇê Á=ZÙ÷Eé°xngw°Ñ~]Btx,Dæw×î!ç´Nï`§+'^¦m=r„Ù]«_Çž|Râu;°ÈùêææúfZéô›^Ìè SxŽ'~Êè­D¼ñ78Œª¡ߌ ïÇ'_îúÙëqúÊ{ü2ú>#ÿÅë0°ÁÞŒcMoÃcæî6`<¯/ îï’²K0·¸ÏÙx[a¸©þóÿŸZÎ~ÇÏ?|l’5endstream endobj 290 0 obj 1758 endobj 294 0 obj <> stream xœ•XÙnÛH}×WÔ[S «†Å­Xî,€éx&­^ö€ HJfC"’Šãùú9·’¦4 ƒ¬å.çž{.?3Ÿ æÓ?û[œVÿø$Ù¡_ùì°ú¼ú%³?ʼný´]…l[`•þo÷+³S°@<Œ˜ ¶=­î¼M¼bß“›õ¶?ã<ìÚ~È}?b›‹ÊUÄ•`ÛÇ•·}¨ØþÒCÝ6ëí_t|d—dà lðÊǼÛgyYfûúXeeUï½ûµÝ3š+.|eöàü‰[î<ìëÙ€»šüT±vÏrÖ·—®ÀåëÀ羑‡c±$´Õ› yœÆl{èþ¢m†®ÞÑ}x#ãØ^âó0 Ì%—¡*ÙÐê{Î]ÕWÍÀÚÝ_U1ðõ&$Ob¡vFÐÂýZ(®”Ð××=ëÏUQ£|x5ŽÜ=i“f¡ ý„ ‘ØÐÐq‹8„¡ ݽ÷øPìtéZ· ‘0 ã\Hu2šv`»J›UÎÃëárs`m‡x5—ã‘ÛºªNG‡RQn… yàŒ¹ó®êu «ÄN‚˜Ë$c&ub<ÐÒ+V´iïë²êèUWíµ?aäóX¸èÖ_évÀ.ŽS—¬Ö>¸‹MÔ#Å“$u† ŠÔÇB¡¬;`¥íž&|#ÿ"Š&Wu—Õå×âˆKœï»«¤Ž·ƒBÙV&§*oèòEí<>%ljÃxCX.]3c©V‘y_¬RP’jÆRašrÒ!s– RžDŽï(53-匘™—JÍ7 „Ó·d²nÔÒË;C@†Á'â†Ô2L b#ˆ €BÓð~)Šªï9Ûb#Å*¥œú#'ÚB±`4 3 ¦˜Â®(À–pâñxÓªÛKodÝXDÚÔÑeÍNx"žÎˆ =™HPkC¸Ûe— Ñ¢ÃWöX7UíØ=9rM–ÄŠfâ\á·ZŒiW 0“ÈqgSM>â"h2û¢ëLv{b_޹$ñé>tS¶…Q-VØhì,½ûpûæz{sûñ×eN•‰Ôd dÙðe5ÒÔé'W&'ïYÝ,NUú©Õjb¿AØÉ Ýk–ÊÔ#Ü3½~a’àf?J¤à€éœTÍTï’ƒD<Œ<òzq.ØHäJºþ§BùÂc:5ßõx&Ê^y7îgÙ·K›D<  /O…?~>ù–¼›Ôz–=¹µ]UÒ'X)å‘!L J+d±uìœ×ݨþû‡Ö|<ÐgA cßÙðx™(Ñ4ûž ôÇB@sñíôcZTWÛÂN ]—?Y÷HDótñEí€ìNGdÄ2¯_€¾øNîBL/'%4í„G‰Z虲vꮲvŸ™@g–å×E2×F‚\{€ÒS´BýüS5É–Û­ÿ"¦àÅsy€zÅЋΛKŽ'ð1S>H—»sùÑòÝvõ/üûÚŠ¦ endstream endobj 295 0 obj 2215 endobj 299 0 obj <> stream xœ¥XmoÛ6þî_Áo•·˜©JûÖ6Ð.]¶ÔÛ0ă!K´£Õ–RI®“þúÝñHYVš,ÀI,ò^ž»çžS>3Ÿ æã—ý™ï&?\+¶i'>ÛL>O„yÈì|ÇÞÌ'›çpJHßóõ„n &•äAÈT³ùnrãÍ¢©Œ|/™Mÿž¿{t+´·fB¥Ü÷C6‹à|1ñŠCÖ¬—EÓ-[×U±¬×Ë­®6Ýíò.+›éüŸ¡SHž€'ïÆö!ˆ ÝïÊjò»»mimÊí–uû¦bÝmÖ1ã­¬ºšµõNw·x.æú®ÛgÛí+ ]up.Õè*l&ôrãñÃ4åi’„„Ç4$Ü>ìVõ–} LeÏÒÄ[·º[®›z·„lÆ ƒ¦©AìBö^‹æ ÆBð8åxãu"ê,¯ôTD» ½MY-³¢htÛ.¦Æè,NèªÑç2H„ €ÌZÀƒCJ˜àZ–5šA¶5Å%ÞA¬Fˆ4úCË" wšM ÈË*“<£[V¶€ÙƒŒ: Y…!ãÄVîÐÓàˆJíp houcŸQÈ¥¯R‚ËȦÔèÙ¾Õ °Ó8ðî˶à n³•†@·šr°›4 'Ÿü¥ olVÞ—lX_&} J°°Õ&S´í ßA‹£7 §ÒÀ ù“ hqÚ—øSeŠ+²+¹JL*Þ¡b 9SïʯÆ&^íw+mè`S¸!åÅÔpAÆÐõ©ePƨ&XéWœAšÝщQKÌ22re˜8ˆ0qUÇ_mÕ]ã½"Fe¹åËJcŒ¦qÊ*kXÛA×íÎXUwæãG¼>êá…õw¬µ¢R…Ù]SçàáÊš&{`»}Ûa‹Dmr̾˜¦N£Ô˶{M\_xëºaÔØRFY½ûlw·| ûh8Vn¼ °sôŽ‰Þ¦1zô®ìãd[~š úC$¹|Ñ ™A'Äw~±Õ ×Ñ/õ™ŠØ,”&üwk;dÝŒ–‚'‘r¤;š_–U¡ïGYH˜ç±…BNbÉ@诺©ÙAÆPãMi‚– nGéxD­ü¤‰¼*Ûö, %ö¯è£¥@”PÞf”œE}{žÿ¹<¿|»ü8¿¾xýay}qyõöõüÝÕ/Ç9%5_M ‰SÃywÿúðæêòÝÛçL¦Š;ZL´­BTìç®OTss×´ª™!¦ªÌ²™mz9«6g{§óŠŒýE^ sxõ`Ê<,ªÂ¡êÐ^éiâç' ŸܵøÙÉ” …ûœfe£`ièó4” ɹ ÛeñÍðEøTøà6éÃ'‹è67rw™Úƒ|~Œ[qÙ ¤O×F:N&æßi–Íp½‘iÏgüà fjíum²£Jý¯T‘ô¸?C¼$îêÌDú}§#Ý#‰Û2¿E×UÝì̤ÁÀÐÞIèê¬â‰’Nºîëi+ÀÈ[wÇ5.ˆ@š„:j®ËÎî‹íº‡±$¹ñc.üøtõ:¡(naÁQðêõ‰ÐØÑ3fS,\ò¾›6åRÔ'IH"8`‰eè´ÞW¹ÜäÚ1¯}h‰dHë?–W?Ü$îj÷9J Îñ‘1ÞSÄ»¸¾¾º—0uYÜ AÝ40o",^àqšÓ,¼!¶Ÿ]—riä Tô¬Wç:×Fò¥­C>&„áhá%ª8µ>‡ÁÊŠé+Ôy ˆÛ­p ‡†]f¦[éÙ°TîÂL?7¯ZÀÂ)Ù1 °âÇ%nüº<׫ý†«i_|xé¾â°“u}Ñ<ùHŸI3xzð²ï ÊÜ«a%f!%&x$[‘kœÐ JH'Óîáë{6¹¶Ð…ÙR<¸ƒ-T£|†BøÍ7h¡Ê<éß[…fÎzðþDQW]VVæ%ætUkxèŒñB¯ A£šC¹7ª(¤±¸ßØLZÎ,kS^iû%èO>Ò)»€KÐïô¸”)76ÿCÅn6ê‰ÑÂÌSõ”†…ää%@)by"bì›2Eˆ§>àóзÉ|k²ûIðTø>¼9ôo3C3_"b1Wýnþœv±gÕ‰fd ÑøÃ½Ù­Ïi—©O˜>•a ã^<¥^!¹ÈŸ’±Ãðõ.\þÏJÚTæ ¾9 ,JËðTÁ$hš=|¤›P´XþðiKÍĺÖ0JÛU~¿¢|ƒd\!£àŒÉˆ½Ïª=¾æH_šStT#=Jðé¿Q.æ“ßàë_X²Ùºendstream endobj 300 0 obj 1810 endobj 304 0 obj <> stream xœXÛrÛF}çWÌ›Á]av.¸Ìäͱõ ”ï:ÜÚÚS,RØ€¦•¯ßة”T% ˜ééË9§{øa”†?þïî´øÇ§œº#‡Åo n_ÿgw"߯’¬v°Š ¿«ýÂíäDä‚Ê„ä2#«Óâ1ŠÓ¥HY¤ãå/«À슓”±„Ä),*aÑCOZÓ_Úº#©›:þÝ´ ù¼ Õ:ŠãŦ&Ýe·3]wGŠº´æàüÄŸ/XF³\ƒ[®þ7qŽQá^=F`Ç´mÓ.Ó”2Î#ê-)Â9®Ϩç¤Ä ‚æ)Y]QJsÊÁL‰¶NsƽÍèZ´ûMQ–›¢-êƒÙl×Ñzé]þÅa D›˜5úÞnýwÝU‡Ú”¤|ÅÚIsš‘láinÏ?7ïÍör åöp‡Kðå‡ðòmY¶dkUÆZÌÙò͋ӎ¦>ôO¯½éžOÛæ¸©êÒ|yí½©ËÍ|PTÝÄd]höûÎô›}Ûœ6ã\}þ=–ƒüÍVòöæ¶r± ÝçŒ îÎX=²¿Ô»¾jêY¢3(«¡4¯et¨Í$·–ÝX 0¬›þɴħØÍ¤o «ø rŸaZÄæy( í1êŒõŽìšº/ªºª3cU½oÚS‹î-Ív)ÐBÊèrðÞvœBÙÚ>ì]nB¤œÓDgšøÜ¤Ìu^RuÀ©ž §f[Ò (†ÈZC.ºÚ_q©tFw‹<§,‘~aÓá;KežPž‡çö̳kMу91›$É4•À©Û,EëètézH꬈IB³,áÞðûÿlÞx·ùù¿?~ÿñÃûͧûß½]=|üéçy%uNƒ¸b]:³¿_ÒêMFŒÉ…ն̬jE…ÒÞN3¥­óW@€<(B`k´C⟠þíRWÒͮڻr§2ªMÛç¹ A^© ˜¼­çÜ9N™Òa!}!; øÀpF¯SržÆ,‡ZåÎfJ5|´ÑŒ ´ªø7ãã<ùƒøâpHðlŽÛ¹O< "þ"JMg<óoGÐÝlŠ3ÎD ‹âCD iMkJº„vèÑÔ&ÝZ)2bðŽœ‹ª%×êxD`uO IZ[»…:¦,øp½ŒQ4Ée(ÐÙ’!O|Ü’ –;<Õ6‰­96;+ ÀǶxö­Ñ%q7W)UÙTëPÝÑÄUæÉŒÑŒåAò@ðæÀ‘*£ À8”ÇY/[ÀNÕvý¦Ùo\¢7˜–™y©Á|Ãv=·î¼´ºÙ¾j^HA•ô¹ ÃahëÓìo3Ø‚µ¶ì,`xšA…‚<¬¼xK¥q`™ÈxÐ]NV²ÏçcåmÙÊc) LEïÐPÕ 3]s2ý.‡;sî/ÅñøLªÒÔ=l†MVxSÔæ1¢×¥Fp%¸wÓOÉß-»xZEª’˜¬×r«q XG7‚Ìo„ó1ê Ìh°ŒFÞŠ$º;À3å¶z¡ÙJåH²²¨,:ÈA ¾tÔïlË€hû˜'ÚH‰³"ÎCË\'@«$POH'Ÿàr¼Ž[äÓÚ³íÇ®Å6òP¹k?†›â’Ð'àHÈöÚ¶Kx,ÓIJËg Æ·Ôërkbè Äq\g2úRu=VðXl 8r}2.ÿ¿ Óå‰Qéø.7áèÏÅm ˜PC *°p46R´p„¤ŸâxšO'Â)iÕ¹3 @Þï×ÚÄsê) c©r£Ðµ&ë9Óœªß­Mçx}9m¥ƒÒ !¯—– "Ô+>÷- +ýfhh<„'†3Dº,Ãè'†Æ¹fÎq» 5ǾævoŸŠgË'"›ª.ÚgÒõ€¹Ó]fºèX}Äf0ÞXiß²€ÀäÜ6xo°sÍkkg8¬tÄv‡ëGªÝýÃ2}ÁÌF¬%&‚ÿ¥8Æél^M'ÂÚ j:rgŽÜC Ì©êoÄäXýºä¶‡ªÈù§$†&´ç"Ðéx®CÜlâDX÷ö3…œª4]ë[½Yh¦|*Àe•eaB²79-ýœG•Í@B9§0O…FñÙAG:» ˆ¢º8K`àÖ¼ƒ>,¨pfÑj28,¯O~˜\}ºûã×FI5Ì»s“0îëñô¿6®—ßy¨h eT]¦&ªk¡jÄVu¸C¯-–ÝU¢›Ì\iú3—ÈQRC¶_Œ¼Ò>¹×kIÄï&— ó–S6MR0ÒÁè(,\/^Ï.Bƒ÷Vâ`*äܦ%wHzmü‘ MÅ0þŒc_æ¶MâHä8=®Æ8àâ— =öIÂì=ÂÝóð»q–Th_+V{#ôÛ›†mÁ¾òׇd ÃcHóWø‡£Z(’Ÿ/À#ëÝÅðúTížÜmî(8èÚÃ=Ê­ÛÙ۰ʇïK¾4Ë æb ÂÑßáÈúÏÇÄùdy ¿?î‡ôa.]ÏÛ&ǦóW‚}Ú| eÀçŸìcÛbá Ðú™ßt}ró Må)ù¡¨/Ø7|4‘ƒÚŽÁL¿º_-þ?ÿG‡56endstream endobj 305 0 obj 1964 endobj 309 0 obj <> stream xœVÛŽÛ6}÷Wð­ÒbÅò¢ëcŠÝ MÙÖu»…AK´­D–QZÃýú)R²å(6€“œžsæp¾"‚)"úÏ~æ‡ÅËíÔ‚ Ýâ낚Ed?òúiµàh•Ã.Êü[mÃIŠXÂ0QÂc´:,^¼ öYD<øÿ¬>@¼áThO4É0!! "Ø_,¼f»U²[oÛæ°–u±Vçæ©üÕç«\1Å!dÓJ…Ê]Ý´²ÀzW@ÓÖ‚éÕï—µ²ëÛZ!ê¦þ•mƒÞ|â,K­žþZ?ÿ:‹'xT4ÄÊ›¶P†þíà õJYÁo 0íº¯`ƒ¶-œhb]d:Ä[M1ÒÄÆ­DB‡ªªìM½Ó7¤”)YÎÏ‹’#>Z¸Ú7}U DG¡TÖ::Ã3,sÆ6ò>‡‚àØÆ=ôªÓQÁøûª :ÙÊZt@u-Üþ&¾9ëâÏ•87~ð8ͬ¯à¾j|ç.êàòššï´/ó=êÎGx¶Öެ¥1ã¢ËáZm[޶–`’1š]ØšWAÿƒ’ꫜâˆq§Ÿ·fòEŠ“˜ŒoWõæSójÅý]cOàTâÒþOg¿™†'#ή¯æ> stream xœíVMoã6½ëWÌ-R±ü’(S8)²]4­«vIaÈí¨¨e¯$ï6ýõ’¢­hÝ —="@œyœyo>ô(a@Ío|V»à륂mPØfa|T;ø¦Z1øWlçÉ€+N„%R(vÁc§OhÈâè×ââY¯ ˜0N1§‚P*!Nr(ê@ž@ñ9’c,uTüˆœ$‚gŽáç²Û¬Êº^Žë¶ÜéUù>EÆc‘c,±÷A|ãE-fÓP_ò7Þ‰")Ĉ`.YX«V ½>n¡^o¯‰9|?9l4Ô¾Ž®‚°z.;øÊCšöµ3½íº=žjóÀP¯¦¬Åî^fx?@§‡c×ö³„dJÒ)rf‹«Åû_VßV,UÄÓ´o¡?V•î{(Ûz†¦$,} v»\>,gxYN¤³z4€6(Ie,$VΘ«Œ0Å1ƒÌ¢ÝÛjhиêt9è(ƒ…®ôn­;à”eÄÝÀÌBN9QÙ­ðWdDQ ä²î—T÷¯TwüÜöͶÅx¾(€ÿŽüŒI¹ ºxÖ°©œe™)"Sêi¹Î‰—Sg&Œð“Úö0 þèýAWÍÆf˜pÂÕ(¹†¹ÆAÞÖ/_ö%¹8³6Mÿo Éi2ìm½keßeÓ6íÖÕ_CC´­•8èì/!µ^›·œš©±!$I¤Å=n= =äp2£ÔÇ.îogAò”0‘ Ä<äð\š¦Å¥(Ôl×2ê—-.zyÙŠ./[ïóö²õþÿpÚþ¿fÿÕ5k÷{Váv¸¸gdöIì=bå|–¶öí!¦F¬Oì\¥É´×ñãì°úÞ•í±ì^0bÎÎÈ[®Nýúûñ¶~Äß_Üʪendstream endobj 315 0 obj 971 endobj 319 0 obj <> stream xœÅVßs›F~ç¯Ø·@Ç\ï<º#»ã4S·ŠÚ<Ø ‚“L[!P\÷¯ÏÞÁD¥$“v¦#5öÛÛow¿÷@ j>ýw¾õ¾+Ø4…÷Þcö&ô_ù¾[x9>Å8àßbíu‘ ¸âDHP"†ÅÖ{ðÃ8àõyü¶xx]”ì£BN¡TBáó…çÏž³z½ü¥jÊM¥ (ìϬ(–ûê}ÙëG?XüîEŠÄ"ÊòÓr¦W‡ «Í•yÄÜ|st³ÔP”ú*xåùùSVÃ7Xe[½4ÿìåîÑ›ºÞá]m¾¼~TcØååÔäeœ°/?{þâIÃúPåm¹«L„¤ MÁ†øgÊÁ]Ä@dÄH ““äÁǰZLÕÇB³×y¹8E•ðKäkõbi>aXR’J9ÐÕGÛº'©SF¤ ¬KÍ å©-¯ÝÙ´¶B¾«Ú¬¬ÊjãNÒ\AI41hœr’ô‡÷I¡WÝEBÕ“ ¸‡£¡!€N¨KcB£ivw39k(%"M\]´#©}ÊZ¨õ¾Ö®ÚŽ/×XishSxe3òw:®ðÜ2q½+§tq†ÓÐWjn… Œ1 䉹úàß™³´‡ºj ƒjW…ëz.Iš*?ûó ÏÕò\7ÈbVÿ8³OC§³B ïn=øˆc‡6ˆaÆðHR† 3,&‰Ù4n‰l"ÂÜ\‘EEß%K§Ÿ5-\Û³Á£ÿ¬³?,yÍc÷{]g†ÔfÚãքȨ`lq3v£Å° ˜6Ùia)îKjFä³ÙÜàu JI$zÞ ¸ìÀ¯+xûý]XèµÅH#æ—FA´JQiÜO¶ÿW«Q` ¢éšÀ‚Ÿ ’ÿã®…}V·°[CÓb_²º€™}“J#cŒ¢07ï®ÍM«o,!Q4ôe~(s $9n‰°\1ã~ãÀÕõ„MA-. ¤Ä5ÜMá Žžev¤!ÃÒ» ¾ ]MeÕ ê1Àjê'ÔÔ }µ”íɤ¬#Ž"'Ÿ³wËÙ›_—÷?Lf.VÄñ3n“]¦S4%‰ÖƒÝÌç÷ó ^’ùéµ ¹JSÜ­ºë4&¯5Ît(£3ëíJ×À)ŽD—[ÏL !Œ=q¢Žn[þÊ“Š`¿Ôñ³ýîCNú}ÑKG¤ÿÊLÿUûq7õY#E©¼É?WË'•yHOŒtP4gƒr\°Raf@ d U_œGú5u´Ð0–d°µó* “Êyè ”çL”¡}¤B^´Q%ãÔÉ)C÷úzÅ÷qñ=„á)Ìä û?evH’#ÿÿuðѤ«cn˰¯ÃLÕí‘?°ÑÜk :נƿΪCV¿ 0p6F£<¥jÈ~úâ|³ð~ÆÏGi0úendstream endobj 320 0 obj 1072 endobj 324 0 obj <> stream xœÝXKoÛF¾ëWì-«ÀÜrßËc ÙEÒ i¥9(…@K”Ì ¦’Ê£¿¾³OQ´•-z)d@¹óþæÛB9¡(·Ÿð½º›üt­Ñ¶›äh;ù4¡î% _«;ôó|ÂÑ|§(Cð7ßL¼$EL3ÂÒ\¡ùÝd35e2Ç<›þ9úœ”ATX¡Œåœä¹@™‚7ë 'Í¿L°$ ôM_öõj:ÿ0QaT!w$w®öͪ¯w zUÞUz}_µ¥ýÝÙ㯲 †œ0¡ÆYXàùm…Ⱥº™²œäTJ¼ß.7 µq »Ê«_íš¾¬›õpÜ¿ÚmPç•>,—¤PÆ»Ä;_ûªé¬™àÕmÙ¢§VÛÒªsÏü¹Ë¶ÝÁ«Ê~‹OŽÚË›óî ¨óp>€Å($-ˆÔ*d?FÊC¢¥‚Ó‡n´e-ÇíèªË@–RÑÝW«Úáš"™É=ŽjÙÍ·‘·œ p–SrFî)Cø¡´½oäÔÍö»ÒÅ®c&'&vþ G@ÏòC8€qIz |¿µwÂCö8›ýuü_!%ìÇL`œ$ÂÇhP§ø\D΃;Y±u"=$ü1Ñ,õôIþ+ˆL§À+Bkÿ &Lí†<Œ ß'®á.%°ÍÍh•àèªþXeÝjwïB,1ÚÐÁŒ¸Ào»ªrmGoŠÝüiçpʘÇà|Ê¼ÓøÛ}õpç!%2ˆÒÖ!Y¢7Û–æT"ih‹{°qÎ.¸¶ÚÛ0ܨ\À»"ÎYœé‹aÅ]dÖZ{ÌÍïÒNÆi~ÇÛÚ=¶«“mÐÀe ö¹ò«ÓEØ,h"µfwè¸üÓpûÓPX>D„wþh':n? íW(zÜ~Ü ž·1“®ÈÇW¢QC¦(&0Ì$žëÿûösØy s¢×N”Û­%„@ÉDò ;Ò‹²Ù—í7'=Hk;H&ËÇÿ>¸œO~‡Ïß\d1endstream endobj 325 0 obj 1450 endobj 329 0 obj <> stream xœÝWÛnÛF}çWì›ÉÂÜî•—Çv §AÝ:júàE®d2©”÷ë;{£(Új‚ E!ÈÙ¹œ9gvüLÑ÷]>ßߥhÓm‚5/‘û*Ñ‹€£E V”!ø[¬{’"–2ÌJy‚Á}'“$qôçâ5ø3§2D¹>3Â1!Å2G‹*à˜I´ø„SÉTÑâC L8ËÀ;X„ŸŠn½,ªj9<íTS<ªeñ>|iCÈF¸lb"ècÄx­›U/:ÐÇeŠƒ æÊ˜ýº¼R«ýU«Í¥6Ñ/ßL^Ö UµºŒ.‚°|(:ôö¹ÔNÍ3kwÝu-¼Rú ½˜¢Û 6IŽs™˜Du†…zp…Š~V]ža‘f¹CäyEšÍû$ „‘î¬ú¬íLW(ÅT8”¹1Ñ™”j7@&Å€Úõû²T½Î ÒëÔ°ïšyj1K–;ùÇòêÍ»åíÏÎÐ瑤Ø3½¹‹¦Ò1Ö%@‰4 ‹z»ïÔi0Í¡I4ÊLsæŠq¡®ïînïfѲ g… 2,#˜ÃIøaž¾Ú7åPCü²SÅ *D(ºR¥z\©1B3l=s©vȹfÃ锯†±H1œ`çû"]Ý‘ºZúüÞôõ¦Œ^êó‚·çiêx«ÐÚ!9+1ÉpB û"g§T™ñl€±Õ„¶FíÀ]IÀ³³Ò©dVë[÷e»Shß«NBÄñÆR¥€i9ÎsIa.¨ÊP+JÀN‚Ó\XzêM„;Z|7;-Oõ];Ýd…ß ¦‹ìýq18¸•'‡¼#=‡ ádµ)ókvÛƒåí¿¹Ú‚ËoÞt¾j³¥„ñžo¶®ž\lAÌ"ýÂb«ùÖÅ(žÿ_Û„šîß)h¢Q,¬³À1?eèd’øh’_"àøë¢ÙݸbÆÊžNá¢IÇ+âôÀëEð|þô˜É4endstream endobj 330 0 obj 1313 endobj 334 0 obj <> stream xœíXËnÛFÝë+fW*0§óàkÐUZ»€Ó´i µYØ…1"GŠTø°ë~}ï<)KNA7  áÜç¹ç\æ"˜"¢ÿÜg¹_|{“£í° h»ø´ æ¹r¾_-8Z•ðeþ­6 {“"–3Ì”ó ­ö‹Û(Ζ,%Q/ÿ\½{æV(Õ—bF8&$Aqš¢Uµ`8‡ÏÇE”bš` áTËÕ‡E’cFÀ ÑÏÜF²ßÜ˪ºXR×SÉ~ D‘‰¨•{uÝ-?0qÆÞ 8ÕvˆqtiŒýÞõ¶UªfÛ²·–tiŽ3ƒ)¸ç®üz©ÖÓUëí…~D¾=:¬ªju±üf•;Ù£W`ð^[4?ÙÇ®ú¾ƒ¥? àoŽë[Ÿ6VŠó„»Ú)´™Úr¬»V{=Ê/+0£™­QôBàÀ^K(N Š‚ª]ÜFpk@#8Ò÷P·Am–T`!hT7*Êî Ð0ʱ.у)3-NSg šQËu£´»˜ p(Bñ†ƒ*ë>bN|¼s“^ -X?$ÆfYâû2ž$“q,<>ÆÎ„?(S&ø.GTví(ëvNlЙm–Lˆó³ÄLZ1Áæ1åºT!‰©½,SŠ óEä8綆¶ª”uAiÕ­ÉÎDЭ?@t¨W‡^ ªmÞ'ˆe¼À4õ]oµSa\<›-3=;YzŒ&n:HÁ‰FSnÑÄf8)Í´«â™”¼Þï5Úh®1âîeýtWŸégÝŽN4½¸ü²B¾ ¢Aw Ƕ39¹4$ž0–ŸUÎï¾ 0ý™E±–5‰Lˆ†—5›B]¨'É xB¸¤ ia´:ãMPÙ¹!Ñ BÄS(»Jh9›’|Öïe;íLÑPjôD•ÍT)âLSkfh0ôcxŒ€^!»&À¶»ð0D1ÂÌXY«7—µÎÖ`ÜÔµ™Ü^Äͦ©ç0µŸuƒá0 yp¢‹†Ñ/ €¯LN9DôaƨÏɉ®ƒºµ˜Ãp¤ HP½8mP§Â.c/[ÕMƒ&Q Á§jFÜ«ÙÏWø¢ðóž=[j-¶<%7ºª^ëX >2´óÂælÖ$¸ Œ´ézÛÁ³(`ΊSX …±UÕÆw86ëÁ4€_.cªgZ+ wkôþõ\¶Z4çæG¿ùÜEk»·¥4kUèh;Ø…v²ÝªcBµÛQ<Ì(ÅÜ À¡«ÍŠ‹•c}ì#ÇIxÚâz¸[btm¦,Ë1ÏçEÓ={Z€©G©ß\5¥*g’MÎÃbò´™«/ ÔW[{±£¬·0-N½’ÕÅù0d)è( Ì€”¹"°!Xœ[€ƒƒÅúÇ<žnìzqâ,÷"Vxf¸|ùöû«››w7'>¯æÀ ÀÔxf-=rhwŒçV LB¾ú«)‡YÃz³oI¿œ^0O” ¡Wq·?Ý̵ 8¾P/f'„á ÊÞ&øî§ÓEfâÙ®bC2{z´/t,‹äà7°ÍÔœ 1à Ǚ̱ÏËÜÔÎB§7¡$ù:¡›íü‹R÷UÚ¦W´ä\ܦ6vúF …ý…‡ÝÛ‰1  R¨#옋®•Ã.ñŸ™FnmZÌÛî³Yª¤Âé—g0&âÿ!üo ¡=Î]‘ç—ë¡ñ4=_yqÊ/ŒêÙN²BŒ0:ßÎa×σ†=ÿO£«Õâ7øûËæendstream endobj 335 0 obj 1778 endobj 339 0 obj <> stream xœíXYoÛF~ׯX !k»÷’íS§@Si]µy° "— ‰txøø÷=xXŽ“¶(ЗÂd‹»s|óÍ7Ã|DSDìOøÌ«¯/5ºéVݬ>®¨{ˆÂG~Do6+Ž69œ¢ Á¿M¹ò7)bša.æ mŽ««h­b&I¤Öñï›w`ÏÝJåöÒšŽ h-S´)V3‰6÷«Hb*1GE¼ùc%&œ%`N\E÷Y[n»>kûí1ËÛ˜&`!aQ³-Áü®eTÌut;—£1®GSà×#ÎWU÷¨8± Æœs÷ýOÛs³nP±»9³IZƒY°ŽüZwÕMm t¨jS7î˜=pñì€5\Õ…y8‹_ß¶mӢׯ~\Ç߃µ÷á㌦;Öìt•à„%©‡†bÂRŸQ‡²Ù ?ÿ}¾'šO@>T1çkÅ£ºŸ«ÃÖ,Õ㩽A¸0»˜€Vòh¸ÙÚÑÞd…i¿A=pž¬É•§©š\5Þ•L¢réJcž¤! ë©t°¥˜R¶H*±I]Ù¢¢:;¯e"±Riô‹16gqÍøät*L9Ôy_5uÀl$œÒL±àÔ>+ WðmaòƒcÜž‘\R<ÞÄ{ÈåA5&ŠÑ)@e"õ˜¦'ÈI!˜)'ÁqŽmÊݾÚxP•*T¶Œ 4Ñø»w¸Y¨¥7Á<¶NÖ8 a˜håÒ”î^Þo«CfQBC]õ¨k†6³}g%ºŽî÷U¾?Cp<‡'9³ë¦GúªªóÃPØêÛ\[xóùЧ ¦z걜8álð:Æ>Fd ”îÒôC[w§•£ ,j„ùüÃöüâ·íÛËË÷—'h¦ *èÄ k’Îêu¦f–c.eà[äzð´:ÄÚ»B˜Öm6]ÐÞQ¾JRÌÕt_ÎéƒTÑ‘ŸL‘C,‚±§)¾ÿñm¿Œ'ÔY@O$#†Ä3ÈU9;Ð}Lm eê†<7]W4rTdI­f=Õa:üê“2lêb! $ÿ‚6ÿ¶ŸŠèSÌž êÿû¯Æõs‚É vƒÖ¥ZªhÑ´[óÐÿNÝ-nšO 2~i¤çM ›AÝ/†úæõU”ï3  #AHÔõmUƒ)¯ÃØóaÁË×h1Ü—´ôŽCØX?Á7€êÑd5ØD^«Oê +ÄT¡1ÂÓ25E2òÁ²ó¹!˳ŸÅóÙ¤ä8™„ кùáú@ÙïݰEðv€}Àr•ÂПÀ rƧþ%8nÆG»GtîNPÊmø1ÞÿðÝ’èrüþ*ºü>L¬3´sÓ1Õ,z¢O ‡®·sú©i‹ªÎÚGT@ÛÞ´Gø³‡:û£v½Ð˜®¡ ÐŽÜUçw Á°&<#:l'n(B³ÆvÚÃŽzDú’r·Ç¬(–®ŸO ²ò[ˆsÏ`o¡jìùì3¾x&¦Í.òä ‚ËdÂÿx{xD¦Îv-Ú7™©†íÑo¶oMîÛžz1%¦úë°b^Uí« Ù@ÐX¤?bÑ?©¦ÆŒé/¦Š&ަîÝr X§£z¾(Ü2ýkº­&!~Y­“y¼ Öl²ò’Xƒ+>7VXsXú¥nñ/ª3ìñˆ,4¸ ÛÜB†©zQ†…ÓJ`GWkÞ½yMz¬ÐEãÙ%Ã[ƒšvôû —@]AN'¬Ö@挘;d #ÉDBX¯çºÃB*yú$—ùeCIû²Q¶°ò_Ǩ¹5­£g7Šÿ$¡”P¬'¥8%¡'AE;XŽÃ{@lÔxõr®Ü2NžF¦@)Tª4-tñéÐá XÇæµ~çf ÞŸT ø›’iû‡.Exm×d1Ë`Ôº¯áíx35\r¹©:*÷d‰V 6H㳬³Ë64õí­Ó23ãʾ’C¿iú}˜-’•íÚX²dm*ª°½vq23"™·óÂÜÂ<ûós£]aú|´ûÉ^›ûmY˜m6¾n-+:ótìzG§ u³tÞÑ™KrA£K~† ŽwY=X©g„ÑÙ„€Â4=žþÅÛÍêgøù£,gendstream endobj 340 0 obj 1614 endobj 344 0 obj <> stream xœ­XÛn7}×Wð­«@by]î¢OIåI$uÔöÁ)„Õ.%o!­œ½ÄñßwH.÷&Yu‹Âd˜CÎpæÌ™C}ESDÌOû™g?Þ*´¯fíg_gÔ.¢ö#=¢7ëGë¬(Cð»ÞÍÜNŠ˜b˜ ¤xˆÖÇÙ]° çL’@-ç®ßÃyn—hw-ᘖì³Y5Ê“r·)ôãf—éMò%˜¯ÿšI…C´„Æje->mVzÛìQ¶Ý/Œ‰YüÐ/¾Í4zeN85õbþƒ_¸)ËS‰^ióñeÿ\bé¼0b¼0,õ8 >¨jÒTWªï5Ú5EZç§ÂøÜ…2ØLCd7g—_Ξ ìcåíK]7eQMÎäŽ[ƒÕ›Õ‡ß7™£æ*d­URd¨= %ÆrÉC£0ò¹#X†ÂÞêáÉÖ%ªOîV®ú¾<5ûû³‹EX(Úzh3jlB8kŠI°h-ñÚÙ’ÓG±h¯BܶG@øÍt•–ùC E©îOÍ!C[šJg&°íœÀçA“ÃJ‚ÒÓñá kmÑ4%Va‘·«‹ ‚•šÆÈ(öiÇŸ»Á“>Fá¶™›m¥¿6€™&‡Ce‚,Õy¡ ’º ’Rá‚lL>§2ã˜{·mtØb(#ﻵtØUÉQOгäp.ÅYoü'."†[˜Ü}ÖçRà8ŠÃÛ—ÖªmbƒxW£Ëè!¥œôæööãíÔsìAqœ d{o.¥IšwKyˆ‰4͹ µM†ÒR'5 P´Ò©>n²ŒÐ;¢Ôv 7Íϰ’6f‰rø,ƒ Ãß"ÃÆ´e—Po=ÊÁT²ñ ÿ…^LBÐÜæ¿Áúyæ %f¡—˜çïPjñ´Vañ"CÌ ÷5}œR5”å÷^…𤬋¨oqÛ0ÕŽ€yÔ¡—b+×vç, ÿ‘¨€ºÇbÜd ÎŒ^ÄTaÆíÝ©Ûö?2D^a€¥ †;=O¿°ÿcà Æ£—TäÙæºæ§Å’ ß… Â&éÿfÉ_á(нãäg“ȇÝôX8ììŒGj=@sêæïÁ€›b’Ã%ј…Þ¼^½^­¦V=Ý´»FtÓË ³þݤ÷ ðLÒìÚ ûú|,C'urÈ÷ÅÙR–ÔÉ3KX¹)õ~°ø©.Q^äõfûTëj°ð[QÁ1ÐÌýêæ ‹K¯Ì5ó"Ó߯궟®r&ãgÂí }R½!ùˆ>Ÿ/\‡¥0€áª|3 ‰\Tp ƒ¤+¥ÖÚ.Òž•¨‘lQç¦aå€K@´B2ñ3DÔßëçw–p®h¡E2ôiö¢$‡Â²@¦BÝq‘!6¯î‚ﵕü§Ü~Ôu¯ü¹€·AGVNlZbkµè”ÛèP_Œ€1)FÌ{>?HÐaqÜÍó.¦½ŸOF5H†y¢(¯]í®GS7Ÿ¶O‡@’Ó1Ï_÷vT6g ƒSÕç‹5Æ>_Ƶ›GP†ÛJyr2f†Ã¹n` í K,r+<_JB¤ÌЇ–«ªªºÌ‹½5¾0ª@‚ëEe›³að@Ì+˜[,t±åªtšïæ46i§Aî’4q¡8æa§:‚rÏ {Ús­1~V(©:T}&“°@o‡,òqõcçê~HWÜ3ß™(€Þ¢r(r»y5e˜ŒwvæÂunL­lyAú*ÓÃ*RÏËwÁáiÉÀÂN2ô¨Xu7ì‡àô†P ±vïôÊ?Óí>§:Ký4¶¥^ÂÃJôè3jõ4|c‡_õ 8àýrq ¬oµ­6ìÑ>Í.‰²˜ávvc3öÏD™ÀBú“[ĉùÖÁbn¢ÜM´û¦hìKð´sÏàx®Â±xv©:íÐðöv> stream xœíXKoÛF¾ëWlO¡q»’»Do A§®ÒâB È•ÄT">âøßwöER´äÖK`–½;ïo¾™õD0ED¹Ÿùiñë­@ûvAÐ~ñeAÍ!r?òú}½àhÃ-Ê|¯w +I ó ž õiñ)“%‹I Ãå?ë· ¤BF8&$Ba —ŠÃ"hý°ÖÕ(T¶¨ªQ^WËõçENI-%¦D€ ¾*}f´QŠi$íß?U©ª=,SœÊ˜ÇAöˆºíU¥š¬S¨;(ã8yǹÀœP§¸¬Ên³}ìT« LâÂxinŃÃmרì„ÑMeJR¥Ò9£Ã’æÖç¾íÐ!kÁeÔ†à\$8uêòì˜÷GíhÙ¡í#ÈTªÔªûLû|Cië“êeµGewБAÊšFå\ÿÒ«*WH‹÷­qM›z·Š‡å øŒã(r!S(7Ö³fWô§{~5‚Y¡Ž;t€õö³>»[š#mý[jçvè`ôGVM¾`R`ʘËç·b,T¢¯L¬FÆ*hU.R«L}É>¶‰¢'I:$ÊßH4eÝÃ/Õ,”$XzT<‡–\ýb$)˜JÓ…Lš³› ©¦È¡êú¦òˆðÀ‘€1‘ø@¯þÞ\½ûks}{{s;ƒŽLpänÙ°¨H0£­×}•we]¡rÞ©¯T®N[È #Tb«Q"JµBÎu-5¾LBb ©…î@Ô6$¼WPÓMV›]“Ô&/Õ]p·œzhÌ1ÍWFöcÕ–û \*.©ÒŠb(‘/ú°¹RÛ~Ší~5Á^~Èô2ë÷'èQÕ¬À['ðç);¾…ÚdG°÷ä¨Èºì™#(Žv«Ù4j?9üÐAé†fž §›£šê½6uiÊ·ü &Å m¼Ìµ8c‰g.´seœ¥Ha .-ÿpz‡Jyã,Ip»ÚZ°@ÌìE)&2õõæÚTÉ>£lF!{k•Âqû6 *Ó¿añlå"p]„©,L‹qlÐÌãÔ“ò·nÉÁ’Ë .Ç9À¸‚º[A·‚îÏ€¼u,ÐViæ*414jgènÞ„¨ÔÓ²õrˆx&™j_Ïä¼÷—åÛ³±(ñ)jœ§ÛÇ™…¦œ þÚë«ÁýŽ•nJU,޽xíê0ôÃÚ(ħ …JÜ<—Ù}]²¨ŒÈ ;ö€€Ù€ H5$Æ$e¯®3C=0Éô,Ñ—/ IÎaHñèù< LâK äÜÞ«¼Ü™Á@±”þH;mÀS^JXÈÓK1ÒÉÀú¢°Ív–¹$Âèx=f0 é'ïQ3! ˆ[óˆÖ‹Œƒ©Ä1Þ÷,ïêÆ4gŽAC¯-Xg0`Æškæ4ýaÍ€1݃é€]`ÞêiiÒSmk%“˜Ô|âÓŽ@<0æ]Õ€R»ŽìËR:”zÖ€Eêwƒ •æ'i’Ž:…Å`màŠÎøÂ#_ãù¾£™0îIlàüù¾åóºšw¼°w ƒ4Ì:”_Ö4&\Œ†ö·w6Gº ¦óeæc e| ~Wží!°[’Ïn­ÇÇeaQ–MÍò® &‡Özv?•@¦În>êRß×eÕµ–;ÝfeY¶Q÷à°Fªƒ@ÈxŠ“ˆ4Ÿ¸íµ¬€z3ÙÚç@߇`ú ýl•&·ê¬ô>9ׯ‚„=‰Xé™fJ"Å^óH:Ðuœª#ŽtZ“‡ª7›U½³½¹mlºdÚTÁv;[Õ~ùºüfyñóÉòóÉò‘úi6ÿÏÊõzñ|ý†à¥Iendstream endobj 350 0 obj 1587 endobj 354 0 obj <> stream xœ¥XmoÛ6þî_Áo“‡šã«(í[×d@†vÝRÛ‚lɶ6[Ê$¹I÷ëw$EI¦'Ý`6DòŽw÷ÜÇúLÑŸîw}˜}s«Ð¶™´ý=£fu?ëún9ãh¹†Y”!ø.73»’"¦æ)¢åav,Â9“$ˆó?–?€=»Jt«ŒpLˆ@ ó³YP”-ÊÒz“¤Y–lêô'›,OÖƒùòÏ‹p„°\Ͻ2ó~J®òÕq‹²Õö•ž¢ßƒßg9¯æ_9ÊŠñ³_ʦؖy†Ö'_gY>u«wSë…aßçË*Øã>/õ25¡ù|HŠìqÊe7”T›$/3=ÃD91»¨6›&o!#ÕAOK`Փξ.Ê,LÚ*9üº®«úk”ëŸsx>ªß¦–›Ô2ЉÆôrW4hs,×mQ•þï‹¿Lš¥ÀT]W"×OFee1„uƒåü€{X²ÄE>”Ä œw–õ<J1Q÷|ß·¨Ý¥­çyÁÃÇ…É`²þÇn#ˆ™Jkž2,࿎—6¨ÌmÄöáz&`˜Ç.ø‡´ …ÑPšàU7XoûýÇXE„¸Ž‡¼lÔV(Ýï«Sû1Ã’» <{ œ@Y¢x´G[£&GE»;KE™”C*®~M®Þ¾I>üþî»÷ooÞ$·×oß¿y½¼yÿã?±Â °´ÌPÚåÁt>q‰'2@CÇŒ=“‚;›‚:ou õ4½Š4|çT€ÁƒGŒ u,XÈq4H5Ô°¢yP/¡ÀQx ‰ÓX#¬úU0¿Ñ[óL¢P8|uíalp7ÞÜçëbÓQ˜€471ж«Ïž ®]Ä]½ØíEGÀ}ј¦€ò+èÐ.«gÇ¡Ïë@¡‹a3îŰÞB¤ªûjõg¾n¡¢÷uÞ@yM\fd[œ´< ûÎö§|ºÏý‚ºdÛûÉ6ŠýN`’ÚSÆB'ò÷WKÌž©–b¢«Ö"84°èqus†ˆš¼†45üŽgv4µA)t檩ãßaoœ>˜³2ùTa§oWv‚elÛdº Æ}#¿¸ Ú(õ€ZOO¡ߘ=»IþEª7ÑŽ Žû,ݰãw7?}øææöæ7;Š Š5º2Ü@Ç"v ûkòÚ”NF]ßËDÛÑ=Ò¶­‹•5#iplsزjáò òhùF*HMß?åw PÎòÕœSÇm¢ „îÓ¦R·ÔbCÛ7›!i €Âeê.Hë9ôi$ƒ­áHì[[Pº‰öd¬§M¹zŽ$WcD[êµuÒ#ë™”XJîêôX¹AKôRO£“EŒB‡ž³F¡bLo¦…r{ ÍMÇ4»ê¸NÉѱnÒYt¼ï6_´Eº5Vf…îP.Umà®U…ë]1)fÎæYG0…ãá̰-!Ì|¿+F|¤Ûq ÛÖç 3ú•½¤ôíB×9Ôù¾Z§mºÚ‚am€ƒ„<ìŠõÎLÐ"tX†8TlDêBÀl8f>¹ú«‹Äp@QÛîpüµ²çw$h°-Êæác8ŽÀÿP«‚½„Hµè•–·oH DøûÖ{ñ6Þ´c^“Š÷ÈÞ.ç‰]/â™VCDh|÷wbgï`g\ˆeUí56WÆöB[P¢§BÉûÃÝêêLäªkï<ãÆ‘ N|ú Š”¦&æêiº¦h>Î}D …lîã#އÁÖ4‹ôäÑÿè„Zõ Zü„=ájajµ1³ézW”zAÓÖÇu߯S§#Pá•ú">O´MKl‹¡ºæõŽ:oÎt }/ŸÞÎ|¡> stream xœ•XÛ’ã¶}×Wàm©d¯Nf·j§ÖËqªvR*Š„$Ø)“Ô\òõ9¸‘”FÇ5[5³"Ñ—Óçt7ô‰(#‘þq¿«ãâ›ÇŒìúEDv‹ßÌ<$îWu$Y-YUx‹q‚«ížd„gœŠ˜d"%«ãâKfKžDA.ÿ½úöì©Ø YVÐ(ŠI˜àýz´Ûm/‡õ¶kkÙÔëþí¸\ýrá(Îi,28Ãû9MñçêŽTO†½$íþ`2g¶D´%ó–6íô'Y)¼ш%I dM6o&¶‹°œüaÂÂᵪ_×íVGuQÑÜÆP÷Ì[*hÎ"–º§U[ËõA6WRFcqûl±1#µkÚNÖt |2E°Úãã\²˜y΃jB„DN¥êÈ‹:ðôûÖ¤$Œ­jÁ£Iä£x9kÿ¦ ifÂÒŸ‡1"qy Ê#o b'mUªmHÙuå>Î]cA¼Ìœå ÍS—TP¿”Ýv½Ci'kÕlÛ§àiyžiä*”=)¯L‡"Oiœcy¬õºqT׺L@y7ì×–+ó¢€ùÌVŽåœ¬»Þ[ïeÕ‚”ÿÓ<œæÂa‚Ÿ©ÐÔ§ÝÎì`­«{C–¤¨Pì‚Zí¥)…È -&Hd !‚þ|TÍŽ”§ÓA9[¦òº(S9X6¨fhIßå°×¯ã`%Où<Þˆªe3à0µÚUÂHÈsíåK@_–…&W <âT¨µógO¼‚ M<’§'K4M¦tDì)è'Š1š¦1³™} †Rãèíµ’´Å0Íí9VD¹(¬.V†ˆe´½Ú3«vP¥“ ¶K®õ‘äÁ ¸ÙZò"xm™1 f^mô׸ê|@¯ëzJkí!aßEJq úyÕ¼ S® ^É ÷.ðAvãP$±”ƒ‰Qž¸”:ž{Iº©^U?è¢ÊD /{ispÿ7iZœ"*¬Ä¨â² žË9þÏGü,¤ÉTÛ;ÙŸÀjíÍÁÉ8·ÍSõÖšb¦·_“˨S)§YnR ^òh™´GõcÓÞœiàRÜHùiièÏS½p¢I`ÌÖDWú‚Â1£LùäξqAZ˜yŽ2LlÜ1tu_uý§«úº¬k`а"*+'ôQ×õ6ª)»7Ò`ÝñŽ4ípÝ ­”ï 6ýÄDáüMµvs ª%§®­àQÃs³«Ïý )^[5[ÇäÙºHŠ <œ¥•÷S°m;b‰-´d2ßå_Ëãé ms ý£y'ù4R·J+•4·%×Ä!G5Ì:ÈAýºdzp²<°.ÿ¯¶" Õ{¿šjàºöky–%$Œ¹­pÎl…>7¤?W.¢7oúëYò¾£ßÿ¼¾ÿþŸëÏ»j̺:˧¶ïmÈÚ”,±>«E~e¬ð’y–qÓ|:7•ÑW%  èÿ÷²’¦'ñkµ˜ÆŒg$ð½n3‰I-¡,¥Ûq½ü°ˆ34qæ kvt4¡ò(5x³f\)ü™G`÷æìOM-!Õ·L^ftjföÐë{¹9ïH½ÙÝ™æëxLJŸjIpüÑN”$µš6z®.>þí<+V7FýÁß Øo³ú•›¹­yfû£&ÈŸ,O€Ò‡yC›'÷s™±ql]ù®`MÑ@²‘7ñ{·\2Ìà˜ù3x»÷ª™ŽFé~ºÿx­ÂXoõ~Ì»…žbئÇ]_ÝZŠ…6œ_×÷…塵3»±SðbMÍM‹Iä.Nl)izu9ãØÁ|´Ûy#*ÄlJí¦Šyb.R›_d¥î ÃË¢IÇ<¹ês,Å>UüÑFWÀߨcðø‰)ä÷wª‹£êˆÓ‚»<:]w³‘· ÓˆMpÿp‹“3¥G¤z7r¹®õ´DnÑf„Æb×bï3„%ú:Ôí€Ís¸Ð£ËE® ùÈ¿V¸Ž³äŽžH[f_çæ×+ry´z_‘DßÓÙï ¦ŸXU"ºžÑvÕ(æñ8[3Y¶³É wBøÚ¼+-VìÙTùë­Òz’¸zélßžµÞ ±´ÖúV€¥å|2à«F 7)}7Tºz=Ù:]¯9Ã_F¼/ÌL¢|>¢5K¨ÃNøt9ÒÃÅìt[ãøï?üøÍÃãÿ<0m‹"P¹·— ÿhíÏëoM9y꿇À=k­­è>JÊaèÔÆ|kOÁyš¡zn¤¬e½ \Ú±›ê/ h-Ý«Bç¹æãFÚ»ËK#ÌU~y«Å±ˆ”·”˜°97ÕžúˆËn‰Qn¾ØÙ"u{%.×ÚF cåq†<:òÈ•g6»Êy®'âŽð„|W6g} àgÓi,ZE6"vùe×ÇÕâøù/Ëè endstream endobj 360 0 obj 2002 endobj 364 0 obj <> stream xœ¥XmsÛ6þ®_o¡n"¯yßÒØQ'izŽ:ís£¡HJbO"]’ª“þú[H´ÜäÆž±GvÝgŸ}V ‚)"ú§ÿ›žßÝ)th,h·ˆú?é}¿Yp´Iae~7û…9IS sÑæ¼¸VjÉ$ èjùŸÍ`N­á˜V6e‹`Ý¢:o/uÙ ¤DE™åËÍïÆCD±#° ûîƒÏmg¬jcLàPÑØìŽ9:úð ÞuëóPÐ~ýÏÎrwRLEo9(õÇðÑ¿ÆÚÛ›«ŒÞÉ(ûEl–"D©^YQE1“ ­„Òë +‰6‹@bbŽÊô¡0#`ËØxLêý6ɲí¾NÎùümwŸ‚OKï>+{ b§Ï‘ÎðMwú—²)ež¡lÞ˜6%Üzæ´OsìçíM¾»P¶;¼Ö[ôâ»añ‡,G`àõòÕè@‘£¬æ|§“ßdYþ,êVß¦Ö pý¹+§Üñ”—zË웚/çm‘}žsÙ/m«ý6/3½ƒE8énQí÷MÞBDª³Þ¶…S¾³Ûº®ê \ÿÈ¿§{e"g¢¹'Jt'7Ç¢AûK™¶EmЩøoE)0µh˽,² b3?“-›xÞq})‰8ï-žÇqš?´¨=&­Æ8†º´x+xÎ- ¡½[ʰ ÓǤAen^l>L–yL²û§0v…¨¯úÅúàîcbp9çeÛ ¶BÉéTMíÇ Kn#ðxq8´D¶d›=íñI"ˆŸäCüº½y÷vûñßï¿ÿðnýv{wûîÃÛ7›õ‡Ÿ>ú!ˆã’_™OV,êJSÂ{LäžûPà(dôùÔÏ?Œ°ãæì‡À}PAÔ£ÐRÒ7·>_ mÂznò´Øë-P+‚öÇôLyPW»/ž®=DÏ3¢ö`Q ‰ƒ+B54!ì kÚê£^í=Û©8éôú~oqn³?tÌn깪;ïÕî÷<Õ=å¡ÎÀS÷¨nÅk4ìÜcsæ|±9 d’š¦g`‘ú§%æŒG/¤J1ѧj ªE¸vw³~‡‰ÍC˜:{©=+¨¥¡Ð“÷U}N,Ù wãÀÁ¬=€O_AæÜu‚elð5Ÿ áH|m´Qê5êÐxz=xÝÝÙn¢ð_¤œ‰vpLpì¢t¯UÅûõÏ¿[ß­³o§À§±bA‘¢›NPP"¶uðëöM—:P'¡-Žû`³Õvt½£¤mëbgÌH\Ú\¶¬Z Õ<ƒ8j›¡‰\ uD8ËwKÄGy\[ ô4 ¤ ¼%ÚÆ¸ØÄIs6R÷AR/iæ¥ )cßèq4tˆNçM¹Œ_@´ÔZq@ô ÍJºK邸¹Z²X«>¦S6Áú „ O4š]a¼+ŒÑU»ÂhŽÕåÔ‘£KÔJâòÐß±h‹ä¦Ì ] ªÚtèÔ’¸œ&4Ï›>S8vðè‘/ºý>øG´¤»¨®NŸj8ìp' óÞ z€ ®=¨óS•&m²;Pál¸‚€<‹ôØmкmx° u6FÕÆW^ÌÂx*ǹ9påÉz‡påh j—/!q$hp(Êæ5 ™Ò8Çʵ?#½PHYpwò. aXˆ¿qᦗTÜAqŒhshšG$ž@Z~ÅHýßË ¼eW4*wí•¶ „#]ÂËè‹Þþtª±y5¸R$L.„¾€¥¹‡Mê¥h>-}, x -̬Ü÷±ü?Øš§ ÇMñ—¨Q!é.žÐ#ô˜¶Vûn÷9IE©4m}I]¥Îµ!F +ÂKõU\NÄKK#™–»š¸{n\?>Ð!¥Š¦Àìg_B;¢a/a’„;ºlÐ_y]AÏI'Ù"P¥TÙXïžL‡±°Q¶úwswûæý5õÅGsªª=£+Á˜‘5ß «•ÓÕŸ–ÿô ëî2¨¥+0äRö)€ù@šñä[ùl'âh‹gäÉ Æ;ˆ¨PezöÞc- ­çY‹ ¡^b­H„ñ×°–Ñ ¬%l›%fó£G_½ /6’5š¾@çsûôÅXD_¦¯®¿š²…¢½ %&¡_A_àÖÍC×`C,l®°—’#/±‡ñI^Ÿ°ôC&²}JcZµÇáH1ðèÿ¤2€™vYüz—Õ;lþ'l6ås6Ìø×i ètd‰[Fò˜èïîFÃᓯj|“<ÆÑxàKjO©áÓOæŒhø^qfÚä÷êÔ~'A*‘eܲ*W–u/M‹ž°,%0ƒ¸ð~ êYß f•¡ W˜q½þÖÕËþrêI§þâî._¾êÛÈrîD%,í$ùkÄ$ú1)/Iý1ÂèÐì°“rµ=ýþöv³øüü>å¦èendstream endobj 365 0 obj 1894 endobj 369 0 obj <> stream xœWÛrÛ6}×Wà-Pj¢xlët¦™NÒ¦Jû`w8 Il$R!©Èî×÷àFÒŒ“tœ™$Äb±—sή?Ÿqâ«ûwyZ}ÿ.!û~å“ýêãŠëCbÿ*OäÇÍ* ›V\üÙìVæ&'",IÄdsZÝQ/Y‹È§Â[ÿ½y æVhoy<ɘï‡Ä‹`_­è§ºò¢ªºõ柹û$bYœ©G`•2gds]Ѻ'ÃA’v§Ì£%¾MeqGw½È®kOÚ²w%*ÛJæGÙ|^£»¾À3ª÷MÛÉŠ­Ñý„…YF7|ÞÊ5Y–¦‚îëÆCHä\Ô¹ÖÇ#IhuJöU¢Oè‚^Ôûhi& þ¬¾£%Âå0á'F.b'mY uÛ¢ëŠG|.]cŠø4sžF,mR´ºÝ.ߣµ“‹¼nví=½_/Ê!PÏØ·¦EOŠ%j‚4f!îÚc¼W Æ®îúAµ UÞ‡\•eá>Èà>qc;'ïÖàsï½,[€ò«îE XØZÇÀg¬ ¨ûÓîæìà­«z ÅèPhƒÚ¤nEfJ*l ¾v„úË©nö¤8Ÿµõ¥;¯Z6ƒACÝ -éÛ“ÊKy.ÅñøHêJ6.ãR«•©z厲ë:Sà )Â#–…Š;ß9àe"PÀ#¹¿7@S`ŠÇŠÝÓ~‚gqZ]º£C¡êèüi¶Ò'””G/NÍ=–Ïpªy±Ñ@,z¤íض*$H°ÕŸy(èØl x¼ò̳L ÛD`„Rå0¨|­V€~Ð”ÖøC:±EJ!<$®Y×aÊ5R&6WŠ'Qà£ìl½ú«eËÄ™ˆ2“R'½K/‰­nЇºTÓŽÅV"ëAšìÿuš¦N> Å@Å=ý©˜×ßéXÿŽRgªüìÏ@µzÍ–“ aijîÍB„,˜ñíC£â ³,ÅHuwèµ!÷TѤ=ÕÿjŸ&ðærÚJ͛ʔï×þ"ÐS;%"83=Q~aFWÈwé‰Ñà rˆgª,RtaŒu«©ÄÕõÔõ\ýÓö\RÙ÷/ …ŠÒ*j5o[7E÷Hú˜;ݦ–Rhˆ|®©„}oê´Rà,9wm‰UqžÕÔÓ¥À+Ãeó0ù´ QF‹ãErßÓ]Ûë@fÆÅé|”FZ=w4ב;ÚH%”Úk§¦á c ä©fúq¬?¬¹^Rjžü_¢á!'œwï* éê]ƒ²$"^(tø¿ v²ê r­tU5ÐS Ë8up~ôòÔÓò„„â„g ÷µ®Úžês%ž˜"çL1B›å ·ßw&”¹àCàæÓ›b¶pµ¡o"»®íÆBŸE.›Z'0tS<ƒò¹8LÁ`Ä#§éí_ùí¯æoÞþôöý›Í·—“”ðÀl9$-.Ô¥§}¤ia{d!у1Œ™·\¸z‚2 ]q’j‚XbÝjóRóå.å1ú¹’ͺY¿˜]¬%©jý-abfþ¾é±jaT”æÔmsø‚Œk÷×.Ûõnöæxf7ÈçŽ&²ä éÏðÌfŒÊVp²þÃxµöJ'rù &¿Z¹¥þýWrX˜ÎžñŸ3©#Îñ†­õ"˜W ø/ þshz¦ÉôæUÈüTh,΄ÛÒ®·#KÅ|YæÆÏÉRê#|žÞ@81ºw—¦Ô²zP;$ék%‰詚;!æŽ[Ï•3»zk‰…œ—Y~Pâ§tv§åÏÏRZÔÇ &ð8S ”jO±›ÔRÓ<Ò¿ç!ì”7mövÊ+¸ýŠiÐ]ë^.ØŽ­!˜J±d ên‰· >~o ÜŠÀ )ÃGmZäQ¬nE™óV`ù £åüôáísÇÑRõ/ ô·w“–£É§Ä|¶G‘™V°(¸!¦×EsQ“Xø‚O.ÈÛæ—¿L¿Ú¬~ÇÏç3Rœendstream endobj 370 0 obj 1697 endobj 374 0 obj <> stream xœ•X]s›8}÷¯Ð[I§VÑH<¶q:“nvÓM¼ÛÝIw ¦kC ¸I÷×ï•„c'mÇ™ñ¤«ûqî9Wþ‚|L¯?Ýwº›½¾hÝÌ|´ž}™óu_é½]ÎZ¦°ŠPË|fwDÅŒ#ÁB´ÜÍî¼¹8£ï±ùÙ?Ë÷`vͩϰïs4`Q6#X`îaæ]—¨Ù§©j´Ü(”ïË´-ªòlùYÅÝQTbAá4ØëeIÇI–ÅyìTœg*N?yŸÎºM½ÂÇޱ»jÕîë²™f!º%‹ñâêÏøú½ˆ["áa·öU¢™àÃDú‘ó.3gÌ9 0cÍá,ý¼Ý¨iPKŸ‘nß»ÅÅÄʱ`‘{ßÜ«´ÈõÈ'¡} õc‘Id¡2´ú6 âˆS—8HÔÉ#do‹Sm…À[´-šUùÄdH0eôÐifv¤Š:Ïó!UD‡ìRUÕæœjõY¥-ªÕ}­U¶&óf]˜T‚cÒì–Ì™ýªÆf w•™b'Ò)’Ü•gµžæ`ðô•­\Õ,F“2Ãè>ieJD8’¢ ·g‹Ò¦×€FãÊytç=V¦#òvèªÑáÒ¨Ÿ)´JÒ!îºÚ¯7&þûª€tÔSÜ ;TëCã¶Šk;§"Ä"”hN¥uz-?#>ö¡¼¤ØîkðZ'Þv†ömœ7€gà°ázãâææúfr ±Ë.6 $’cºs½w]O£´V‰®®OÐB¥j·R5¢>‘Ø”ˆZÈàÕŒb˜Ü˜ÀÀSÙÙ‹vP—Ø e‰ÖDý*^N˜D5w€’†ú-Œ¡?ʦX—àà”aÀ®1gª/.<Ç|´ÿC¼P«ýÆ ’ô¢+Ý®ò`ѻ̔û„3l,Ê ó ü;åSjßj’í_¾É²}-êVûZ?·¹ŽÜªrtfÿ®ù¶‹‹ìñÔ+Uf1¼^UÛØí´Už7ª…TU»xءךÖVßZ«Ýz€v«ÇTÝkpÄm²Úªæ™&KŸ>梮«ú%Rú ðâ )lùºÚcªŸ‘žð$$yZ{N)OÀ n¬nÐ1ýsPDIŸcIzU9ÍþO¾6DÏ‘þÈò³d?g‚á0 zs„ÿ£l†œŒ‰òç),úiÊÿ²·\E©}¿'I·Èþ`¢hzP€«¹ª¡ŒúõòÃíë˛˿PWª•p¯H‘:Jˆ"Î<Vdq@CØ+«%ƒÕ B®(<Ì–/ï¼6©Ï`2ˆ¤$ÞZµ°E© OiL{{êßZV ¤ïÌ ‚ònf8L`Î]Ù¼Åå2Îh7ɨÆÞßæjà_Ý*H“h½KÌsÈÄàó)–Tîæ' ÙS­ƒÈÒÂi p°Ñ‹ü`”L:%´'=…o|i'žn A? h…ïöqÔgéNKüp ‘ 8 S`Bæ‘ã„ñS:]ä÷’·ŒµM<(iÛºXY3ñö­rÓ˜<&úÜHÜX:V¶‰hà°¿Ž®‹²9J2÷¥nåÞãÓ#ÏÔqHŸöw¸F]At¶Íz°Î£Q¥vÌG’F‡M¤]gÖª¾µøyÐE~×A!•= v÷(-­Á„x´áZm«411!“n€Q/t ”ͤ«v`«mYJ¥ð2·Ø÷$ ‡žóí%b:É:¢üOÕÕ\Cˆ¥‹äX¶Ö~åµkh£éLìsWϪr—áž›3ÍÜ`o? þ0‡¯ÛIó#9vØÎŸ¼Ý†±ÕÑÀÈG㔽Ƿÿúöúêò<¾¹¸º>³¼¼þív ¸É9eìÓœï·ýØ:tŒ¦ë÷MÞ_-&„ Ç'pÓ »Ÿ ,lì #°pª¥d±Õ7ݪo feWûée‡ÚéÄ$%ú!ÓÞY&n…aä@ˆÝe^£BŠÌÓ›‚ôôWð¯d„åñÄ ´ý ѽOÊ}Rƒ +%ƒ ¸½6þòu±œýŸÿ@ endstream endobj 375 0 obj 1839 endobj 379 0 obj <> stream xœWÛnÛF}×Wì[(ÔÜî…ä.û–8~HĨö(¬B Ä•Ć…¤,;_ßÙ)ÉNØ€eqwfÎÌ™3ïˆ`Šˆþq×õì×;¶ýŒ íì댚‡ÈýY×èM6ã([Ã)Êüf›™½I ó ž ¬žÝ¡˜³˜Q8ÿ'{öì­ÈÝ ©H1! c8_Ì‚v³éÕ°Ütm½TM±ìŸêU[ͳÏ|%s.À\‰q ³#ø*{4ìj7à¬JhcH3¬1ÔïÕº„3J£ TZ=™ðÎ"sNBøJG6E³,›B=^ÆDcÌlDvϼ­§IBüÓu[¨e¥š  Åq’Ø3D_И4¤rÛ´*ŒÑXâ8MÒé”CžíààJÍi„S™°`[6!ŒöyÙ¡cYUðõ»Ö ¤qÙqé ŽÚnÈÓÐ&-ÅTF&€Ã•É^§ªveÛ ¼ëò'øb8tÍÞ9`*2‘ÎCqÌ»Ír eL@7í"XÌ/Ó˜Bpmoæ=Ê/L‡\J¥l¬‹µ^t@š²ë‡e»ÑÉÝ»¥až§'ÂW"oŠgÖÝçÖ{µn?4Ï8Ã’»"&8ᶈ¦ íæ4ƒXëŠÞ•Æ Ž‰Çœí”­äÉBŒ!ˆ ?Ôe³Eù~_•Ζ©¯.”)lÍËfhQßÖjØéãpq­öÃ!¯ª'Tªà2\j ©( ™Ô^î|œC餌MœG¿˜¶ÒôJeðR¢-†_FF*‹ ×^LëSŠ“$¢êë¼zû%ü—EgI&Òžu±̸ôl×lÌ{Àî{Û^¾t ÊÖ|M# ­e04ˆáƒ"ßDŒ§&¹Ð3¡A;¥€ÞEi­=‰Û³# ÂWì8Løb}Äã—åJu.Ñ!‡ÎcDL]ÆâÔBêTx貜&_‚–ÜGpi’2-*^¼Á¿?¾¹ýðîúG&S½Ê-æ¿9.A§¦‰/<Ñ<“eÃe#1¦ìȵ—n|Cö¼Ù*­«§[Xg c U_?!Lf­ã³%4‰°¯ÂÕ‰r,©ï +{‰ˆ±<íQ#‰ð>dà¥Ð‰àß ’;ÐéÒ'¬£³Èc}„8›"×+h̦qr–^ÛOn´0 g#~†ºÑ,-ô sו݆My~cú½%™S9†ýƒv”ÉÈ¢+lDb¨ØŽ]¹Þi×°îÖFt`Úž¾#í9={–~…»Ûy›z :2L¯<†qEÅ”8—,§è7ÕfLŸÎ¥A$Á;[ÃÎ7O½#OCð'ßU¨O^ÚèC*É“î n­†ߌà [$Jäˆ{0ïUí h½DÐt}!n „iù²âFž ÛåË‹û~S¨ hŒNœµP„Þh˜—†à¶Aªë¬Á±pUC7 )l|>›…‹``¿æã.c…ìÏå§ÛëÛ?>e—‰'d÷B&¥öÝ.…UNkçn°Œ1ªÂ{œy/¢1BG¦™7è(x^+ýcWÏ&žy“qÍáý}(15aÜMÅM"“®Ñ“ò”+8æWˆÅè}Þô £“ ƒ{j„óí›lö;üü–üA|endstream endobj 380 0 obj 1682 endobj 384 0 obj <> stream xœ•Xm“›6þî_¡oų‚^iœÌ\'MÒÔm:sé0d›Öp.é¯ïJBcr™Ìeær°ZI»Ï>û,ÿ¢êŸþw~Z<{¡}»Ñ~ñ—¨ÿ•ŸÐO›C›¬Eðo³[Ø•шbÆQÄ$ÚœÁ*ZRbµükó3ø³«x¿jEC†Ã£•ûb¬³f—þ^µå¾R*ÌŸYQ¤»&;©´¬võÇ`¹ù{!",Ñ  «Þ¥kµ½ìQ±ÝßiýòõðòU¡Ð®PwËF J…ŠrüÌo_=~^ úT6>L£_Dnðx»¬.TzT•6 ç Ú/§´,>|ÿf_Ô»]«:¸bW§ês®Î]YWi—mª;àÄ&ÇÛú8²|Ù4uó#Rú×Ç%<¥keãGC¿G"2gÝ F—*×nuG©’™$Ȭæ»ØE’b¾í"0oQwPÏœc±¸7zµ~9qBfÞG{Vy¹Ó4ÆœÈþq Ù~™8fÚqLzÈýSŽ»Z ˶Óf+ ‡‰ÇX½›x''‰$×Çž–%ر5Lx*y¿Ô¢¤nÌöõöo•w¨QçFµªê̵̛}iŽ5Òlßûþ¤Æ¾ wÁœ&ѧo»ŸÆb8(ž,ZQAl‘ÒØ®.ç"I} çs(£ÜܵTs0`sïç`0ìѲQ˜Œ?\ôx¨[øS#id6§Ì:ˆAY!\¨í’†8$, .{C蜵-¤ vË,6´q±ñqµÏ»H=Y³$1¸"Ø_N€<õ¶¾éÏ!š°ˆ|Ñ‚EcDà l2™}“/„ÀB0—§Ïµ{)M®„6#³IŒ¥CÏM¡o}¡¼˜+ÂD2œQš3šŠiõ圢ХnÒƒžs9÷‡/»2;B «ŠR×K‹ t ÜIGï}2 ¦ÎçMEÐ'7}Ipc?­Š‚p'tÙN9¨œú•¾O..[OÈ¡QÇ:ÏL«Dz­ÀA@e~0ºsˈŽh zâÂthŒŸ\þ£'/ r@‘Llu8þÚª%„$‰9 öeÕÞ¡¬*¦NbبU“€¹HœÍäÜ,@ Ÿž[Ÿerð¶󚈘Gæðv!°8Óm³¯E@> stream xœíWMsÛ6½ëWàªc!Äð˜TöLÒÌ$u”öw44 9ìX¤BPqýï»ø")FNšœ;öXcjwßâíî[ð3J1A©ý Ÿå~ñüZ¢;³HÑÝâó‚¸/Qø(÷èåfÁЦ+Bünv ïI•3Ž$h³_|LVrI³4«å_›×Ï{ñൢ)ÃiÊÑ*ûj‘¬ÿÜþzõbÛîvF÷ËÍßSˆ\b&™°L±”m¢=è®èë¶AµAæ Ëz·$9ÎÍ“ZWèöÑaO` e8TIâÜGJ:}÷£Í'm ð9˜5©M¯»€á­íŠ¥ *Ð À^àšùÔï+Ô´=Òÿ”’è¶î ^®ˆd ˜J]¶M…ÜAìçõ„MÚÆ{ci{˜qƒÎœÚy¼|¶ ©õN^õ¨Óý±k ‚ë7lßþ†ÀÑËRc-ÏØ\^_¿½¶fºëÚÎ…S.ÜÕ±)pÙé¢Ì” µ.õþx¡)QÖöùµB„X²³^ËÌ"ÃD`øƒ*°âƒõ,'E·Ûî*½-wE8æMr³ m0ôLtZQ_OŽs~·½ª4ªÎ²a2‰‡"¸€ñ…5ð|‡¯>4¦¾kà€Põ K’üÞ?ôq'Ï/-OèGdýlÚ»+2Æ:Ëfm‹¿ tÎŽ)8γÈÌù Ô C(ÎÆ¦%\:”âpÐMeP1ƒÈRœsAÆ7GOÀ0ˆUA§lÌ)›´á¦e^×NUS]+ªÊ p -³-ÎêZp:ѵºéƒžÍü¸ž½ß÷÷@ÜD³‰ûRÜ“'žÓŸÑ8¸¨ïk\Ž9;Õ¸é)Ï)Ï]`çò1k_Ó±&­Ÿgä©ÖÜ];¢žÍQr,•Œr×·èkA[ñ”ba·P`?hÚTP8V™ AÌ(\ s"âHÑL>-^0D*r*^Âû<¥]øƒ5bшÀ`SB"a‡~I%ò¤í++ØÔ)ô¯Êò˜Ï}ùZÔNÕP¥tÌ]ù÷kPY4èVŸ¨t'«›¯*À ñd¶ùbÖj~4…ã]ãN€E7$›4ÕŒ8’Ùó«1<Ì}#<~9†‡+† 1½Âã$ÅBgIrÙM›”k¬5I9ÜUb‡œæ©0ÉX<Æ›úÖ Á¬`©§*YV»Ò}j=c6…r‘‘i§<ìÇŠA±G碙:‰dXc•½‰O,nÑi´×E‹ow¼G;Ð0+ªìõn˜îÔã1zåÖ˜°Ž— FŽií*u¡ ]‰80=Và‹žV~LºëÍ”yøÇÍ*‚O׺®§¨*ú¢<e7ñbbt/0”CCGÇbÊ€"i>fÊÂÞC‡Â@7„‹ÏT˜}ñ͈zðµœÍE†Ñah 3o ¸äãÕìD“çqÒthá›%ö]ÂrqºJÆõ6¿#ÁÚʆa^æm(˜éÞ´p.T<³pÊ}ÿcHîEc¦`3DÍŠËw™e $Á^·ƒ}9ý¯%¶ôÂ-Äk »ËµavëÆ>#“ˆ²± +þuÑ‹îBQ/V^(àš.iLõôm÷r³ø~þ~Zendstream endobj 390 0 obj 1368 endobj 394 0 obj <> stream xœXßoÚH~ç¯Ø·šìí/{íÇT¤R{•ÚËÑ»‡ä„ â l×6øïof×»6&´ê)•RðÎìÌ73ß|Î7Â(' ºß›ãä÷MöÍ„‘ýäÛ„›‡¤ûµ9’·Ë‰$Ë œâ‚À¿ånb-9ZP©ˆ–Y'Á\OEÈ=Ÿþ»üþŒUL8G£¹`’2¦È< Ér;TÃï—IRÑÂÙN—_'JSÁà†g‚—´Þ­ÒívµÛf«¼hÚ§àiŠÇ ÕE3w&p1ãuaL?¯Þm3²}Å : 5ÈáUC86Ãøè£{ô×1=HYͦoÜW_Š&ßÙ–|OüÆ÷bðý}]—5ù-Ã_Ç›!¨sÍpc“ÇòÂ9›6/‹QâQB•tH½–£‡ÊN%Ʊ1y àtCZ¸ ¬²:ÅHSe›|7å M’9ä°>›r.æ‘2•´7—Õø–„êX'Ýã¶Ä+®jưfúï÷#/BÑ8Ô“.,8!bªxd¿fTÀ D©‹óò))×1ï\,ø<²6ý,8í<ô ’î×4œ;Àªv*4‡’ l *s˜#'´q&.0•Øò½”¤Df„¤1}ìæxð ¨Ä&-È:– Ö&³¼¸ª€„ ¸Ì°ù\Ôñ8µ˜våf©„sú`ƒb;އ˜Ü»¹¸§o{÷0‘pá¥Mf.˜+Îh¤ýÄ!H#h;߄ŖôµæLÁd»ϳ«8cÊCéÒø˜¯ÍŒú(â”ʼn‹r ¾·YCžK‹†°™„|Ø)/ǾbPìÞ8-†F"Wîѹ¯2 7°qÅM댳´È‹ýît ;àn,æ"F.ô³ À\X`¬1%ï[SFw!÷‡ÒCS’%ìFS"H÷øž +ß]·Íyø`f•¤UU—U§-pgÚ¦í¹Èž‚.` Ь¡ ¡Ý%çtˆ@ÌYÒG*M¤€@•6Ð pϘ$®à Ç×t6&)üЦ͸1ÐWä"»ä䱯| ?M©-ˆŠ¨LŒã~¡¼oIµ§º°˜íó Àµ¤2ôu ð1ƒ'—ÜtÉ~.;dåÓf“5ÍŒ¤W³ª5•ŽƒÅ?«ÅÇ¿Woïw‹ÅÃU¦’zê§f MÈ„´cØÖÒnë$¡zRj4@jé—µîVuD™.72*«[_³ÕúÜfÍ«;»³½ØÙyÑv»ú†Ÿ›K{‘­O{²]ïÍÚú¹Òf¥¿¹~K²b°¤?·5ÉÍ…ÿgs3Ê´øéæV¾ç~˜ïÕ‡]DcíÑXÙ~D ™:=àV%@ ‰¥­íg K÷ËöjSÂÀ2%¼[sûèf(˜ðG·ì„]îÁ}û<Î2¢*ì|ÂËÆðÆö}„„K’‚ôØíz ÓÀ4wÓR§ÇŒ LõÉ€ÛÀ‡Ž¹úAò©!GEr,˜‹Ú¡xïb5‡8üO&^´¹ 1ÑA“bdTGÜ –bS+Tëƒåxä·Hû ¼äWhŸIéä¶œC5}©Æ•r¡Í¶ÓÅt¤aÀûÐT—¾•$eKN 4LÙ>ûþl‚]oÖ?Gqé—Û¾ã:Ëú·¹ VÁùw2 <”¨†„7WÂOì#ÌÓtã¡ üìšP£˜&a×`ȦÖ÷iOÉic ÄÓ+?÷¼ª³&ÞÈ[r„Þ/‹ÃEÔ´: @Yl2“Ú˜¯AVÐ0T¿Ê×x­_í¾™°l·›iÙû†Ò¸> ®41Åš_ÌåJH| Gt ª±ö=;ÞäPöBUâËàˆà!ne7WFv§x 3MÑq]ñ2|±Ž]léùÒˆÑÐ#:[÷F‚²D ±æÔZ Ò4§ceÞIòÆI¥Þ'€¾G’¸÷› «1Ÿ ô®.]2s‰â(ñ(A’uJ¼\Í6-éÄ·L‚üáò}†p0 +Ì»† ò€’Ó4¯d s˜gèÒj[hqƒéé˜Õ·¶ÁÜ_ŠŸ}Ö/„zõZ)yÌ\“™Ìðó Í2ºš êåJ'>ý1–ÎÚ¯©_!÷ŸÆ$Rù™ÁÉQ–ã{=~ž2÷šãˆ†û—>œ2ázZ}FàÓ‡´8¥õ™ÀØó ð6†ÒÅdÿ€ï¶±û#Æýrò'üü¹$]åendstream endobj 395 0 obj 1640 endobj 399 0 obj <> stream xœ½˜MsâF†ïús”ª‚2ß’®±IÖ©Z{c+§lŠ0`Å ±3b]ä×g¾0,¤\ ›ƒ°Í£·»ßîÑ7S yùãdýü˜¹Š ˜Gß"d?þ0Y‚_Jý„" œEîG`†RRÀ3 Êeß<Ü—Ãûò))ÿ‰(Ç)dpÊiôWŒÒd@!IsÊã»ûò1¡0~¸ýó¦¼{¸Oþ.æ)öÛEš1P¾FqÚÓ@!½ä±-"J¹Æ(0‰oÚUR¤E‘³x#ëùsg! –bÙ\HèÖó„Ðhb0ñóËZ®Z%@ÕLÁÓ¤] §%…FÂ^ÅÜjè–:D$;ÄÛv²^ЦŸjÕµrãIÖ{´v„v© Ê4`³ÃBÂ㺩»ºm” tž~Dœ=¢]- d;Â‡ï ¢&³XÈïµH°ùñøÕqâÈÆljÍw¨Ži-Q¯•–ò â¨÷êö˜ˆr0ÀÈê‚Sw*…”“m£ZnÌyhÏ‘T;“§ó7¶`›ˆì§Fž§„ò⃬ÊÜu·Ñq¥áг~ÕB“«‰¬WÙÛAöf[ýoÝB‡ˆ_ÝWK¡VÕD€Z©µP>5hÏ|{Œ…etùáIÐõxúš ã :ô•œYs.ÜQŠE;©vÙ€Šüêà[ÒœHIÂh릒ÐJP)%–ã… ]w«µkU(+zé€98wùC¾ ÔÇ:jíœrÏõ t­Ñԡ꽺†ì¤†äãcÌyoítËé–8D Z•Ú,ÇíBýªéT qóVöڥX‡5Òþ7š lšÑ¸Z/º‘ê¤NÔѬ•Ë7ZLÉ;irSºÿå9 ÕɪQfåQ׎¦µz±£jBè;5Óp4ºOAOR̵,JØ‚7P!DlrrSŠ»Ê;‹³ë®:fíhÒ®›î"UøUáïÁØe³ÞŒ]²ÇÈ—½»ÎQv’HwôÃH]‘¨8I”Ÿ-*›=®†TWuêj©SœJâÿ½g– ]ä9Ë̶L= t¡ Ê›5 ›õ­[Ž‚£x=Ÿk‰t»1îÜzØtzº‘b×Å1¥Î;ºìÀˆðÓÖó¢öamh M°†Þ³zro\î*{\§]»ñ p¿ZÀ _­£<ÿ¨Ê]uï´"=漄Xzëx½§BûçS?»ØÞ´»¡«å‹Û§P3øÉæ4|ZÛ{ ˜To©8±*ÔæÜ°ŒþЯÿ|æÝendstream endobj 400 0 obj 1214 endobj 404 0 obj <> stream xœµ™Ms«6†÷ü -aaª£>–içvÑé´ÓŽwM‡! »ôÚØÜäþû IÄÈ6n¼HÆ€üXçœ÷¼GyE؄ۗùíþ Ѷv0Ú:¯¨‹ÈüÊöèǵ¼ŠÖG?|J„­÷Î_.÷©Þ* bŸPpó7°‡nZm’4Ï“¼É>­¾z±Ç,d®¨’ôÙ}ö¼¿×¿8ƒr¹ö:wâö¯õ›ãúS~¡Þú_geV\o×Ô„dp+›DZ$¬-DÃ7‰ ¦°!n¿d ƼUD?&Ô}jšªxñˆDÃ1qO@?U"mŠC©!hè/²M7@¹Þ?¹=Öö±;~òÚ¬À˜»ëdwÈs"<àím±û~ìÇ›ïñ?"ÙÄð’m8´—leºý°FÜ's"«¸B½gz- ŒŽËû£LBk›0û(‹Çá:,³Š…ÅFc«C~Ê„¢wÆŠ \F‘¦JK•Y˜S÷[òŸG¸›îN"©wâ¥*ËåÑà~àég-¾à`–u£Àä42tŶyQ6}ÄŽàC$ÖPòn‹(MTì»"+vþ|'¦¢ ™ô V47§Ùñ}Èx^ Oå§¡Œ‚;„ˆ$ï´¥{+2'³dÛ(·}N(QDuÓÔOÙd0š¬I+"y]RmÛ«•¨ë$ë‰>LÈ3D»Î dd4Ù‹lH_—} Š>ÐÑhy*·Ml¼ÐDÔ¡]y ‰ÆF£),ÅÔ4‘ ÑNô£ >š§«:SsÕ!TF3 6)ÁÃ&ÙÙ5UøHäD%ÊLô«ož—`0è% Û(+ Ô-ÞOG…ˆ¥¹Ž,D黨72¼oñè}ÛìÒ¾ˆBÈgøœ3›™HÔj¶k/ûW ¿ˆ†16¨ad¼ð¿Í?J-d5Dó]>cƒ.¼ä·º A/”ÑLQÕhf8Ò«ÙlÚß:{¥¢Ò/è‰Sæn¥§Viì7s‡^?æK~ž/¿¼+9š]̕쬠ßc°ìAÊhüÆXY írHä¾™Qòj’Ï.ƒ+J½¦Ey{À4p!(º­(­B%3ñëæKbCÝ.m¨¶“÷ÚÁ2ò È¿1`J,iÀã0TXÙ©’m Ik÷ojaõR€É¤ˆ™.pE8> stream xœµ—K“£6F÷ü -Å WB¯åäÑUIM’Ê„dã)йËIû1€Û™ AcÚÆ®ièöÂn°/‡ÃÕ'é Š È½Ú÷||÷A¢‡*ˆÐCð%€æ$jßò ú>±_Š€¡dø˜@BR”l‚O˜I \H¡ e€‹c‰ ’8+WiViVfÛ“æK¼ ÃÏÉ/mk%E ‰ä(9˜LøC\†É?Á´@ à®®…Rͱˆ0’< Ò_ÿøÑÜ1°W¤ò'"‡ñ ¿ûpÇ)Ì}HíMDšâÃCZö¨2y½ÞmQ^šÌ}ð÷¡c"5t/HD )…˜ðŽßYU7¬:H{ Zsh!{¿R9ǯ÷Ú‘EÜUëÕêV-h>p{—õn)Q‡·¸ªÑ»<7U…–x¸ßfS-CôûÞ”ÑÊý”"BóÉÝѳÃЪ¾aµ%K³^¦¢M"-Œ>±Ñë¯û‹iSvú ëØ]µV›õH¯zth§%'“{òÄ%%§= 0ÙæÑdÿ¢‘¶ÔŠÄñDŸHÐv¤¡C›pæC;kK5QgÏÃ{•mZ&.DS†ÿ¬­ŠÝ¶>s’N9 }èLËu$XÛsp<ꆨ•E<ÅîI×Q @/¸b½«»õ£YTùnoÐ_•)›yb……YùIEÄx½5JBÙÄ7Çv Œ8ÕŒ|›ÒgR!†Áì†:7\ßD]|U]|Q]Ûq‡n¹XÊuvÿ8¦IƯè»g²XDÅ7D=…”ÛÇÈ”=òRØLo|aâí•ñ^Ù¯Y^îÐÏÛÕ®Ü4BЃŠÒߨ?·Ù¸›‚¾è/~E›íýtãP{SœÎ`êŒÊWbÑQ¬Ãö˜à3õªø9…ªê¬¬=TÚ&†bØYW$£ÙJC®x”Ël‹0=¤š©÷[2_mÇGážB;lµ’1¶˜»25Íÿ:¢ø¿úÍz®#Õ/IE?@ßïšK3—}v Û™Ú->¾ïö(þ¤µÊ¥j·F ˪ýˆ5OȸovE@NYWåq‰ûŽ-¯Ù`GCž÷ »}ª´‘e8»a„B,‰²Ûº‰+1¶ÂWÒak|¢R…éªêÛ<²ó˜Wb¢YX8mi¾žzl7¯¾Öi<$z$ç+ŸuU¨Z E^òŒ‡Cϳ¶sÑ)_ÃM B’Ž­Å•Dh¼¬šC‘‡Yº³±å2Bh¼ªL=ïOò‹y*ˆ¸®¬pªzþm’쉟=E9ŠdQŒ{ž©î¿Öv3Ô‘ÑH½’ IßäL“ØfZP&›BëõÚø) þ°¯ÿÙ+Ìendstream endobj 410 0 obj 1007 endobj 414 0 obj <> stream xœ…UËŽÛ8¼ë+ú¶2°îð!JäÞœÌ ‡]G@Ád‰ö0k‰Žd¿~›Ôc&À d‹¬îêª"ý r`á³<ë6ys,à2$ .É·„ÇEXu oËDb¡ ¬i£NßÎÉŒåÀ Ç"“…¹„²MÒÃ_»òk²g(Š€Î2C»Ë&I{YXàµ6zYh¦ÚöðÑúªÿï»Ñö窶0z¸‹õ8êˆÒ•P êóa+'2d’ñeáxÞi žÂ{®4 žÃž©°çKzW=º]cûA£ ž¾ÛýS~X2"E JÃí³wxû©<v"`tú®\bEp­03jEp”†H|'hùàh|=µ¶¡±CÝ»“ êÀÅ™#%Uº _ÁuÑÄŸáøŸJr)(u 4ý>>•ÌÖuáÁ>³h5·¡i`üÉ÷áÁO×fÖ‹¢Âôf‹”N\{»Ú°™ðïgAÉ;ŒpóÃàNW þ6ºÖý7³ÇP“œ+?&³ph©ZI´¶ÖDÓe±î¢àêÝî·'ó%€ñkóBƒ|N5¹÷¸ã“‘ÞCH†ÀÝ>7 éè§Ÿ¦ÛÍ÷#§[Ã9µä‚ uéŒiäf³ôîó“†L+–ž%‹=ÓÃñ^¾»B„hèW㟽€Í%]YÚ¼ŠUQÄîúnU?ºêúMŽ ]Ùš…Àt–¿êŸ8ÓÜSO&®«írE.ÓKRä¯NÏÖÉÔUGÇ((ó5Ðà<ʲ}2ÈÚ9Æ"^ßäçëüyˆ·•üèׇª›Â­#˜à+Ù¥ŠfXH.7ú‘墖Éßôùþ¢þendstream endobj 415 0 obj 796 endobj 4 0 obj <> /Contents 5 0 R >> endobj 18 0 obj <> /Contents 19 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 28 0 obj <> /Contents 29 0 R >> endobj 33 0 obj <> /Contents 34 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 48 0 obj <> /Contents 49 0 R >> endobj 53 0 obj <> /Contents 54 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 68 0 obj <> /Contents 69 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 78 0 obj <> /Contents 79 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 88 0 obj <> /Contents 89 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 98 0 obj <> /Contents 99 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 108 0 obj <> /Contents 109 0 R >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 118 0 obj <> /Contents 119 0 R >> endobj 123 0 obj <> /Contents 124 0 R >> endobj 128 0 obj <> /Contents 129 0 R >> endobj 133 0 obj <> /Contents 134 0 R >> endobj 138 0 obj <> /Contents 139 0 R >> endobj 143 0 obj <> /Contents 144 0 R >> endobj 148 0 obj <> /Contents 149 0 R >> endobj 153 0 obj <> /Contents 154 0 R >> endobj 158 0 obj <> /Contents 159 0 R >> endobj 163 0 obj <> /Contents 164 0 R >> endobj 168 0 obj <> /Contents 169 0 R >> endobj 173 0 obj <> /Contents 174 0 R >> endobj 178 0 obj <> /Contents 179 0 R >> endobj 183 0 obj <> /Contents 184 0 R >> endobj 188 0 obj <> /Contents 189 0 R >> endobj 193 0 obj <> /Contents 194 0 R >> endobj 198 0 obj <> /Contents 199 0 R >> endobj 203 0 obj <> /Contents 204 0 R >> endobj 208 0 obj <> /Contents 209 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 218 0 obj <> /Contents 219 0 R >> endobj 223 0 obj <> /Contents 224 0 R >> endobj 228 0 obj <> /Contents 229 0 R >> endobj 233 0 obj <> /Contents 234 0 R >> endobj 238 0 obj <> /Contents 239 0 R >> endobj 243 0 obj <> /Contents 244 0 R >> endobj 248 0 obj <> /Contents 249 0 R >> endobj 253 0 obj <> /Contents 254 0 R >> endobj 258 0 obj <> /Contents 259 0 R >> endobj 263 0 obj <> /Contents 264 0 R >> endobj 268 0 obj <> /Contents 269 0 R >> endobj 273 0 obj <> /Contents 274 0 R >> endobj 278 0 obj <> /Contents 279 0 R >> endobj 283 0 obj <> /Contents 284 0 R >> endobj 288 0 obj <> /Contents 289 0 R >> endobj 293 0 obj <> /Contents 294 0 R >> endobj 298 0 obj <> /Contents 299 0 R >> endobj 303 0 obj <> /Contents 304 0 R >> endobj 308 0 obj <> /Contents 309 0 R >> endobj 313 0 obj <> /Contents 314 0 R >> endobj 318 0 obj <> /Contents 319 0 R >> endobj 323 0 obj <> /Contents 324 0 R >> endobj 328 0 obj <> /Contents 329 0 R >> endobj 333 0 obj <> /Contents 334 0 R >> endobj 338 0 obj <> /Contents 339 0 R >> endobj 343 0 obj <> /Contents 344 0 R >> endobj 348 0 obj <> /Contents 349 0 R >> endobj 353 0 obj <> /Contents 354 0 R >> endobj 358 0 obj <> /Contents 359 0 R >> endobj 363 0 obj <> /Contents 364 0 R >> endobj 368 0 obj <> /Contents 369 0 R >> endobj 373 0 obj <> /Contents 374 0 R >> endobj 378 0 obj <> /Contents 379 0 R >> endobj 383 0 obj <> /Contents 384 0 R >> endobj 388 0 obj <> /Contents 389 0 R >> endobj 393 0 obj <> /Contents 394 0 R >> endobj 398 0 obj <> /Contents 399 0 R >> endobj 403 0 obj <> /Contents 404 0 R >> endobj 408 0 obj <> /Contents 409 0 R >> endobj 413 0 obj <> /Contents 414 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 18 0 R 23 0 R 28 0 R 33 0 R 38 0 R 43 0 R 48 0 R 53 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 88 0 R 93 0 R 98 0 R 103 0 R 108 0 R 113 0 R 118 0 R 123 0 R 128 0 R 133 0 R 138 0 R 143 0 R 148 0 R 153 0 R 158 0 R 163 0 R 168 0 R 173 0 R 178 0 R 183 0 R 188 0 R 193 0 R 198 0 R 203 0 R 208 0 R 213 0 R 218 0 R 223 0 R 228 0 R 233 0 R 238 0 R 243 0 R 248 0 R 253 0 R 258 0 R 263 0 R 268 0 R 273 0 R 278 0 R 283 0 R 288 0 R 293 0 R 298 0 R 303 0 R 308 0 R 313 0 R 318 0 R 323 0 R 328 0 R 333 0 R 338 0 R 343 0 R 348 0 R 353 0 R 358 0 R 363 0 R 368 0 R 373 0 R 378 0 R 383 0 R 388 0 R 393 0 R 398 0 R 403 0 R 408 0 R 413 0 R ] /Count 81 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 16 0 obj <> endobj 17 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 47 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 67 0 obj <> endobj 71 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 87 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 97 0 obj <> endobj 101 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 107 0 obj <> endobj 111 0 obj <> endobj 112 0 obj <> endobj 116 0 obj <> endobj 117 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <> endobj 131 0 obj <> endobj 132 0 obj <> endobj 136 0 obj <> endobj 137 0 obj <> endobj 141 0 obj <> endobj 142 0 obj <> endobj 146 0 obj <> endobj 147 0 obj <> endobj 151 0 obj <> endobj 152 0 obj <> endobj 156 0 obj <> endobj 157 0 obj <> endobj 161 0 obj <> endobj 162 0 obj <> endobj 166 0 obj <> endobj 167 0 obj <> endobj 171 0 obj <> endobj 172 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 181 0 obj <> endobj 182 0 obj <> endobj 186 0 obj <> endobj 187 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 211 0 obj <> endobj 212 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 226 0 obj <> endobj 227 0 obj <> endobj 231 0 obj <> endobj 232 0 obj <> endobj 236 0 obj <> endobj 237 0 obj <> endobj 241 0 obj <> endobj 242 0 obj <> endobj 246 0 obj <> endobj 247 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 256 0 obj <> endobj 257 0 obj <> endobj 261 0 obj <> endobj 262 0 obj <> endobj 266 0 obj <> endobj 267 0 obj <> endobj 271 0 obj <> endobj 272 0 obj <> endobj 276 0 obj <> endobj 277 0 obj <> endobj 281 0 obj <> endobj 282 0 obj <> endobj 286 0 obj <> endobj 287 0 obj <> endobj 291 0 obj <> endobj 292 0 obj <> endobj 296 0 obj <> endobj 297 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 306 0 obj <> endobj 307 0 obj <> endobj 311 0 obj <> endobj 312 0 obj <> endobj 316 0 obj <> endobj 317 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 327 0 obj <> endobj 331 0 obj <> endobj 332 0 obj <> endobj 336 0 obj <> endobj 337 0 obj <> endobj 341 0 obj <> endobj 342 0 obj <> endobj 346 0 obj <> endobj 347 0 obj <> endobj 351 0 obj <> endobj 352 0 obj <> endobj 356 0 obj <> endobj 357 0 obj <> endobj 361 0 obj <> endobj 362 0 obj <> endobj 366 0 obj <> endobj 367 0 obj <> endobj 371 0 obj <> endobj 372 0 obj <> endobj 376 0 obj <> endobj 377 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 416 0 obj <> endobj 417 0 obj <> endobj 14 0 obj <> endobj 12 0 obj <> endobj 422 0 obj <> endobj 10 0 obj <> endobj 8 0 obj <> endobj 15 0 obj <> endobj 418 0 obj <>stream xœXTT×Ö¾̽WÅÆx0™k„¨XQcT `£–  Qš…ŽôΡ—¡*Ø,‰-*:± Ê‹-&šõYy1ÿÛ7ëÌËûÏ 8÷š—¼õ¯-‹NÙ{ŸoßwŽŒ22 d2ë¹qmÐFíßã…a2á=á}Ã8ì!üþ›\PSyÆ2dlˆŒ¶¿÷þXaÞ`83bQF2Ù§n~5£=y[;Î!|}ìÆµk¾ˆ>ÁöãIÃWÅïýÏpÇ Mkׄ Iþˆ _á¾6tUä¦ánáaáÃ,¾(hMdˆÿÆw¿WüÿíAQ”Óga>³Ã—:¬÷uÜà´Ñy“K„k䜨hÿy1«æÇ¸Åºy¬^°æ‹Ek/ ö ñ õÿÑJÛ'Lœ4yø”iÓíG[ñ·œ¢FPÔTÊ’Z@ÙQVÔBjõ!µˆI-¦FQK¨Ñ”'eMyQc(oʇšM£–RÔxÊ—r¤>¢ü('ʆr¦l)êcÊ•šCM¤æR“¨O¨ùÔdÊú”r§¦P¨Ô,j0eB)¨!G ¥d”9õõ>ÅS}¨¾T?j:ÕŸ²§œÉ©QFT$²ÆÀÕà¤áDÃ#†‚‘—Ñ=¹§ü,=‰¾Ç|Á\a³'úôñês´ïŒ¾mý¼û]5jœfÜÝmÿ¦fâ\h9°r 0(qпǾdir^1O±_ñlÈ”!·¸Éœ7ÅU˜™ºšî:mhÙ@3³l³6sóÏÍ÷™ƒE E™ÅQ‹G‹ ¤s5ìUË„0ŸScs¹ •œ§J­çÁ–®¯(«­I.‹ä×Ñx©P&ÇtdrZ\\…ö߆4ž­ñ—‡÷̨H­ãa¬8Ñ> ærHSs8œ~{å¥tφ?¨MÚAîÝ•-Cà3áSÎŽŽL!«j7UÜnÀÚ]tK’]Ìèz•nÉ(>2è ß€¢­ÛbwDWD õ,N gÄñ2º®¢w|dÓwœÚm”ŠîhM¬×bV௖Á8ÂDÈ+t!×&—FòؤÒÇ[âyØ æÉ›tQ<6“­ ÁGàù8E¾YR‚¡b ¼h>ðö‘/•d$‘Ð[“`5x«M _ hI!eùú©9_ÉQ´Ó¿ÕùðòªS3x…ÐÒ¸óËS?̼µ<..59Z[+•6¾(%6Çß0pWX"¿Œ5x2U–\«MB †PÊà;šÅò¹Œ~W-p«Å𕚠“ l ¦¹oÀ(,ÙV&,-Á›æ²xƒxB t‹ÆŸüAÉ<+yðq6d˜ËO>²ÍgÿP¢¶xÕâ æCw…eðnÙy¯Ÿ‘ª+ÆØà~Øø¥ ˜ðŠ®.ÔºëÄ9GØôt±*u›¶^ŠúCWt‘bZ Y§Å]+¦ÔŒ¤˰Ãê·e3ffçãG·n<ãÿØQ-Ï[BÈ1i`&V°¤£u•)'•áÄòb Ò9l%u¡qaÄæÒøKRñ Éh2-ߟí).tªW‘W’; ”÷§£’Rãã+RêùÜiK>¥lîa‚NWU'•“6™ ´ÂöPû¶V‡¶¤îØTš^S†Øj•ª¦<£,¦š_¿=²,y£e&Î`%yÊzò„>¤ß&U–¢M£îO’<ûn’ËÄV{7IH™ ›÷tÞuð»zm©ìYØyv¨b>Œ¾\M²j³n;ÝÊ5Ú}ûB¾:aôýáì݃Ñ‚ëùuÛV«ÜŠ'–gæEVƪ’«Q{èLÃÍ®ÓëW‘¾‹-M­îí»ëŒâ=t|BJÊæ²Ò®µ+*=‡œåëºnKÈÞX¾!¶!ýoé­»2vmÞ™X‰¢Xßùk&OuÝ´—ÓìÕP¯å"²ü¹2I.^=”¤Cš9VÒK6†¤û`Ž˜|†ò7Ôºû±Ã_8VÓŠ¢ŽÕE~yÑoI¡Žÿ™©O+KM‰Rf3+=kæ“©–ØËñ‡¼ƒ'€Ì ì®^¬=x¥7˜‡ä„†“³YBàF"¥`#gFIVÑ3/-}yò¬jK³ò˪šJTÍV%«2³r3R•‘ÎñK;gÕÞ“<”Á:f›ª—?ßBÿP‘Œ p°ŸD‡‹ùþuM3 º{cx7KÈÙXlý:¿T™%+úA°Ý=mWC:_>T(8›~'ò·"&L0"‘¢Ï:V_ä¹0|î0¿ ƒ$·oF2z&=… h»³^ß+Ž—Ñ¹­§% ¾›ô®PFÀ.‰¶KŒ,4þØB‚æ. ,t« VOMÁN0’)YfœHæí4‘ÐNy?„Nù¹?ô Ó5FrýšÂ"ÓûdÉj뺊ÐÉàÛÑ_ÓóðÑ)"_@OÅ)sà¨üÄ;j¨XMÿ@V=O?„ìq¶¼§ÂjøDMì ‘ìævÝ(L0í–Ôx³/”Ñ]ŽgÆÍMŒY¢LÈLOCIl‚*¹²¨ ¯°RynËÑÒ&Äv6‡®àÝê+‚M'yLà©öW¼žw´n;s‘´Ýy£¹ÞΈuõolnë<üúëæÌ´}!ê§#œõÜíkOB.ìÂ~æ?‹BçM;À¼ µÍaXfU´°¸ŸØM4®Â1rˆé`ÄØÓA»`/ž¡3ý–oeð3„s0¬å…’Šˆ…$nn¦±1ÐÄÍIGèqXHÃlñtyšÄÍ™‹ûyÒ` æ0‚˜doÉ3qD:ýö„~Ðh–‹ðšX…¨ KNirˆ®ùê¿éþ–Vœtk>vc |Õ ƒa°õK<ˆWsB!+°`ˆÈÝLë±ööcyÅñqöĄݺ#5sÈy$žx,iïD±˜5þ¶b1…å°’®ë‘ÂEãp5Ó#àBYª¡˜sÁïËñ IõÄÃ]LC¡%/—œª¸Ñ ÇíØÚåÇ$ÐfÄ•ô[ïIÄä®V,…ÕÇ4zÕ. `|ßzñ3ÜsvíêÖƒgø½uÕ[ˆ\T&«Ó2sRS•K—»G8 öƒYÝ¿vÝøçýkAK‹ùüèÒ´j=M+lu—FtIïS¯µ†¤H߃¶ðR®ùÜ™sŒØEaï¤%ÇâñxøQn%„býÎl=8…•Z@½‹%œ¸“0s„Öük4­WàfHdp3¾#ÿ\à^iQÅê”ÔW2pîÈßÅñT[´=J(Ò!J”n¼š^ÑîÑèHª7pô(‚÷A¯F€›ÎM(aV7£OÍ—ÆÑðҬѼbŸMcfÞ~ñüÖígJ=”^¶€Ö`š e Œ¦1¢VthfÓø”)—ü©ÿR‘Ù4œÒDöä“ÔðáÉíàÍ•2% õ [`³ÇãþØ dÿú5¥Õ¿Œ¬œŒ4e@¨C¤²D3.'ÅF`†yíuèǘÂïc [l@FÚ‚ óÇÄ1Ëø·'GnÈ2ˆ$«îŒ8˜/é¬ù­ô‰cM—¾lÈNkS–ä¢|Ä֨ʫ+ÓÊ øàçâÄÚ¸zÎâ—L½í}Üi#Qщ*Íê¥45$õ 怎`£80¡}òí³¿OîÂ2gü%A¾kÙ Ê’À’¹}Ñ{Þ\gÏOùÿtèwÞ:tâÐW¶yï"tûŒ‡Éïgã qß×Ñ™Ý_Ÿe±Œ)\°pÑü<³Úýcãu;2ôÃÌïgÏ‹nñŸ}Êjîé bÑmmÈMææÍGüÛ‡h]–UÚ,ÿgMÎ^ôî²èÝ{k·5ìØ]þ:„ê´o1(œÅ)’‹ã;³ÒéûÎíãT ±Z‹›ï!£0óÓD`}ô0½uËÑ{Þ×þ”ïʆšœÿ'’ÉäZÓK4¬Êä»%¢-‰î=4˰‹°L~]2b¬8bO¯kþ]mR F>j˜¨ýѾâõ%ø&yéhÀa´â6*róݪ}—#QÕÔê^@¾ ‡Rúà™½Û÷#¶qOð<¾~O”§0Ý?¶ïCì¾=¡ky|ã#yÓÛA_XzÚ}Uhœ_€rÓ×ÁõþˆU<@añ!A¬˜lÓ. „@iÈ»è‹$ír‰‘¤ý3í¥q¶‚ßåNôøßÞ‚‹ü§?¨ÒfEDµr ˆÓ£I#a-2`s šaçØr”L;Ú´÷ð¡à½þ:öeÉüû˜åôÖ\{w¾ZØEâ§t¤$¤À/ÄØÎŠ¸Wf« JkO¼ƒ)`€¾LTâ‡O8tqË•†ãõMMµGÐaÔWܰbË\äÆNb{윰QÁëâQZWÕv<ö*ºÐs•’Ám ¿qx‰GLFFJ0O¬HªÈ/ÏÏ+TÂàCrM ¶´_—h‘zoQjAEršE–¦æ¾9qñÜ÷÷ÀŒëÐyöé„ïFº- ÷ RFoL E1l’*¹ª²´¤¦PYÛvþÈÄþíò¢¹ŸÇnüèc~Êô™NNî©if®‚õwâ›E(ó¶*&‚ƒî%§šà7.*9%^§@Ïsn{ Y¬Ãl÷‰‹}¶ðS¦gæ§#61991¾2ñ`,ß~2QXèûüûî+Ë/:5òŠöŸ> endobj 419 0 obj <>stream xœyyXS׺þŽ!{ïZkULÐ&ÖÖjµŽÕªÕ:‚#ZdFEæy È@HV „yžAë€óPël[­§sZÚž®ÍYô>wýþî½ç¹ÜþÈfí¬µ¾ï{¿÷}ׂE¸L X,Ö$¿˜„È´…>I á‰ÎçùÌ 3só*Û%þsÕ¨‡L"À$6˜äR=óµ¦1ISá•—aæÂ…ÅZ¹3°dž¿Oà[ ¼½9)9;5&*:}Ö²%K—ÏŠÈžõ|d–GdZLTâ¬7ñ‡ÌÈø¤ä„ÈÄôÝ1 i³Æ×啞úÿÿí¯Ùþoóá³11hSRðædÏÔ-i[Ó·elÏÜ‘¾Sá•}p—øÐîÈ{GEûÄøÆúÅùÇ$.\¶x‰dé2Ù;ËW¼;kåk«f¯~ý½5ïÏ÷ÖüûÞÞO³‰ˆÕÄë„7ññ±‡˜Cøo¾Ä\˜GøoÄ|"X@›ˆ·‰`b3±ØKx‹ˆ“XLl!–[‰¥Ä6b;ñ±ƒXNì$V^Ä»Ä.b%±›XEL&^&6Sˆ©Ä>báJ„¯\˜N°1àlÂp!f3 A/‰‰µÄ$â}â%bá‹+‹‡#‰{¬¤ ®Â&Üf{²/¸¬pià¸sDœ§d,ùµê£ù´/}ì—ì×N~ÑÿÅ¡I.“4“>{i÷KúÉôäØÉ—_ö|¹vŠë”¯¦†L½?mñ´]½\K_yó•ÒWnsp¹Eºe»•¹µº™>{ºhz?o"/œ÷=¿Ê}²ûT÷÷ݵ3&ÌØ:£æì™!3μ÷ê˯ú½Z&HT †…áNhš(¦ 5E†AÏõÈ6] ZæÖ…/ÐÓ¸ZÊ&fY«ùkXö5š˜\4}é$@3¿› §Ái?þ…·ø{ôŠ0'‰ûäÂô*"C·m8t¸®/S˜tZr |Lÿ0tù¶à_…€7GØ£¾Îb$‰ÈÓúŠ\”yr¥½Ž2yhLU”k*€e–6c(6í@í"긮Lö3z NG~<´‰Ò¿£R-ÉÃù¹à –slú4  à<˜y鈚Sã9– 2¿ö±0øØ£ÈUÁ N&©É”ȳ€ HMÒ½Á–}`5X¿ËÏsWäb€&Ðè䣙0r~úô¢ »r“Ƕ„U€ï|«ôøˆÿ@nÿÒpÎùÓ™‡úmqö$ÇgÆPLP¶1“/N»÷f<îZZˆ¸P[In0È‹õWi¸”rÅvÕ*Ì€/~]à8Åó«ù¾ai~a”ÆèŸã'æK(«¡GOw˜•û„cÑP(½5´ëQ¸ˆiå¶œëº{b=zAà„&ìݰyŸOWËxš»™Ï»Y¿0$d±ËÝ`7 ið{ûås×.t~_'>ô=»õ#ÄêB¯ÕŠÈGjKîsÈm’Ë7hièÃ\å¶[Ž|qUs\ðп@@#V¾·/(q|9 Ê1€œ¹ÄLmbÕ=…’'l8Æ¼Ï mH°ÄO{±Ñ4õú²ï‡Ï6"<¿o¶Ä3CEå_¢6ëhæ{JaàlB¹ -/G©ÊÈŽ•ǃx\œåˆkɼ nÐpâ‡w>¿Ü»]0™˜ .öCkëï#læ{ø>7‰ y-4½®§“É×Mzè¥!€‹¨'ºRyéjºJÓIù{2ùJÁTÒÐRPÐh8çEW%+_FדùðuÎX“ˆ¼£-É1nvfB·9G¶ƒ‹é¦&瘴VU±î?aºAµÜf””é.Ð0ƒj;r²©ÈªUÚvi‰¶ÐuöЦö̪˜ð¤ŒÍÁÂo)­Ñ7#Jæ›ËY†ªÐõVI˜™(] Fã¥Àùð¿„”%\¼eJ±V,[·HÞ„VÎ…$Üý}Ó7ƒ''®4ÞçÀIQOTKbyJýnº–Ì…Qœ R“•“ ”@bÊ6‡Ú÷YB1öB0™ÌEÞjÜpÎ[x}ËO‘pøÀ)}4 £Œ—l%ç èɰUyš™Ôƺ…¡ka¸oBš,Ö™´‚=+bÅ µÆ™’|ƒÎ¤£?DgÈ•-.œè©;Ý.ȱe¤HT€XÚxE{¡žiçñAØUÅúcža;Ü`«ƒÜP$/Ñߦa<‡qTŠ÷5juPÏGoÊp§¸ø“\«ˆz )V6Ò(ÃlöoFÆ+=>‹³û†™iU¬ŸÀ-O0tNrµä^£Ú¢?FÃÑ21u9¿D ‚i$§@’V&S$gÄË}(®ãˆ>Boʨc˜S !4*¤ÖºÓÝ[ÞØ(ଢ t'«ºl§ÊøãðgnjÄ©Ø'äj£¬Lw×¹sã½Ò’Ç&¼¿“"êó¿”k½\±2ß¹?Y³¶ŠÅ¤àä"¡”lË·+(uÊ<åšÈ©$-—Ù/i( ‘cì-Ž”yÉ b,KîM¬Æ§0 Óº|˜›£×€<Üv*Û¹ŠMÅ>IŒb»Ó#Z …À èn«2Bˆ–P‘mÉ6§ù¢á³ÍlôÊÝå}®§êX‡p'Uçžæ ¹@­–+â¬e" Wú§@—wïŸ9¾/@ˆ{YQ¥r&kš3Yï Nw:Ó%‘ŸhKŦ×hô55ÆeD´^D€²Ü¾}ôØ®›µ™”“¬pÞ*˜ZÒô[iÅ#³37Ê`b¤ºXÌÛp7dýÄÀhN<ŸÝ£nÓ]¦á%2÷š²9µ-¡ku û²#cöE${€Õ4Ü^©î]€ÄzßæÚvt_—@]Réòqïbþ£‹ÕíÅ:H²áŸ£«¸ÈÍĦ taÛâ3>Âa¯¯}‰=`0œ‰0¡O|êwAèõÑÊ®€ŽrCÙ]qgö¶.èEà-ß’¨J§¦§GG‡f€ý ´2ª5h(öÙ`¤é§#ÇèÞ5gýÌ*ÎnƒáM¬_±©¸ì좗±«¸àhé©)U&V ÊSJ”Ø'VVÖv…5|à˜š"L ÍÒ¯¡WÇ}†nº J…‡óØ[j§V›6p†7àdê™S¬îƒ'»Y?@‰ÓÞcª½›kUžS©Zµ^ý ‘k±D;©tÕ «Ð7€GàÃ⺋m]—ÀupDÖ“Ü|ppyÓB • l²<¸fs#œqyß󽃕%3Óãtp^©‡±½…M¬¦[Pò ±‰ÍÄ2Ø/€ç)­)Zžšë'á';IºÀ`ľƒ°äŽÅaJÕæú¨qâíÔžÂ\›_Cj©èô‰ú(O!ÚKél‰Âı‰ÑñÙá ¬ô….Þ·>XiÍ)Ì©ôöàý›–î: ' ÒÉÍ©!]½†’2û ¨Ès¨ñLÒžþÜÞþòÑoŸù]E¼ÛÂÙçÃÁYúì‘îËGˆ¢:­qe)åÞø„„CG‰Ðk<üoÇÃÿú3û¹ZÓ®´È_'}ìF»3ìZ«×öe ¬ÏOUdi”²\V0¥Y\]+³bÑJÏgÄõ¦Ÿì+«ovµÕÜh×_‚F×ÿ»äàc*óÓ4c?äà®.È)ÁÝÈXÎPøW-®A,ºŽÔÀuœ±K¤­ãÔ‘µU])#}f,ŸÔ¯P)W:©ôèsK³¨ŠõÙ¶Ù æØÉ,C¸ û¤n>ô¢à,ôAÖ¤5åó-J“hi•J#ˆ¤0ÑN†™âá§ÐBÀkn„S¡KcùU¶?dT¯Þ–r€J•#ËA¯¢ÉqžfºDÔ£ççœkÚøéj¸²îuÞìÔ±4,£Œ¿ÛÊ>µ>0ëoOØÕnPa'½LŠbý9ç­Až1HrXá«XDÙ %ì¢ÚŠeû„c)”Þ_&Û•GKÙèKU¬Ñ]Îm†‹È³y•J$êdyš;Ææ¡ð›Ø»¹5ÀÎUeÖ6c!°J÷MuŸ–AýØÏNÂTf¸ý‘Ív»”Q. ï4ëéèåüu^³¤ÚÉ ƒÄ¦ï£a'Œ–b³¹¾v ¢Ѓ5ј(Ráëäõt;å d庫4,¤ZÚ*ú|eò*!Š¢tÞõ ~)ÉN¥ã vÐˇœxèâº=A){üÙçcýA(HÎYµ“¾G©¢E€ó´äÙhƒU"DE”Î7Gæ‡EéŸÏÒðÏUÎ4`§sJ[©É K“¬LBSÑ·<ă߫+ó-º¾ªZã6PW[|Æ™†*u^_¬êXÓ¾š7 u¢7˜Iêʼñû¹š²¢Søˆ:¥µgw/„þcÎL-bÖÀåck8vò)´›«!~è8m³~XìÔGp…Õ õì^XÌõ‚ú+ÔdhR@6ëd³áÔŸ¹ ©©q‰õ©Í­ u-­) Î;&Ä;Ébò{rLŒ¿Ð*«`3ׇéf‰²ÿܹI:O› £ÓXu?ÂÒÙÐŒý@¸äpÔßHDô@Ú}Ì·;ìTÚ08*º:‡Ïö@À—h¾¾†¦ òS¸OŽbó‰"Ãf­Xö<cŽÂ OñFÒGçáUwÝeÃ_Ñ:îÖòŒVý}®¥ôŸ‹ê7VÞu8 OœÏ†û5­7Ëi…¦€C±:l˜¶PzÏìÔíÙ×E•©OyR¦Y=±p  Çû{t ž7æ)NtƒÍvrÛôÇiæ'*׈¶-áà~µ×™±Í«¶Jã„Ø{ê¼Ä²õã´à>S{—¿yÊf’à«ÜœÂÃ{ê}z>Ê%áZèñÕw½÷ÁCþÏï=xÝ/0ãàaA\Œ4NìQ­åõý­³í ??ç³ríþÅ+— Ñ´‡#gÜ©ÿg ŽÓmt)÷†¤6Þ°žF8®w©w³7ŠD)ú•ÎgýúôømZAá@zÛÿ áÊp«²þºc{ev½þ =©|HD¶¡gb_öÍÅiðãG‘·±Á…ð1÷¨ÕÕª®¤÷ø‚-ô»¾;7&e™ë °½7‹1éJe™Ñ·î?jè?.<Ö_? n€Ó’¡¤ÖÌQÉ–§›Çê»Ï¸æuvQp˜8.J„OØóx}w¶]ôõÁ;£¤Ñ©)Â<´5íYÂáÜ«ÌûØá}¸î–&J¸s˜=a$º1¶‡³v 5”ë/àšm»ÊEjªáÎÿ_Ⱥ™óX¹Å†Û™O¸0ˆ¬&ƒÉÒóOe–f©4€"IÄBJ½莯)ÐYÚzÕ9G:|z7˜K/ø`ÃÚ,‰¹&AW—aMt’Lž9”vÿñíÆS§„GVŸ÷ÁmÑÐÞ“aƒ>µhbõxöš—!VÇw°àk6ã3º‹HåѦ D¬óF$@î`yã;Á=agÒ.co;åéP¹›?A/„e©#½„pt\Ú@£ÔËýâÄfÜüíö|Çÿ{¸ø”¥©Ê.¬.oµv:¬ ¯˜[ÅܹËbœ$?F’ÞhnEnÿ Gé9&hïØwœk$ŒÍÁ}­ú9Aã 6Ü=¸GWLÊ6PÆ?-jЉÍJØ—bY_²A`õ.ÚkL°"‚g^ÃMHOKÀÊÙÒ^[ÝÒ’Z7Þ첦ÑÉMÓÎÝ÷¼ “>ò»?Ýõ`(îÏg:úÁMú±Ç…7ë½mKv8_,pý ±Ve&nqëá6HÂI®ÿú æ8zéAöÜ;uQÀ—Þºc}ÐðÓkÕýŽ \œxÀ]65ÎÑÃGû¯ÜÛ²;åàÖPìß}‡pšÙÌ5UKÖòûÖ‹ ™®U¦§‰²ÓÅeK+ç Ð<·ÿe•ŒK«å[ö… .t)=ë¸yâ·û—pÀ4\½¾€ÜЋËÞD3ÐäÛïAâì‘òþh%bÏBo§Ðð催<•B•œ)‹ôú{ðÅóå«„Uõ¶f@qtZ+|å ³Ðý,Üíq°Ž;—¬‚îœßÏÎ'[`(g™€B9ˆO¶Ž?Ä;&úÁ d&rç Úï2Ås†ÉvÏîxÜùÐê|`‘H÷p³œï¹“ÕxNÌ»˜¨¡“õ§N²žÉ„ýO¶FÈå28lÕTI~ƒzÈž†¿)ïîºíô÷£Ž‹à"}*º'4*=#Fàš[#ê6› †"k´±Ð 3,EšÜ¸¤Ãþ‡…=ÌC®kò_“×7?—‡KpÒuè~Å´2nÜ1ÃvÆ@"w—g00™~cÁ­½ì0žÜíG/áOF÷†F§¥ÇÄÕˆzÌEÎå í\-6) ¯†¿èÃqÌÉDZlÜ›zx¿Çòè¹ã:òJ÷ü/çô‡4dœŽ+)ç­¹’Ô•|7í†âøü^ú¸ñRÓå–®ÛÃôóI`ÈSvòäÞ=ÑRß=ôñ?ø€¯þ鑈ã)5mr ï¯Æè¦ uÛlÀ›`vÎêäÝÉ»âoÞãìüñI4Œ?× 2h€¤hRäqjQž(hQ¹ØQ]é¨.Ê/Ñ– r:Õ= —6SæüêÜÚ¬†8~}|…¼+G™½¦Aj 3 Å–¤–çòN49̃æÞ¢’bÐ@×ÊÊ3¤âœ¤4AjBZFº\Çk ¡§JRž•%•f) DE™‚âèÂxlÕs¨Èê¬ò¸®¬:¹{ã,™43Õ‘sB%ìV·(965/"U¢Ù¯ ÍËA YšS[n-tTšÛ -æbKAAw3=hIý¨µžõå}6<=:•[¢þ¼£êWP1™]ßE.§ m6[»§áÆú¾ë,h¼Î†FØËEIÛaJ¾“aÒu”“·“ÿ²*\3(÷({t Æ®É Áip ßÇ|ÿ ×긿Àw࿃ﯭÂ÷ï³;Ðtn*Œ½€¢RŸRú2©!Šþs9¥S(b±,Ëʘ€bZFöL|übiÒ¤G“^"ˆÿŽ›k; endstream endobj 11 0 obj <> endobj 420 0 obj <>stream xœXwpSWº¿BXº”д)duM„^BÈ&Ћ1¦×ظ77YÍê]G’Õ,Û’l¹ËÆlS ¶)&„jha—@àeÙIÙ$ç’ãWŽHf6oÞo4žÑÈ×çèû¾ß÷+fÇ ã¥-”‚Yk ÷eg$E>˜AOfЯ £ÿÌDSQÒ¯‚çFÑ‚ÑÍ£‡_á'@4Ö…âqÄpãµÛ|Ó¶nÚþæŒ3—íÏ•æg¤¥FÏŸ;ï­èDiô￉^žR‘–=¿)JÉÞŸ+LÉ)Ü!LDoÚ/Ü—ýÛýüè߇ýÿŽ'bÆÒœö/Ë]¾"eA¡hM‘xŸ$q½4I–œ’º1-}SÆæ-YÙÂí³fÇGO{“ þBį‰×‰8â b ±™˜Jl!¶ÛˆéÄvbñ±“XFÌ"vˉÝÄ b%±Š˜G¬&Ö ˆµÄ[ÄÛÄz"†Ø@,"Æc‰%ƒAŒ$fâ.ÉT2J?Û1ì3…ùŸÃ÷•u›%ddG³?#“Füi„{ÄÓ‘Ú‘÷G­õdôšÑ×_Ú9fƘÓc×·w\ëø…ãmr'üÂÅ™ÎyóGÍ9chB0±ƒžbП¸›œòæ,ú/…™ÿŠøu’Ž/‡±ö§Î êA•Ãl„Q<˜Ë ¡I6­M t|¢Ð®3rheñ¡Ÿ §Ãò#¨b®»'ÂQÇáKwïSÇO\_O@ÿÖRD¼(¡Š~ù0ƒû ó =•[k«±…”@ΪtD¥!^áBñ’âõš½ U‚#fŸŸ½Gæ©©Þݦꕕ¦Z@Â)p6|¾u7¾wùÚÝYïÆQMßÛœ6|‡ÅnXYh¶( pÙ–ª<° ¬ÊY˜³/v·p; ÷‹ý5mípbó-ªñÊÙ}f\yê‹¡3è‡É„Ÿç^0Tè@.e>ÿ£”CŽ¿¸sæÙõA8 @’„‹ë'´R€°àºxx~w}Ê–‚éëÀû Û‡˜«VmŒ],| {%¾†rg(xžŠ ­•~ÐÊx>æù«Ü!ƒœuÞàÜ‹!j”¼¸W¶I§ÜK—°ÏÃ…rÏžµyù b~ªl•æC@n.,­++ë­{Dµ@vÀê·ÿ˜5l­3º |¯Þ®Çë µ¨Œ¢‘wKKRjôóÌ|Ȳ¦[/CÏU[ê8‹;:·]«´[eTµ¯%„è7B øÒÄøa°ûض3‚À JLNGæ1†Ù¨li–Tï/Ì-ÎÍ£’âäIŠ4ÞI(4Û?Rj-©ø2vMI‰ÍÈšrT€|µzA,ô3\7?R·Qκd(3üïÕ‰Õ6ép¿vœCêÍÀk/sׇ¼NKµn«×ä×¹•¸H¹EeÈy·¡RêüxžÙŠþjáãú\¡ W7àÃ÷Û•ëôÀhÕPV-°XuÕ.R’VÓ3k%¡ qóØíI[œÂ£Q–7XRâ>Pi a2ÉÖ×úÍÁÉκ}¨èðž³TJ¯ü“­Õ¡öæÔ÷K畤¢,­Â`*: µKœø/=ù »lòÒ= «³ªz¶R‡vÓA¹W˜¿YØý­\0PŸ€¿¶0à z ÷=VøG›àßeq f«Î HÞ³#K›¯Ó€XÅf&?g-Ca‹Öj2ëøšL}6ÐEÕòÆc­á§J÷®õr¹ðµw¹ [ õ|õ€Y¿“;zé‘!uhBÏøÁÝIœlz¦ÜmkJL¹z“Ëç êuD-emEÓÔù/'9Á™±»vdMVêJýà°9¨Çð¿Íö8Eªa‹ž¯`wY(5:-N-Э±@›‘Šþ“,5d)™Z)m¿~òÜ Ù!"ŠWÉYŸ])kî­©úçU܇ÏC L¶æk“[ía²—z[áX:–WyÖí,%ÈÙŸè|z°›ÅºÜ?næz£4D¿ƒ•jT?³‹ã·QR*«˜ã[áCSÁ2ÇfðÔ?þNù— ½¯á"8H¶ä5 Ê"¹KU)”«œ: {Ö¢aË–fgñôðUÀòsñÀ®F ·êÌrSŒ*Óø‚-CôÂÆýìø$ÎÕ¾2dk·º,î"~Yf½R2«dÏžl×yñ÷Öw\uúBíÍ'¿†syMè†=×nv¾”zÛpºJœðÏpÑ-8\$ˆj„ùø[)Ú€B(v© $dlC“Ð;Yð'ž#Ãh¶èŒLăækêŸÔWùœ¹Õ·j2ƈYiÖ4}–ÑÔµåëžØ¢gÕL>€;nN⥓á0îþýYYj­ðu—;Ô—ôÂ)G©Ín÷ê¼ z³Y½[×™S€If¡µhÁŠƒ‰¯n…ã¾¢ŠÞµè@>ɑ䔩Â]uUo Ð{ð·ÍRSÒÁ;;ÐÈUKIÎÑÜ‚ YÎä4QøØ™Îï\ ºÎké6G&¦> ŸaÐS “«Ó ZU¡P¥QЖëÃf°[ù?¨ÿÑ»í‡+ xÍ^c™Þmñ2Tᯮ‘ù âSÓ¢WPêÓŠ+êP.à‚,]L‘Á€ÑRRÌ;Tê¶•b_âÒVÄ6¡±¼wш"¡Dª|Ð84.¥[ãÐR¬(çUÉ(óžë£[kš»O7£Ñ¼òíåÅ-à h¨;ûÍ‹.ÖÒãN0hÞ—L8ìù$î9‹Ó D@kQë -‹ÞŠxè•!K”‰]x[8gÀÅð#8ÿÚ®¾Õ+¶'¢aËý0Ö> —¼ÚãGZ&£jÌmkvFÇÆP©) EXŸ³‹}µçšÿÑs‹:rçèÁãXŸé“ ƒþ ð©˜4Qö‘Êù¿« §]ì³p•Ø•¾,7+^ÄO—%rI¾§ÁSRíª¦"Kåïo¨:WÂÇC@‰!ú_øØ‰]L?ý:·Ìá±ù@7¨’‡¶6.@™ Èõr…djá~•²H¤Ö)ñŽjOq™Æ©¤H&åUK›/bÑî† ê ¾NÍùõÂBy±HîÑ„”‚*µ[‹g›”öÁÛè/bHòŠ¿Þ ÒIJXÍÀtÖTÃ6Ѫ4+,/àÑASÕŒæ‡Psƒ ü™»ec²h 7eôÜø²ý›3g©¦æ®Ê.@ÖVèTF‹Ñ¤¥ôJ ž+YàWÔ…CU½ñmÐt¦ ¹3OmyzëdóO±Éã/®¦—œcÀOO3ïÃóÜÐ ¿ï˜Û º0Dzµòr'VÒТìÍéËnU6²ïHGW¢¢H¬PJt­KE9 v0“ZµAž¯òvg â%åqåð0|Æó¡Nv6bG .™ãôøÚ þG0KŒ„NÂhß²^£“R£ó”À‘mp8UûEèæ¸ãb»:͸VOÊØ§-n3( «Y±--âéz¤dl¿&¢…h#š¾¼+áÒ•#-ß]¡Ô;,Å 0²jAi}ÏÉî›ý´^ã6[ü†7Í| -™“^ØÐõ·>8âò5A¸©³*ü[“Òªex%—™ðWÈà.Û˜-ÇÞ"µã´ß^ái¡Â%pzõÏ·ÁC~°a'zÍC‹ÐŒÅ§6ß½~§û³O(Îá¶}ýù~@VWdKÒ²…TjzŠôí"«Jª¦ïµ@I MýŒ^u•ÙNGs¿a-Z$ŠÎܲðU:··Äfw8©—­¸Èji°¨H.-LoË;úõÕ˜Á x3 2X®–(D°šàüÎkgYá1ê0tÌ&ʨ³^^S[UYs0µqçîdÑÞ40I¼W8ƒœÃú-Íì„mØèYdÂ)Øç ê+´ û©r9ôþ¿}‡%À^ï5:@;ðÙ=¥O­¼C¥ü \ öèël: >!ÿ±ä$zE€l,¸<Žëª.s‡±âÔ†Š¤>!ØÖîÏË–%ëb€ HŽ3B"(±~U ·ª¨™à9ÝzÎ8—yoç¿èlúMî–í:Wnefi ž5sÞ³¶W ÏæQ“¤bP”U•bÚZü~/¹òòÇßà >ytaÏá ‚x_^øImC¹Ý¬×â³úÉùáÉÓûwƒæ ¡†êcq~EwÐc® ³+æWk©9`ü%£#·5.éƒ÷ö¼Xç ª•Ý-غq~†ÓèÉÜΪ‚=iªI%JÌe2Eî}2øÅ%ê!®ûžãnD\R"!nµJõ"ÄyJ}óÁªéiÕ-POvå6&¯]¾M™-€£é-Fg¬"Ù§Ç®ÁVk«Tƒb>P`‘cµ˜Æ¢z'yq”낳ËÛº>¸wå|;Žrå*¥ œÚ‚’”»°Rñ9åyAy¸¯½ñÑ9Áo&ó;dqó3 :F&+Ö`éÑéÜžRGÀ]I9+mö(;û+xËlC"1'›qONY½flpuf™A²­àÉc 9@L¦ÄͽÍEôqn®X”UUÔÔP[n*lÈÌDÚNµF¬í¤¯àøG“8‹èt:Û…3]!KQ¤5Š€¨E’sÇ[”éÌžüÚÒ•onõçœ[G9MAIPùåmï®ò<@.Ù·ô˜ëÿÄ Àîˆí¨ ª’å®õ•†°»ñ›´Çd†8I°=„¬K¢ƒsŸPók+° \è9ôÙ¡feAµ &ß“i_ýBÊBô·íŒç/Eükš]i: ‰Ö œiá£×‡êåÛ äkŒ|9<`¿í6ÙA'(ÃMï€mäfÝhÉߌãŠEF#qe£z 14£¦çcþJ‹1¤˜6‹Z“ÿa,/î‚ÓदÐqvëäìÃÖ2®]¼s÷ìeÅj~aîå)†Mž°Uêm‹LŸ«ÜkR˜ÕEËã,Aœ!1†áq¸º§%ßS™Îç¨×·TJš&wúúc"d§1ºï0¡Žå®]¤Ó‰0É]eG¹³’²•àŒj#íl8ƒ¾Á}Êo¸?2ÈLØ;è($ª7kpFÑóSƒ’–¶ð³KœO_,XÔÀøË¸sÅÑç+ð†™ŒF£É kÕV«¨@£W`4™œ¾’’ «kp‰Íi7¿#¿1S,Öve%î^‰†5Ü­8 ªÈŽÂºŒ +Ö 7æÎ³}«ºÈ´0ò”cØÌ{±™/Ñc¡WÌIGãñŠ>4É•;ÈHæû¶ >üät ËÝZ¹RˆF&¡W)]ŽI¡ÜEFVun¨¿ÿÚ‰+}G°vú¼Z¬Ï£˜ŠC2M²Y4xU…ò†Þ#­ŸŸ8ÝQcž. =bü*ˆ¸›9ë”ñ…Ñ—é ¹(vh8/‰žbuâêàƒ®ŠòSN> endobj 421 0 obj <>stream xœXiTSçºÞ1²÷V)UâVâ uÀªÕVëÐSçyBœQ™!ÌHÆ|a†0Š  2Z´Nu¨Ú:ÔöØõx:Oç¼›~¬³îlïí]ë޵ö—/ïð¼Ïó¼P#GP`ÌÞ°(™rþZydýå›üd?e?UˆpÀoaƒ[x‰#……ÈqdÃq¾3?ot¼бÔH`éæ½¥nûv˜3wî¼uòµ",$4Îõ…o/v P»þþÄu½Lí:‹ü‘ ‹”ÇDÉ¢ãÜââ•®»åQþÑ®öÿó?þëªÿßåE­X-_³>vƒb£rSÜæø- ‰þª€íêÀIAî²Á!¡»ÃöìØ¹?êÀü·|¾ý΢Åï.q]ºl¹Ûœy5ÚIyP3¨]ÔLj75‹ÚCͦöRnÔ>jµŸz“:@yRk©ƒÔ:j>uˆZO½E¦6P ¨ÔBjõ6µ™ÚB-¢¶R‹©w©íÔjµ”r§–QNÔëÔjjåL‰¨ñGM &RÊ…S“¨QÔhê5j%i 5’ ¡¾Ì”Œˆñ¹p£°n$52Ía„Ç^z }îbÞcn±röãQG5ŽúutÐè†1’1š188â×Úœ¤N6'þõ¢×Žõ{eìoãv;tFÎVç‹Î÷D‹D‰¢‡ã÷·ŒÇœœSpæ ³&Ø&|;qñÄÈw FØp’ßh n°q¾(­rŒÃJ¾ÁENcÅP¯l~jÊaX¾6fgA¼ 5¢ŠbkýùªNˆ§ÛÞ/Eñ(^« ÍÍ2h )V˜¡Hã^Bö8ÛÁ‰?‡,ü„›ç{  H'Š<ùV.8O[eìd¡€y¼ÿÃå;½åÁQï}¼GÉôd”èŒ~,îc ~z¯žUB¦• )КQ; å›ÊÊXуúzkyÃäãÕ1{¤8‹1È´Éá9äp*ãÄ礴ð+Z6˜ oÃl!ðQ?g:ž‚ßx9\`Â×?ƒ+L›û3æ¤ÆHîRí^¼ ¿•x`—GâäMëj®JI}Týƒ£Zg`ƒpp&Ìã%ºRÃ)–®aVìñ쉬8ˆÄx‚é¤HS?› ‚þ6sç))–2†ízݶ41 ƒ÷Ã.=X‘†Ø‘7`"L9vûZgSÄa’ÅÔÂC›àX"4J¹›9µÉyØ!“»?%u]&«à¿d:!ÈANGnN”‡D{ïK^‰Ø­êŠn)d1 @§‚Ê1Ë6³XZƒé LYÐ0¥°ôLÛ$6ðºG;ñÞË-z‹óWvh/„~+瞟Va¸ÆÂ.f ¹»µ¤4#Ù$©©Ò5"¶½±¹ãtX«×AYì&/©èö—x—’éÊ2¥ý‡ñæ—AúUK È28âÏiX4ÆýN†lÌ;ùªòÜ ,¤0?å¶W’¨mðLA«1:ýôϯ$…•Ô+L1•ÛY+‰ü:‰\œÒÆ/k4ý’o„ð¾à`f<“©ÉÌÒ¢L¤ËK.Œ0ÅÄ!vá–K·œòþÑOz;ªI"Ø ¨XŸ Þ½O$r¼ÜF›ê‹ŠJQ!*É-Ë>’z6íbŸ]»úOeݳ»¤›ŽÈm¨mm¶u45¦%ÔKêMê*_Öi°VÕ:èÒ*h‡ 0 …ƒÙÐÉáoôß²«Òóö°ÓÏèøÍÛýk»Ã%¾#pd!ø™²×úºÕ²îÿã”â2e3 øg ¬7¤ bòîšÊï³Nð8õSø­Gp‡ .ñþÜ|X¡ Ýß ôÙº—À˜­Ý·ovýò”DaJ”%§$ ±<­ºS ç_2$Bž—ûà„EðO‚æLÒ§Adã6”$Uβ¼Š1~PWýq>kÃ/Ì­‹„$œL~rËþä æFV&ÏÓÞWÃÁdí&=éë?lÌúbu…á’ '1¹žIÚõäÉ Æ>C7<í˜s¾ñ¡öòmÝœ_^j…¡›…!ì­dÎä”§}Y|‚ OL‹Fl€Æòžc%sJ_¬³Ã­YtöÀWÇÍg/I¶2ÝUÖ‚ŬÈój1!m1ÁÞX‹HR¹Y«dNf µ[Œ9yú|ý&¼ÊEy=ä…êlV2‰QuYqs9¦P2Y™M[Àmh´‹•†qpí'|Í¡†ü̪ö’’¦Bñï s¶s ž S'ŠnóQ×¹ôôœœC§d”TK¡’y´j;a‡Už«ý­ÊSÍֶʬ ­Y¢+Ë)BEl]“ù„Dôâ²-Æ]º–ÁcB©‚c}£Ãë~ÚçÆÅÓ–³JLžõª3¨µ˜;N±¢ñ‹\Ldbª±Q M—ººþZG¨5g˜ˆ¼ÊÊ%fd˜°¨\~çÚ‹©¥PlÅï+™þ¬|R#Mz’<"3S£Ò$$4kk²‹Ž¥Ö£TQQÔö{#³Š²-Q0t‰Ž ץȃ䑪T]fZŽ:—0Ô +C$¼U!s㩎ÓùùE%Å¥5òÊ„²”ªx—2M‰ éQª63Â~8s¶Çø™ça›Å>o°”ˆrõ +׫/ÕØ¡_Ê™/.œö?¡9‹Ä ~ñ3¼ Ò•_cá¡Ðä@™Êñ~öãÛ\Mw­¹±W[¶`,Ú¶Í?¦¥ÿç:X¿Ú‡Ð¹h:|EbdhD@ðõ ĺ۹dòTV<²£÷'ó1Ñã0z RÒÖ“ÁãïÛÑ‹ý/ò-3ŒòqÿÂi¹:bÞë²v$~€*!./¶å›.†¯áôso¿‹zÒAE„‰uú’R#Ê3æK…ÆBTÀ‰³„Êbce^ÛŽ˜êë$u –Îã/a?Í¥º«¬¬%Ÿ%ò’r“Û}Ì4!¿\°lJbï}S~>vmÀ\¥O+’êH,þƃÕñˆíj´ž¼º¹ž2{ž¥OçÀ¸Zî]’:ý¶þÕ\ÿÚÅ7ÃáoómܪÒô²Ü»,ïÎäÝ«¬¼S@jSÈ`¯¡HìÅG:à"}'«:‘:Ƀ»6u¥†´6æ½B•ÅpåÃ(zæÐDC!ÿO‡¡"&w·6u]1¨£€_‹99­Ò©“ãB½•éïØh’ùÙC “§;4Ò¶¯ÍàjÀÚ!7/†Ì ?í 67Bvgø–nÎ'?¥u±ü¡dnd—e3‚·1~§£ÌÞ„úG,wÅ3‰{˜óë¹VóÙ>éVæt…­ð*¡·íWKD­øÐse¦'¥jãÒâ»_qÆ×tùRk‹RVi·BjK®½Vοôðëzˆi5O€D½ªD]k¸Ãò³º{†N94óit±¢òF)©\„‚¹›aI@ëY|‰Á?ñkpˆ‚¶ jMÿnv(š1x$k Ðìm½;Ûaq‹€Ÿ㸀CQj?„¢kŽ«é[³‰Ï+¤3ÿ¦é‹èˆ8éeÙCr»Ô ϳ¾œ cžiyyCŠ«`—Ž5gPª ËÃBVÃü§®'ºú/â[ù©ƒ›8ŒÝðl,#–s6žMÌùM~‚À°Ä\ì#5„s0â:~ áw,À,fv€|!ò°0JJÄ’´rZn|Jô’XÃ+½1/Õdø˜…›Ozƒóaeý‰SFjVNffºD§ÉNGild£²­Ýfk¿¼ëÔ’Í”¾1’„P}z—Ýí{?¦ ¾i©>Ùì+»#8.øHé{°ZHÊýÄF¯(Õ—æÞcÁÉÆ¶‚žê‡-=WÐç,°ó>Æ‘àû úVV¥&o;äÎv¤Äûdç ôÜ´\ üç\CuyëW­¾˜Úž*‹“(Ã3Ö#Ö>ãÇøÛçt-Îͦ’u`rðE›ù~:wO`DG̾ò¢ÀÉxÌÒ-óBË#¬ri½¢VÛ§z?&0y¢€õõ8Vtr»><6`Ò®ûaà y2ðýƒ]ÝÓò$[KŒšBÔ,ni®ë|^€ªZ%¢‹Wv_„:SÊ›Yѧ+‡ösç“ü÷ƺ-ònè©+657HEóžò:®¯VöÖ[êÇÕÇ_¾¬iï—þ±EÙÙóö+Õò-V.Ô˜RƒN±`^¢ö'î: 6¼WÉœÖe’j¨øÛ¡ ŠËÊʆ(ÄþO”}5´ÛO IC¶Á*á ¯S#maz%ö†—˵¶òæÆ#MæNÔKÚávonÇìÊ”¼5övä®Ñ¥¯´Û™g6†°Œ)÷ žM âÀŸÚÆË¡¢‚ªü¢¢2s¡ ±ÏÛý¦oÓE$Hc“Â2VˆCkæû°Àù ,À³ìóÿJ¬\X¶ u°üX{®=úÝþ9Cï“NÐ3D'Gàû…†úû´†÷ô´µöô„µùÙKIæcR‹ÊâÜCž c&Š–ñ*^ÎAT£ÉÌP™šŸ@ÈâAµwDQÐd©ïnïíhü ½`ác¼Ri¾Vú "öªÝ´›x‚Œ”l1t²üS¼[É´ªUFÙpJ2uBÄpJÌ0·N'&r8¬0ýI¶YÈsR“ü°é‚ILªÓÙ&T%F U¦Ž¼BTa¬2’øž*˜³¥zÛ^(úÆ…¨žŠÿ›õjeÅ@11§÷þøªãÓW3úÊ{ ~hådFm•ñÔ_wìŠÛæ)‰ºjÝŽ¶!ŸÙNVtfø»®¬ò?킾ö]0ÃÊ„¤V¢“Ãs[d®©0±¢‡æ:sqÍä“Uq;í“k ÒjBr^õ#,Ÿ yÇðáBsmEY}59‰ØŽ*¥ÇðÑ@­&ØnÊtŒÓoePjüf¯ÄV}>§*E"mŽ&;Ä߸` ž¦µå”£21²V•öäç‘E¯È^‰ æT®EgRŸë‚Gã°#OeUç£R1:R^:`w} ¦+³LW}B‡¾wi¦Á…UC±v»àÅ_ÑY_×F\=<†UÀ z [ö-0³M;A¾VNÁ !1â 9o™Ìûð‰à¾þŽ}ý²/»éÅoÜðÙø îöPæF»{Ó6Š›Vx¦À;BÈ\ÏmE[|ÖE쟖‘ ì%á1Løš ðz“È'¹5Ì!ý ]LZtr Ùyª.Á)¨˜WsñÌË<[2ì±§ u7!ïnåÞ6ªÍˆLèÍ$bC,Sš_œ_×Tf+®@¬Íï%âã{ j7>~Œ=Bb~Ð8S„¼B8%½>-s†ÅsílûÖ÷ßDŸ‰ÿµê3,8x81$T”&_Í6Ó-×ڛΣÔ¦ª )O(‘“ÝÇWµ7âçÊP?b²qüâáì,ë¡3œ€Y«ž(zt‰·pµ6 öÚÉ m[BCçEI“˜¯¢[“N„±¢Û-Ñ5>‡'­“yïTªLÇÂ%A'£Í‘ˆ•Å(Ãö] yï¤aVŸ¦+ú¸4Á–d ¬aE®Ÿ¬=ryÒc÷fº­>8cï« ÁXòo[œÁ3ñðÆDÑĺ–pü†¿0+±3^¶iÞÎybìF<ƒ!|>f\!-z&` 28KVÐýG|ˆü¨Ï…ğ栅O¿‰¿û:£3³7EüT~nÚÌîñõÝS~4Pâw,ª"±!±ŠÐý—BŸÂrõLûeÛ_± E*3E,/´ë¿¶ þÝK‡ ’9'äà P°Xµ=~õ¼;¦FR&•Õ¦K“ZÓï¢èjÑÅâÂ’¢Š‚*â9 ÿÕŠf†©>–ŒÛÐbÚ+ltõÕ#Ö 4±Ý'¾¦íñĹ^Ã#€#IH±Ø.T/`#<àv«”Z…"Z®‘!_væ£M é‹¿‚ã¿«®·$¢»ß´uvÞ˜ôtõìˆ'¿³qÚªÎ}ß{HÀñ;ni·÷‡èÛwâDß…c>+ëãÂ}Éþ9³ÖZ#ÐvsxÀ>÷sO?4í¼bo¨Ö¨þÝ$h„y¤T …-Z\-·lŸ_þé³ó@!±°f8`W<îm7<¾ûœ´V6Küð¼÷ÞÇ3¢IvƒS¸FdN/WVÅ”­GëQLnDŽO®é Ù­!+'WŸ¥ÎÖ vGÜ%2¼lùÑ~»é\bœ!\ÜÊí—',YàG#<-°-î_yz]wàwl3³»]aK躚òÁTÒÊš¯XzlW:Ùßïµä¢&ü>wµµ¹îd×£g§a =Süýðï;~s.³ræbˆ-¶ÎçèŽÊOEX’2K¾3ÑW»3ÐÞÄL‹9Â[E~ñfØ›g?FÙÛ};†GxJDuÞG"z ‹±H"ò3¾Ì›l*Ñ¥…ù¯> uRÕòþåà[E·ŽɘÖBGG”9¾FQÿ¬ˆzv endstream endobj 423 0 obj <>stream 2021-01-28T15:25:58-08:00 2021-01-28T15:25:58-08:00 groff version 1.22.4 Untitled endstream endobj 2 0 obj <>endobj xref 0 424 0000000000 65535 f 0000157724 00000 n 0000193669 00000 n 0000157041 00000 n 0000143667 00000 n 0000000182 00000 n 0000002041 00000 n 0000157790 00000 n 0000166035 00000 n 0000185973 00000 n 0000165609 00000 n 0000180525 00000 n 0000165015 00000 n 0000172256 00000 n 0000164542 00000 n 0000166494 00000 n 0000157831 00000 n 0000157861 00000 n 0000143827 00000 n 0000002061 00000 n 0000004976 00000 n 0000157924 00000 n 0000157954 00000 n 0000143989 00000 n 0000004997 00000 n 0000007513 00000 n 0000158017 00000 n 0000158047 00000 n 0000144151 00000 n 0000007534 00000 n 0000009882 00000 n 0000158099 00000 n 0000158129 00000 n 0000144313 00000 n 0000009903 00000 n 0000011892 00000 n 0000158192 00000 n 0000158222 00000 n 0000144475 00000 n 0000011913 00000 n 0000013948 00000 n 0000158274 00000 n 0000158304 00000 n 0000144637 00000 n 0000013969 00000 n 0000016660 00000 n 0000158367 00000 n 0000158397 00000 n 0000144799 00000 n 0000016681 00000 n 0000018875 00000 n 0000158460 00000 n 0000158490 00000 n 0000144961 00000 n 0000018896 00000 n 0000020703 00000 n 0000158542 00000 n 0000158572 00000 n 0000145123 00000 n 0000020724 00000 n 0000023327 00000 n 0000158615 00000 n 0000158645 00000 n 0000145285 00000 n 0000023348 00000 n 0000026237 00000 n 0000158688 00000 n 0000158718 00000 n 0000145447 00000 n 0000026258 00000 n 0000028024 00000 n 0000158761 00000 n 0000158791 00000 n 0000145609 00000 n 0000028045 00000 n 0000030359 00000 n 0000158843 00000 n 0000158873 00000 n 0000145771 00000 n 0000030380 00000 n 0000032301 00000 n 0000158925 00000 n 0000158955 00000 n 0000145933 00000 n 0000032322 00000 n 0000034718 00000 n 0000159007 00000 n 0000159037 00000 n 0000146095 00000 n 0000034739 00000 n 0000037040 00000 n 0000159089 00000 n 0000159119 00000 n 0000146257 00000 n 0000037061 00000 n 0000038727 00000 n 0000159171 00000 n 0000159201 00000 n 0000146419 00000 n 0000038748 00000 n 0000041047 00000 n 0000159253 00000 n 0000159284 00000 n 0000146583 00000 n 0000041069 00000 n 0000042918 00000 n 0000159328 00000 n 0000159359 00000 n 0000146749 00000 n 0000042940 00000 n 0000044933 00000 n 0000159412 00000 n 0000159443 00000 n 0000146915 00000 n 0000044955 00000 n 0000047289 00000 n 0000159496 00000 n 0000159527 00000 n 0000147081 00000 n 0000047311 00000 n 0000049092 00000 n 0000159580 00000 n 0000159611 00000 n 0000147247 00000 n 0000049114 00000 n 0000050897 00000 n 0000159664 00000 n 0000159695 00000 n 0000147413 00000 n 0000050919 00000 n 0000052093 00000 n 0000159748 00000 n 0000159779 00000 n 0000147579 00000 n 0000052115 00000 n 0000054067 00000 n 0000159832 00000 n 0000159863 00000 n 0000147745 00000 n 0000054089 00000 n 0000055672 00000 n 0000159916 00000 n 0000159947 00000 n 0000147911 00000 n 0000055694 00000 n 0000057256 00000 n 0000160000 00000 n 0000160031 00000 n 0000148077 00000 n 0000057278 00000 n 0000058663 00000 n 0000160084 00000 n 0000160115 00000 n 0000148243 00000 n 0000058685 00000 n 0000059790 00000 n 0000160168 00000 n 0000160199 00000 n 0000148409 00000 n 0000059812 00000 n 0000060949 00000 n 0000160252 00000 n 0000160283 00000 n 0000148575 00000 n 0000060971 00000 n 0000062587 00000 n 0000160336 00000 n 0000160367 00000 n 0000148741 00000 n 0000062609 00000 n 0000064037 00000 n 0000160420 00000 n 0000160451 00000 n 0000148907 00000 n 0000064059 00000 n 0000065324 00000 n 0000160504 00000 n 0000160535 00000 n 0000149073 00000 n 0000065346 00000 n 0000066509 00000 n 0000160588 00000 n 0000160619 00000 n 0000149239 00000 n 0000066531 00000 n 0000068324 00000 n 0000160672 00000 n 0000160703 00000 n 0000149405 00000 n 0000068346 00000 n 0000069446 00000 n 0000160756 00000 n 0000160787 00000 n 0000149571 00000 n 0000069468 00000 n 0000070868 00000 n 0000160840 00000 n 0000160871 00000 n 0000149737 00000 n 0000070890 00000 n 0000072509 00000 n 0000160924 00000 n 0000160955 00000 n 0000149903 00000 n 0000072531 00000 n 0000074181 00000 n 0000161008 00000 n 0000161039 00000 n 0000150069 00000 n 0000074203 00000 n 0000075465 00000 n 0000161092 00000 n 0000161123 00000 n 0000150235 00000 n 0000075487 00000 n 0000076927 00000 n 0000161176 00000 n 0000161207 00000 n 0000150401 00000 n 0000076949 00000 n 0000078759 00000 n 0000161260 00000 n 0000161291 00000 n 0000150567 00000 n 0000078781 00000 n 0000080538 00000 n 0000161344 00000 n 0000161375 00000 n 0000150733 00000 n 0000080560 00000 n 0000081702 00000 n 0000161428 00000 n 0000161459 00000 n 0000150899 00000 n 0000081724 00000 n 0000083045 00000 n 0000161512 00000 n 0000161543 00000 n 0000151065 00000 n 0000083067 00000 n 0000084959 00000 n 0000161596 00000 n 0000161627 00000 n 0000151231 00000 n 0000084981 00000 n 0000086690 00000 n 0000161680 00000 n 0000161711 00000 n 0000151397 00000 n 0000086712 00000 n 0000088644 00000 n 0000161764 00000 n 0000161795 00000 n 0000151563 00000 n 0000088666 00000 n 0000090337 00000 n 0000161848 00000 n 0000161879 00000 n 0000151729 00000 n 0000090359 00000 n 0000091875 00000 n 0000161932 00000 n 0000161963 00000 n 0000151895 00000 n 0000091897 00000 n 0000093418 00000 n 0000162016 00000 n 0000162047 00000 n 0000152061 00000 n 0000093440 00000 n 0000095339 00000 n 0000162100 00000 n 0000162131 00000 n 0000152227 00000 n 0000095361 00000 n 0000096869 00000 n 0000162175 00000 n 0000162206 00000 n 0000152393 00000 n 0000096891 00000 n 0000098579 00000 n 0000162259 00000 n 0000162290 00000 n 0000152559 00000 n 0000098601 00000 n 0000100369 00000 n 0000162343 00000 n 0000162374 00000 n 0000152725 00000 n 0000100391 00000 n 0000102223 00000 n 0000162427 00000 n 0000162458 00000 n 0000152891 00000 n 0000102245 00000 n 0000104534 00000 n 0000162511 00000 n 0000162542 00000 n 0000153057 00000 n 0000104556 00000 n 0000106440 00000 n 0000162595 00000 n 0000162626 00000 n 0000153223 00000 n 0000106462 00000 n 0000108500 00000 n 0000162679 00000 n 0000162710 00000 n 0000153389 00000 n 0000108522 00000 n 0000109981 00000 n 0000162763 00000 n 0000162794 00000 n 0000153555 00000 n 0000110003 00000 n 0000111048 00000 n 0000162847 00000 n 0000162878 00000 n 0000153721 00000 n 0000111069 00000 n 0000112215 00000 n 0000162931 00000 n 0000162962 00000 n 0000153887 00000 n 0000112237 00000 n 0000113761 00000 n 0000163015 00000 n 0000163046 00000 n 0000154053 00000 n 0000113783 00000 n 0000115170 00000 n 0000163099 00000 n 0000163130 00000 n 0000154219 00000 n 0000115192 00000 n 0000117044 00000 n 0000163183 00000 n 0000163214 00000 n 0000154385 00000 n 0000117066 00000 n 0000118754 00000 n 0000163267 00000 n 0000163298 00000 n 0000154551 00000 n 0000118776 00000 n 0000120557 00000 n 0000163351 00000 n 0000163382 00000 n 0000154717 00000 n 0000120579 00000 n 0000122240 00000 n 0000163435 00000 n 0000163466 00000 n 0000154883 00000 n 0000122262 00000 n 0000124260 00000 n 0000163519 00000 n 0000163550 00000 n 0000155049 00000 n 0000124282 00000 n 0000126358 00000 n 0000163594 00000 n 0000163625 00000 n 0000155215 00000 n 0000126380 00000 n 0000128348 00000 n 0000163678 00000 n 0000163709 00000 n 0000155381 00000 n 0000128370 00000 n 0000130141 00000 n 0000163762 00000 n 0000163793 00000 n 0000155547 00000 n 0000130163 00000 n 0000132076 00000 n 0000163846 00000 n 0000163877 00000 n 0000155713 00000 n 0000132098 00000 n 0000133854 00000 n 0000163930 00000 n 0000163961 00000 n 0000155879 00000 n 0000133876 00000 n 0000135895 00000 n 0000164014 00000 n 0000164045 00000 n 0000156045 00000 n 0000135917 00000 n 0000137359 00000 n 0000164098 00000 n 0000164129 00000 n 0000156211 00000 n 0000137381 00000 n 0000139095 00000 n 0000164182 00000 n 0000164213 00000 n 0000156377 00000 n 0000139117 00000 n 0000140405 00000 n 0000164266 00000 n 0000164297 00000 n 0000156543 00000 n 0000140427 00000 n 0000141651 00000 n 0000164330 00000 n 0000164361 00000 n 0000156709 00000 n 0000141673 00000 n 0000142754 00000 n 0000164394 00000 n 0000164425 00000 n 0000156875 00000 n 0000142776 00000 n 0000143646 00000 n 0000164458 00000 n 0000164489 00000 n 0000166997 00000 n 0000172831 00000 n 0000180885 00000 n 0000186397 00000 n 0000165516 00000 n 0000192245 00000 n trailer << /Size 424 /Root 1 0 R /Info 2 0 R /ID [<37D9A114DD4F1FE1291D54E8B527117F><37D9A114DD4F1FE1291D54E8B527117F>] >> startxref 193823 %%EOF libdwarf-20210528/libdwarf/dwarf_fission_to_cu.c0000664000175000017500000002451113764007262016472 00000000000000/* Copyright (C) 2018-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_str_offsets.h" #include "dwarf_loc.h" #include "dwarf_rnglists.h" #define TRUE 1 #define FALSE 0 static int load_xu_loclists_into_cucontext(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, struct Dwarf_Debug_Fission_Per_CU_s*fsd, UNUSEDARG const char * xu_type, int fsd_index, UNUSEDARG Dwarf_Error *error) { Dwarf_Unsigned size = 0; Dwarf_Unsigned soff_hdroffset = 0; Dwarf_Unsigned soff_size = 0; struct Dwarf_Loclists_Context_s localcontxt; Dwarf_Loclists_Context buildhere = &localcontxt; Dwarf_Unsigned nextset = 0; int res = 0; size = fsd->pcu_size[fsd_index]; soff_hdroffset = fsd->pcu_offset[fsd_index]; soff_size = dbg->de_debug_loclists.dss_size; if (!soff_size) { return DW_DLV_NO_ENTRY; } if (soff_hdroffset >= soff_size) { /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } memset(buildhere,0,sizeof(localcontxt)); res = _dwarf_internal_read_loclists_header(dbg, 0,soff_size, dbg->de_debug_loclists.dss_data, dbg->de_debug_loclists.dss_data +soff_size, soff_hdroffset, buildhere, &nextset,error); if (res != DW_DLV_OK) { return res; } cu_context->cc_loclists_base_present = TRUE; cu_context->cc_loclists_base_contr_size = size; cu_context->cc_loclists_base = buildhere->lc_offsets_off_in_sect; return DW_DLV_OK; } /* ASSERT: cc_str_offsets_base_present FALSE ASSERT: cc_str_offsets_header_length_present FALSE If .debug_cu_index or .debug_tu_index is present it might help us find the offset for this CU's .debug_str_offsets. */ static int load_xu_str_offsets_into_cucontext(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, struct Dwarf_Debug_Fission_Per_CU_s*fsd, UNUSEDARG const char * xu_type, int fsd_index, UNUSEDARG Dwarf_Error *error) { Dwarf_Small *soff_secptr = 0; Dwarf_Small *soff_hdrptr = 0; Dwarf_Unsigned soff_hdroffset = 0; Dwarf_Unsigned soff_size = 0; Dwarf_Small *soff_eptr = 0; int res = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets, error); if (res != DW_DLV_OK) { return res; } soff_hdroffset = fsd->pcu_offset[fsd_index]; soff_secptr = dbg->de_debug_str_offsets.dss_data; soff_size = dbg->de_debug_str_offsets.dss_size; soff_eptr = soff_secptr + soff_size; soff_hdrptr = soff_secptr + soff_hdroffset; if (soff_hdroffset >= soff_size) { /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } { Dwarf_Unsigned length = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; Dwarf_Unsigned header_length = 0; res = _dwarf_read_str_offsets_header(dbg, soff_hdrptr, soff_size - soff_hdroffset, soff_eptr, cu_context, &length,&offset_size, &extension_size,&version,&padding, &header_length, error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } res = DW_DLV_NO_ENTRY; return res; } cu_context->cc_str_offsets_base_present = TRUE; cu_context->cc_str_offsets_header_length_present = TRUE; cu_context->cc_str_offsets_header_offset = soff_hdroffset; cu_context->cc_str_offsets_base = soff_hdroffset + header_length; cu_context->cc_str_offsets_header_length = header_length; cu_context->cc_str_offsets_offset_size = offset_size; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int load_xu_debug_macro_into_cucontext(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, struct Dwarf_Debug_Fission_Per_CU_s*fsd, UNUSEDARG const char * xu_type, int fsd_index, UNUSEDARG Dwarf_Error *error) { Dwarf_Unsigned size = 0; Dwarf_Unsigned soff_hdroffset = 0; Dwarf_Unsigned soff_size = 0; int res = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_macro, error); if (res != DW_DLV_OK) { return res; } size = fsd->pcu_size[fsd_index]; soff_hdroffset = fsd->pcu_offset[fsd_index]; soff_size = dbg->de_debug_macro.dss_size; if (!soff_size) { return DW_DLV_NO_ENTRY; } if (soff_hdroffset >= soff_size) { /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } /* Presently assuming that DW_AT_macros and the fission entry both indicate the beginning of a .debug_macro sectiom macro header. (not true for str_offsets or for loclists!) */ cu_context->cc_macro_base_present = TRUE; cu_context->cc_macro_base_contr_size = size; cu_context->cc_macro_base = soff_hdroffset; /* FIXME cc_macro_header_length_present? */ return DW_DLV_OK; } static int load_xu_rnglists_into_cucontext(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, struct Dwarf_Debug_Fission_Per_CU_s*fsd, UNUSEDARG const char * xu_type, int fsd_index, UNUSEDARG Dwarf_Error *error) { Dwarf_Unsigned size = 0; Dwarf_Unsigned soff_hdroffset = 0; Dwarf_Unsigned soff_size = 0; struct Dwarf_Rnglists_Context_s builddata; Dwarf_Rnglists_Context buildhere = &builddata; Dwarf_Unsigned nextoffset = 0; int res = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_rnglists, error); if (res != DW_DLV_OK) { return res; } size = fsd->pcu_size[fsd_index]; soff_hdroffset = fsd->pcu_offset[fsd_index]; soff_size = dbg->de_debug_rnglists.dss_size; if (!soff_size) { return DW_DLV_NO_ENTRY; } if (soff_hdroffset >= soff_size) { /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } memset(buildhere,0,sizeof(builddata)); res = _dwarf_internal_read_rnglists_header(dbg, 0,soff_size, dbg->de_debug_rnglists.dss_data, dbg->de_debug_rnglists.dss_data+soff_size, soff_hdroffset,buildhere, &nextoffset,error); if (res != DW_DLV_OK) { return res; } cu_context->cc_rnglists_base = buildhere->rc_offsets_off_in_sect; cu_context->cc_rnglists_base_present = TRUE; cu_context->cc_rnglists_base_contr_size = size; /* FIXME cc_rnglists_header_length_present? */ return DW_DLV_OK; } static const char *keylist[2] = { "cu", "tu" }; /* ASSERT: The context has a signature. _dwarf_make_CU_Context() calls finish_up_cu_context_from_cudie() which calls us here. Then, _dwarf_make_CU_Context() calls _dwarf_merge_all_base_attrs_of_cu_die() if there is a tied (executable) object known. */ int _dwarf_find_all_offsets_via_fission(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Error *error) { struct Dwarf_Debug_Fission_Per_CU_s fission_data; struct Dwarf_Debug_Fission_Per_CU_s*fsd = 0; int si = 0; int smax = 2; int fdres = 0; int res = 0; fsd = &fission_data; for (si = 0; si < smax ; ++si) { int sec_index = 0; memset(&fission_data,0,sizeof(fission_data)); fdres = dwarf_get_debugfission_for_key(dbg, &cu_context->cc_signature, keylist[si], fsd,error); if (fdres == DW_DLV_NO_ENTRY) { continue; } if (fdres == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; continue; } for (sec_index = 1; sec_index < DW_FISSION_SECT_COUNT; ++sec_index) { if (!fsd->pcu_size[sec_index]) { continue; } res = DW_DLV_OK; switch(sec_index) { /* these handled elsewhere, such as by _dwarf_get_dwp_extra_offset() _dwarf_get_fission_addition_die() case DW_SECT_INFO: case DW_SECT_ABBREV: case DW_SECT_LINE: */ case DW_SECT_LOCLISTS: res = load_xu_loclists_into_cucontext(dbg, cu_context, fsd,keylist[si],sec_index,error); break; case DW_SECT_STR_OFFSETS: res = load_xu_str_offsets_into_cucontext(dbg, cu_context, fsd,keylist[si],sec_index,error); break; case DW_SECT_MACRO: res = load_xu_debug_macro_into_cucontext(dbg, cu_context, fsd,keylist[si],sec_index,error); break; case DW_SECT_RNGLISTS: res = load_xu_rnglists_into_cucontext(dbg, cu_context, fsd,keylist[si],sec_index,error); break; default: res = DW_DLV_OK; break; } if (res == DW_DLV_ERROR) { return res; } } } return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_elf_access.c0000664000175000017500000011220414004651163015704 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved. Portions Copyright 2009-2019 David Anderson. All rights reserved. Portions Copyright 2009-2010 Novell Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This file is ONLY used for libelf and with libelf For */ #include "config.h" #ifdef DWARF_WITH_LIBELF #include #ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_UNISTD_H #include /* for close */ #endif /* HAVE_UNISTD_H */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #define FALSE 0 #define TRUE 1 #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_elf_access.h" #include "dwarf_elf_rel_detector.h" /* Include the ELF definitions depending on system headers if any. */ #include "dwarf_elf_defines.h" #ifdef HAVE_ELF64_GETEHDR extern Elf64_Ehdr *elf64_getehdr(Elf *); #endif #ifdef HAVE_ELF64_GETSHDR extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); #endif #ifdef WORDS_BIGENDIAN #define READ_UNALIGNED_SAFE(dbg,dest, source, length) \ do { \ Dwarf_Unsigned _ltmp = 0; \ dbg->de_copy_word( (((char *)(&_ltmp)) + \ sizeof(_ltmp) - length),source, length); \ dest = _ltmp; \ } while (0) #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((char *)source) +srclength-len_out, \ len_out) ; \ } #else /* LITTLE ENDIAN */ #define READ_UNALIGNED_SAFE(dbg,dest, source, srclength) \ do { \ Dwarf_Unsigned _ltmp = 0; \ dbg->de_copy_word( (char *)(&_ltmp), \ source, srclength) ; \ dest = _ltmp; \ } while (0) #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((char *)source) , \ len_out) ; \ } #endif /* *-ENDIAN */ /* ident[0] == 'E' for elf when using libelf. ident[1] = 1 */ typedef struct { char ident[8]; const char * path; int is_64bit; Dwarf_Small length_size; Dwarf_Small pointer_size; Dwarf_Unsigned section_count; Dwarf_Endianness endianness; Dwarf_Small machine; char libdwarf_owns_elf; dwarf_elf_handle elf; Elf32_Ehdr *ehdr32; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *ehdr64; #endif /* Elf symtab and its strtab. Initialized at first call to do relocations, the actual data is in the Dwarf_Debug struct, not allocated locally here. */ struct Dwarf_Section_s *symtab; struct Dwarf_Section_s *strtab; } dwarf_elf_object_access_internals_t; /* Using this for rel and rela. For Rel, r_addend is left zero and not used. */ struct Dwarf_Elf_Rela { Dwarf_Unsigned r_offset; /*Dwarf_Unsigned r_info; */ Dwarf_Unsigned r_type; Dwarf_Unsigned r_symidx; Dwarf_Unsigned r_addend; /* if is_rela is non-zero r_addend is meaningless */ char r_is_rela; }; static int dwarf_elf_object_access_load_section(void* obj_in, Dwarf_Half section_index, Dwarf_Small** section_data, int* error); /* dwarf_elf_object_access_internals_init() On error, set *error with libdwarf error code. */ static int dwarf_elf_object_access_internals_init(void* obj_in, dwarf_elf_handle elf, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; char *ehdr_ident = 0; Dwarf_Half machine = 0; obj->elf = elf; if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { *error = DW_DLE_ELF_GETIDENT_ERROR; return DW_DLV_ERROR; } obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); if (ehdr_ident[EI_DATA] == ELFDATA2LSB){ obj->endianness = DW_OBJECT_LSB; } else if (ehdr_ident[EI_DATA] == ELFDATA2MSB){ obj->endianness = DW_OBJECT_MSB; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETEHDR obj->ehdr64 = elf64_getehdr(elf); if (obj->ehdr64 == NULL) { *error = DW_DLE_ELF_GETEHDR_ERROR; return DW_DLV_ERROR; } obj->section_count = obj->ehdr64->e_shnum; machine = obj->ehdr64->e_machine; obj->machine = machine; #else *error = DW_DLE_NO_ELF64_SUPPORT; return DW_DLV_ERROR; #endif } else { obj->ehdr32 = elf32_getehdr(elf); if (obj->ehdr32 == NULL) { *error = DW_DLE_ELF_GETEHDR_ERROR; return DW_DLV_ERROR; } obj->section_count = obj->ehdr32->e_shnum; machine = obj->ehdr32->e_machine; obj->machine = machine; } /* The following length_size is Not Too Significant. Only used one calculation, and an approximate one at that. */ obj->length_size = obj->is_64bit ? 8 : 4; obj->pointer_size = obj->is_64bit ? 8 : 4; obj->ident[0] = 'E'; obj->ident[1] = 1; #ifdef _WIN32 if (obj->is_64bit && machine == EM_PPC64) { /* The SNC compiler generates the EM_PPC64 machine type for the PS3 platform, but is a 32 bits pointer size in user mode. */ obj->pointer_size = 4; } #endif /* _WIN32 */ if (obj->is_64bit && machine != EM_MIPS) { /* MIPS/IRIX makes pointer size and length size 8 for -64. Other platforms make length 4 always. */ /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus tools, and the dwarfv2.1 64bit extension setting. This is not the same as the size-of-an-offset, which is 4 in 32bit dwarf and 8 in 64bit dwarf. */ obj->length_size = 4; } return DW_DLV_OK; } /* dwarf_elf_object_access_get_byte_order */ static Dwarf_Endianness dwarf_elf_object_access_get_byte_order(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->endianness; } /* dwarf_elf_object_access_get_section_count() */ static Dwarf_Unsigned dwarf_elf_object_access_get_section_count(void * obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->section_count; } static int _dwarf_get_elf_flags_func( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; Elf32_Shdr *shdr32 = 0; #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr *shdr64 = 0; #endif Elf_Scn *scn = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETSHDR shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also section 'sh_type' and sh_info' fields, so the caller can use it for additional tasks that require that info. */ *flags_out = shdr64->sh_flags; *addralign_out = shdr64->sh_addralign; return DW_DLV_OK; #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif /* HAVE_ELF64_GETSHDR */ } if ((shdr32 = elf32_getshdr(scn)) == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also the section type, so the caller can use it for additional tasks that require to know the section type. */ *flags_out = shdr32->sh_flags; *addralign_out = shdr32->sh_addralign; return DW_DLV_OK; } /* dwarf_elf_object_access_get_section() If writing a function vaguely like this for a non-elf object, be sure that when section-index is passed in as zero that you set the fields in *ret_scn_doas to reflect an empty section with an empty string as the section name. Adjust your section indexes of your non-elf-reading-code for all the necessary functions in Dwarf_Obj_Access_Methods_s accordingly. Should have gotten sh_flags, sh_addralign too. But Dwarf_Obj_Access_Section is publicly defined so changing it is quite painful for everyone. */ static int dwarf_elf_object_access_get_section_info( void* obj_in, Dwarf_Half section_index, Dwarf_Obj_Access_Section* ret_scn_doas, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; Elf32_Shdr *shdr32 = 0; #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr *shdr64 = 0; #endif Elf_Scn *scn = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETSHDR shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also section 'sh_type' and sh_info' fields, so the caller can use it for additional tasks that require that info. */ ret_scn_doas->type = shdr64->sh_type; ret_scn_doas->size = shdr64->sh_size; ret_scn_doas->addr = shdr64->sh_addr; ret_scn_doas->link = shdr64->sh_link; ret_scn_doas->info = shdr64->sh_info; ret_scn_doas->entrysize = shdr64->sh_entsize; ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx, shdr64->sh_name); if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif /* HAVE_ELF64_GETSHDR */ } if ((shdr32 = elf32_getshdr(scn)) == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also the section type, so the caller can use it for additional tasks that require to know the section type. */ ret_scn_doas->type = shdr32->sh_type; ret_scn_doas->size = shdr32->sh_size; ret_scn_doas->addr = shdr32->sh_addr; ret_scn_doas->link = shdr32->sh_link; ret_scn_doas->info = shdr32->sh_info; ret_scn_doas->entrysize = shdr32->sh_entsize; ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx, shdr32->sh_name); if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } /* dwarf_elf_object_access_get_length_size */ static Dwarf_Small dwarf_elf_object_access_get_length_size(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->length_size; } /* dwarf_elf_object_access_get_pointer_size */ static Dwarf_Small dwarf_elf_object_access_get_pointer_size(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->pointer_size; } #define MATCH_REL_SEC(i_,s_,r_) \ if (i_ == s_.dss_index) { \ *r_ = &s_; \ return DW_DLV_OK; \ } static int find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, struct Dwarf_Section_s **relocatablesec, int *error) { MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_ranges, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_funcnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_typenames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_varnames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_weaknames, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_rnglists, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loclists, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets, relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_addr,relocatablesec); /* dbg-> de_debug_tu_index,reloctablesec); */ /* dbg-> de_debug_cu_index,reloctablesec); */ /* dbg-> de_debug_gdbindex,reloctablesec); */ /* dbg-> de_debug_str,syms); */ /* de_elf_symtab,syms); */ /* de_elf_strtab,syms); */ *error = DW_DLE_RELOC_SECTION_MISMATCH; return DW_DLV_ERROR; } #undef MATCH_REL_SEC static void get_rela_elf32(Dwarf_Small *data, unsigned int i, UNUSEDARG int endianness, UNUSEDARG int machine, struct Dwarf_Elf_Rela *relap) { Elf32_Rela *relp = 0; relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ relap->r_type = ELF32_R_TYPE(relp->r_info); relap->r_symidx = ELF32_R_SYM(relp->r_info); relap->r_is_rela = TRUE; relap->r_addend = relp->r_addend; } static void get_rel_elf32(Dwarf_Small *data, unsigned int i, UNUSEDARG int endianness, UNUSEDARG int machine, struct Dwarf_Elf_Rela *relap) { Elf32_Rel *relp = 0; relp = (Elf32_Rel*)(data + (i * sizeof(Elf32_Rel))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ relap->r_type = ELF32_R_TYPE(relp->r_info); relap->r_symidx = ELF32_R_SYM(relp->r_info); relap->r_is_rela = FALSE; relap->r_addend = 0; } static void get_rela_elf64(Dwarf_Small *data, unsigned int i, int endianness, int machine, struct Dwarf_Elf_Rela *relap) { #ifdef HAVE_ELF64_RELA Elf64_Rela * relp = 0; relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff) #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff) if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){ /* This is really weird. Treat this very specially. The Elf64 LE MIPS object used for testing (that has rela) wants the values as sym ssym type3 type2 type, treating each value as independent value. But libelf xlate treats it as something else so we fudge here. It is unclear how to precisely characterize where these relocations were used. SGI MIPS on IRIX never used .rela relocations. The BE 64bit elf MIPS test object with rela uses traditional elf relocation layouts, not this special case. */ /* We ignore the special TYPE2 and TYPE3, they should be value R_MIPS_NONE in rela. */ relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info); relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info); #undef MIPS64SYM #undef MIPS64TYPE } else { relap->r_type = ELF64_R_TYPE(relp->r_info); relap->r_symidx = ELF64_R_SYM(relp->r_info); } relap->r_addend = relp->r_addend; relap->r_is_rela = TRUE; #endif } static void get_rel_elf64(Dwarf_Small *data, unsigned int i, int endianness, int machine, struct Dwarf_Elf_Rela *relap) { #ifdef HAVE_ELF64_RELA Elf64_Rel * relp = 0; relp = (Elf64_Rel*)(data + (i * sizeof(Elf64_Rel))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff) #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff) if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){ /* This is really weird. Treat this very specially. The Elf64 LE MIPS object used for testing (that has rela) wants the values as sym ssym type3 type2 type, treating each value as independent value. But libelf xlate treats it as something else so we fudge here. It is unclear how to precisely characterize where these relocations were used. SGI MIPS on IRIX never used .rela relocations. The BE 64bit elf MIPS test object with rela uses traditional elf relocation layouts, not this special case. */ /* We ignore the special TYPE2 and TYPE3, they should be value R_MIPS_NONE in rela. */ relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info); relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info); #undef MIPS64SYM #undef MIPS64TYPE } else { relap->r_type = ELF64_R_TYPE(relp->r_info); relap->r_symidx = ELF64_R_SYM(relp->r_info); } relap->r_addend = 0; relap->r_is_rela = FALSE; #endif } static void get_relocations_array(Dwarf_Bool is_64bit, int endianness, int machine, int is_rela, Dwarf_Small *data, unsigned int num_relocations, struct Dwarf_Elf_Rela *relap) { unsigned int i = 0; void (*get_relocations)(Dwarf_Small *data, unsigned int i, int endianness, int machine, struct Dwarf_Elf_Rela *relap); /* Handle 32/64 bit issue */ if (is_64bit) { if ( is_rela) { get_relocations = get_rela_elf64; } else { get_relocations = get_rel_elf64; } } else { if ( is_rela) { get_relocations = get_rela_elf32; } else { get_relocations = get_rel_elf32; } } for (i=0; i < num_relocations; i++) { get_relocations(data, i,endianness,machine, &(relap[i])); } } static int get_relocation_entries(Dwarf_Bool is_64bit, int endianness, int machine, Dwarf_Small *relocation_section, Dwarf_Unsigned relocation_section_size, Dwarf_Unsigned relocation_section_entrysize, struct Dwarf_Elf_Rela **relas, unsigned int *nrelas, int is_rela, int *error) { unsigned int relocation_size = 0; if (is_64bit) { #ifdef HAVE_ELF64_RELA relocation_size = is_rela? sizeof(Elf64_Rela):sizeof(Elf64_Rel); #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif } else { relocation_size = is_rela? sizeof(Elf32_Rela):sizeof(Elf32_Rel); } if (relocation_size != relocation_section_entrysize) { /* Means our struct definition does not match the real object. */ *error = DW_DLE_RELOC_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } if (relocation_section == NULL) { *error = DW_DLE_RELOC_SECTION_PTR_NULL; return DW_DLV_ERROR; } if ((relocation_section_size != 0)) { size_t bytescount = 0; if (relocation_section_size%relocation_size) { *error = DW_DLE_RELOC_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } *nrelas = relocation_section_size/relocation_size; bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela); *relas = malloc(bytescount); if (!*relas) { *error = DW_DLE_MAF; return DW_DLV_ERROR; } memset(*relas,0,bytescount); get_relocations_array(is_64bit,endianness,machine, is_rela, relocation_section, *nrelas, *relas); } return DW_DLV_OK; } /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. The caller may decide to ignore the errors or report them. */ static int update_entry(Dwarf_Debug dbg, Dwarf_Bool is_64bit, UNUSEDARG Dwarf_Endianness endianess, UNUSEDARG Dwarf_Half machine, struct Dwarf_Elf_Rela *rela, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, Dwarf_Small *symtab_section_data, Dwarf_Unsigned symtab_section_size, Dwarf_Unsigned symtab_section_entrysize, int is_rela, int *error) { unsigned int type = 0; unsigned int sym_idx = 0; #ifdef HAVE_ELF64_SYM Elf64_Sym sym_buf; Elf64_Sym *sym = 0; #else Elf32_Sym sym_buf; Elf32_Sym *sym = 0; #endif Elf32_Sym *sym32 = 0; Dwarf_Unsigned offset = 0; Dwarf_Signed addend = 0; Dwarf_Unsigned reloc_size = 0; Dwarf_Unsigned symtab_entry_count = 0; if (symtab_section_entrysize == 0) { *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO; return DW_DLV_ERROR; } symtab_entry_count = symtab_section_size/symtab_section_entrysize; /* Dwarf_Elf_Rela dereferencing */ offset = rela->r_offset; addend = rela->r_addend; type = rela->r_type; sym_idx = rela->r_symidx; if (sym_idx >= symtab_entry_count) { *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; return DW_DLV_ERROR; } if (offset >= target_section_size) { /* If offset really big, any add will overflow. So lets stop early if offset is corrupt. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if (is_64bit) { #ifdef HAVE_ELF64_SYM sym = &((Elf64_Sym*)symtab_section_data)[sym_idx]; #else /* We cannot handle this object without 64_SYMs. */ *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; #endif } else { sym32 = &((Elf32_Sym*)symtab_section_data)[sym_idx]; /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at an Elf64_Sym local variable (sym_buf) to allow us to use the same pointer (sym) for both 32-bit and 64-bit instances. */ sym = &sym_buf; sym->st_name = sym32->st_name; sym->st_info = sym32->st_info; sym->st_other = sym32->st_other; sym->st_shndx = sym32->st_shndx; sym->st_value = sym32->st_value; sym->st_size = sym32->st_size; } /* Determine relocation size */ if (_dwarf_is_32bit_abs_reloc(type, machine)) { reloc_size = 4; } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { reloc_size = 8; } else { *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; } if ( (offset + reloc_size) < offset) { /* Another check for overflow. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if ( (offset + reloc_size) > target_section_size) { *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } { /* .rel. (addend is zero) or .rela */ Dwarf_Small *targ = target_section+offset; Dwarf_Unsigned presentval = 0; Dwarf_Unsigned outval = 0; /* See also: READ_UNALIGNED_SAFE in dwarf_elfread.c */ if (!is_rela) { READ_UNALIGNED_SAFE(dbg,presentval, targ,reloc_size); } /* There is no addend in .rel. Normally presentval is correct and st_value will be zero. But a few compilers have presentval zero and st_value set. */ outval = presentval + sym->st_value + addend ; WRITE_UNALIGNED_LOCAL(dbg,targ, &outval,sizeof(outval),reloc_size); } return DW_DLV_OK; } /* Somewhat arbitrarily, we attempt to apply all the relocations we can and still notify the caller of at least one error if we found any errors. */ static int apply_rela_entries(Dwarf_Debug dbg, Dwarf_Bool is_64bit, Dwarf_Endianness endianess, Dwarf_Half machine, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, Dwarf_Small *symtab_section, Dwarf_Unsigned symtab_section_size, Dwarf_Unsigned symtab_section_entrysize, int is_rela, struct Dwarf_Elf_Rela *relas, unsigned int nrelas, int *error) { int return_res = DW_DLV_OK; if ((target_section != NULL) && (relas != NULL)) { unsigned int i; if (symtab_section_entrysize == 0) { *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO; return DW_DLV_ERROR; } if (symtab_section_size%symtab_section_entrysize) { *error = DW_DLE_SYMTAB_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } for (i = 0; i < nrelas; i++) { int res = update_entry(dbg, is_64bit, endianess, machine, &(relas)[i], target_section, target_section_size, symtab_section, symtab_section_size, symtab_section_entrysize, is_rela, error); if (res != DW_DLV_OK) { return_res = res; } } } return return_res; } static int loop_through_relocations( Dwarf_Debug dbg, dwarf_elf_object_access_internals_t* obj, struct Dwarf_Section_s *relocatablesec, int *error) { Dwarf_Small *target_section = 0; Dwarf_Small *symtab_section = obj->symtab->dss_data; Dwarf_Unsigned symtab_section_entrysize = obj->symtab->dss_entrysize; Dwarf_Unsigned symtab_section_size = obj->symtab->dss_size; Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data; Dwarf_Unsigned relocation_section_size = relocatablesec->dss_reloc_size; Dwarf_Unsigned relocation_section_entrysize = relocatablesec->dss_reloc_entrysize; int ret = DW_DLV_ERROR; struct Dwarf_Elf_Rela *relas = 0; unsigned int nrelas = 0; Dwarf_Small *mspace = 0; int is_rela = relocatablesec->dss_is_rela; ret = get_relocation_entries(obj->is_64bit, obj->endianness, obj->machine, relocation_section, relocation_section_size, relocation_section_entrysize, &relas, &nrelas, is_rela,error); if (ret != DW_DLV_OK) { free(relas); return ret; } if (!relocatablesec->dss_data_was_malloc) { /* Some systems read Elf in read-only memory via mmap or the like. So the only safe thing is to copy the current data into malloc space and refer to the malloc space instead of the space returned by the elf library */ mspace = malloc(relocatablesec->dss_size); if (!mspace) { free(relas); *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL; return DW_DLV_ERROR; } memcpy(mspace,relocatablesec->dss_data, relocatablesec->dss_size); relocatablesec->dss_data = mspace; relocatablesec->dss_data_was_malloc = TRUE; } target_section = relocatablesec->dss_data; ret = apply_rela_entries( dbg, obj->is_64bit, obj->endianness, obj->machine, target_section, relocatablesec->dss_size, symtab_section, symtab_section_size, symtab_section_entrysize, is_rela, relas, nrelas, error); free(relas); return ret; } /* Find the section data in dbg and find all the relevant sections. Then do relocations. */ static int dwarf_elf_object_relocate_a_section(void* obj_in, Dwarf_Half section_index, Dwarf_Debug dbg, int* error) { int res = DW_DLV_ERROR; dwarf_elf_object_access_internals_t*obj = 0; struct Dwarf_Section_s * relocatablesec = 0; if (section_index == 0) { return DW_DLV_NO_ENTRY; } obj = (dwarf_elf_object_access_internals_t*)obj_in; /* The section to relocate must already be loaded into memory. */ res = find_section_to_relocate(dbg, section_index, &relocatablesec,error); if (res != DW_DLV_OK) { return res; } /* Sun and possibly others do not always set sh_link in .debug_* sections. So we cannot do full consistency checks. */ if (relocatablesec->dss_reloc_index == 0 ) { /* Something is wrong. */ *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; return DW_DLV_ERROR; } /* Now load the relocations themselves. */ res = dwarf_elf_object_access_load_section(obj_in, relocatablesec->dss_reloc_index, &relocatablesec->dss_reloc_data, error); if (res != DW_DLV_OK) { return res; } /* Now get the symtab. */ if (!obj->symtab) { obj->symtab = &dbg->de_elf_symtab; obj->strtab = &dbg->de_elf_strtab; } if (obj->symtab->dss_index != relocatablesec->dss_reloc_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; return DW_DLV_ERROR; } if (obj->strtab->dss_index != obj->symtab->dss_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX; return DW_DLV_ERROR; } if (!obj->symtab->dss_data) { /* Now load the symtab */ res = dwarf_elf_object_access_load_section(obj_in, obj->symtab->dss_index, &obj->symtab->dss_data, error); if (res != DW_DLV_OK) { return res; } } if (!obj->strtab->dss_data) { /* Now load the strtab */ res = dwarf_elf_object_access_load_section(obj_in, obj->strtab->dss_index, &obj->strtab->dss_data,error); if (res != DW_DLV_OK){ return res; } } /* We have all the data we need in memory. */ res = loop_through_relocations(dbg,obj,relocatablesec,error); return res; } /* dwarf_elf_object_access_load_section() We are only asked to load sections that libdwarf really needs. It would be much better if a 'user data pointer' were passed through these interfaces so one part of libdwarf could pass through to this. Or even just if a Dwarf_Debug were passed in. Sigh. */ static int dwarf_elf_object_access_load_section(void* obj_in, Dwarf_Half section_index, Dwarf_Small** section_data, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; if (section_index == 0) { return DW_DLV_NO_ENTRY; } { Elf_Scn *scn = 0; Elf_Data *data = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { /* The section_index does not exist or obj->elf is NULL. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } /* When using libelf as a producer, section data may be stored in multiple buffers. In libdwarf however, we only use libelf as a consumer (there is a dwarf producer API, but it doesn't use libelf). Because of this, this single call to elf_getdata will retrieve the entire section in a single contiguous buffer. */ data = elf_getdata(scn, NULL); if (data == NULL) { /* Most likely means that the Elf section header is damaged/corrupt and the data is impossible to read into memory. The size specified in the Elf section is too large to allocate memory for so the data could not be loaded. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (!data->d_buf) { /* If NULL it means 'the section has no data' according to libelf documentation. No DWARF-related section should ever have 'no data'. Happens if a section type is SHT_NOBITS and no section libdwarf wants to look at should be SHT_NOBITS. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } *section_data = data->d_buf; } return DW_DLV_OK; } /* dwarf_elf_access method table for use with libelf. See also the methods table in dwarf_elfread.c for non-libelf. */ static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods = { dwarf_elf_object_access_get_section_info, dwarf_elf_object_access_get_byte_order, dwarf_elf_object_access_get_length_size, dwarf_elf_object_access_get_pointer_size, dwarf_elf_object_access_get_section_count, dwarf_elf_object_access_load_section, dwarf_elf_object_relocate_a_section }; /* Interface for the ELF object file implementation. On error this should set *err with the libdwarf error code. */ int dwarf_elf_object_access_init(dwarf_elf_handle elf, int libdwarf_owns_elf, Dwarf_Obj_Access_Interface** ret_obj, int *err) { int res = 0; dwarf_elf_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); if (!internals) { *err = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = dwarf_elf_object_access_internals_init(internals, elf, err); if (res != DW_DLV_OK){ /* *err is already set. */ free(internals); return DW_DLV_ERROR; } internals->libdwarf_owns_elf = libdwarf_owns_elf; intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ *err = DW_DLE_ALLOC_FAIL; free(internals); return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &dwarf_elf_object_access_methods; /* An access method hidden from non-elf. Needed to handle new-ish SHF_COMPRESSED flag in elf. */ _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func; *ret_obj = intfc; return DW_DLV_OK; } /* Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init. */ void dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj) { if (!obj) { return; } if (obj->object) { dwarf_elf_object_access_internals_t *internals = (dwarf_elf_object_access_internals_t *)obj->object; if (internals->libdwarf_owns_elf){ /* Happens with dwarf_init_path(), dwarf_init(), or dwarf_init_b() interfaces. */ elf_end(internals->elf); } } free(obj->object); free(obj); } /* This function returns the Elf * pointer associated with a Dwarf_Debug. This function only makes sense if ELF is implied and there actually is an Elf * pointer available. */ int dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, Dwarf_Error * error) { struct Dwarf_Obj_Access_Interface_s * obj = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } obj = dbg->de_obj_file; if (obj && obj->object) { dwarf_elf_object_access_internals_t *internals = 0; char typeletter = *(char *)(obj->object); if (typeletter != 'E') { /* Not libelf Elf */ return DW_DLV_NO_ENTRY; } internals = (dwarf_elf_object_access_internals_t*)obj->object; if (internals->elf == NULL) { _dwarf_error(dbg, error, DW_DLE_FNO); return DW_DLV_ERROR; } *elf = internals->elf; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_FNO); return DW_DLV_ERROR; } #else int dwarf_elf_access_dummy_var_avoid_warn = 0; #endif /* DWARF_WITH_LIBELF */ libdwarf-20210528/libdwarf/dwarf_weaks.c0000664000175000017500000000660713764007262014747 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_weaks.h" #include "dwarf_global.h" int dwarf_get_weaks(Dwarf_Debug dbg, Dwarf_Weak ** weaks, Dwarf_Signed * ret_weak_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_weaknames, error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_weaknames.dss_size) { return DW_DLV_NO_ENTRY; } return _dwarf_internal_get_pubnames_like_data(dbg, ".debug_weaknames", dbg->de_debug_weaknames.dss_data, dbg->de_debug_weaknames.dss_size, (Dwarf_Global **) weaks, /* Type punning for sections with identical format. */ ret_weak_count, error, DW_DLA_WEAK_CONTEXT, DW_DLA_WEAK, DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD, DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_weaks_dealloc(Dwarf_Debug dbg, Dwarf_Weak * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count); return; } int dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; if (weak == NULL) { _dwarf_error(NULL, error, DW_DLE_WEAK_NULL); return DW_DLV_ERROR; } *ret_name = (char *) (weak->gl_name); return DW_DLV_OK; } int dwarf_weak_die_offset(Dwarf_Weak weak_in, Dwarf_Off * weak_off, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_die_offset(weak, weak_off, error); } int dwarf_weak_cu_offset(Dwarf_Weak weak_in, Dwarf_Off * weak_off, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_cu_offset(weak, weak_off, error); } int dwarf_weak_name_offsets(Dwarf_Weak weak_in, char **weak_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_name_offsets(weak, weak_name, die_offset, cu_offset, error); } libdwarf-20210528/libdwarf/dwarf_elfstructs.h0000664000175000017500000001126113644370703016030 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Typed in from the SystemV Application Binary Interface but using char arrays instead of variables as for reading we don't need the struct members to be variables. This simplifies configure. https://www.uclibc.org/docs/elf-64-gen.pdf used as source of Elf64 fields. It is expected code including this will have included an official (for various definitions needed) before including this. But that is not strictly necessary given other headers. The structs were all officially defined so files could be mapped in. Fields are arranged so there will not be gaps and we need not deal with alignment-gaps. */ #ifndef DW_ELFSTRUCTS_H #define DW_ELFSTRUCTS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef EI_NIDENT #define EI_NIDENT 16 #endif #ifndef TYP #define TYP(n,l) char n[l] #endif typedef struct { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); TYP(e_entry,4); TYP(e_phoff,4); TYP(e_shoff,4); TYP(e_flags,4); TYP(e_ehsize,2); TYP(e_phentsize,2); TYP(e_phnum,2); TYP(e_shentsize,2); TYP(e_shnum,2); TYP(e_shstrndx,2); } dw_elf32_ehdr; typedef struct { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); TYP(e_entry,8); TYP(e_phoff,8); TYP(e_shoff,8); TYP(e_flags,4); TYP(e_ehsize,2); TYP(e_phentsize,2); TYP(e_phnum,2); TYP(e_shentsize,2); TYP(e_shnum,2); TYP(e_shstrndx,2); } dw_elf64_ehdr; typedef struct { TYP(p_type,4); TYP(p_offset,4); TYP(p_vaddr,4); TYP(p_paddr,4); TYP(p_filesz,4); TYP(p_memsz,4); TYP(p_flags,4); TYP(p_align,4); } dw_elf32_phdr; typedef struct { TYP(p_type,4); TYP(p_flags,4); TYP(p_offset,8); TYP(p_vaddr,8); TYP(p_paddr,8); TYP(p_filesz,8); TYP(p_memsz,8); TYP(p_align,8); } dw_elf64_phdr; typedef struct { TYP(sh_name,4); TYP(sh_type,4); TYP(sh_flags,4); TYP(sh_addr,4); TYP(sh_offset,4); TYP(sh_size,4); TYP(sh_link,4); TYP(sh_info,4); TYP(sh_addralign,4); TYP(sh_entsize,4); }dw_elf32_shdr; typedef struct { TYP(sh_name,4); TYP(sh_type,4); TYP(sh_flags,8); TYP(sh_addr,8); TYP(sh_offset,8); TYP(sh_size,8); TYP(sh_link,4); TYP(sh_info,4); TYP(sh_addralign,8); TYP(sh_entsize,8); }dw_elf64_shdr; typedef struct { TYP(r_offset,4); TYP(r_info,4); } dw_elf32_rel; typedef struct { TYP(r_offset,8); TYP(r_info,8); } dw_elf64_rel; typedef struct { TYP(r_offset,4); TYP(r_info,4); TYP(r_addend,4); /* signed */ } dw_elf32_rela; typedef struct { TYP(r_offset,8); TYP(r_info,8); TYP(r_addend,8); /* signed */ } dw_elf64_rela; typedef struct { TYP(st_name,4); TYP(st_value,4); TYP(st_size,4); unsigned char st_info[1]; unsigned char st_other[1]; TYP(st_shndx,2); } dw_elf32_sym; typedef struct { TYP(st_name,4); unsigned char st_info[1]; unsigned char st_other[1]; TYP(st_shndx,2); TYP(st_value,8); TYP(st_size,8); } dw_elf64_sym; typedef struct { TYP(d_tag,4); /* signed */ TYP(d_val,4); /* Union in original */ } dw_elf32_dyn; typedef struct { TYP(d_tag,8); /* signed */ TYP(d_val,8); /* Union in original */ } dw_elf64_dyn; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DW_ELFSTRUCTS_H */ libdwarf-20210528/libdwarf/crc32.c0000664000175000017500000001216714004665675013372 00000000000000/* Copyright 2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "libdwarfdefs.h" #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" /* For the function prototype */ #define uint32_t unsigned int /* Table computed by David Anderson with Mark Adler's table builder logic on October 20,2020 with pattern from polynomial (0xedb88320) */ static const uint32_t crc32_table[256] = { 0x00000000,0x77073096,0xee0e612c,0x990951ba, 0x076dc419,0x706af48f,0xe963a535,0x9e6495a3, 0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988, 0x09b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91, 0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de, 0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7, 0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec, 0x14015c4f,0x63066cd9,0xfa0f3d63,0x8d080df5, 0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172, 0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b, 0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940, 0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59, 0x26d930ac,0x51de003a,0xc8d75180,0xbfd06116, 0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f, 0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924, 0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d, 0x76dc4190,0x01db7106,0x98d220bc,0xefd5102a, 0x71b18589,0x06b6b51f,0x9fbfe4a5,0xe8b8d433, 0x7807c9a2,0x0f00f934,0x9609a88e,0xe10e9818, 0x7f6a0dbb,0x086d3d2d,0x91646c97,0xe6635c01, 0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e, 0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457, 0x65b0d9c6,0x12b7e950,0x8bbeb8ea,0xfcb9887c, 0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65, 0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2, 0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb, 0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0, 0x44042d73,0x33031de5,0xaa0a4c5f,0xdd0d7cc9, 0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086, 0x5768b525,0x206f85b3,0xb966d409,0xce61e49f, 0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4, 0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad, 0xedb88320,0x9abfb3b6,0x03b6e20c,0x74b1d29a, 0xead54739,0x9dd277af,0x04db2615,0x73dc1683, 0xe3630b12,0x94643b84,0x0d6d6a3e,0x7a6a5aa8, 0xe40ecf0b,0x9309ff9d,0x0a00ae27,0x7d079eb1, 0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe, 0xf762575d,0x806567cb,0x196c3671,0x6e6b06e7, 0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc, 0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5, 0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252, 0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b, 0xd80d2bda,0xaf0a1b4c,0x36034af6,0x41047a60, 0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79, 0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236, 0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f, 0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04, 0xc2d7ffa7,0xb5d0cf31,0x2cd99e8b,0x5bdeae1d, 0x9b64c2b0,0xec63f226,0x756aa39c,0x026d930a, 0x9c0906a9,0xeb0e363f,0x72076785,0x05005713, 0x95bf4a82,0xe2b87a14,0x7bb12bae,0x0cb61b38, 0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0x0bdbdf21, 0x86d3d2d4,0xf1d4e242,0x68ddb3f8,0x1fda836e, 0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777, 0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c, 0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45, 0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2, 0xa7672661,0xd06016f7,0x4969474d,0x3e6e77db, 0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0, 0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9, 0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6, 0xbad03605,0xcdd70693,0x54de5729,0x23d967bf, 0xb3667a2e,0xc4614ab8,0x5d681b02,0x2a6f2b94, 0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d }; /* The following is essentially identical to every crc32 anyone uses up to trivial differences in starting conditions. The algorithm appears on https://en.wikipedia.org/wiki/Cyclic_redundancy_check in a simple logic loop (written in no actual language but English) and the following is a translation into C. Just like every other crc calculation. */ unsigned int _dwarf_crc32 (unsigned int crc, const unsigned char *buf, size_t len) { const unsigned char *end = 0; crc = ~crc; for (end = buf + len; buf < end; ++buf) crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); return ~crc; } libdwarf-20210528/libdwarf/dwarf_elf_access.h0000644000175000017500000000305713763460440015723 00000000000000#ifndef _DWARF_ELF_PORT_H #define _DWARF_ELF_PORT_H /* Copyright (C) 2008-2011 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* ELF (usually libelf) object access for the generic object file interface */ int dwarf_elf_object_access_init(dwarf_elf_handle elf , int libdwarf_owns_elf, Dwarf_Obj_Access_Interface** ret_obj, int *err ); void dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj ); /* End ELF object access for the generic object file interface */ #endif libdwarf-20210528/libdwarf/dwarf_reloc_mips.h0000664000175000017500000001105514012266121015753 00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_MIPS_H #define DWARF_RELOC_MIPS_H /* Definitions for MIPS */ #define DWARF_RELOC_MIPS /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for MIPS */ #define R_MIPS_NONE 0 #define R_MIPS_16 1 #define R_MIPS_32 2 #define R_MIPS_ADD R_MIPS_32 #define R_MIPS_REL 3 #define R_MIPS_REL32 R_MIPS_REL #define R_MIPS_26 4 #define R_MIPS_HI16 5 #define R_MIPS_LO16 6 #define R_MIPS_GPREL 7 #define R_MIPS_GPREL16 R_MIPS_GPREL #define R_MIPS_LITERAL 8 #define R_MIPS_GOT 9 #define R_MIPS_GOT16 R_MIPS_GOT #define R_MIPS_PC16 10 #define R_MIPS_CALL 11 #define R_MIPS_CALL16 R_MIPS_CALL #define R_MIPS_GPREL32 12 #define R_MIPS_UNUSED1 13 #define R_MIPS_UNUSED2 14 #define R_MIPS_UNUSED3 15 #define R_MIPS_SHIFT5 16 #define R_MIPS_SHIFT6 17 #define R_MIPS_64 18 #define R_MIPS_GOT_DISP 19 #define R_MIPS_GOT_PAGE 20 #define R_MIPS_GOT_OFST 21 #define R_MIPS_GOT_HI16 22 #define R_MIPS_GOT_LO16 23 #define R_MIPS_SUB 24 #define R_MIPS_INSERT_A 25 #define R_MIPS_INSERT_B 26 #define R_MIPS_DELETE 27 #define R_MIPS_HIGHER 28 #define R_MIPS_HIGHEST 29 #define R_MIPS_CALL_HI16 30 #define R_MIPS_CALL_LO16 31 #define R_MIPS_SCN_DISP 32 #define R_MIPS_REL16 33 #define R_MIPS_ADD_IMMEDIATE 34 /* Keep this the last entry. */ #define R_MIPS_NUM 35 #endif /* _WIN32 */ /* Relocation types for MIPS */ static const char *reloc_type_names_MIPS[] = { "R_MIPS_NONE", /* 00 */ "R_MIPS_16", /* 01 */ "R_MIPS_32", /* 02 */ "R_MIPS_REL32", /* 03 */ "R_MIPS_26", /* 04 */ "R_MIPS_HI16", /* 05 */ "R_MIPS_LO16", /* 06 */ "R_MIPS_GPREL16", /* 07 */ "R_MIPS_LITERAL", /* 08 */ "R_MIPS_GOT16", /* 09 */ "R_MIPS_PC16", /* 10 */ "R_MIPS_CALL16", /* 11 */ "R_MIPS_GPREL32", /* 12 */ "R_MIPS_UNUSED1", /* 13 */ "R_MIPS_UNUSED2", /* 14 */ "R_MIPS_UNUSED3", /* 15 */ "R_MIPS_SHIFT5", /* 16 */ "R_MIPS_SHIFT6", /* 17 */ "R_MIPS_64", /* 18 */ "R_MIPS_GOT_DISP", /* 19 */ "R_MIPS_GOT_PAGE", /* 20 */ "R_MIPS_GOT_OFST", /* 21 */ "R_MIPS_GOT_HI16", /* 22 */ "R_MIPS_GOT_LO16", /* 23 */ "R_MIPS_SUB", /* 24 */ "R_MIPS_INSERT_A", /* 25 */ "R_MIPS_INSERT_B", /* 26 */ "R_MIPS_DELETE", /* 27 */ "R_MIPS_HIGHER", /* 28 */ "R_MIPS_HIGHEST", /* 29 */ "R_MIPS_CALL_HI16", /* 30 */ "R_MIPS_CALL_LO16", /* 31 */ "R_MIPS_SCN_DISP", /* 32 */ "R_MIPS_REL16", /* 33 */ "R_MIPS_ADD_IMMEDIATE", /* 34 */ }; #endif /* DWARF_RELOC_MIPS_H */ libdwarf-20210528/libdwarf/dwarf_debug_sup.c0000664000175000017500000001303013764007262015576 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This provides access to the DWARF5 .debug_sup section. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_global.h" #include "dwarfstring.h" #define FALSE 0 #define TRUE 1 static void get_sup_fields(Dwarf_Debug dbg, struct Dwarf_Section_s **sec_out) { if (!dbg) { return; } *sec_out = &dbg->de_debug_sup; } static int load_sup(Dwarf_Debug dbg, Dwarf_Error *error) { struct Dwarf_Section_s * sec = 0; int res; get_sup_fields(dbg,&sec); res = _dwarf_load_section(dbg,sec,error); return res; } /* New for DWARF5 in July 2020. */ int dwarf_get_debug_sup(Dwarf_Debug dbg, Dwarf_Half * version_out, Dwarf_Small * is_supplementary_out, char ** filename_out, Dwarf_Unsigned * checksum_len_out, Dwarf_Small ** checksum_out, Dwarf_Error * error) { Dwarf_Unsigned version = 0; Dwarf_Small is_supp = 0; char *filename = 0; Dwarf_Unsigned checksum_len = 0; Dwarf_Small *checksum_ptr = 0; int res = 0; Dwarf_Small *data = 0; Dwarf_Small *enddata = 0; Dwarf_Unsigned size = 0; res = load_sup(dbg,error); if (res != DW_DLV_OK) { return res; } data = dbg->de_debug_sup.dss_data; size = dbg->de_debug_sup.dss_size; if (dbg->de_filesize && size > dbg->de_filesize) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_SUP_ERROR: " ".debug_sup section size 0x%x bigger than file " "size! Corrupt", size); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_SUP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } enddata = data + size; res = _dwarf_read_unaligned_ck_wrapper(dbg, &version, data,DWARF_HALF_SIZE, enddata,error); data+= DWARF_HALF_SIZE; if ((data+4) > enddata) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_SUP_ERROR: " " .debug_sup section size 0x%x" " too small to be correct! Corrupt", size); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_SUP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } is_supp = (Dwarf_Small)*data; ++data; res = _dwarf_check_string_valid(dbg,data,data,enddata, DW_DLE_DEBUG_SUP_STRING_ERROR,error); if (res != DW_DLV_OK) { return res; } filename = (char *)data; data += strlen((char *)data) +1; res = _dwarf_leb128_uword_wrapper(dbg, &data,enddata, &checksum_len,error); if (res != DW_DLV_OK) { return res; } if (checksum_len >= size) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_SUP_ERROR: " " .debug_sup checksum length 0x%x" " too large to be correct! Corrupt", checksum_len); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_SUP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } if ((data +checksum_len) > enddata) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_DEBUG_SUP_ERROR: " " .debug_sup checksum (length 0x%x) " " runs off the end of the section, Corrupt data", checksum_len); _dwarf_error_string(dbg,error, DW_DLE_DEBUG_SUP_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } checksum_ptr = data; if (version_out) { *version_out = version; } if (is_supp) { *is_supplementary_out = is_supp; } if (filename_out) { *filename_out = filename; } if (checksum_len_out) { *checksum_len_out = checksum_len; } if (checksum_out) { *checksum_out = checksum_ptr; } return DW_DLV_OK; } libdwarf-20210528/libdwarf/dwarf_types.h0000644000175000017500000000226013743575426015004 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Type_Context_s *Dwarf_Type_Context; /* type never completed see dwarf_global.h */ libdwarf-20210528/libdwarf/dwarf_harmless.c0000664000175000017500000001657113764007262015454 00000000000000/* Copyright (C) 2010-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This implements _dwarf_insert_harmless_error and related helper functions for recording compiler errors that need not make the input unusable. Applications can use dwarf_get_harmless_error_list to find (and possibly print) a warning about such errors. The initial error reported here is DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE which was a bug in a specific compiler. It is a fixed length circular list to constrain the space used for errors. The assumption is that these errors are exceedingly rare, and indicate a broken compiler (the one that produced the object getting the error(s)). dh_maxcount is recorded internally as 1 greater than requested. Hiding the fact we always leave one slot unused (at least). So a user request for N slots really gives the user N usable slots. */ #include "config.h" #include "dwarf_incl.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_frame.h" #include "dwarf_harmless.h" /* The pointers returned here through errmsg_ptrs_array become invalidated by any call to libdwarf. Any call. */ int dwarf_get_harmless_error_list(Dwarf_Debug dbg, unsigned count, const char ** errmsg_ptrs_array, unsigned * errs_count) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; if (!dhp->dh_errors) { dhp->dh_errs_count = 0; return DW_DLV_NO_ENTRY; } if (dhp->dh_errs_count == 0) { return DW_DLV_NO_ENTRY; } if (errs_count) { *errs_count = dhp->dh_errs_count; } if (count) { /* NULL terminate the array of pointers */ --count; errmsg_ptrs_array[count] = 0; if (dhp->dh_next_to_use != dhp->dh_first) { unsigned i = 0; unsigned cur = dhp->dh_first; for (i = 0; cur != dhp->dh_next_to_use; ++i) { if (i >= count ) { /* All output spaces are used. */ break; } errmsg_ptrs_array[i] = dhp->dh_errors[cur]; cur = (cur +1) % dhp->dh_maxcount; } errmsg_ptrs_array[i] = 0; } } dhp->dh_next_to_use = 0; dhp->dh_first = 0; dhp->dh_errs_count = 0; return DW_DLV_OK; } /* strncpy does not null-terminate, this does it. */ static void safe_strncpy(char *targ, char *src, unsigned spaceavail) { unsigned goodcount = spaceavail-1; if (spaceavail < 1) { return; /* impossible */ } strncpy(targ,src,goodcount); targ[goodcount] = 0; } /* Insertion made public is only for testing the harmless error code, it is not necessarily useful for libdwarf client code aside from code testing libdwarf. */ void dwarf_insert_harmless_error(Dwarf_Debug dbg, char *newerror) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; unsigned next = 0; unsigned cur = dhp->dh_next_to_use; char *msgspace; if (!dhp->dh_errors) { dhp->dh_errs_count++; return; } msgspace = dhp->dh_errors[cur]; safe_strncpy(msgspace, newerror, DW_HARMLESS_ERROR_MSG_STRING_SIZE); next = (cur+1) % dhp->dh_maxcount; dhp->dh_errs_count++; dhp->dh_next_to_use = next; if (dhp->dh_next_to_use == dhp->dh_first) { /* Array is full set full invariant. */ dhp->dh_first = (dhp->dh_first+1) % dhp->dh_maxcount; } } /* The size of the circular list of strings may be set and reset as desired. Returns the previous size of the list. If the list is shortened excess error entries are simply dropped. If the reallocation fails the list size is left unchanged. Do not make this a long list! Remember the maxcount we record is 1 > the user count, so we adjust it so it looks like the user count. */ unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, unsigned maxcount ) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; unsigned prevcount = dhp->dh_maxcount; if (maxcount != 0) { ++maxcount; if (maxcount != dhp->dh_maxcount) { /* Assign transfers 'ownership' of the malloc areas to oldarray. */ struct Dwarf_Harmless_s oldarray = *dhp; /* Do not double increment the max, the init() func increments it too. */ dwarf_harmless_init(dhp,maxcount-1); if (oldarray.dh_next_to_use != oldarray.dh_first) { unsigned i = 0; for (i = oldarray.dh_first; i != oldarray.dh_next_to_use; i = (i+1)%oldarray.dh_maxcount) { dwarf_insert_harmless_error(dbg, oldarray.dh_errors[i]); } if (oldarray.dh_errs_count > dhp->dh_errs_count) { dhp->dh_errs_count = oldarray.dh_errs_count; } } dwarf_harmless_cleanout(&oldarray); } } return prevcount-1; } /* Only callable from within libdwarf (as a practical matter) */ void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size) { unsigned i = 0; memset(dhp,0,sizeof(*dhp)); dhp->dh_maxcount = size +1; dhp->dh_errors = (char **)malloc(sizeof(char *)*dhp->dh_maxcount); if (!dhp->dh_errors) { dhp->dh_maxcount = 0; return; } for (i = 0; i < dhp->dh_maxcount; ++i) { char *newstr = (char *)malloc(DW_HARMLESS_ERROR_MSG_STRING_SIZE); dhp->dh_errors[i] = newstr; if (!newstr) { dhp->dh_maxcount = 0; /* Let it leak, the leak is a constrained amount. */ dhp->dh_errors = 0; return; } /* We make the string content well-defined by an initial NUL byte, but this is not really necessary. */ newstr[0] = 0; } } void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp) { unsigned i = 0; if (!dhp->dh_errors) { return; } for (i = 0; i < dhp->dh_maxcount; ++i) { free(dhp->dh_errors[i]); dhp->dh_errors[i] = 0; } free(dhp->dh_errors); dhp->dh_errors = 0; dhp->dh_maxcount = 0; } libdwarf-20210528/libdwarf/dwarf_debuglink.c0000664000175000017500000006542414004665541015601 00000000000000/* Copyright (c) 2019-2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_MALLOC_H #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDDEF_H #include /* ptrdiff_t */ #endif /* HAVE_STDDEF_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_UNISTD_H #include /* getcwd */ #endif /* HAVE_UNISTD_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_debuglink.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #define MINBUFLEN 1000 #define TRUE 1 #define FALSE 0 #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #if _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int extract_buildid(Dwarf_Debug dbg, struct Dwarf_Section_s * pbuildid, unsigned *type_returned, char **owner_name_returned, unsigned char **build_id_returned, unsigned *build_id_length_returned, Dwarf_Error *error); struct joins_s { dwarfstring js_dirname; dwarfstring js_basenamesimple; dwarfstring js_basesimpledebug; dwarfstring js_binname; dwarfstring js_cwd; dwarfstring js_originalfullpath; dwarfstring js_linkstring; dwarfstring js_tmp2; dwarfstring js_tmp3; dwarfstring js_buildid; dwarfstring js_buildid_filename; }; static void construct_js(struct joins_s * js) { memset(js,0,sizeof(struct joins_s)); dwarfstring_constructor(&js->js_dirname); dwarfstring_constructor(&js->js_basenamesimple); dwarfstring_constructor(&js->js_basesimpledebug); dwarfstring_constructor(&js->js_cwd); dwarfstring_constructor(&js->js_originalfullpath); dwarfstring_constructor(&js->js_linkstring); dwarfstring_constructor(&js->js_tmp2); dwarfstring_constructor(&js->js_tmp3); dwarfstring_constructor(&js->js_buildid); dwarfstring_constructor(&js->js_buildid_filename); } static void destruct_js(struct joins_s * js) { dwarfstring_destructor(&js->js_dirname); dwarfstring_destructor(&js->js_basenamesimple); dwarfstring_destructor(&js->js_basesimpledebug); dwarfstring_destructor(&js->js_cwd); dwarfstring_destructor(&js->js_originalfullpath); dwarfstring_destructor(&js->js_linkstring); dwarfstring_destructor(&js->js_tmp2); dwarfstring_destructor(&js->js_tmp3); dwarfstring_destructor(&js->js_buildid); dwarfstring_destructor(&js->js_buildid_filename); } static char joinchar = '/'; static char* joinstr = "/"; #if defined (HAVE_WINDOWS_PATH) static char joincharw = '\\'; /* Large enough it is unlikely dwarfstring will ever do a malloc here, paths usually < 100 characters. */ static char winbuf[200]; static void transformtoposix(dwarfstring * out, char *in) { char *cp = in; for ( ; *cp ; ++cp) { if ( *cp == joincharw ) { dwarfstring_append_length(out,joinstr,1); } else { dwarfstring_append_length(out,cp,1); } } } #endif /* HAVE_WINDOWS_PATH */ /* ASSERT: the target chars already have the transformtoposix() done. */ int _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input) { char *inputs = dwarfstring_string(input); char *targ = dwarfstring_string(target); size_t targlen = 0; #if defined (HAVE_WINDOWS_PATH) dwarfstring winput; dwarfstring_constructor_static(&winput,winbuf,sizeof(winbuf)); transformtoposix(&winput,inputs); targlen = dwarfstring_strlen(target); inputs = dwarfstring_string(&winput); if (!targlen) { dwarfstring_append(target,inputs); return DW_DLV_OK; } #else /* !HAVE_WINDOWS_PATH */ targlen = dwarfstring_strlen(target); #endif /* HAVE_WINDOWS_PATH */ if (!targlen) { dwarfstring_append(target,inputs); return DW_DLV_OK; } targ = dwarfstring_string(target); if (targ[targlen-1] != joinchar) { if (*inputs != joinchar) { dwarfstring_append(target,joinstr); dwarfstring_append(target,inputs); } else { dwarfstring_append(target,inputs); } } else { if (*inputs != joinchar) { dwarfstring_append(target,inputs); } else { dwarfstring_append(target,inputs+1); } } #if defined (HAVE_WINDOWS_PATH) dwarfstring_destructor(&winput); #endif /* HAVE_WINDOWS_PATH */ return DW_DLV_OK; } /* ASSERT: the last character in s is not a / */ static size_t mydirlen(char *s) { char *cp = 0; char *lastjoinchar = 0; size_t count =0; for (cp = s ; *cp ; ++cp,++count) { if (*cp == joinchar) { lastjoinchar = cp; } } if (lastjoinchar) { /* ptrdiff_t is generated but not named */ Dwarf_Unsigned sizetoendjoin = (lastjoinchar >= s)?(lastjoinchar-s):0xffffffff; /* count the last join as mydirlen. */ if (sizetoendjoin == 0xffffffff) { /* impossible. */ return 0; } return sizetoendjoin; } return 0; } struct dwarfstring_list_s { dwarfstring dl_string; struct dwarfstring_list_s *dl_next; }; static void dwarfstring_list_constructor(struct dwarfstring_list_s *l) { dwarfstring_constructor(&l->dl_string); l->dl_next = 0; } static int dwarfstring_list_add_new(struct dwarfstring_list_s * base_entry, struct dwarfstring_list_s *prev, dwarfstring * input, struct dwarfstring_list_s ** new_out, int *errcode) { struct dwarfstring_list_s *next = 0; if (prev) { next = ( struct dwarfstring_list_s *) malloc(sizeof(struct dwarfstring_list_s)); if (!next) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } dwarfstring_list_constructor(next); } else { next = base_entry; } dwarfstring_append(&next->dl_string, dwarfstring_string(input)); if (prev) { prev->dl_next = next; } *new_out = next; return DW_DLV_OK; } /* destructs passed in entry (does not free it) and all those on the dl_next list (those are freed). */ static void dwarfstring_list_destructor(struct dwarfstring_list_s *l) { struct dwarfstring_list_s *curl = l; struct dwarfstring_list_s *nextl = l; nextl = curl->dl_next; dwarfstring_destructor(&curl->dl_string); curl->dl_next = 0; curl = nextl; for ( ; curl ; curl = nextl) { nextl = curl->dl_next; dwarfstring_destructor(&curl->dl_string); curl->dl_next = 0; free(curl); } } static void prepare_linked_name(dwarfstring *out, dwarfstring *dirname, dwarfstring *extradir, dwarfstring *linkname) { dwarfstring_append(out, dwarfstring_string(dirname)); if (extradir) { _dwarf_pathjoinl(out,extradir); } _dwarf_pathjoinl(out,linkname); } static void build_buildid_filename(dwarfstring *target, unsigned buildid_length, unsigned char *buildid) { dwarfstring tmp; unsigned bu = 0; unsigned char *cp = 0; dwarfstring_constructor(&tmp); dwarfstring_append(&tmp,".build-id"); dwarfstring_append(&tmp,joinstr); cp = buildid; for (bu = 0; bu < buildid_length; ++bu ,++cp) { dwarfstring_append_printf_u(&tmp, "%02x",*cp); if (bu == 0) { dwarfstring_append(&tmp,"/"); } } _dwarf_pathjoinl(target,&tmp); dwarfstring_append(target,".debug"); dwarfstring_destructor(&tmp); return; } #if 0 static void dump_bytes(const char *msg,unsigned char * start, unsigned len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* If the compiler or the builder of the object file being read has made a mistake it is possible for a constructed name to match the original file path, yet we do not want to add that to the search path. */ static int duplicatedpath(dwarfstring* l, dwarfstring*r) { if (strcmp(dwarfstring_string(l), dwarfstring_string(r))) { return FALSE; } /* Oops. somebody made a mistake */ return TRUE; } /* New September 2019. Access to the GNU section named .gnu_debuglink See https://sourceware.org/gdb/onlinedocs/ gdb/Separate-Debug-Files.html The default global path was set to /usr/lib/debug by set_global_paths_init() called at libdwarf object init time. So there is always the default global path present. */ int _dwarf_construct_linkedto_path( char **global_prefixes_in, unsigned length_global_prefixes_in, char *pathname_in, char *link_string_in, /* from debug link */ dwarfstring *link_string_fullpath_out, UNUSEDARG unsigned char *crc_in, /* from debug_link, 4 bytes */ unsigned char *buildid, /* from gnu buildid */ unsigned buildid_length, /* from gnu buildid */ char ***paths_out, unsigned *paths_out_length, int *errcode) { char * depath = pathname_in; int res = 0; struct joins_s joind; size_t dirnamelen = 0; struct dwarfstring_list_s base_dwlist; struct dwarfstring_list_s *last_entry = 0; unsigned global_prefix_number = 0; dwarfstring_list_constructor(&base_dwlist); construct_js(&joind); dirnamelen = mydirlen(depath); if (dirnamelen) { /* Original dirname, before cwd (if needed) */ dwarfstring_append_length(&joind.js_tmp2, depath,dirnamelen); } if (depath[0] != joinchar) { /* Meaning a/b or b, not /a/b or /b , so we apply cwd */ char buffer[2000]; unsigned buflen= sizeof(buffer); char *wdret = 0; buffer[0] = 0; wdret = getcwd(buffer,buflen); if (!wdret) { printf("getcwd() issue. Do nothing. " " line %d %s\n",__LINE__,__FILE__); dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } dwarfstring_append(&joind.js_cwd,buffer); dwarfstring_append(&joind.js_dirname,buffer); _dwarf_pathjoinl(&joind.js_dirname,&joind.js_tmp2); buffer[0] = 0; } else {/* else leave js_cwd empty */ dwarfstring_append(&joind.js_dirname, dwarfstring_string(&joind.js_tmp2)); } /* Creating a real basename. No slashes. */ dwarfstring_append(&joind.js_basenamesimple, depath+dirnamelen); dwarfstring_append(&joind.js_basesimpledebug, dwarfstring_string(&joind.js_basenamesimple)); dwarfstring_append(&joind.js_basesimpledebug,".debug"); build_buildid_filename(&joind.js_buildid_filename, buildid_length, buildid); dwarfstring_reset(&joind.js_tmp2); /* Now js_dirname / js_basenamesimple are reflecting a full path */ /* saves the full path to the original executable */ dwarfstring_append(&joind.js_originalfullpath, dwarfstring_string(&joind.js_dirname)); _dwarf_pathjoinl(&joind.js_originalfullpath, &joind.js_basenamesimple); /* js_originalfullpath is a true full path to the object we started with as input. */ /* First, do the build-id method if it applies at all */ for (global_prefix_number = 0; buildid_length && (global_prefix_number < length_global_prefixes_in); ++global_prefix_number) { char * prefix = 0; struct dwarfstring_list_s *now_last = 0; prefix = global_prefixes_in[global_prefix_number]; dwarfstring_reset(&joind.js_buildid); dwarfstring_append(&joind.js_buildid,prefix); _dwarf_pathjoinl(&joind.js_buildid, &joind.js_buildid_filename); res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_buildid, &now_last,errcode); if (res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } /* end loop on global prefix numbers */ /* end of the build-id name-finding. */ /* Now for the debug link method of finding debug files. */ if (link_string_in) { /* First try dir of executable */ struct dwarfstring_list_s *now_last = 0; dwarfstring_append(&joind.js_linkstring, link_string_in); dwarfstring_reset(&joind.js_tmp3); dwarfstring_reset(&joind.js_tmp2); prepare_linked_name(&joind.js_tmp3, &joind.js_dirname, 0,&joind.js_linkstring); dwarfstring_append(link_string_fullpath_out, dwarfstring_string(&joind.js_tmp3)); if (!duplicatedpath(&joind.js_originalfullpath, &joind.js_tmp3)) { res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp3, &now_last,errcode); if (res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } dwarfstring_reset(&joind.js_tmp2); dwarfstring_reset(&joind.js_tmp3); dwarfstring_append(&joind.js_tmp3,".debug"); prepare_linked_name(&joind.js_tmp2, &joind.js_dirname, &joind.js_tmp3,&joind.js_linkstring); if (! duplicatedpath(&joind.js_originalfullpath, &joind.js_tmp2)) { res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp2, &now_last,errcode); if (res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } /* Now look in the global locations. */ for (global_prefix_number = 0; global_prefix_number < length_global_prefixes_in; ++global_prefix_number) { char * prefix = global_prefixes_in[global_prefix_number]; dwarfstring_reset(&joind.js_tmp2); dwarfstring_reset(&joind.js_tmp3); dwarfstring_append(&joind.js_tmp2, prefix); prepare_linked_name(&joind.js_tmp3, &joind.js_tmp2, &joind.js_dirname, &joind.js_linkstring); if (!duplicatedpath(&joind.js_originalfullpath, &joind.js_tmp3)) { res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp3, &now_last,errcode); if (res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } } } /* Now malloc space for the pointer array and the strings they point at so a simple free by our caller will clean up everything. Copy the data from base_dwlist to the new area. */ { struct dwarfstring_list_s *cur = 0; char **resultfullstring = 0; unsigned long count = 0; unsigned long pointerarraysize = 0; unsigned long sumstringlengths = 0; unsigned long totalareasize = 0; unsigned long setptrindex = 0; unsigned long setstrindex = 0; cur = &base_dwlist; for ( ; cur ; cur = cur->dl_next) { ++count; pointerarraysize += sizeof(void *); sumstringlengths += dwarfstring_strlen(&cur->dl_string) +1; } /* Make a final null pointer in the pointer array. */ pointerarraysize += sizeof(void *); totalareasize = pointerarraysize + sumstringlengths +8; resultfullstring = (char **)malloc(totalareasize); setstrindex = pointerarraysize; if (!resultfullstring) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(resultfullstring,0,totalareasize); cur = &base_dwlist; for ( ; cur ; cur = cur->dl_next,++setptrindex) { char **iptr = (char **)((char *)resultfullstring + setptrindex*sizeof(void *)); char *sptr = (char*)resultfullstring + setstrindex; strcpy(sptr,dwarfstring_string(&cur->dl_string)); setstrindex += dwarfstring_strlen(&cur->dl_string)+1; *iptr = sptr; } *paths_out = resultfullstring; *paths_out_length = count; } dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return DW_DLV_OK; } static int extract_debuglink(Dwarf_Debug dbg, struct Dwarf_Section_s * pdebuglink, char ** name_returned, /* static storage, do not free */ unsigned char ** crc_returned, /* 32bit crc , do not free */ Dwarf_Error *error) { Dwarf_Small *ptr = 0; Dwarf_Small *endptr = 0; unsigned namelen = 0; unsigned m = 0; unsigned incr = 0; Dwarf_Small *crcptr = 0; int res = DW_DLV_ERROR; Dwarf_Unsigned secsize = 0; if (!pdebuglink->dss_data) { res = _dwarf_load_section(dbg, pdebuglink,error); if (res != DW_DLV_OK) { return res; } } secsize = pdebuglink->dss_size; ptr = pdebuglink->dss_data; endptr = ptr + secsize; res = _dwarf_check_string_valid(dbg,ptr, ptr, endptr, DW_DLE_FORM_STRING_BAD_STRING, error); if ( res != DW_DLV_OK) { return res; } namelen = (unsigned)strlen((const char*)ptr); m = (namelen+1) %4; if (m) { incr = 4 - m; } crcptr = (unsigned char *)ptr +namelen +1 +incr; if ((crcptr +4) != (unsigned char*)endptr) { _dwarf_error(dbg,error,DW_DLE_CORRUPT_GNU_DEBUGLINK); return DW_DLV_ERROR; } *name_returned = (char *)ptr; *crc_returned = crcptr; return DW_DLV_OK; } /* The definition of .note.gnu.buildid contents (also used for other GNU .note.gnu. sections too. */ struct buildid_s { char bu_ownernamesize[4]; char bu_buildidsize[4]; char bu_type[4]; char bu_owner[1]; }; static int extract_buildid(Dwarf_Debug dbg, struct Dwarf_Section_s * pbuildid, unsigned * type_returned, char **owner_name_returned, unsigned char **build_id_returned, unsigned * build_id_length_returned, Dwarf_Error *error) { Dwarf_Small * ptr = 0; Dwarf_Small * endptr = 0; int res = DW_DLV_ERROR; struct buildid_s *bu = 0; Dwarf_Unsigned namesize = 0; Dwarf_Unsigned descrsize = 0; Dwarf_Unsigned type = 0; Dwarf_Unsigned finalsize; Dwarf_Unsigned secsize = 0; if (!pbuildid->dss_data) { res = _dwarf_load_section(dbg, pbuildid,error); if (res != DW_DLV_OK) { return res; } } secsize = pbuildid->dss_size; ptr = pbuildid->dss_data; if (secsize < sizeof(struct buildid_s)) { _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID); return DW_DLV_ERROR; } endptr = ptr + secsize; /* We hold gh_content till all is closed as we return pointers into it if all goes well. */ bu = (struct buildid_s *)ptr; ASNAR(dbg->de_copy_word,namesize, bu->bu_ownernamesize); ASNAR(dbg->de_copy_word,descrsize,bu->bu_buildidsize); ASNAR(dbg->de_copy_word,type, bu->bu_type); if (descrsize != 20) { _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID); return DW_DLV_ERROR; } res = _dwarf_check_string_valid(dbg, (Dwarf_Small *)&bu->bu_owner[0], (Dwarf_Small *)&bu->bu_owner[0], endptr, DW_DLE_CORRUPT_GNU_DEBUGID_STRING, error); if ( res != DW_DLV_OK) { return res; } if ((strlen(bu->bu_owner) +1) != namesize) { _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_STRING); return res; } finalsize = sizeof(struct buildid_s)-1 + namesize + descrsize; if (finalsize > secsize) { _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_SIZE); return DW_DLV_ERROR; } *type_returned = type; *owner_name_returned = &bu->bu_owner[0]; *build_id_length_returned = descrsize; *build_id_returned = (unsigned char *)ptr + sizeof(struct buildid_s)-1 + namesize; return DW_DLV_OK; } /* Caller frees space returned by debuglink_fillpath_returned and The following return pointers into the dbg itself and are only valid while that dbg is open. debuglink_path_returned. crc_returned, buildid_owner_name_returned, buildid_returned, */ int dwarf_gnu_debuglink(Dwarf_Debug dbg, char ** debuglink_path_returned, /* do not free*/ unsigned char ** crc_returned, char ** debuglink_fullpath_returned, /* caller frees */ unsigned * debuglink_fullpath_length_returned, unsigned * buildid_type_returned , char ** buildid_owner_name_returned, unsigned char ** buildid_returned, unsigned * buildid_length_returned, char *** paths_returned, unsigned * paths_count_returned, Dwarf_Error* error) { dwarfstring debuglink_fullpath; int linkres = DW_DLV_ERROR; int res = DW_DLV_ERROR; char * pathname = 0; int buildidres = 0; int errcode = 0; struct Dwarf_Section_s * pdebuglink = 0; struct Dwarf_Section_s * pbuildid = 0; if (!dbg) { _dwarf_error(dbg,error,DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (dbg->de_gnu_debuglink.dss_size) { pdebuglink = &dbg->de_gnu_debuglink; } if (dbg->de_note_gnu_buildid.dss_size) { pbuildid = &dbg->de_note_gnu_buildid; } if (!pdebuglink && !pbuildid) { return DW_DLV_NO_ENTRY; } if (pdebuglink) { linkres = extract_debuglink(dbg, pdebuglink, debuglink_path_returned, crc_returned, error); if (linkres == DW_DLV_ERROR) { return linkres; } } if (pbuildid) { buildidres = extract_buildid(dbg, pbuildid, buildid_type_returned, buildid_owner_name_returned, buildid_returned, buildid_length_returned, error); if (buildidres == DW_DLV_ERROR) { return buildidres; } } dwarfstring_constructor(&debuglink_fullpath); pathname = (char *)dbg->de_path; if (pathname && paths_returned) { res = _dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, pathname, *debuglink_path_returned, &debuglink_fullpath, *crc_returned, *buildid_returned, *buildid_length_returned, paths_returned, paths_count_returned, &errcode); if (res != DW_DLV_OK) { dwarfstring_destructor(&debuglink_fullpath); return res; } if (dwarfstring_strlen(&debuglink_fullpath)) { *debuglink_fullpath_returned = strdup(dwarfstring_string(&debuglink_fullpath)); *debuglink_fullpath_length_returned = dwarfstring_strlen(&debuglink_fullpath); } } else if (paths_count_returned) { *paths_count_returned = 0; } dwarfstring_destructor(&debuglink_fullpath); return DW_DLV_OK; } /* This should be rarely called and most likely only once (at dbg init time from dwarf_generic_init.c, see set_global_paths_init()). Maybe once or twice later. */ int dwarf_add_debuglink_global_path(Dwarf_Debug dbg, const char *pathname, Dwarf_Error *error) { unsigned glpath_count_in = 0; unsigned glpath_count_out = 0; const char **glpaths = 0; const char * path1 = 0; glpath_count_in = dbg->de_gnu_global_path_count; glpath_count_out = glpath_count_in+1; glpaths = (const char **)malloc(sizeof(char *)* glpath_count_out); if (!glpaths) { _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (glpath_count_in) { memcpy(glpaths, dbg->de_gnu_global_paths, sizeof(char *)*glpath_count_in); } path1 = strdup(pathname); if (!path1) { free(glpaths); _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } free((char *)dbg->de_gnu_global_paths); glpaths[glpath_count_in] = path1; dbg->de_gnu_global_paths = (const char **)glpaths; dbg->de_gnu_global_path_count = glpath_count_out; return DW_DLV_OK; } libdwarf-20210528/libdwarf/pro_frame.h0000664000175000017500000000745114012266121014413 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Largest register value that can be coded into the opcode since there are only 6 bits in the register field. */ #define MAX_6_BIT_VALUE 0x3f /* This struct holds debug_frame instructions */ typedef struct Dwarf_P_Frame_Pgm_s *Dwarf_P_Frame_Pgm; struct Dwarf_P_Frame_Pgm_s { Dwarf_Ubyte dfp_opcode; /* opcode - includes reg # */ char * dfp_args; /* operands */ Dwarf_Unsigned dfp_nbytes; /* number of bytes in args */ Dwarf_P_Frame_Pgm dfp_next; }; /* This struct has cie related information. Used to gather data from user program, and later to transform to disk form */ struct Dwarf_P_Cie_s { Dwarf_Half cie_version; /* augmentation. The string is an strdup() copy and on freeing the Dwarf_P_Cie the string must be freed. */ char *cie_aug; Dwarf_Ubyte cie_code_align; /* alignment of code */ Dwarf_Sbyte cie_data_align; Dwarf_Ubyte cie_ret_reg; /* return register # */ char *cie_inst; /* initial instruction */ long cie_inst_bytes; /* no of init_inst */ Dwarf_P_Cie cie_next; }; /* producer fields */ struct Dwarf_P_Fde_s { Dwarf_Unsigned fde_unused1; /* function/subr die for this fde */ Dwarf_P_Die fde_die; /* index to asso. cie */ Dwarf_Unsigned fde_cie; /* Address of first location of the code this frame applies to If fde_end_symbol non-zero, this represents the offset from the symbol indicated by fde_r_symidx */ Dwarf_Addr fde_initloc; /* Relocation symbol for address of the code this frame applies to. */ Dwarf_Unsigned fde_r_symidx; /* Bytes of instr for this fde, if known */ Dwarf_Unsigned fde_addr_range; /* linked list of instructions we will put in fde. */ Dwarf_P_Frame_Pgm fde_inst; /* number of instructions in fde */ Dwarf_Signed fde_n_inst; /* number of bytes of inst in fde */ Dwarf_Signed fde_n_bytes; /* offset into exception table for this function. */ Dwarf_Signed fde_offset_into_exception_tables; /* The symbol for the exception table elf section. */ Dwarf_Unsigned fde_exception_table_symbol; /* pointer to last inst */ Dwarf_P_Frame_Pgm fde_last_inst; Dwarf_P_Fde fde_next; /* The symbol and offset of the end symbol. When fde_end_symbol is non-zero we must represent the length in relocs. */ Dwarf_Addr fde_end_symbol_offset; Dwarf_Unsigned fde_end_symbol; int fde_uwordb_size; Dwarf_P_Debug fde_dbg; /* If fde_block is non-null, then it is the set of instructions. so we should use it rather than fde_inst. */ Dwarf_Unsigned fde_inst_block_size; void *fde_block; }; libdwarf-20210528/libdwarf/dwarf_die_deliv.h0000644000175000017500000000355613743575426015575 00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This struct holds information about an abbreviation. It is put in the hash table for abbreviations for a compile-unit. It's dealloced by dwarf_finish(). */ struct Dwarf_Abbrev_List_s { Dwarf_Unsigned abl_code; Dwarf_Half abl_tag; Dwarf_Half abl_has_child; /* Section global offset of this abbrev entry. */ Dwarf_Off abl_goffset; /* Singly linked synonym list in case of duplicate hash. */ struct Dwarf_Abbrev_List_s *abl_next; /* Points to start of attribute/form pairs in the .debug_abbrev section for the abbrev. */ Dwarf_Byte_Ptr abl_abbrev_ptr; /* The number of at/form[/implicitvalue] pairs in this abbrev. */ Dwarf_Unsigned abl_count; }; libdwarf-20210528/libdwarf/dwarf_groups.c0000664000175000017500000002521313764007262015146 00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_tsearch.h" #define TRUE 1 #define FALSE 0 #define HASHSEARCH /* It has not escaped our attention that the section-group tsearch hash table could be replaced by a simple array with space for each possible section number, each element being the group number. This would be much simpler than what follows here. */ /* Each section number can appear in at most one record in the hash because each section belongs in only one group. Each group number appears as often as appropriate. */ struct Dwarf_Group_Map_Entry_s { unsigned gm_key; /* section number */ unsigned gm_group_number; /* What group number is. */ /* The name is from static storage or from elf, so there is nothing to free on record delete. */ const char * gm_section_name; }; static void * grp_make_entry(unsigned section, unsigned group,const char *name) { struct Dwarf_Group_Map_Entry_s *e = 0; e = calloc(1,sizeof(struct Dwarf_Group_Map_Entry_s)); if (e) { e->gm_key = section; e->gm_group_number = group; e->gm_section_name = name; } return e; } static DW_TSHASHTYPE grp_data_hashfunc(const void *keyp) { const struct Dwarf_Group_Map_Entry_s * enp = keyp; DW_TSHASHTYPE hashv = 0; hashv = enp->gm_key; return hashv; } static int grp_compare_function(const void *l, const void *r) { const struct Dwarf_Group_Map_Entry_s * lp = l; const struct Dwarf_Group_Map_Entry_s * rp = r; if (lp->gm_key < rp->gm_key) { return -1; } if (lp->gm_key > rp->gm_key) { return 1; } /* match. */ return 0; } int _dwarf_insert_in_group_map(Dwarf_Debug dbg, unsigned groupnum, unsigned section_index, const char *name, Dwarf_Error * error) { struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; void *entry2 = 0; struct Dwarf_Group_Map_Entry_s * entry3 = 0; if (!grp->gd_map) { /* Number of sections is a kind of decent guess as to how much space would be useful. */ dwarf_initialize_search_hash(&grp->gd_map, grp_data_hashfunc,grp->gd_number_of_sections); if (!grp->gd_map) { /* It's really an error I suppose. */ return DW_DLV_NO_ENTRY; } } entry3 = grp_make_entry(section_index,groupnum,name); if (!entry3) { _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } entry2 = dwarf_tsearch(entry3,&grp->gd_map,grp_compare_function); if (!entry2) { free(entry3); _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } else { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)entry2; if (re != entry3) { free(entry3); _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_DUPLICATE); return DW_DLV_ERROR; } else { ++grp->gd_map_entry_count; /* OK. Added. Fall thru */ } } return DW_DLV_OK; } int _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber_out, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Group_Map_Entry_s entry; struct Dwarf_Group_Map_Entry_s *entry2; struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; if (!grp->gd_map) { return DW_DLV_NO_ENTRY; } entry.gm_key = obj_section_index; entry.gm_group_number = 0; /* FAKE */ entry.gm_section_name = ""; /* FAKE */ entry2 = dwarf_tfind(&entry, &grp->gd_map,grp_compare_function); if (entry2) { struct Dwarf_Group_Map_Entry_s *e2 = *(struct Dwarf_Group_Map_Entry_s **)entry2;; *groupnumber_out = e2->gm_group_number; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* New May 2017. So users can find out what groups (dwo or COMDAT) are in the object and how much to allocate so one can get the group-section map data. */ int dwarf_sec_group_sizes(Dwarf_Debug dbg, Dwarf_Unsigned * section_count_out, Dwarf_Unsigned * group_count_out, Dwarf_Unsigned * selected_group_out, Dwarf_Unsigned * map_entry_count_out, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; *section_count_out = grp->gd_number_of_sections; *group_count_out = grp->gd_number_of_groups; *selected_group_out = dbg->de_groupnumber; *map_entry_count_out = grp->gd_map_entry_count; return DW_DLV_OK; } static Dwarf_Unsigned map_reccount = 0; static struct temp_map_struc_s { Dwarf_Unsigned section; Dwarf_Unsigned group; const char *name; } *temp_map_data; static void grp_walk_map(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } temp_map_data[map_reccount].group = re->gm_group_number; temp_map_data[map_reccount].section = re->gm_key; temp_map_data[map_reccount].name = re->gm_section_name; map_reccount += 1; } /* Looks better sorted by group then sec num. */ static int map_sort_compar(const void*l, const void*r) { struct temp_map_struc_s *lv = (struct temp_map_struc_s *)l; struct temp_map_struc_s *rv = (struct temp_map_struc_s *)r; if (lv->group < rv->group) { return -1; } if (lv->group > rv->group) { return 1; } if (lv->section < rv->section) { return -1; } if (lv->section > rv->section) { return 1; } /* Should never get here! */ return 0; } /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' values and this function fills in the array entries. Output ordered by group number and section number. */ int dwarf_sec_group_map(Dwarf_Debug dbg, Dwarf_Unsigned map_entry_count, Dwarf_Unsigned * group_numbers_array, Dwarf_Unsigned * sec_numbers_array, const char ** sec_names_array, Dwarf_Error * error) { Dwarf_Unsigned i = 0; struct Dwarf_Group_Data_s *grp = 0; if (temp_map_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } map_reccount = 0; grp = &dbg->de_groupnumbers; if (map_entry_count < grp->gd_map_entry_count) { _dwarf_error(dbg,error,DW_DLE_GROUP_COUNT_ERROR); return DW_DLV_ERROR; } temp_map_data = calloc(map_entry_count, sizeof(struct temp_map_struc_s)); if (!temp_map_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } dwarf_twalk(grp->gd_map,grp_walk_map); if (map_reccount != grp->gd_map_entry_count) { /* Impossible. */ _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } qsort(temp_map_data,map_reccount,sizeof(struct temp_map_struc_s), map_sort_compar); for (i =0 ; i < map_reccount; ++i) { sec_numbers_array[i] = temp_map_data[i].section; group_numbers_array[i] = temp_map_data[i].group; sec_names_array[i] = temp_map_data[i].name; } free(temp_map_data); map_reccount = 0; temp_map_data = 0; return DW_DLV_OK; } static const char *dwo_secnames[] = { ".debug_info.dwo", ".debug_types.dwo", ".debug_abbrev.dwo", ".debug_line.dwo", ".debug_loc.dwo", ".debug_str.dwo", ".debug_loclists.dwo", ".debug_rnglists.dwo", ".debug_str_offsets.dwo", ".debug_macro.dwo", ".debug_cu_index", ".debug_tu_index", 0 }; /* Assumption: dwo sections are never in a COMDAT group (groupnumber >2) and by definition here are never group 1. Assumption: the map of COMDAT groups (not necessarily all sections, but at least all COMDAT) is complete. */ int _dwarf_dwo_groupnumber_given_name( const char *name, unsigned *grpnum_out) { const char **s = 0; for (s = dwo_secnames; *s; s++) { if (!strcmp(name,*s)) { *grpnum_out = DW_GROUPNUMBER_DWO; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } static unsigned target_group = 0; static int found_name_in_group = 0; const char *lookfor_name = 0; static void grp_walk_for_name(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } if (re->gm_group_number == target_group) { if (!strcmp(lookfor_name,re->gm_section_name)) { found_name_in_group = TRUE; } } } /* returns TRUE or FALSE */ int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, const char * scn_name, unsigned groupnum) { struct Dwarf_Group_Data_s *grp = 0; grp = &dbg->de_groupnumbers; found_name_in_group = FALSE; target_group = groupnum; lookfor_name = scn_name; dwarf_twalk(grp->gd_map,grp_walk_for_name); return found_name_in_group; } static void _dwarf_grp_destroy_free_node(void*nodep) { struct Dwarf_Group_Map_Entry_s * enp = nodep; free(enp); return; } void _dwarf_destroy_group_map(Dwarf_Debug dbg) { dwarf_tdestroy(dbg->de_groupnumbers.gd_map, _dwarf_grp_destroy_free_node); dbg->de_groupnumbers.gd_map = 0; } libdwarf-20210528/libdwarf/dwarf_vars.h0000644000175000017500000000225613743575426014620 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Var_Context_s *Dwarf_Var_Context; /* struct never completed: see dwarf_global.h */ libdwarf-20210528/libdwarf/dwarf_test_errmsg_list.c0000664000175000017500000002050613764007262017220 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #include #ifdef HAVE_STDLIB_H #include /* For exit(), strtoul() declaration etc. */ #endif #include "dwarf_errmsg_list.h" #define FALSE 0 #define TRUE 1 /* This is just to help localize the error. */ static void printone(int i) { int arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); if ( i >= arraysize) { printf("%d is outside the array! Missing something!\n",i); } else { printf("%d is: %s\n",i,_dwarf_errmsgs[i]); } } /* Arbitrary. A much smaller max length value would work. */ #define MAX_NUM_LENGTH 12 /* return TRUE on error */ static int check_errnum_mismatches(unsigned i) { unsigned nextstop = 0; const char *sp = _dwarf_errmsgs[i]; const char *cp = sp; unsigned innit = FALSE; unsigned prevchar = 0; unsigned value = 0; for ( ; *cp; cp++) { unsigned c = 0; c = 0xff & *cp; if ( c >= '0' && c <= '9' && !innit && prevchar != '(') { /* Skip. number part of macro name. */ prevchar = c; continue; } if ( c >= '0' && c <= '9') { value = value * 10; value += (c - '0'); nextstop++; if (nextstop > MAX_NUM_LENGTH) { break; } innit = TRUE; } else { if (innit) { break; } prevchar= c; } } if (innit) { if (i != value) { return TRUE; } return FALSE; } /* There is no number to check. Ignore it. */ printf("mismatch value %d has no errnum to check %s\n", i,_dwarf_errmsgs[i]); return TRUE; } /* We don't allow arbitrary DW_DLE line length. */ #define MAXDEFINELINE 200 static int splmatches(char *base, unsigned baselen,char *test) { if (baselen != strlen(test) ) { return FALSE; } for ( ; *test; ++test,++base) { if (*test != *base) { return FALSE; } } return TRUE; } static void check_dle_list(const char *path) { /* The format should be #definenamenumberoptional-c-comment and we are intentionally quite rigid about it all except that the number of spaces before any comment is allowed. */ char buffer[MAXDEFINELINE]; unsigned linenum = 0; unsigned long prevdefval = 0; unsigned foundlast = 0; unsigned foundlouser = 0; FILE*fin = 0; fin = fopen(path, "r"); if (!fin) { printf("Unable to open define list to read %s\n",path); exit(1); } for ( ;;++linenum) { char *line = 0; unsigned linelen = 0; char * curdefname = 0; char * pastname = 0; unsigned curdefname_len = 0; char *numstart = 0; char * endptr = 0; unsigned long v = 0; line = fgets(buffer,MAXDEFINELINE,fin); if (!line) { break; } linelen = strlen(line); if (linelen >= (unsigned)(MAXDEFINELINE-1)) { printf("define line %u is too long!\n",linenum); exit(1); } if (strncmp(line,"#define DW_DLE_",15)) { printf("define line %u has wrong leading chars!\n", linenum); exit(1); } curdefname = line+8; /* ASSERT: line ends with NUL byte. */ for ( ; ; curdefname_len++) { if (foundlouser) { printf("define line %u has stuff after " "DW_DLE_LO_USER!\n", linenum); exit(1); } pastname = curdefname +curdefname_len; if (!*pastname) { /* At end of line. Missing value. */ printf("define line %u of %s: has no number value!\n", linenum,path); exit(1); } if (*pastname == ' ') { /* Ok. Now look for value. */ numstart = pastname + 1; break; } } /* strtoul skips leading whitespace. */ v = strtoul(numstart,&endptr,0); /* This test is a bit odd. But is valid till we decide it is inappropriate. */ if (v > DW_DLE_LO_USER) { printf("define line %u: number value unreasonable. %lu\n", linenum,v); exit(1); } if (v == 0 && endptr == numstart) { printf("define line %u of %s: number value missing.\n", linenum,path); printf("Leaving a space as in #define A B 3" " in libdwarf.h.in will cause this.\n"); exit(1); } if (*endptr != ' ' && *endptr != '\n') { printf("define line %u: number value terminates oddly\n", linenum); exit(1); } if (splmatches(curdefname,curdefname_len,"DW_DLE_LAST")) { if (foundlast) { printf("duplicated DW_DLE_LAST! line %u\n",linenum); exit(1); } foundlast = 1; if (v != prevdefval) { printf("Invalid: Last value mismatch! %lu vs %lu\n", v,prevdefval); } } else if (splmatches(curdefname,curdefname_len, "DW_DLE_LO_USER")) { if (!foundlast) { printf("error:expected DW_DLE_LO_USER after LAST! " "line %u\n", linenum); exit(1); } if (foundlouser) { printf("Error:duplicated DW_DLE_LO_USER! line %u\n", linenum); exit(1); } foundlouser = 1; continue; } else { if (linenum > 0) { if (v != prevdefval+1) { printf("Invalid: Missing value! %lu vs %lu\n", prevdefval,v); exit(1); } } prevdefval = v; } /* Ignoring rest of line for now. */ } fclose(fin); } int main(int argc, char **argv) { unsigned arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); unsigned i = 0; const char *path = 0; if (argc != 3) { printf("Expected -f of DW_DLE lines " "from libdwarf.h"); exit(1); } if (strcmp(argv[1],"-f")) { printf("Expected -f"); exit(1); } path = argv[2]; check_dle_list(path); if (arraysize != (DW_DLE_LAST + 1)) { printf("Missing or extra entry in dwarf error strings array" " %u expected DW_DLE_LAST+1 %d\n", arraysize, DW_DLE_LAST+1); printone(1); printone(100); printone(200); printone(250); printone(260); printone(262); printone(263); printone(264); printone(265); printone(273); printone(274); printone(275); printone(300); printone(328); exit(1); } for ( i = 0; i <= DW_DLE_LAST; ++i) { if (check_errnum_mismatches(i)) { printf("mismatch value %d is: %s\n",i,_dwarf_errmsgs[i]); exit(1); } } /* OK. */ exit(0); } libdwarf-20210528/libdwarf/ChangeLog20110000664000175000017500000003712313644370703014361 000000000000002011-12-14 DavidAnderson * libdwarf.h, dwarf_error.c: Add a new error code for DW_OP location codes. * dwarf_loc.c: Implement support for new DW_OP_GNU codes. 2011-12-13 DavidAnderson * dwarf.h: Added some GNU extensions. * libdwarf.h: Added dwarf_lineoff_b() as dwarf_lineoff() wrongly returns a signed column number. Added dwarf_add_lineentry_b() as preparation for creating DWARF3/4 output. * dwarf_line.h: Added new struct fields to accomodate DWARF3/4 isa and discriminator fields. * dwarf_line.c: Now deals with the VLIW line calculations in DWARF4. Adds support for computing the discriminator and isa fields. Adds dwarf_lineoff_b() (and dwarf_lineoff is now deprecated). Adds dwarf_prologue_end_etc() which returns some DWARF3/4 line fields. * dwarf_print_lines.c: Adds handling of DWARF3/4 line operations and fields and prints the details. * libdwarf2.1.mm: Documents the new functions in dwarf_line.c Version set to 2.02. * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Documents the new function dwaf_add_line_entry_b(). Version set to 1.32. * libdwarf2p.1.pdf: Regenerated. * pro_incl.h: Add parentheses so the WRITE_UNALIGNED macro works correctly in all circumtances. * pro_opaque.h: Add DEBUG_RANGES and dEBUG_TYPES to the list of sections we could generate. Define struct Dwarf_P_Line_Inits_s to hold initialization values for line table data so we can later make the choices at runtime rather than compile time. The new struct is a field of the Dwarf_P_Debug struct. * pro_line.h: Added some DWARF3/4 support and preparations for emitting DWARF3/4. * pro_line.c: Define dwarf_add_line_entry_b() for DWARF3/4 line fields, and _dwarf_init_default_line_header_vals() to provide a default set of values, the defaults match what was previously done. Add support for the new DWARF3/4 line table fields. * pro_section.c: Add the beginnings of support for creating new DWARF3/4 sections and the new standard opcodes. Move the field-writing code to small functions making the line table writing smaller and easier to read. Added the beginnings of allowing writing DWARF3/4 line table fields. Some if() missing {} were modified by adding {} to avoid future problems. 2011-12-08 DavidAnderson * dwarf_frame.c: Corrected a typo by adding a space to a comment. * libdwarf2p.1.mm: A sentence about dwarf_lne_end_sequence() was missing its introductory words. New version is 1.31. * libdwarf2p.1.pdf: Regenerated. 2011-11-02 DavidAnderson * dwarf.h: Spelling fix: specfic->specific. Rearranged a few comments about MIPS/SGI for a better appearance. 2011-10-29 DavidAnderson * dwarf_alloc.c: Add support for the .debug_types section. * dwarf_arange.c,dwarf_global.c: Add commentary about debug_info vs debug_types and a new argument to an internal function. * dwarf_arange.h,dwarf_global.h: Add comment that this is debug_info related only. * dwarf_die_deliv.c: Now handles .debug_types as well as .debug_info, and context information for the two sections is kept seperate. * dwarf_elf_access.c: Add a check for relocations of .debug_types. * dwarf_error.c: Added error strings related to .debug_types. * dwarf_form.c: Changes for .debug_types, mainly due to removing 'info_' from certain struct member names. * dwarf_init_finish.c: Notice the .debug_types section. New function dwarf_get_section_max_offsets_b() returns the size of debug_types (added to existing arguments). * dwarf_opaque.h: Fields named *_info_* have the info_ removed as they apply to debug_types as well. A new struct Dwarf_Debug_InfoTypes holds the data for either of .debug_types and .debug_info sections. Separating them so the sections can be accessed simultaneously. Moved data items from Dwarf_Debug to the new struct. DIE structs now have a 'is_info' field so a CU and a DIE know whether they are from .debug_info or .debug_types. * dwarf_query.c: The query functions now work for debug_info and debug_query as appropriate. * dwarf_util.h: Added _dwarf_load_debug_types() and altered a couple internal function prototypes with an 'is_info' flag argument. * dwarf_util.c: Added _dwarf_load_debug_types(). Altered functions so the deal with .debug_types or .debug_info as appropriate. * libdwarf.h: Added debug_types error codes. Added dwarf_siblingof_b() and dwarf_offdie_b() and Added dwarf_next_cu_header_c() and dwarf_get_cu_die_offset_given_cu_header_offset_b() to account for .debug_types or .debug_info as required. Added dwarf_get_die_infotypes_flag() so client code can know if a DIE is debug_info or debug_types based. Added dwarf_get_section_max_offsets_b(), adding a debug_types size argument. * libdwarf2.1.mm: Documented the new functions. New version is 2.0 (somewhat arbitrarily changed from 1.x to 2.0) * libdwarf2.1.pdf: Regenerated 2011-10-26 DavidAnderson * Makefile.in, README: Added Make settings of PREINCS POSTINCS PRELIBS, POSTLIBS to simplify building when libdwarf or libelf are not in the normal locations. Documented usable ways to deal with unusual situations at build time. 2011-10-09 DavidAnderson . * dwarf_die_deliv.c, dwarf_elf_access.c: Fix bad indentation. 2011-10-05 DavidAnderson . * dwarf_die_deliv.c: When relocations fail, record a 'harmless error' and continue the CU loading. No way to be sure the error is really harmless, of course. But it seems to often be harmless. For some if() tests add {} to make the clause extent clear. * dwarf_harmless.c: Add a comment prefix to dwarf_harmless_init(). 2011-10-03 DavidAnderson * dwarf_line.c: Introduce {} in a test to avoid future mistakes. 2011-09-23 DavidAnderson * dwarf_arange.c: Test for a zero address-size: that indicates broken dwarf generation. * dwarf_line.c: Test for irrational line number header data and error off with DW_DLE_LINE_NUMBER_HEADER_ERROR if we find it. Add accidentally-omitted check for version 4. * dwarf_error.c, libdwarf.h: New error code DW_DLE_LINE_NUMBER_HEADER_ERROR. 2011-09-16 DavidAnderson * dwarf_elf_access.c: Give up relocating if the Elf symtab header sh_entrysize is zero, and refine the test for invalid symbol index to be a >= test. * dwarf_error.c: Define text message for DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO. * libdwarf.h: New error code DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO. 2011-09-15 DavidAnderson * dwarf_elf_access.c: Adding fields to the object structs dwarf uses and using them for error checks when processing relocations. * dwarf_error.c: Adding descriptions of new error messages for Elf object file interpretation problems. * dwarf_init_finish.c: Adding 'entrysize' field about objects do dwarf_elf_access.c can check for object and relocation data errors and avoid a coredump. And we memset() a struct to ensure there are no uninitialized contents. * dwarf_opaque.h: Adding new dss_entrysize and dss_reloc_entrysize fields so elf error checks can be added to dwarf_elf_access.c. These changes mean you must recompile all of libdwarf source, not just a subset, when rebuilding (the first time one sees this change). * libdwarf.h: Adding entrysize element to Dwarf_Obj_Access_Section_s. Non-elf object formats can just set this field zero and ignore it. Added new elf-specific error codes for the new checks in dwarf_elf_access.c. 2011-09-14 DavidAnderson * BLDLIBDWARFTAR: Moved a local disk file. Irrelevant to everyone but DA. * dwarf_arange.c: check that the address_size and segment selector size fields are sensible. * dwarf_die_deliv.c,dwarf_frame2.c: Give DW_DLE_ADDRESS_SIZE_ERROR or DW_DLE_CU_ADDRESS_SIZE_BAD if the address size read from a section is obviously wrong. Similarly for a bad segment-selector-size give DW_DLE_SEGMENT_SIZE_BAD. * dwarf_error.c: Added text for the DW_DLE_SEGMENT_SIZE_BAD error. * dwarf_frame.c: If dwarf_set_default_address_size() is handed an address_size that we cannot handle, ignore the input so we don't wind up coredumping the library or consumer code. * libdwarf2.1.mm: Updated list of error codes a little bit. Rev 1.99 * libdwarf2.1.pdf: Regenerated. 2011-09-08 DavidAnderson * dwarf_frame.c: Fixed bad indents. 2011-09-02 DavidAnderson * libdwarf2.1.mm: Document the new function dwarf_set_default_address_size(). Updated revision to 1.97. * libdwarf2.1.pdf: Regenerated. * dwarf_frame.c: Implement dwarf_set_default_address_size(). * libdwarf.h: Declare the new function dwarf_set_default_address_size(). * dwarf_form.c(dwarf_formref): Removed c99-ish declaration so C90 can compile the code. * Makefile.in, configure.in: If building shared lib CFLAGS gets -fPIC added in. * configure: Fegenerated. * dwarf_loc.c: New test returns DW_DLE_LOC_BAD_TERMINATION in case of compiler bug in location expression. * dwarf_error.c, libdwarf.h: Define and document the new error. * pro_opaque.h: Fixed a bad indent. 2011-06-12 DavidAnderson * libdwarf.h: Added dwarf_producer_init_c() and its callback functions. Adds a user_data void* to the init and callback functions for user convenience. * libdwarf2p.1.m: Documented dwarf_producer_init_c(). Rev 1.30. * libdwarf2p.1.pdf: Regenerated * pro_init.c: Implement dwarf_producer_init_c(). * pro_opaque.h: Add fields for dwarf_producer_init_c(). * pro_reloc_stream.c: Implement dwarf_producer_init_c() callback. * pro_reloc_symbolic.c: Implement dwarf_producer_init_c() callback. * pro_section.c: Implement dwarf_producer_init_c() callback. 2011-06-09 DavidAnderson * dwarf_form.c: Code getting access to CU context and dbg was repeated many times. Refactored the common code into a file-static subprogram. 2011-06-08 DavidAnderson * libdwarf2.1.mm,libdwarf2.1.pdf: Now discusses DW_AT_data_member_location in the context if dwarf_loclist_n(). Rev 1.96 2011-06-08 DavidAnderson * dwarf_init_finish.c: Inserted missing include of dwarf_harmless.h. 2011-06-07 DavidAnderson * dwarf_elf_access.c: Added EM_QUALCOMM_DSP6 machine so that relocations work on a Qualcomm relocatable object in the dwarf regressiontests. * dwarf_util.c: Fixed indent problems added in previous change. 2011-06-07 DavidAnderson * dwarf_util.c(_dwarf_get_abbrev_for_code): If there is no section padding the code could read-from-memory one past the end of the section which could (in very rare circumstances) coredump an application. In addition, earlier in the same funcion we did not account for the case where we had already read to end of section. Both fixed. 2011-06-06 DavidAnderson * dwarf_error.c: Fix a typo in an error string. * dwarf_query.c: Implement the new function dwarf_get_verion_of_die(). * libdwarf.h: Add prototype for dwarf_get_verion_of_die(). * libdwarf2.1.mm: for dwarf_form_{s,u}data, mention the DW_FORM_data{4,8} class ambiguity. Document the new function dwarf_get_verion_of_die(). Document version now 1.95. * libdwarf2.1.pdf: Regenerate. 2011-06-04 DavidAnderson * NEWS: Mention the non-elf documentation oversight. * dwarf_arange.c,dwarf_elf_access.c, dwarf_frame3.c, dwarf_funcs.c,dwarf_global.c,dwarf_init_finish.c, dwarf_line.c,dwarf_loc.c,dwarf_macro.c,dwarf_print_lines.c, dwarf_pubtypes.c,dwarf_query.c,dwarf_ranges.c,dwarf_string.c, dwarf_types.c,dwarf_vars.c, dwarf_weaks.c: Everything loading a section now checks the result for 'empty' and returns DW_DLV_NO_ENTRY explicitly. This makes it easier to do nothing safely when there is no data. 2011-06-04 DavidAnderson * dwarf_line.c (_dwarf_internal_srclines): Created new local functions to unify some repeated code in into function calls. One of the earlier inline-repetitions was coded wrong. Added {} to ensure clarity on the intended scope a couple places. Added initializers to a couple of local variables. 2011-06-04 DavidAnderson * dwarf_alloc.c: Added include "dwarf_harmless.h" so a prototype is visible here. * dwarf_form.c (dwarf_convert_to_global_offset,dwarf_global_formref): Deleted unused local variables. * dwarf_frame.c (dwarf_initialize_fde_table): Uses local instead of ignoring it (avoids compiler warning). * dwarf_frame2.c (_dwarf_get_fde_list_internal): Delete unused local variable. * dwarf_line.c (dwarf_srcfiles): Call uses variable expected signedness now, avoiding compiler warning. * dwarf_print_lines.c: Printf was missing %, gcc -Wall pointed out the mistake. 2011-04-23 DavidAnderson * pro_error.c (_dwarf_p_error): The code attempting to deal with an unexpected error code was doing an inappropriate cast and an inappropriate (possibly out-of-bounds) reference to an array of strings. Removed the cast and removed the questionable array reference. * dwarf_frame.c: A couple lines were indented badly. Fixed the indentation. * pro_line.h: Now __x86_64 also gets MIN_INST_LENGTH 1 2011-03-29 DavidAnderson * everything: Redid all indentations for consistency. Updated copyrights. Interfaces did not change, existing clients should not encounter difficulty. 2011-03-13 DavidAnderson * libdwarf.h, dwarf_error.c: Added DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH. 2011-01-20 DavidAnderson * dwarf.h: Added some Apple attribute extensions. 2011-01-13 DavidAnderson * dwarf_print_lines.c: Handles DW_FORM_exprloc now. With -vvv it now prints the dwarf version of the line table header. * dwarf_line.c: Handles DW_FORM_exprloc now. 2011-01-13 DavidAnderson * libdwarf.h: Added new function dwarf_get_die_address_size(). * libdwarf2.1.mm: Documented new function dwarf_get_die_address_size(). Rev 1.91, 12 January 2011 * libdwarf2.1.pdf: Regenerated. * dwarf_form.c: Corrected handling of DW_FORM_exprloc. * dwarf_query.c: Implemented dwarf_get_die_address_size(). Corected handling of DW_FORM_exprloc. * dwarf_util.c: Added handling of DW_FORM_exprloc and DW_FORM_flag_present. libdwarf-20210528/libdwarf/dwarf_peread.c0000664000175000017500000007103613764007262015073 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of a Windows PE file appropriate to reading DWARF debugging data. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include /* memcpy */ #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_TYPES_H #include /* open(), off_t, size_t, ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* open() */ #endif /* HAVE_SYS_STAT_H */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "memcpy_swap.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #include "dwarf_pe_descr.h" #include "dwarf_peread.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define DOS_HEADER_LEN 64 #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYP */ #ifndef SIZEOFT32 #define SIZEOFT32 4 #endif /* SIZEOFT32 */ #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s len %ld ",msg,len); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif static int _dwarf_pe_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static unsigned long magic_copy(char *d, unsigned len) { unsigned i = 0; unsigned long v = 0; v = d[0]; for (i = 1 ; i < len; ++i) { v <<= 8; v |= 0xff&d[i]; } return v; } static int check_valid_string(char *tab, Dwarf_Unsigned size, Dwarf_Unsigned startindex) { Dwarf_Unsigned i = startindex; for ( ; i < size; ++i) { if (!tab[i]) { return DW_DLV_OK; } } return DW_DLV_ERROR; } #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* Name_array is 8 byte string, or it is supposed to be anyway. */ static int pe_section_name_get(dwarf_pe_object_access_internals_t *pep, const char *name_array, const char ** name_out, int *errcode) { if (name_array[0] == '/') { long v = 0; unsigned long u = 0; const char *s = 0; char temp_array[9]; int res = 0; memcpy(temp_array,name_array+1,7); temp_array[7] = 0; v = atoi(temp_array); if (v < 0) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } u = v; if (!pep->pe_string_table) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } if (u >= pep->pe_string_table_size) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } res = check_valid_string(pep->pe_string_table, pep->pe_string_table_size,u); if (res != DW_DLV_OK) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } s = pep->pe_string_table +u; *name_out = s; return DW_DLV_OK; } *name_out = name_array; return DW_DLV_OK; } static Dwarf_Endianness pe_get_byte_order (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_endian; } static Dwarf_Small pe_get_length_size (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_offsetsize/8; } static Dwarf_Small pe_get_pointer_size (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_pointersize/8; } static Dwarf_Unsigned pe_get_section_count (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_section_count; } static int pe_get_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); if (section_index < pep->pe_section_count) { struct dwarf_pe_generic_image_section_header *sp = 0; sp = pep->pe_sectionptr + section_index; return_section->addr = pep->pe_OptionalHeader.ImageBase + sp->VirtualAddress; return_section->type = 0; /* SizeOfRawData can be rounded or truncated, use VirtualSize for the real analog of Elf section size. */ return_section->size = sp->VirtualSize; return_section->name = sp->dwarfsectname; return_section->link = 0; return_section->info = 0; return_section->entrysize = 0; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int load_optional_header32(dwarf_pe_object_access_internals_t *pep, Dwarf_Unsigned offset, int*errcode) { int res = 0; IMAGE_OPTIONAL_HEADER32_dw hdr; pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); if ((pep->pe_optional_header_size + offset) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&hdr, (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER32_dw), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* This is a subset of fields. */ ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, hdr.Magic); pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.ImageBase, hdr.ImageBase); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, hdr.SizeOfCode); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, hdr.SizeOfImage); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, hdr.SizeOfHeaders); pep->pe_OptionalHeader.SizeOfDataDirEntry = sizeof(IMAGE_DATA_DIRECTORY_dw); return DW_DLV_OK; } static int load_optional_header64(dwarf_pe_object_access_internals_t *pep, Dwarf_Unsigned offset, int*errcode ) { IMAGE_OPTIONAL_HEADER64_dw hdr; int res = 0; pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); if ((pep->pe_optional_header_size + offset) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&hdr, (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER64_dw), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* This is a subset of fields. */ ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, hdr.Magic); pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.ImageBase, hdr.ImageBase); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, hdr.SizeOfCode); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, hdr.SizeOfImage); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, hdr.SizeOfHeaders); pep->pe_OptionalHeader.SizeOfDataDirEntry = sizeof(IMAGE_DATA_DIRECTORY_dw); return DW_DLV_OK; } static int pe_load_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); if (0 < section_index && section_index < pep->pe_section_count) { int res = 0; struct dwarf_pe_generic_image_section_header *sp = pep->pe_sectionptr + section_index; Dwarf_Unsigned read_length = 0; if (sp->loaded_data) { *return_data = sp->loaded_data; return DW_DLV_OK; } if (!sp->VirtualSize) { return DW_DLV_NO_ENTRY; } read_length = sp->SizeOfRawData; if (sp->VirtualSize < read_length) { /* Don't read padding that wasn't allocated in memory */ read_length = sp->VirtualSize; } if ((read_length + sp->PointerToRawData) > pep->pe_filesize) { *error = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } /* VirtualSize > SizeOfRawData if trailing zeros in the section were not written to disc. Malloc enough for the whole section, read in the bytes we have. */ sp->loaded_data = malloc((size_t)sp->VirtualSize); if (!sp->loaded_data) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)sp->loaded_data, (off_t)sp->PointerToRawData, (size_t)read_length, (off_t)pep->pe_filesize, error); if (res != DW_DLV_OK) { free(sp->loaded_data); sp->loaded_data = 0; return res; } if (sp->VirtualSize > read_length) { /* Zero space that was allocated but truncated from the file */ memset(sp->loaded_data + read_length, 0, (size_t)(sp->VirtualSize - read_length)); } *return_data = sp->loaded_data; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } void _dwarf_destruct_pe_access( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_pe_object_access_internals_t *pep = 0; Dwarf_Unsigned i = 0; if (!aip) { return; } pep = (dwarf_pe_object_access_internals_t*)(aip->object); if (pep->pe_destruct_close_fd && pep->pe_fd !=-1) { close(pep->pe_fd); pep->pe_fd = -1; } free((char *)pep->pe_path); pep->pe_path = 0; if (pep->pe_sectionptr) { struct dwarf_pe_generic_image_section_header *sp = 0; sp = pep->pe_sectionptr; for (i=0; i < pep->pe_section_count; ++i,++sp) { if (sp->loaded_data) { free(sp->loaded_data); sp->loaded_data = 0; } free(sp->name); sp->name = 0; free(sp->dwarfsectname); sp->dwarfsectname = 0; } free(pep->pe_sectionptr); pep->pe_section_count = 0; } free(pep->pe_string_table); pep->pe_string_table = 0; free(pep); free(aip); return; } static int dwarf_pe_load_dwarf_section_headers( dwarf_pe_object_access_internals_t *pep,int *errcode) { Dwarf_Unsigned i = 0; Dwarf_Unsigned input_count = pep->pe_FileHeader.NumberOfSections; Dwarf_Unsigned offset_in_input = pep->pe_section_table_offset; Dwarf_Unsigned section_hdr_size = sizeof(IMAGE_SECTION_HEADER_dw); struct dwarf_pe_generic_image_section_header *sec_outp = 0; Dwarf_Unsigned cur_offset = offset_in_input; Dwarf_Unsigned past_end_hdrs = offset_in_input + section_hdr_size*input_count; /* internal sections include null initial section */ pep->pe_section_count = input_count+1; if (past_end_hdrs > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } if (!offset_in_input) { *errcode = DW_DLE_PE_OFFSET_BAD; return DW_DLV_ERROR; } pep->pe_sectionptr = (struct dwarf_pe_generic_image_section_header * ) calloc((size_t)pep->pe_section_count, sizeof(struct dwarf_pe_generic_image_section_header)); if (!pep->pe_sectionptr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } sec_outp = pep->pe_sectionptr; sec_outp->name = strdup(""); sec_outp->dwarfsectname = strdup(""); sec_outp++; for ( ; i < input_count; ++i, cur_offset += section_hdr_size, sec_outp++) { int res = 0; IMAGE_SECTION_HEADER_dw filesect; char safe_name[IMAGE_SIZEOF_SHORT_NAME +1]; const char *expname = 0; res = _dwarf_object_read_random(pep->pe_fd, (char *)&filesect,(off_t)cur_offset, sizeof(filesect), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* The following is safe. filesect.Name is IMAGE_SIZEOF_SHORT_NAME bytes long and may not (not sure) have a NUL terminator. */ strncpy(safe_name,filesect.Name,IMAGE_SIZEOF_SHORT_NAME); /* Then add NUL terminator. */ safe_name[IMAGE_SIZEOF_SHORT_NAME] = 0; sec_outp->name = strdup(safe_name); res = pe_section_name_get(pep, safe_name,&expname,errcode); if (res != DW_DLV_OK) { return res; } if (expname) { sec_outp->dwarfsectname = strdup(expname); } else { sec_outp->dwarfsectname = strdup(""); } if ( !sec_outp->name || !sec_outp->dwarfsectname) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } sec_outp->SecHeaderOffset = cur_offset; ASNAR(pep->pe_copy_word,sec_outp->VirtualSize, filesect.Misc.VirtualSize); ASNAR(pep->pe_copy_word,sec_outp->VirtualAddress, filesect.VirtualAddress); ASNAR(pep->pe_copy_word,sec_outp->SizeOfRawData, filesect.SizeOfRawData); ASNAR(pep->pe_copy_word,sec_outp->PointerToRawData, filesect.PointerToRawData); if (sec_outp->SizeOfRawData > pep->pe_filesize || sec_outp->PointerToRawData > pep->pe_filesize || (sec_outp->SizeOfRawData+ sec_outp->PointerToRawData > pep->pe_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } ASNAR(pep->pe_copy_word,sec_outp->PointerToRelocations, filesect.PointerToRelocations); ASNAR(pep->pe_copy_word,sec_outp->PointerToLinenumbers, filesect.PointerToLinenumbers); ASNAR(pep->pe_copy_word,sec_outp->NumberOfRelocations, filesect.NumberOfRelocations); ASNAR(pep->pe_copy_word,sec_outp->NumberOfLinenumbers, filesect.NumberOfLinenumbers); ASNAR(pep->pe_copy_word,sec_outp->Characteristics, filesect.Characteristics); /* sec_outp->loaded data set when we load a section */ } return DW_DLV_OK; } static int dwarf_load_pe_sections( dwarf_pe_object_access_internals_t *pep,int *errcode) { struct dos_header_dw dhinmem; IMAGE_FILE_HEADER_dw ifh; void (*word_swap) (void *, const void *, unsigned long); unsigned locendian = 0; int res = 0; Dwarf_Unsigned dos_sig = 0; Dwarf_Unsigned nt_address = 0; char nt_sig_array[4]; unsigned long nt_signature = 0; if ( (sizeof(ifh) + sizeof(dhinmem)) >= pep->pe_filesize) { /* corrupt object. */ *errcode = DW_DLE_PE_SIZE_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd,(char *)&dhinmem, 0, sizeof(dhinmem),(off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } dos_sig = magic_copy((char *)dhinmem.dh_mz, sizeof(dhinmem.dh_mz)); if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian load, so we intrepet a match the other way. */ /* BIG ENDIAN. From looking at hex characters in object */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_noswap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_swap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_OBJECT_MSB; } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { /* raw load, so intrepet a match the other way. */ /* LITTLE ENDIAN */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_swap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_noswap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_OBJECT_LSB; } else { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } if (locendian != pep->pe_endian) { /* Really this is a coding botch somewhere here, not an object corruption. */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } pep->pe_copy_word = word_swap; ASNAR(word_swap,nt_address,dhinmem.dh_image_offset); if (pep->pe_filesize < (nt_address + sizeof(nt_sig_array))) { /* The nt_address is really a file offset. */ *errcode = DW_DLE_FILE_TOO_SMALL; /* Not dos header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&nt_sig_array[0], (off_t)nt_address, sizeof(nt_sig_array), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } { unsigned long lsig = 0; ASNAR(word_swap,lsig,nt_sig_array); nt_signature = lsig; } if (nt_signature != IMAGE_NT_SIGNATURE_dw) { *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } pep->pe_nt_header_offset = nt_address + SIZEOFT32; if (pep->pe_filesize < (pep->pe_nt_header_offset + sizeof(ifh))) { *errcode = DW_DLE_FILE_TOO_SMALL; /* Not image header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd,(char *)&ifh, (off_t)pep->pe_nt_header_offset, sizeof(ifh), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } ASNAR(word_swap,pep->pe_FileHeader.Machine,ifh.Machine); ASNAR(word_swap,pep->pe_FileHeader.NumberOfSections, ifh.NumberOfSections); ASNAR(word_swap,pep->pe_FileHeader.TimeDateStamp, ifh.TimeDateStamp); ASNAR(word_swap,pep->pe_FileHeader.PointerToSymbolTable, ifh.PointerToSymbolTable); ASNAR(word_swap,pep->pe_FileHeader.NumberOfSymbols, ifh.NumberOfSymbols); ASNAR(word_swap,pep->pe_FileHeader.SizeOfOptionalHeader, ifh.SizeOfOptionalHeader); ASNAR(word_swap,pep->pe_FileHeader.Characteristics, ifh.Characteristics); pep->pe_optional_header_offset = pep->pe_nt_header_offset+ sizeof(ifh); if (pep->pe_offsetsize == 32) { res = load_optional_header32(pep, pep->pe_optional_header_offset,errcode); pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); } else if (pep->pe_offsetsize == 64) { res = load_optional_header64(pep, pep->pe_optional_header_offset,errcode); pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } pep->pe_section_table_offset = pep->pe_optional_header_offset + pep->pe_optional_header_size; pep->pe_symbol_table_offset = pep->pe_FileHeader.PointerToSymbolTable; if (pep->pe_symbol_table_offset >= pep->pe_filesize) { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (pep->pe_symbol_table_offset) { pep->pe_string_table_offset = pep->pe_symbol_table_offset + (pep->pe_FileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL); } if (pep->pe_string_table_offset >= pep->pe_filesize) { *errcode = DW_DLE_OFFSET_SIZE; pep->pe_string_table_size = 0; return DW_DLV_ERROR; } if (pep->pe_string_table_offset) { /* https://docs.microsoft.com/en-us/\ windows/desktop/debug/pe-format#coff-string-table */ /* The first 4 bytes of the string table contain the size of the string table. */ char size_field[4]; if ((pep->pe_string_table_offset+sizeof(size_field)) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } memset(size_field,0,sizeof(size_field)); res = _dwarf_object_read_random(pep->pe_fd, (char *)size_field, (off_t)pep->pe_string_table_offset, sizeof(size_field), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } ASNAR(pep->pe_copy_word,pep->pe_string_table_size, size_field); if (pep->pe_string_table_size >= pep->pe_filesize ) { *errcode = DW_DLE_PE_OFFSET_BAD; return DW_DLV_ERROR; } if ((pep->pe_string_table_offset+pep->pe_string_table_size) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } pep->pe_string_table = (char *)malloc((size_t)pep->pe_string_table_size); if (!pep->pe_string_table) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)pep->pe_string_table, (off_t)pep->pe_string_table_offset, (size_t)pep->pe_string_table_size, (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { free(pep->pe_string_table); pep->pe_string_table = 0; return res; } } res = dwarf_pe_load_dwarf_section_headers(pep,errcode); return res; } int _dwarf_pe_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_pe_object_access_internals_t *pep = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_pe_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_pe_access(binary_interface); return res; } pep = binary_interface->object; pep->pe_path = strdup(true_path); return res; } static Dwarf_Obj_Access_Methods pe_methods = { pe_get_section_info, pe_get_byte_order, pe_get_length_size, pe_get_pointer_size, pe_get_section_count, pe_load_section, 0 /* ignore pe relocations. */ }; /* On any error this frees internals. */ static int _dwarf_pe_object_access_internals_init( dwarf_pe_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_pe_object_access_internals_t * intfc = internals; struct Dwarf_Obj_Access_Interface_s *localdoas = 0; int res = 0; /* Must malloc as _dwarf_destruct_pe_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); intfc->pe_ident[0] = 'P'; intfc->pe_ident[1] = '1'; intfc->pe_fd = fd; intfc->pe_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->pe_offsetsize = offsetsize; intfc->pe_pointersize = offsetsize; intfc->pe_filesize = filesize; intfc->pe_ftype = ftype; /* pe_path set by caller */ #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; intfc->pe_endian = DW_OBJECT_LSB; } else { intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; intfc->pe_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; intfc->pe_endian = DW_OBJECT_LSB; } else { intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; intfc->pe_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ res = dwarf_load_pe_sections(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_pe_access(localdoas); localdoas = 0; return res; } free(localdoas); localdoas = 0; return DW_DLV_OK; } static int _dwarf_pe_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_pe_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_pe_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_pe_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ /* *err is already set. and the call freed internals */ return DW_DLV_ERROR; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &pe_methods; *binary_interface = intfc; return DW_DLV_OK; } libdwarf-20210528/dwarfdump/0000775000175000017500000000000014054271043012545 500000000000000libdwarf-20210528/dwarfdump/buildopscounttab.c0000664000175000017500000001070414003113376016212 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. This software file is hereby placed in the public domain. For use by anyone for any purpose. */ /* This uses this condensed table to make a simple fast-access C table. Build and run with cc -I ../libdwarf buildopscounttab.c dwarf_names.c -o buildop ./buildop >opscounttab.c */ #include #include "dwarf.h" #include "dwarf_names.h" #include "opscounttab.h" struct ops_table_s { unsigned char ot_first; unsigned char ot_last; signed char ot_opcount; }; /* Must match libdwarf.h macros */ #define DW_DLV_OK 0 #define DW_DLV_ERROR -1 struct ops_table_s optabsource[]= { {DW_OP_addr , 0 , 1 }, {DW_OP_deref , 0 , 0 }, {DW_OP_const1u, DW_OP_consts , 1}, {DW_OP_dup, DW_OP_over , 0}, {DW_OP_pick, 0 , 1}, {DW_OP_swap, DW_OP_plus , 0}, {DW_OP_plus_uconst, 0 , 1}, {DW_OP_shl, DW_OP_xor , 0}, {DW_OP_bra , 0 , 1}, {DW_OP_eq, DW_OP_ne , 0}, {DW_OP_skip, 0 , 1}, {DW_OP_lit0 , DW_OP_lit31 , 0}, {DW_OP_reg0 , DW_OP_reg31 , 0}, {DW_OP_breg0 , DW_OP_breg31 , 1}, {DW_OP_regx , DW_OP_fbreg , 1}, {DW_OP_bregx, 0 , 2}, {DW_OP_piece, DW_OP_xderef_size , 1}, {DW_OP_nop , DW_OP_push_object_address ,0}, {DW_OP_call2, DW_OP_call_ref , 1}, {DW_OP_form_tls_address, DW_OP_call_frame_cfa , 0}, {DW_OP_bit_piece, DW_OP_implicit_value , 2}, {DW_OP_stack_value, 0 , 0}, {DW_OP_implicit_pointer, 0 , 2}, {DW_OP_addrx, DW_OP_constx , 1}, {DW_OP_entry_value, 0 , 2}, {DW_OP_const_type, 0 , 3}, {DW_OP_regval_type, DW_OP_deref_type , 2}, {DW_OP_xderef_type, 0, 0}, {DW_OP_convert, DW_OP_reinterpret , 1}, {DW_OP_GNU_push_tls_address, 0,0 }, {DW_OP_GNU_uninit, 0 , 0}, {DW_OP_GNU_encoded_addr, 0 , 1}, {DW_OP_GNU_implicit_pointer,DW_OP_GNU_entry_value , 2}, {DW_OP_GNU_const_type, 0 , 3}, {DW_OP_GNU_regval_type,DW_OP_GNU_deref_type , 2}, {DW_OP_GNU_convert, DW_OP_GNU_variable_value, 1}, {0,0} }; int main() { struct ops_table_s *op; int inindex = 0; int outindex = 0; int f = 0; int l = 0; int c = 0; int res = 0; int lastop = 0; printf("/* Generated expression ops table,\n"); printf(" do not edit. */\n"); printf("#include \"opscounttab.h\"\n"); printf("\n"); printf("struct dwarf_opscounttab_s dwarf_opscounttab[] = {\n"); for ( ; ; ++inindex) { const char *opn = 0; op = &optabsource[inindex]; f = op->ot_first; if (!f) { break; } if (lastop && f < lastop) { printf("FAILED buildopscounttab on OP,out of sequence" " f=0x%x lastop=0x%x\n", (unsigned)f,(unsigned)lastop); return 1; /* effectively exit(1) */ } l = op->ot_last; c = op->ot_opcount; while (f > outindex) { printf("{/* %-26s 0x%02x*/ %d},\n","unused",outindex,-1); ++outindex; } if (!l) { res = dwarf_get_OP_name(f,&opn); if (res != DW_DLV_OK) { printf("FAILED buildopscounttab on OP 0x%x\n", f); return 1; /* effectively exit(1) */ } lastop = f; printf("{/* %-26s 0x%02x*/ %d},\n",opn,f,c); ++outindex; } else { int j = f; for ( ; j <= l; ++j) { res = dwarf_get_OP_name(j,&opn); if (res != DW_DLV_OK) { printf("FAILED buildopscounttab on OP 0x%x\n", f); return 1; /* effectively exit(1); */ } printf("{/* %-26s 0x%2x*/ %d},\n",opn,j,c); ++outindex; lastop = j; } } } while (outindex < DWOPS_ARRAY_SIZE) { printf("{/* %-26s 0x%02x*/ %d},\n","unused",outindex,-1); ++outindex; } printf("};\n"); return 0; } libdwarf-20210528/dwarfdump/glflags.h0000664000175000017500000003752014020776756014302 00000000000000/* Copyright (C) 2017-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef GLFLAGS_H #define GLFLAGS_H /* All the dwarfdump flags are gathered into a single global struct as it has been hard to know how many there were or what they were all for. */ struct esb_s; struct dwconf_s; enum line_flag_type_e { singledw5,/* Meaning choose single table DWARF5 new interfaces. */ s2l, /* Meaning choose two-level DWARF5 new interfaces. */ orig, /* Meaning choose DWARF2,3,4 single level interface. */ orig2l /* Meaning choose DWARF 2,3,4 two-level interface. */ }; /* Check categories corresponding to the -k option */ typedef enum /* Dwarf_Check_Categories */ { abbrev_code_result, pubname_attr_result, reloc_offset_result, attr_tag_result, tag_tree_result, type_offset_result, decl_file_result, ranges_result, lines_result, aranges_result, /* Harmless errors are errors detected inside libdwarf but not reported via DW_DLE_ERROR returns because the errors won't really affect client code. The 'harmless' errors are reported and otherwise ignored. It is difficult to report the error when the error is noticed by libdwarf, the error is reported at a later time. The other errors dwarfdump reports are also generally harmless but are detected by dwarfdump so it's possble to report the error as soon as the error is discovered. */ harmless_result, fde_duplication, frames_result, locations_result, names_result, abbreviations_result, dwarf_constants_result, di_gaps_result, forward_decl_result, self_references_result, attr_encoding_result, duplicated_attributes_result, total_check_result, attr_formclass_result, LAST_CATEGORY /* Must be last */ } Dwarf_Check_Categories; struct section_high_offsets_s { Dwarf_Unsigned debug_info_size; Dwarf_Unsigned debug_abbrev_size; Dwarf_Unsigned debug_line_size; Dwarf_Unsigned debug_loc_size; Dwarf_Unsigned debug_aranges_size; Dwarf_Unsigned debug_macinfo_size; Dwarf_Unsigned debug_pubnames_size; Dwarf_Unsigned debug_str_size; Dwarf_Unsigned debug_frame_size; Dwarf_Unsigned debug_ranges_size; Dwarf_Unsigned debug_pubtypes_size; Dwarf_Unsigned debug_types_size; Dwarf_Unsigned debug_macro_size; Dwarf_Unsigned debug_str_offsets_size; Dwarf_Unsigned debug_sup_size; Dwarf_Unsigned debug_cu_index_size; Dwarf_Unsigned debug_tu_index_size; }; /* Options to enable debug tracing. */ #define MAX_TRACE_LEVEL 10 struct glflags_s { /* This so both dwarf_loclist_n() and dwarf_get_loclist_c() and the dwarf_loclist_from_expr variations can be tested. Defaults to new dwarf_get_loclist_c(). See -g option. original IRIX dwarf_loclist() no longer tested as of October 2015. */ Dwarf_Bool gf_use_old_dwarf_loclist; enum line_flag_type_e gf_line_flag_selection; Dwarf_Bool gf_abbrev_flag; Dwarf_Bool gf_aranges_flag; /* .debug_aranges section. */ Dwarf_Bool gf_debug_names_flag; /* .debug_names section */ Dwarf_Bool gf_eh_frame_flag; /* GNU .eh_frame section. */ Dwarf_Bool gf_frame_flag; /* .debug_frame section. */ Dwarf_Bool gf_gdbindex_flag; /* .gdbindex section. */ Dwarf_Bool gf_gnu_debuglink_flag; /* .gnu_debuglink section. */ Dwarf_Bool gf_debug_gnu_flag; /* .debug_gnu_pubtypes, pubnames*/ Dwarf_Bool gf_debug_sup_flag; /* .debug_sup */ Dwarf_Bool gf_info_flag; /* .debug_info */ Dwarf_Bool gf_line_flag; Dwarf_Bool gf_no_follow_debuglink; Dwarf_Bool gf_line_print_pc; Dwarf_Bool gf_line_skeleton_flag; Dwarf_Bool gf_loc_flag; Dwarf_Bool gf_macinfo_flag; /* DWARF2,3,4. Old macro section*/ Dwarf_Bool gf_macro_flag; /* DWARF5 */ Dwarf_Bool gf_pubnames_flag; Dwarf_Bool gf_ranges_flag; /* .debug_ranges section. */ Dwarf_Bool gf_reloc_flag; /* Elf relocations, not DWARF. */ Dwarf_Bool gf_static_func_flag;/* SGI only */ Dwarf_Bool gf_static_var_flag; /* SGI only */ Dwarf_Bool gf_string_flag; Dwarf_Bool gf_pubtypes_flag; /* SGI only */ Dwarf_Bool gf_types_flag; /* .debug_types, not all CU types */ Dwarf_Bool gf_weakname_flag; /* SGI only */ Dwarf_Bool gf_header_flag; /* Control printing of Elf header. */ Dwarf_Bool gf_section_groups_flag; /* Print list of CUs per compiler */ Dwarf_Bool gf_producer_children_flag; Dwarf_Bool gf_check_abbrev_code; Dwarf_Bool gf_check_pubname_attr; Dwarf_Bool gf_check_reloc_offset; Dwarf_Bool gf_check_tag_attr; Dwarf_Bool gf_check_tag_tree; Dwarf_Bool gf_check_type_offset; Dwarf_Bool gf_check_decl_file; Dwarf_Bool gf_check_macros; Dwarf_Bool gf_check_lines; Dwarf_Bool gf_check_fdes; Dwarf_Bool gf_check_ranges; Dwarf_Bool gf_check_aranges; Dwarf_Bool gf_check_harmless; Dwarf_Bool gf_check_abbreviations; Dwarf_Bool gf_check_dwarf_constants; Dwarf_Bool gf_check_di_gaps; Dwarf_Bool gf_check_forward_decl; Dwarf_Bool gf_check_self_references; Dwarf_Bool gf_check_attr_encoding; /* Attributes encoding */ Dwarf_Bool gf_generic_1200_regs; Dwarf_Bool gf_suppress_check_extensions_tables; Dwarf_Bool gf_check_duplicated_attributes; /* lots of checks make no sense on a dwp debugfission object. */ Dwarf_Bool gf_suppress_checking_on_dwp; /* suppress_nested_name_search is a band-aid. A workaround. A real fix for N**2 behavior is needed. */ Dwarf_Bool gf_suppress_nested_name_search; Dwarf_Bool gf_uri_options_translation; Dwarf_Bool gf_do_print_uri_in_input; /* Print global (unique) error messages */ Dwarf_Bool gf_print_unique_errors; Dwarf_Bool gf_found_error_message; Dwarf_Bool gf_check_names; /* During '-k' mode, display errors */ Dwarf_Bool gf_check_verbose_mode; Dwarf_Bool gf_check_frames; Dwarf_Bool gf_check_frames_extended; /* Extensive frames check */ Dwarf_Bool gf_check_locations; /* Location list check */ Dwarf_Bool gf_print_usage_tag_attr; /* Print basic usage */ Dwarf_Bool gf_print_usage_tag_attr_full; /* Print full usage */ Dwarf_Bool gf_check_all_compilers; Dwarf_Bool gf_check_snc_compiler; /* Check SNC compiler */ Dwarf_Bool gf_check_gcc_compiler; Dwarf_Bool gf_print_summary_all; Dwarf_Bool gf_file_use_no_libelf; /* The check and print flags here make it easy to allow check-only or print-only. We no longer support check-and-print in a single run. */ Dwarf_Bool gf_do_check_dwarf; Dwarf_Bool gf_do_print_dwarf; Dwarf_Bool gf_check_show_results; /* Display checks results. */ Dwarf_Bool gf_record_dwarf_error; /* A test has failed, this is normally set FALSE shortly after being set TRUE, it is a short-range hint we should print something we might not otherwise print (under the circumstances). */ Dwarf_Bool gf_check_debug_names; Dwarf_Bool gf_no_sanitize_strings; /* Display parent/children when in wide format? */ Dwarf_Bool gf_display_parent_tree; Dwarf_Bool gf_display_children_tree; int gf_stop_indent_level; /* ====Searching for function name (printing frame data). */ /* split dwarf lookup by address or die. if non-zero then .debug_addr is needed but missing. Tells dwarfdump to only search by address locally. */ char gf_debug_addr_missing; /* Other error in lookup by address or by_die */ int gf_error_code_search_by_address; /* Avoid some unneccesary work lookup by address. */ char gf_all_cus_seen_search_by_address; /* Die indents >= this prefix an indent count instead of actual spaces. */ int gf_max_space_indent; /* ====End searching for function name. */ /* Print search results in wide format? */ Dwarf_Bool gf_search_wide_format; /* -S option: strings for 'any' and 'match' */ Dwarf_Bool gf_search_is_on; Dwarf_Bool gf_search_print_results; Dwarf_Bool gf_cu_name_flag; Dwarf_Bool gf_show_global_offsets; Dwarf_Bool gf_display_offsets; Dwarf_Bool gf_print_str_offsets; Dwarf_Bool gf_expr_ops_joined; Dwarf_Bool gf_print_raw_rnglists; Dwarf_Bool gf_print_raw_loclists; unsigned long gf_count_major_errors; unsigned long gf_count_macronotes; char ** gf_global_debuglink_paths; unsigned gf_global_debuglink_count; /* Base address has a special meaning in DWARF4,5 relative to address ranges. */ Dwarf_Bool seen_PU; /* Detected a PU */ Dwarf_Bool seen_CU; /* Detected a CU */ Dwarf_Bool need_CU_name; /* Need CU name */ Dwarf_Bool need_CU_base_address; /* Need CU Base address */ Dwarf_Bool need_CU_high_address; /* Need CU High address */ Dwarf_Bool need_PU_valid_code; /* Need PU valid code */ Dwarf_Bool in_valid_code; /* set/reset in subprogram and compile-unit DIES.*/ Dwarf_Bool seen_PU_base_address; /* Detected a Base address for PU */ Dwarf_Bool seen_PU_high_address; /* Detected a High address for PU */ Dwarf_Addr PU_base_address; /* PU Base address */ Dwarf_Addr PU_high_address; /* PU High address */ Dwarf_Off DIE_offset; /* DIE offset in compile unit */ Dwarf_Off DIE_overall_offset; /* DIE offset in .debug_info */ /* These globals enable better error reporting. */ Dwarf_Off DIE_CU_offset; /* CU DIE offset in compile unit */ /* CU DIE offset in .debug_info */ Dwarf_Off DIE_CU_overall_offset; int current_section_id; /* Section being process */ /* Base Address is needed for range lists and must come from a CU. Low address is for information and can come from a function or something in the CU. */ Dwarf_Addr CU_base_address; /* CU Base address */ Dwarf_Addr CU_low_address; /* CU low address */ Dwarf_Addr CU_high_address; /* CU High address */ Dwarf_Off fde_offset_for_cu_low; Dwarf_Off fde_offset_for_cu_high; const char *program_name; const char *program_fullname; const char *search_any_text; const char *search_match_text; const char *search_regex_text; int search_occurrences; /* -S option: the compiled_regex */ #ifdef HAVE_REGEX regex_t *search_re; #endif /* Start verbose at zero. verbose can be incremented with -v but not decremented. */ int verbose; int gf_show_dwarfdump_conf;/* Incremented with --show-dwarfdump-conf, never decremented */ Dwarf_Bool dense; Dwarf_Bool ellipsis; Dwarf_Bool show_form_used; /* break_after_n_units is mainly for testing. It enables easy limiting of output size/running time when one wants the output limited. For example, -H 2 limits the -i output to 2 compilation units and the -f or -F output to 2 FDEs and 2 CIEs. */ int break_after_n_units; struct section_high_offsets_s *section_high_offsets_global; /* pRangesInfo records the DW_AT_high_pc and DW_AT_low_pc and is used to check that line range info falls inside the known valid ranges. The data is per CU, and is reset per CU in tag_specific_checks_setup(). */ Bucket_Group *pRangesInfo; /* pLinkonceInfo records data about the link once sections. If a line range is not valid in the current CU it might be valid in a linkonce section, this data records the linkonce sections. So it is filled in when an object file is read and remains unchanged for an entire object file. */ Bucket_Group *pLinkonceInfo; /* pVisitedInfo records a recursive traversal of DIE attributes DW_AT_specification DW_AT_abstract_origin DW_AT_type that let DWARF refer (as in a general graph) to arbitrary other DIEs. These traversals use pVisitedInfo to detect any compiler errors that introduce circular references. Printing of the traversals is also done on request. Entries are added and deleted as they are visited in a depth-first traversal. */ Bucket_Group *pVisitedInfo; /* Compilation Unit information for improved error messages. If the strings are too short we just truncate so fixed length here is fine. */ #define COMPILE_UNIT_NAME_LEN 512 char PU_name[COMPILE_UNIT_NAME_LEN]; /* PU Name */ char CU_name[COMPILE_UNIT_NAME_LEN]; /* CU Name */ char CU_producer[COMPILE_UNIT_NAME_LEN]; /* CU Producer Name */ /* Options to enable debug tracing. */ int nTrace[MAX_TRACE_LEVEL + 1]; /* Output filename */ const char *output_file; int group_number; /* Global esb-buffers. */ struct esb_s *newprogname; struct esb_s *cu_name; struct esb_s *config_file_path; struct esb_s *config_file_tiedpath; struct dwconf_s *config_file_data; /* Check errors. */ int check_error; int gf_print_alloc_sums; }; extern struct glflags_s glflags; void init_global_flags(void); void reset_global_flags(void); void set_checks_off(void); void reset_overall_CU_error_data(void); Dwarf_Bool cu_data_is_set(void); /* Shortcuts for additional trace options */ #define DUMP_OPTIONS 0 /* Dump options. */ #define DUMP_RANGES_INFO 1 /* Dump RangesInfo Table. */ /* Dump Location (.debug_loc) Info. */ #define DUMP_LOCATION_SECTION_INFO 2 /* Dump Ranges (.debug_ranges) Info. */ #define DUMP_RANGES_SECTION_INFO 3 #define DUMP_LINKONCE_INFO 4 /* Dump Linkonce Table. */ #define DUMP_VISITED_INFO 5 /* Dump Visited Info. */ #define dump_options glflags.nTrace[DUMP_OPTIONS] #define dump_ranges_info glflags.nTrace[DUMP_RANGES_INFO] #define dump_location_section_info \ glflags.nTrace[DUMP_LOCATION_SECTION_INFO] #define dump_ranges_section_info \ glflags.nTrace[DUMP_RANGES_SECTION_INFO] #define dump_linkonce_info glflags.nTrace[DUMP_LINKONCE_INFO] #define dump_visited_info glflags.nTrace[DUMP_VISITED_INFO] /* Section IDs */ #define DEBUG_ABBREV 1 #define DEBUG_ARANGES 2 #define DEBUG_FRAME 3 #define DEBUG_INFO 4 #define DEBUG_LINE 5 #define DEBUG_LOC 6 #define DEBUG_MACINFO 7 #define DEBUG_PUBNAMES 8 #define DEBUG_RANGES 9 #define DEBUG_STATIC_VARS 10 #define DEBUG_STATIC_FUNC 11 #define DEBUG_STR 12 #define DEBUG_WEAKNAMES 13 #define DEBUG_TYPES 14 #define DEBUG_GDB_INDEX 15 #define DEBUG_FRAME_EH_GNU 16 #define DEBUG_MACRO 17 #define DEBUG_NAMES 18 #define DEBUG_RNGLISTS 19 #define DEBUG_LOCLISTS 20 #define DEBUG_GNU_PUBNAMES 21 #define DEBUG_GNU_PUBTYPES 22 #define DEBUG_SUP 23 /* Print the information only if unique errors is set and it is first time */ #define PRINTING_UNIQUE (!glflags.gf_found_error_message) #endif /* GLFLAGS_H */ libdwarf-20210528/dwarfdump/print_frames.c0000664000175000017500000034202114004372161015322 00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011-2018 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* From 199x through 2010 print_frames relied on the order of the fdes matching the order of the functions in the CUs when it came to printing a function name with an FDE. This sometimes worked for SGI/IRIX because of the way the compiler often emitted things. It always worked poorly for gcc and other compilers. As of 2010 the addrmap.h addrmap.h code provides help in doing a better job when the tsearch functions (part of POSIX) are available. */ #include "globals.h" #include "print_frames.h" #include "dwconf.h" #include "dwconf_using_functions.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "addrmap.h" #include "naming.h" #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #define true 1 #define false 0 static void print_one_frame_reg_col(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned rule_id, Dwarf_Small value_type, Dwarf_Unsigned reg_used, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data, Dwarf_Signed offset_relevant, Dwarf_Signed offset, Dwarf_Ptr block_ptr); static void print_frame_inst_bytes(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Ptr cie_init_inst, Dwarf_Signed len, Dwarf_Signed data_alignment_factor, int code_alignment_factor, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data); /* A strcpy which ensures NUL terminated string and never overruns the output. */ void safe_strcpy(char *out, long outlen, const char *in, long inlen) { if (inlen >= (outlen - 1)) { strncpy(out, in, outlen - 1); out[outlen - 1] = 0; } else { strcpy(out, in); } } static void dealloc_local_atlist(Dwarf_Debug dbg, Dwarf_Attribute *atlist, Dwarf_Signed atcnt) { Dwarf_Signed k = 0; for (; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } /* Executing this for a reporting side effect, PRINT_CU_INFO() in dwarfdump.c. */ static void load_CU_error_data(Dwarf_Debug dbg,Dwarf_Die cu_die) { Dwarf_Signed atcnt = 0; Dwarf_Attribute *atlist = 0; Dwarf_Half tag = 0; char **srcfiles = 0; Dwarf_Signed srccnt = 0; int local_show_form_used = 0; int local_verbose = 0; int atres = 0; Dwarf_Signed i = 0; Dwarf_Signed k = 0; Dwarf_Error loadcuerr = 0; Dwarf_Off cu_die_goff = 0; if (!cu_die) { return; } atres = dwarf_attrlist(cu_die, &atlist, &atcnt, &loadcuerr); if (atres != DW_DLV_OK) { /* Something is seriously wrong if it is DW_DLV_ERROR. */ DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); return; } atres = dwarf_tag(cu_die, &tag, &loadcuerr); if (atres != DW_DLV_OK) { for (k = 0; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dealloc_local_atlist(dbg,atlist,atcnt); /* Something is seriously wrong if it is DW_DLV_ERROR. */ DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); return; } /* The offsets will be zero if it fails. Let it pass. */ atres = dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&loadcuerr); cu_die_goff = glflags.DIE_overall_offset; DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; for (i = 0; i < atcnt; i++) { Dwarf_Half attr = 0; int ares = 0; Dwarf_Attribute attrib = atlist[i]; ares = dwarf_whatattr(attrib, &attr, &loadcuerr); if (ares != DW_DLV_OK) { for (k = 0; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dealloc_local_atlist(dbg,atlist,atcnt); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); return; } /* For now we will not fully deal with the complexity of DW_AT_high_pc being an offset of low pc. */ switch(attr) { case DW_AT_low_pc: { ares = dwarf_formaddr(attrib, &glflags.CU_base_address, &loadcuerr); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); glflags.CU_low_address = glflags.CU_base_address; } break; case DW_AT_high_pc: { /* This is wrong for DWARF4 instances where the attribute is really an offset. It's also useless for CU DIEs that do not have the DW_AT_high_pc high so CU_high_address will be zero*/ ares = dwarf_formaddr(attrib, &glflags.CU_high_address, &loadcuerr); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); } break; case DW_AT_name: case DW_AT_producer: { const char *name = 0; struct esb_s namestr; esb_constructor(&namestr); ares = get_attr_value(dbg, tag, cu_die, /* die_indent_level */ 0, cu_die_goff,attrib, srcfiles, srccnt, &namestr, local_show_form_used,local_verbose, &loadcuerr); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); if (esb_string_len(&namestr)) { name = esb_get_string(&namestr); if (attr == DW_AT_name) { safe_strcpy(glflags.CU_name,sizeof( glflags.CU_name),name, strlen(name)); } else { safe_strcpy(glflags.CU_producer, sizeof(glflags.CU_producer), name,strlen(name)); } } esb_destructor(&namestr); } break; default: /* do nothing */ break; } } dealloc_local_atlist(dbg,atlist,atcnt); return; } #define MAXLEBLEN 10 #define BITSPERBYTE 8 /* decode ULEB */ static int local_dwarf_decode_u_leb128_chk(unsigned char *leb128, unsigned int *leb128_length, Dwarf_Unsigned *value_out, Dwarf_Small *data_end) { Dwarf_Unsigned byte = 0; Dwarf_Unsigned number = 0; unsigned int shift = 0; unsigned int byte_length = 1; byte = *leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } for (;;) { if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= (byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) { if (leb128_length != NULL) *leb128_length = byte_length; *value_out = number; return DW_DLV_OK; } byte_length++; if (byte_length > MAXLEBLEN) { return DW_DLV_ERROR; } ++leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } byte = *leb128; } return DW_DLV_ERROR; } #define BITSINBYTE 8 static int local_dwarf_decode_s_leb128_chk(unsigned char *leb128, unsigned int *leb128_length, Dwarf_Signed *value_out, Dwarf_Small *data_end) { Dwarf_Signed number = 0; Dwarf_Bool sign = 0; unsigned shift = 0; Dwarf_Unsigned byte = 0; unsigned byte_length = 1; /* byte_length being the number of bytes of data absorbed so far in turning the leb into a Dwarf_Signed. */ if (leb128 >= data_end) { return DW_DLV_ERROR; } byte = *leb128; for (;;) { sign = byte & 0x40; if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= (byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) { break; } ++leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } if (byte_length > MAXLEBLEN) { return DW_DLV_ERROR; } byte = *leb128; byte_length++; } if (sign) { /* The following avoids undefined behavior. */ unsigned shiftlim = sizeof(Dwarf_Signed) * BITSINBYTE -1; if (shift < shiftlim) { number |= -(Dwarf_Signed)(((Dwarf_Unsigned)1) << shift); } else if (shift == shiftlim) { number |= (((Dwarf_Unsigned)1) << shift); } } if (leb128_length != NULL) *leb128_length = byte_length; *value_out = number; return DW_DLV_OK; } /* For inlined functions, try to find name. If we fail due to error we hide the error. For now. Returns DW_DLV_OK or DW_DLV_NO_ENTRY for now. */ static int get_abstract_origin_funcname(Dwarf_Debug dbg,Dwarf_Attribute attr, struct esb_s *name_out) { Dwarf_Off off = 0; Dwarf_Die origin_die = 0; Dwarf_Attribute *atlist = NULL; Dwarf_Signed atcnt = 0; Dwarf_Signed i = 0; int dres = 0; int atres = 0; int name_found = 0; int res = 0; Dwarf_Error err = 0; res = dwarf_global_formref(attr,&off,&err); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,err,DW_DLA_ERROR); return DW_DLV_NO_ENTRY; } if (res == DW_DLV_NO_ENTRY) { return DW_DLV_NO_ENTRY; } dres = dwarf_offdie(dbg,off,&origin_die,&err); if (dres == DW_DLV_ERROR) { dwarf_dealloc(dbg,err,DW_DLA_ERROR); return DW_DLV_NO_ENTRY; } if (dres == DW_DLV_NO_ENTRY) { return DW_DLV_NO_ENTRY; } atres = dwarf_attrlist(origin_die, &atlist, &atcnt, &err); if (atres == DW_DLV_ERROR) { dwarf_dealloc(dbg,origin_die,DW_DLA_DIE); dwarf_dealloc(dbg,err,DW_DLA_ERROR); return DW_DLV_NO_ENTRY; } if (atres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg,origin_die,DW_DLA_DIE); return DW_DLV_NO_ENTRY; } for (i = 0; i < atcnt; i++) { Dwarf_Half lattr = 0; int ares = 0; ares = dwarf_whatattr(atlist[i], &lattr, &err); if (ares == DW_DLV_ERROR) { break; } else if (ares == DW_DLV_OK) { if (lattr == DW_AT_name) { int sres = 0; char* tempsl = 0; sres = dwarf_formstring(atlist[i], &tempsl, &err); if (sres == DW_DLV_OK) { esb_append(name_out,tempsl); name_found = true; break; } } } } for (i = 0; i < atcnt; i++) { dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); dwarf_dealloc(dbg,origin_die,DW_DLA_DIE); if (!name_found) { return DW_DLV_NO_ENTRY; } return DW_DLV_OK; } /* Returns DW_DLV_OK if a proc with this low_pc found. Else returns DW_DLV_NO_ENTRY. From print_die.c this has no pcMap passed in, we do not really have a sensible context, so this really just looks at the current attributes for a name. From print_frames.c we do have a pcMap. */ int get_proc_name_by_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, struct esb_s *proc_name, Dwarf_Die * cu_die_for_print_frames, void **pcMap, Dwarf_Error *err) { Dwarf_Signed atcnt = 0; Dwarf_Signed i = 0; Dwarf_Attribute *atlist = NULL; Dwarf_Addr low_pc_for_die = 0; int atres = 0; int funcpcfound = 0; int funcres = DW_DLV_OK; int funcnamefound = 0; int loop_ok = true; if (pcMap) { struct Addr_Map_Entry *ame = 0; ame = addr_map_find(low_pc,pcMap); if (ame && ame->mp_name) { /* mp_name is NULL only if we ran out of heap space. */ esb_append(proc_name,ame->mp_name); return DW_DLV_OK; } } if (glflags.gf_all_cus_seen_search_by_address) { return DW_DLV_NO_ENTRY; } if (glflags.gf_debug_addr_missing) { return DW_DLV_NO_ENTRY; } atres = dwarf_attrlist(die, &atlist, &atcnt, err); if (atres == DW_DLV_ERROR) { load_CU_error_data(dbg,*cu_die_for_print_frames); simple_err_only_return_action(atres, "\nERROR: dwarf_attrlist call fails in attempt " " to get a procedure/function name"); return atres; } if (atres == DW_DLV_NO_ENTRY) { return atres; } for (i = 0; i < atcnt; i++) { Dwarf_Half attr = 0; int ares = 0; char * temps = 0; int sres = 0; int dres = 0; if (!loop_ok) { break; } if (funcnamefound == 1 && funcpcfound == 1) { /* stop as soon as both found */ break; } ares = dwarf_whatattr(atlist[i], &attr, err); if (ares == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); load_CU_error_data(dbg,*cu_die_for_print_frames); esb_append_printf_s(&m, "\nERROR: dwarf_whatattr fails with %s", dwarf_errmsg(*err)); simple_err_only_return_action(ares, esb_get_string(&m)); esb_destructor(&m); return DW_DLV_ERROR; } else if (ares == DW_DLV_OK) { Dwarf_Error aterr = 0; switch (attr) { case DW_AT_specification: case DW_AT_abstract_origin: if (!funcnamefound) { /* Only use this if we have not seen DW_AT_name yet .*/ int aores = get_abstract_origin_funcname(dbg, atlist[i], proc_name); if (aores == DW_DLV_OK) { /* FOUND THE NAME */ funcnamefound = 1; } } break; case DW_AT_name: /* Even if we saw DW_AT_abstract_origin, go ahead and take DW_AT_name. */ sres = dwarf_formstring(atlist[i], &temps, &aterr); if (sres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: " "formstring in get_proc_name failed\n"); esb_append(proc_name, "ERROR in dwarf_formstring!"); dwarf_dealloc(dbg,aterr,DW_DLA_ERROR); aterr = 0; } else if (sres == DW_DLV_NO_ENTRY) { esb_append(proc_name, "NO ENTRY on dwarf_formstring?!"); } else { esb_append(proc_name,temps); } funcnamefound = 1; /* FOUND THE NAME (sort of, if error) */ break; case DW_AT_low_pc: dres = dwarf_formaddr(atlist[i], &low_pc_for_die, &aterr); funcpcfound = 1; if (dres == DW_DLV_ERROR) { if (DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION == dwarf_errno(aterr)) { glflags.gf_debug_addr_missing = 1; } else { glflags.gf_count_major_errors++; printf("\nERROR: dwarf_formaddr() failed" " in get_proc_name. %s\n", dwarf_errmsg(aterr)); /* the long name is horrible */ if (!glflags.gf_error_code_search_by_address){ glflags.gf_error_code_search_by_address= dwarf_errno(aterr); } } dwarf_dealloc(dbg,aterr,DW_DLA_ERROR); aterr = 0; funcpcfound = 0; low_pc_for_die = 0; /* low_pc_for_die = ~low_pc; ??? */ loop_ok = false; /* ensure no match */ } else if (dres == DW_DLV_NO_ENTRY) { funcpcfound = 0; loop_ok = false; } break; default: break; } /* end switch */ } /* end DW_DLV_OK */ } /* end for loop on atcnt */ dealloc_local_atlist(dbg,atlist,atcnt); if (funcnamefound && funcpcfound && pcMap ) { /* Insert the name to map even if not the low_pc we are looking for. This version does extra work in that early symbols in a CU will be inserted multiple times (the extra times have no effect). */ addr_map_insert(low_pc_for_die,esb_get_string(proc_name), pcMap); } if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_for_die) { funcres = DW_DLV_NO_ENTRY; } return funcres; } /* Modified Depth First Search looking for the procedure: a) only looks for children of subprogram. b) With subprogram looks at current die *before* looking for a child. Needed since some languages, including SGI MP Fortran, have nested functions. Return 0 on failure, 1 on success. */ static int load_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, struct esb_s *ret_name, Dwarf_Die *cu_die_for_print_frames, void **pcMap, Dwarf_Error *err) { Dwarf_Die curdie = die; int die_locally_gotten = 0; Dwarf_Die prev_child = 0; Dwarf_Die newchild = 0; Dwarf_Die newsibling = 0; Dwarf_Half tag; int chres = DW_DLV_OK; struct esb_s nestname; esb_constructor(&nestname); while (chres == DW_DLV_OK) { int tres = 0; esb_empty_string(&nestname); tres = dwarf_tag(curdie, &tag, err); newchild = 0; if (tres == DW_DLV_OK) { int lchres = 0; if (tag == DW_TAG_subprogram) { int gotit = 0; Dwarf_Error locerr = 0; gotit = get_proc_name_by_die(dbg, curdie, low_pc, &nestname, cu_die_for_print_frames, pcMap,&locerr); if (gotit == DW_DLV_OK) { if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_append(ret_name,esb_get_string(&nestname)); esb_destructor(&nestname); return DW_DLV_OK; } if (gotit == DW_DLV_ERROR) { dwarf_dealloc(dbg,locerr,DW_DLA_ERROR); locerr = 0; } /* Check children of subprograms recursively should this really be check children of anything, or just children of subprograms? */ lchres = dwarf_child(curdie, &newchild, err); esb_empty_string(&nestname); if (lchres == DW_DLV_OK) { int newprog = 0; Dwarf_Error innererr = 0; /* look for inner subprogram */ newprog = load_nested_proc_name(dbg, newchild, low_pc, &nestname, cu_die_for_print_frames, pcMap,&innererr); dwarf_dealloc(dbg, newchild, DW_DLA_DIE); if (newprog == DW_DLV_OK) { /* Found it. We could just take this name or we could concatenate names together. For now, just take name */ if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_append(ret_name,esb_get_string( &nestname)); esb_destructor(&nestname); return DW_DLV_OK; } else if (newprog == DW_DLV_ERROR) { dwarf_dealloc(dbg,innererr,DW_DLA_ERROR); innererr = 0; } } else if (lchres == DW_DLV_NO_ENTRY) { /* nothing to do */ } else { load_CU_error_data(dbg,*cu_die_for_print_frames); simple_err_only_return_action(lchres, "\nERROR:load_nested_proc_name dwarf_child()" " failed."); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_destructor(&nestname); return lchres; } } /* end if TAG_subprogram */ } else { esb_empty_string(&nestname); if (tres == DW_DLV_ERROR) { struct esb_s m; load_CU_error_data(dbg,*cu_die_for_print_frames); esb_constructor(&m); esb_append_printf_s(&m, "\nERROR: load_nested_proc_name dwarf_tag failed:" " trying to get proc name. " "Error is %s.",dwarf_errmsg(*err)); simple_err_only_return_action(tres, esb_get_string(&m)); esb_destructor(&m); esb_destructor(&nestname); return tres; } if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_destructor(&nestname); return DW_DLV_NO_ENTRY; } /* try next sibling */ prev_child = curdie; esb_empty_string(&nestname); chres = dwarf_siblingof(dbg, curdie, &newsibling, err); if (chres == DW_DLV_ERROR) { struct esb_s m; load_CU_error_data(dbg,*cu_die_for_print_frames); esb_constructor(&m); esb_append(&m, "\nERROR: Looking for function name for " "a frame. " "dwarf_siblingof failed" " trying to get the name. "); print_error_and_continue(dbg, esb_get_string(&m), chres,*err); esb_destructor(&m); DROP_ERROR_INSTANCE(dbg,chres,*err); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_destructor(&nestname); return DW_DLV_NO_ENTRY; } else if (chres == DW_DLV_NO_ENTRY) { if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); } /* Not there at this level */ esb_destructor(&nestname); return DW_DLV_NO_ENTRY; } /* DW_DLV_OK */ curdie = newsibling; if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); } prev_child = 0; die_locally_gotten = 1; } if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } esb_destructor(&nestname); return DW_DLV_NO_ENTRY; } /* For SGI MP Fortran and other languages, functions nest! As a result, we must dig thru all functions, not just the top level. This remembers the CU die and restarts each search at the start of the current cu. Return DW_DLV_OK means found name. Return DW_DLV_NO_ENTRY means not found name. Never returns DW_DLV_ERROR */ static int get_fde_proc_name_by_address(Dwarf_Debug dbg, Dwarf_Addr low_pc, const char *frame_section_name, struct esb_s *name, Dwarf_Die *cu_die_for_print_frames, void **pcMap,Dwarf_Error *err) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_offset = 0; int cures = DW_DLV_OK; int dres = DW_DLV_OK; int chres = DW_DLV_OK; struct Addr_Map_Entry *ame = 0; ame = addr_map_find(low_pc,pcMap); if (ame && ame->mp_name) { esb_append(name,ame->mp_name); return DW_DLV_OK; } if (glflags.gf_all_cus_seen_search_by_address) { return DW_DLV_NO_ENTRY; } if (glflags.gf_debug_addr_missing) { return DW_DLV_NO_ENTRY; } if (*cu_die_for_print_frames == NULL) { /* Call depends on dbg->cu_context to know what to do. */ cures = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_offset, err); if (cures == DW_DLV_ERROR) { /* If there is a serious error in DIE information we just skip looking for a procedure name. Perhaps we should report something? */ printf("\nERROR: Error getting next cu header " "looking for a subroutine" "/procedure name. Section %s. Err is %s\n", sanitized(frame_section_name), dwarf_errmsg(*err)); glflags.gf_all_cus_seen_search_by_address = 1; DROP_ERROR_INSTANCE(dbg,cures,*err); return DW_DLV_NO_ENTRY; } else if (cures == DW_DLV_NO_ENTRY) { /* loop thru the list again */ *cu_die_for_print_frames = 0; } else { /* DW_DLV_OK */ dres = dwarf_siblingof(dbg, NULL, cu_die_for_print_frames, err); if (dres == DW_DLV_ERROR) { /* If there is a serious error in DIE information we just skip looking for a procedure name. Perhaps we should report something? */ printf("\nERROR: Error getting " "dwarf_siblingof when looking for" " procedure name. " "Section %s. Err is %s\n", sanitized(frame_section_name), dwarf_errmsg(*err)); glflags.gf_count_major_errors++; DROP_ERROR_INSTANCE(dbg,dres,*err); glflags.gf_all_cus_seen_search_by_address = 1; return DW_DLV_NO_ENTRY;; } if (dres == DW_DLV_NO_ENTRY) { /* No initial die? Something is wrong! */ return dres; } } } if (dres == DW_DLV_OK) { Dwarf_Die child = 0; if (*cu_die_for_print_frames == 0) { /* no information. Possibly a stripped file */ return DW_DLV_NO_ENTRY; } chres = dwarf_child(*cu_die_for_print_frames, &child, err); if (chres == DW_DLV_ERROR) { printf("\nERROR: Error getting " "dwarf_child(). " "Section %s. Err is %s\n", sanitized(frame_section_name), dwarf_errmsg(*err)); DROP_ERROR_INSTANCE(dbg,chres,*err); glflags.gf_count_major_errors++; glflags.gf_all_cus_seen_search_by_address = 1; return DW_DLV_NO_ENTRY; } else if (chres == DW_DLV_NO_ENTRY) { /* FALL THROUGH to look for more CU headers */ } else { /* DW_DLV_OK */ int gotname = 0; gotname = load_nested_proc_name(dbg, child, low_pc, name, cu_die_for_print_frames, pcMap,err); dwarf_dealloc(dbg, child, DW_DLA_DIE); if (gotname == DW_DLV_OK) { return DW_DLV_OK; } if (gotname == DW_DLV_ERROR) { glflags.gf_all_cus_seen_search_by_address = 1; DROP_ERROR_INSTANCE(dbg,gotname,*err); return DW_DLV_NO_ENTRY; } child = 0; } } for (;;) { Dwarf_Die ldie = 0; cures = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_offset, err); if (cures != DW_DLV_OK) { if (cures == DW_DLV_ERROR) { printf("\nERROR: Error getting " "next_cu_header " "Section %s. Err is %s\n", sanitized(frame_section_name), dwarf_errmsg(*err)); DROP_ERROR_INSTANCE(dbg,cures,*err); glflags.gf_count_major_errors++; glflags.gf_all_cus_seen_search_by_address = 1; return DW_DLV_NO_ENTRY; } glflags.gf_all_cus_seen_search_by_address = 1; break; } dres = dwarf_siblingof(dbg, NULL, &ldie, err); if (*cu_die_for_print_frames) { dwarf_dealloc(dbg, *cu_die_for_print_frames,DW_DLA_DIE); *cu_die_for_print_frames = 0; } if (dres == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,dres,*err); glflags.gf_all_cus_seen_search_by_address = 1; return dres; } else if (dres == DW_DLV_NO_ENTRY) { return dres; } /* DW_DLV_OK In normal processing (ie, when doing print_info() we would call print_attribute for each die including cu_die and thus get CU_base_address, CU_high_address, PU_base_address, PU_high_address, CU_name for PRINT_CU_INFO() in case of error. */ *cu_die_for_print_frames = ldie; { int chpfres = 0; Dwarf_Die child = 0; chpfres = dwarf_child(*cu_die_for_print_frames, &child, err); if (chpfres == DW_DLV_ERROR) { load_CU_error_data(dbg,*cu_die_for_print_frames); glflags.gf_count_major_errors++; printf("\nERROR: Getting procedure name " "dwarf_child fails " " %s\n",dwarf_errmsg(*err)); DROP_ERROR_INSTANCE(dbg,chpfres,*err); glflags.gf_all_cus_seen_search_by_address = 1; return DW_DLV_NO_ENTRY; } else if (chpfres == DW_DLV_NO_ENTRY) { /* FALL THROUGH to loop more */ } else { /* DW_DLV_OK) */ int gotname = 0; gotname = load_nested_proc_name(dbg, child, low_pc, name, cu_die_for_print_frames, pcMap,err); dwarf_dealloc(dbg, child, DW_DLA_DIE); if (gotname == DW_DLV_OK) { return gotname; } if (gotname == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,gotname,*err); glflags.gf_all_cus_seen_search_by_address = 1; return DW_DLV_NO_ENTRY; } } } reset_overall_CU_error_data(); } return DW_DLV_NO_ENTRY; } /* Attempting to take care of overflows so we only accept good as true. */ static Dwarf_Bool valid_fde_content(Dwarf_Small * fde_start, Dwarf_Unsigned fde_length, Dwarf_Small * data_ptr, Dwarf_Unsigned data_ptr_length) { Dwarf_Small * fde_end = fde_start + fde_length; Dwarf_Small * data_end = 0; if (data_ptr < fde_start || data_ptr >= fde_end) { return false; } data_end = data_ptr + data_ptr_length; if ( data_end < fde_start || data_end < data_ptr) { return false; } if ( data_end >= fde_end) { return false; } return true; } /* Gather the fde print logic here so the control logic determining what FDE to print is clearer. */ static int print_one_fde(Dwarf_Debug dbg, const char *frame_section_name, Dwarf_Fde fde, Dwarf_Unsigned fde_index, Dwarf_Cie * cie_data, Dwarf_Signed cie_element_count, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Half version, int is_eh, struct dwconf_s *config_data, void ** pcMap, void ** lowpcSet, Dwarf_Die *cu_die_for_print_frames, Dwarf_Error *err) { Dwarf_Addr j = 0; Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Addr end_func_addr = 0; Dwarf_Ptr fde_bytes = NULL; Dwarf_Unsigned fde_bytes_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Signed eh_table_offset = 0; int fres = 0; int offres = 0; struct esb_s temps; int printed_intro_addr = 0; char local_buf[100]; char temps_buf[200]; fres = dwarf_get_fde_range(fde, &low_pc, &func_length, &fde_bytes, &fde_bytes_length, &cie_offset, &cie_index, &fde_offset, err); if (fres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: calling dwarf_get_fde_range() on " "index %" DW_PR_DUu "gets an error! Error is %s\n", fde_index,dwarf_errmsg(*err)); return fres; } if (fres == DW_DLV_NO_ENTRY) { return DW_DLV_NO_ENTRY; } if (glflags.gf_cu_name_flag && glflags.fde_offset_for_cu_low != DW_DLV_BADOFFSET && (fde_offset < glflags.fde_offset_for_cu_low || fde_offset > glflags.fde_offset_for_cu_high)) { return DW_DLV_NO_ENTRY; } /* eh_table_offset is IRIX ONLY. */ fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, err); if (fres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: Got error looking for SGI-only " "exception table " "offset from fde! Error is %s\n", dwarf_errmsg(*err)); return fres; } esb_constructor_fixed(&temps,temps_buf,sizeof(temps_buf)); if (glflags.gf_suppress_nested_name_search) { /* do nothing. */ } else { struct Addr_Map_Entry *mp = 0; esb_empty_string(&temps); mp = addr_map_find(low_pc,lowpcSet); if (glflags.gf_check_frames || glflags.gf_check_frames_extended) { DWARF_CHECK_COUNT(fde_duplication,1); } fres = get_fde_proc_name_by_address(dbg, low_pc, frame_section_name, &temps, cu_die_for_print_frames, pcMap,err); if (fres == DW_DLV_ERROR) { /* Failing to get the name is not a crucial thing. Do not error off. We should not get here as the invariant for get_fde_proc_name_by_address() says it never returns DW_DLV_ERROR; */ DROP_ERROR_INSTANCE(dbg,fres,*err); fres = DW_DLV_NO_ENTRY; } /* If found the name is in temps now, or temps is the empty string. */ if (mp) { if (glflags.gf_check_frames || glflags.gf_check_frames_extended) { struct esb_s msg; esb_constructor_fixed(&msg, local_buf,sizeof(local_buf)); if (esb_string_len(&temps) > 0) { esb_append_printf_u(&msg, "An fde low pc of 0x%" DW_PR_DUx " is not the first fde with that pc. ", low_pc); esb_append_printf_s(&msg, "The first is named \"%s\"", sanitized(esb_get_string(&temps))); } else { esb_append_printf_u(&msg, "An fde low pc of 0x%" DW_PR_DUx " is not the first fde with that pc. " "The first is not named.", (Dwarf_Unsigned)low_pc); } DWARF_CHECK_ERROR(fde_duplication, esb_get_string(&msg)); esb_destructor(&msg); } } else if (fres == DW_DLV_OK) { addr_map_insert(low_pc,0,lowpcSet); } /* Else we just don't know anything, so record nothing. */ } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { /* Printing the FDE header. */ printf("<%5" DW_PR_DSd ">" "<0x%" DW_PR_XZEROS DW_PR_DUx ":0x%" DW_PR_XZEROS DW_PR_DUx "><%s>" "" "", fde_index, (Dwarf_Unsigned)low_pc, (Dwarf_Unsigned)(low_pc + func_length), sanitized(esb_get_string(&temps)), (Dwarf_Unsigned)cie_offset, (Dwarf_Unsigned)cie_index, (Dwarf_Unsigned)fde_offset, fde_bytes_length); } esb_destructor(&temps); if (!is_eh) { /* IRIX uses eh_table_offset. No one else uses it. */ /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { if (eh_table_offset == DW_DLX_NO_EH_OFFSET) { printf("\n", "none"); } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) { printf("\n", "unknown"); } else { printf("\n", eh_table_offset); } } } else { /* Printing the .eh_frame header augmentation string, if any. */ int ares = 0; Dwarf_Small *data = 0; Dwarf_Unsigned len = 0; ares = dwarf_get_fde_augmentation_data(fde, &data, &len, err); if (ares == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: on getting augmentation data for an fde." " Error is %s\n",dwarf_errmsg(*err)); return ares; } if (ares == DW_DLV_NO_ENTRY) { /* do nothing. */ } else if (ares == DW_DLV_OK) { if (glflags.gf_do_print_dwarf) { printf("\n "); } } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf("\n"); } } end_func_addr = low_pc + func_length; for (j = low_pc; j < end_func_addr; j++) { Dwarf_Half k = 0; Dwarf_Addr cur_pc_in_table = 0; cur_pc_in_table = j; if (config_data->cf_interface_number == 3) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; Dwarf_Small value_type = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Signed offset = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Addr row_pc = 0; Dwarf_Bool has_more_rows = 0; Dwarf_Addr subsequent_pc = 0; int fires = dwarf_get_fde_info_for_cfa_reg3_b(fde, j, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, &has_more_rows, &subsequent_pc, err); offset = offset_or_block_len; if (fires == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: on getting fde details for " "fde row for address 0x%" DW_PR_XZEROS DW_PR_DUx "\n", j); return fires; } if (fires == DW_DLV_NO_ENTRY) { continue; } if (!has_more_rows) { j = low_pc+func_length-1; } else { if (subsequent_pc > j) { /* Loop head will increment j to make up for -1 here. */ j = subsequent_pc -1; } } /* Do not print if in check mode */ if (!printed_intro_addr && glflags.gf_do_print_dwarf) { printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ": ", (Dwarf_Unsigned)cur_pc_in_table); printed_intro_addr = 1; } print_one_frame_reg_col(dbg, *cu_die_for_print_frames, config_data->cf_cfa_reg, value_type, reg, address_size, offset_size,version, config_data, offset_relevant, offset, block_ptr); } for (k = 0; k < config_data->cf_table_entry_count; k++) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; int fires = 0; Dwarf_Small value_type = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Signed offset = 0; Dwarf_Addr row_pc = 0; if (config_data->cf_interface_number == 3) { fires = dwarf_get_fde_info_for_reg3(fde, k, cur_pc_in_table, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, err); offset = offset_or_block_len; } else { /* This interface is deprecated. Is the old MIPS/DWARF2 interface. */ /* ASSERT: config_data->cf_interface_number == 2 */ value_type = DW_EXPR_OFFSET; fires = dwarf_get_fde_info_for_reg(fde, k, cur_pc_in_table, &offset_relevant, ®, &offset, &row_pc, err); } if (fires == DW_DLV_ERROR) { printf("\n"); glflags.gf_count_major_errors++; printf("\nERROR: on getting fde details for " "row address 0x%" DW_PR_XZEROS DW_PR_DUx " table column %d.\n", j,k); return fires; } if (fires == DW_DLV_NO_ENTRY) { continue; } if (row_pc != cur_pc_in_table) { /* row_pc < cur_pc_in_table means this pc has no new register value, the last one found still applies hence this is a duplicate row. row_pc > j cannot happen, the libdwarf function will not return such. */ continue; } /* Do not print if in check mode */ if (!printed_intro_addr && glflags.gf_do_print_dwarf) { printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ": ", (Dwarf_Unsigned)j); printed_intro_addr = 1; } print_one_frame_reg_col(dbg, *cu_die_for_print_frames, k, value_type, reg, address_size, offset_size,version, config_data, offset_relevant, offset, block_ptr); } if (printed_intro_addr) { printf("\n"); printed_intro_addr = 0; } } if (glflags.verbose > 1) { Dwarf_Off fde_off = 0; Dwarf_Off cie_off = 0; /* Get the fde instructions and print them in raw form, just like cie instructions */ Dwarf_Ptr instrs = 0; Dwarf_Unsigned ilen = 0; int res = 0; res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, err); /* res will be checked below. */ offres = dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off, err); if (offres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: on getting fde section offset" " of this fde\n"); return offres; } if (offres == DW_DLV_OK) { /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf(" fde section offset %" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx " cie offset for fde: %" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned) fde_off, (Dwarf_Unsigned) fde_off, (Dwarf_Unsigned) cie_off, (Dwarf_Unsigned) cie_off); } } if (res == DW_DLV_ERROR) { /* DW_DLV_ERROR */ printf("\nERROR: on getting fde instruction bytes " "for fde index " "%" DW_PR_DUu "?\n", fde_index); glflags.gf_count_major_errors++; return res; } if (res == DW_DLV_OK) { int cires = 0; Dwarf_Unsigned cie_length = 0; Dwarf_Small cie_version = 0; char* augmenter = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; Dwarf_Half cie_offset_size = 0; if (cie_index >= cie_element_count) { glflags.gf_count_major_errors++; printf("\nERROR: Bad cie index %" DW_PR_DSd " with fde index %" DW_PR_DUu "! " "(table entry max %" DW_PR_DSd ")\n", cie_index, fde_index, cie_element_count); return DW_DLV_NO_ENTRY; } cires = dwarf_get_offset_size(dbg,&cie_offset_size,err); if ( cires != DW_DLV_OK) { return res; } cires = dwarf_get_cie_info_b(cie_data[cie_index], &cie_length, &cie_version, &augmenter, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &initial_instructions, &initial_instructions_length, &cie_offset_size, err); if (cires == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: Bad cie index %" DW_PR_DSd " with fde index %" DW_PR_DUu "!\n", cie_index, fde_index); return cires; } if (cires == DW_DLV_NO_ENTRY) { ; /* ? */ } else { /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { print_frame_inst_bytes(dbg, *cu_die_for_print_frames, instrs, (Dwarf_Signed) ilen, data_alignment_factor, (int) code_alignment_factor, address_size, cie_offset_size, cie_version, config_data); } } } else if (res == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("ERROR: Impossible: no instr bytes for fde index %" DW_PR_DUu "?\n", fde_index); glflags.gf_count_major_errors++; } } return DW_DLV_OK; } /* Print a cie. Gather the print logic here so the control logic deciding what to print is clearer. */ int print_one_cie(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Cie cie, Dwarf_Unsigned cie_index, Dwarf_Half address_size, struct dwconf_s *config_data, Dwarf_Error *err) { int cires = 0; Dwarf_Unsigned cie_length = 0; Dwarf_Small version = 0; char* augmenter = ""; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; Dwarf_Off cie_off = 0; Dwarf_Half offset_size = 0; cires = dwarf_get_offset_size(dbg,&offset_size,err); if ( cires == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: calling dwarf_get_offset_size() fails\n"); return cires; } cires = dwarf_get_cie_info(cie, &cie_length, &version, &augmenter, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &initial_instructions, &initial_instructions_length, err); if (cires == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: calling dwarf_get_cie_info() fails\n"); return cires; } if (cires == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("ERROR: Impossible DW_DLV_NO_ENTRY on cie %" DW_PR_DUu "\n", cie_index); return cires; } { if (glflags.gf_do_print_dwarf) { printf("<%5" DW_PR_DUu "> version %d\n", cie_index, version); cires = dwarf_cie_section_offset(dbg, cie, &cie_off, err); if (cires == DW_DLV_OK) { printf(" cie section offset %" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned) cie_off, (Dwarf_Unsigned) cie_off); } /* This augmentation is from .debug_frame or eh_frame of a cie. . A string. */ /* (" bytes of initial instructions %"*/ printf(" augmentation %s\n", sanitized(augmenter)); printf(" code_alignment_factor %" DW_PR_DUu "\n", code_alignment_factor); printf(" data_alignment_factor %" DW_PR_DSd "\n", data_alignment_factor); printf(" return_address_register %d\n", return_address_register_rule); } { int ares = 0; Dwarf_Small *data = 0; Dwarf_Unsigned len = 0; /* This call only returns DW_DLV_OK if the augmentation is cie aug from .eh_frame. The return is DW_DLV_OK only if there is eh_frame style augmentation bytes (its not a string). */ ares = dwarf_get_cie_augmentation_data(cie, &data, &len, err); if (ares == DW_DLV_NO_ENTRY) { /* No Aug data (len zero) do nothing. */ } else if (ares == DW_DLV_OK) { /* We have the gnu eh_frame aug data bytes. */ if (glflags.gf_do_print_dwarf) { unsigned k2 = 0; /* (" bytes of initial instructions %" */ printf(" eh aug data len 0x%" DW_PR_DUx , len); for (k2 = 0; data && k2 < len; ++k2) { if (k2 == 0) { printf(" bytes 0x"); } printf("%02x ", (unsigned char) data[k2]); } printf("\n"); } } else { /* DW_DLV_ERROR */ glflags.gf_count_major_errors++; printf("\nERROR: calling " "dwarf_get_cie_augmentation_data()" " fails.\n"); return ares; } } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf(" bytes of initial instructions %" DW_PR_DUu "\n", initial_instructions_length); printf(" cie length %" DW_PR_DUu "\n", cie_length); /* For better layout */ printf(" initial instructions\n"); print_frame_inst_bytes(dbg, die, initial_instructions, (Dwarf_Signed) initial_instructions_length, data_alignment_factor, (int) code_alignment_factor, address_size, offset_size,version,config_data); } } return DW_DLV_OK; } int print_location_operations(Dwarf_Debug dbg, Dwarf_Die die, int die_indent_level, Dwarf_Ptr bytes_in, Dwarf_Unsigned block_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct esb_s *out_string, Dwarf_Error *err) { Dwarf_Locdesc *locdescarray = 0; Dwarf_Signed listlen = 0; Dwarf_Unsigned ulistlen = 0; int res2 = 0; Dwarf_Addr baseaddr = 0; /* Really unknown */ /* See PRINTING_DIES macro in print_die.c */ if (!glflags.gf_use_old_dwarf_loclist) { Dwarf_Loc_Head_c head = 0; Dwarf_Locdesc_c locentry = 0; int lres = 0; Dwarf_Unsigned lopc = 0; Dwarf_Unsigned hipc = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Unsigned section_offset = 0; Dwarf_Unsigned locdesc_offset = 0; Dwarf_Small lle_value = 0; Dwarf_Small loclist_source = 0; res2 = dwarf_loclist_from_expr_c(dbg, bytes_in,block_len, addr_size, offset_size, version, &head, &ulistlen, err); if (res2 == DW_DLV_NO_ENTRY) { return res2; } if (res2 == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: calling dwarf_loclist_from_expr_c()"); return res2; } lres = dwarf_get_locdesc_entry_c(head, 0, /* Data from 0th LocDesc */ &lle_value, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, err); if (lres == DW_DLV_ERROR) { dwarf_loc_head_c_dealloc(head); glflags.gf_count_major_errors++; printf("\nERROR: calling dwarf_locdesc_entry_c()" " on LocDesc 0"); return lres; } else if (lres == DW_DLV_NO_ENTRY) { dwarf_loc_head_c_dealloc(head); return lres; } /* ASSERT: loclist_source == DW_LKIND_expression */ /* ASSERT: lle_value == DW_LLE_start_end */ lres = dwarfdump_print_location_operations(dbg, die, die_indent_level, NULL, locentry, 0, /* index 0: locdesc 0 */ ulocentry_count, DW_LKIND_expression /* loclist_source */, 0, /* no die indent*/ baseaddr, out_string,err); dwarf_loc_head_c_dealloc(head); return lres; } /* Using older loclist code here */ res2 =dwarf_loclist_from_expr_a(dbg, bytes_in,block_len, addr_size, &locdescarray, &listlen,err); if (res2 == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: calling dwarf_loclist_from_expr_a()\n"); return res2; } if (res2==DW_DLV_NO_ENTRY) { return res2; } /* listlen is always 1 */ ulistlen = listlen; res2 = dwarfdump_print_location_operations(dbg, die, die_indent_level, locdescarray, NULL, 0, ulistlen, DW_LKIND_expression, 0, /* no die indent*/ baseaddr, out_string,err); dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC); return res2; } /* DW_CFA_nop may be omitted for alignment, so we do not flag that one. */ static int lastop_pointless(int op) { if (op == DW_CFA_remember_state || op == DW_CFA_MIPS_advance_loc8 || op == DW_CFA_advance_loc || op == DW_CFA_advance_loc4 || op == DW_CFA_advance_loc2 || op == DW_CFA_advance_loc1 || op == DW_CFA_set_loc) { return true; } /* The last op is hopefully useful. */ return false; } /* iregion_start, iregion_end are the overall block of fde/cie instructions. idata, idata end are the area next to be read and they must lie within the iregion* range. The end address is one past the last byte. We are decoding here, libdwarf has not decoded these bytes, so it is up to us to check for corrupt data in the frame section. */ static int check_finstr_addrs(unsigned char *iregionstart, unsigned char *idata, unsigned char *idata_end, unsigned char *iregionend, const char *msg) { if ( idata > idata_end) { /* zero length allowed. But maybe overflow happened. */ glflags.gf_count_major_errors++; printf("ERROR: frame instruction internal error reading %s\n", msg); return DW_DLV_ERROR; } if (idata < iregionstart) { glflags.gf_count_major_errors++; printf("\nERROR: frame instruction overflow(?) reading" " %s\n", msg); return DW_DLV_ERROR; } if (idata_end > iregionend) { Dwarf_Unsigned bytes_in = 0; bytes_in = idata - iregionstart; glflags.gf_count_major_errors++; printf("\nERROR: frame instruction reads off end" " %" DW_PR_DUu " bytes into instructions for %s\n", bytes_in,msg); return DW_DLV_ERROR; } return DW_DLV_OK; } /* Print the frame instructions in detail for a glob of instructions. The frame data has not been checked by libdwarf as libdwarf has not transformed it into simple structs. We are reading the raw data. */ /*ARGSUSED*/ static void print_frame_inst_bytes(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Ptr cie_init_inst, Dwarf_Signed len_in, Dwarf_Signed data_alignment_factor, int code_alignment_factor, Dwarf_Half addr_size, Dwarf_Half offset_size,Dwarf_Half version, struct dwconf_s *config_data) { unsigned char *instp = (unsigned char *) cie_init_inst; unsigned char *startpoint = instp; Dwarf_Unsigned uval = 0; Dwarf_Unsigned uval2 = 0; unsigned int uleblen = 0; unsigned int off = 0; unsigned int loff = 0; unsigned u16 = 0; unsigned int u32 = 0; Dwarf_Unsigned u64 = 0; int res = 0; Dwarf_Small *endpoint = 0; Dwarf_Signed remaining_len = 0; int lastop = 0; char exprstr_buf[200]; void (*copy_word) (void *, const void *, unsigned long) = 0; copy_word = dwarf_get_endian_copy_function(dbg); if (!copy_word) { glflags.gf_count_major_errors++; printf("\nERROR: Unable to print frame instruction bytes. " "Missing the word-copy function\n"); return; } if (len_in <= 0) { return; } remaining_len = len_in; endpoint = instp + remaining_len; for (; remaining_len > 0;) { unsigned char ibyte = 0; int top = 0; int bottom = 0; int delta = 0; int reg = 0; if (check_finstr_addrs(startpoint,instp,instp+1,endpoint, "start next instruction") != DW_DLV_OK) { return; } ibyte = *instp; top = ibyte & 0xc0; bottom = ibyte & 0x3f; lastop = top; switch (top) { case DW_CFA_advance_loc: delta = ibyte & 0x3f; printf(" %2u DW_CFA_advance_loc %d", off, (int) (delta * code_alignment_factor)); if (glflags.verbose) { printf(" (%d * %d)", (int) delta, (int) code_alignment_factor); } printf("\n"); break; case DW_CFA_offset: loff = off; reg = ibyte & 0x3f; res = local_dwarf_decode_u_leb128_chk(instp + 1,&uleblen, &uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in DW_CFA_offset\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_offset ", loff); printreg(reg, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (((Dwarf_Signed) uval) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DUu " * %" DW_PR_DSd ")", uval, data_alignment_factor); } printf("\n"); break; case DW_CFA_restore: reg = ibyte & 0x3f; printf(" %2u DW_CFA_restore ", off); printreg(reg, config_data); printf("\n"); break; default: loff = off; lastop = top; switch (bottom) { case DW_CFA_set_loc: /* operand is address, so need address size */ /* which will be 4 or 8. */ if (check_finstr_addrs(startpoint, instp+1, instp+addr_size+1, endpoint, "DW_CFA_set_loc") != DW_DLV_OK) { return; } switch (addr_size) { case 4: { Dwarf_Unsigned v32 = 0; char b32[4]; memcpy(b32,instp+1,4); ASNAR(copy_word,v32, b32); uval = v32; } break; case 8: { Dwarf_Unsigned v64 = 0; char b64[8]; memcpy(b64,instp+1,8); ASNAR(copy_word,v64, b64); uval = v64; } break; default: glflags.gf_count_major_errors++; printf("\nERROR: Unexpected address size %d in " "DW_CFA_set_loc!\n", addr_size); uval = 0; } instp += addr_size; remaining_len -= (Dwarf_Signed) addr_size; off += addr_size; printf(" %2u DW_CFA_set_loc %" DW_PR_DUu "\n", loff, uval); break; case DW_CFA_advance_loc1: if (check_finstr_addrs(startpoint, instp+1, instp+2, endpoint, "DW_CFA_advance_loc1") != DW_DLV_OK) { return; } delta = (unsigned char) *(instp + 1); uval2 = delta; instp += 1; remaining_len -= 1; off += 1; printf(" %2u DW_CFA_advance_loc1 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_advance_loc2: if (check_finstr_addrs(startpoint, instp+1, instp+3, endpoint, "DW_CFA_advance_loc2") != DW_DLV_OK) { return; } { char u2[2]; memcpy(u2,instp+1,2); ASNAR(copy_word,u16,u2); } uval2 = u16; instp += 2; remaining_len -= 2; off += 2; printf(" %2u DW_CFA_advance_loc2 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_advance_loc4: if (check_finstr_addrs(startpoint, instp+1, instp+5, endpoint, "DW_CFA_advance_loc4") != DW_DLV_OK) { return; } { char u4[4]; memcpy(u4,instp+1,4); ASNAR(copy_word,u32,u4); } uval2 = u32; instp += 4; remaining_len -= 4; off += 4; printf(" %2u DW_CFA_advance_loc4 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_MIPS_advance_loc8: if (check_finstr_addrs(startpoint, instp+1, instp+9, endpoint, "DW_CFA_MIPS_advance_loc8") != DW_DLV_OK) { return; } { char u8[8]; memcpy(u8,instp+1,8); ASNAR(copy_word,u64,u8); } uval2 = u64; instp += 8; remaining_len -= 8; off += 8; printf(" %2u DW_CFA_MIPS_advance_loc8 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_offset_extended: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_offset_extended\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_offset_extended\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_offset_extended ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (((Dwarf_Signed) uval2) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DUu " * %d)", uval2, (int) data_alignment_factor); } printf("\n"); break; case DW_CFA_restore_extended: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_restore_extended\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_restore_extended ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_undefined: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_undefined\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_undefined ", loff); printreg( uval, config_data); printf("\n"); break; case DW_CFA_same_value: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_undefined\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_same_value ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_register: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_register\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_register\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_register ", loff); printreg(uval, config_data); printf(" = "); printreg(uval2, config_data); printf("\n"); break; case DW_CFA_remember_state: printf(" %2u DW_CFA_remember_state\n", loff); break; case DW_CFA_restore_state: printf(" %2u DW_CFA_restore_state\n", loff); break; case DW_CFA_def_cfa: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen, &uval2, endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa ", loff); printreg( uval, config_data); printf(" %" DW_PR_DUu , uval2); printf("\n"); break; case DW_CFA_def_cfa_register: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_register\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa_register ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_def_cfa_offset: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_offset\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa_offset %" DW_PR_DUu "\n", loff, uval); break; case DW_CFA_nop: printf(" %2u DW_CFA_nop\n", loff); break; case DW_CFA_def_cfa_expression: /* DWARF3 */ { Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_expression\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa_expression expr " "block len %" DW_PR_DUu "\n", loff, block_len); if (remaining_len < 0 || block_len > (Dwarf_Unsigned)remaining_len) { glflags.gf_count_major_errors++; printf("\nERROR: expression length %" DW_PR_DUu " too large for section." " DW_CFA_def_cfa_expression.\n", block_len); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_def_cfa_expression") != DW_DLV_OK) { return; } dump_block(" ", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; Dwarf_Error cerr = 0; int gres = 0; esb_constructor_fixed(&exprstring, exprstr_buf, sizeof(exprstr_buf)); gres = print_location_operations(dbg, die, /* indent */ 1, instp+1,block_len,addr_size, offset_size,version, &exprstring,&cerr); if ( gres == DW_DLV_OK) { printf(" %s\n", sanitized(esb_get_string(&exprstring))); } else if (gres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("\nERROR: Unable to get string " "from" " DW_CFA_def_cfa_expression block " "of length " " %" DW_PR_DUu " bytes.\n", block_len); } else { glflags.gf_count_major_errors++; printf("\nERROR: No string from" " DW_CFA_def_cfa_expression block " "of length " " %" DW_PR_DSd " bytes.\n", block_len); printf("Error: %s\n",dwarf_errmsg(cerr)); dwarf_dealloc(dbg,cerr,DW_DLA_ERROR); cerr = 0; } esb_destructor(&exprstring); } instp += block_len; remaining_len -= block_len; off += block_len; } break; case DW_CFA_expression: /* DWARF3 */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_expression\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_expression\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf (" %2u DW_CFA_expression %" DW_PR_DUu " expr block len %" DW_PR_DUu "\n", loff, uval, block_len); if (remaining_len < 0 || block_len > (Dwarf_Unsigned)remaining_len) { glflags.gf_count_major_errors++; printf("\nERROR: expression length %" DW_PR_DUu " too long for section. " "DW_CFA_expression\n", block_len); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_expression") != DW_DLV_OK) { return; } dump_block(" ", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; int gres = 0; Dwarf_Error cerr = 0; esb_constructor_fixed(&exprstring, exprstr_buf, sizeof(exprstr_buf)); gres = print_location_operations(dbg, die, /* indent */ 1, instp+1,block_len,addr_size, offset_size,version, &exprstring,&cerr); if ( gres == DW_DLV_OK) { printf(" %s\n", sanitized( esb_get_string(&exprstring))); } else if (gres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("\nERROR: Unable to get " "string from" " DW_CFA_cfa_expression block " "of length " " %" DW_PR_DUu " bytes.\n", block_len); } else { /* DW_DLV_ERROR */ glflags.gf_count_major_errors++; printf("\nERROR: No string from" " DW_CFA_cfa_expression block " "of length " " %" DW_PR_DUu " bytes.\n", block_len); printf("Error: %s\n",dwarf_errmsg(cerr)); dwarf_dealloc(dbg,cerr, DW_DLA_ERROR); } printf(" %s\n",sanitized( esb_get_string(&exprstring))); esb_destructor(&exprstring); } instp += block_len; remaining_len -= block_len; off += block_len; } break; case DW_CFA_offset_extended_sf: /* DWARF3 */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_offset_extended_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_offset_extended_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_offset_extended_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) ((sval2) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_def_cfa_sf: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , sval2); printf(" (*data alignment factor=>%" DW_PR_DSd ")", (Dwarf_Signed)(sval2*data_alignment_factor)); } printf("\n"); break; case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ { /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ Dwarf_Signed sval = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_def_cfa_offset_sf %" DW_PR_DSd " (*data alignment factor=> %" DW_PR_DSd ")\n", loff, sval, (Dwarf_Signed)(data_alignment_factor*sval)); } break; case DW_CFA_val_offset: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_offset\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_offset\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_val_offset ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (sval2 * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", (Dwarf_Signed) sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_val_offset_sf: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_offset_sf\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_offset\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf(" %2u DW_CFA_val_offset_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd ,(Dwarf_Signed) (sval2 * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_val_expression: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_expression\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; { Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_val_expression\n"); return; } instp += uleblen; remaining_len -= uleblen; off += uleblen; printf (" %2u DW_CFA_val_expression %" DW_PR_DUu " expr block len %" DW_PR_DUu "\n", loff, uval, block_len); if (remaining_len < 0 || block_len > (Dwarf_Unsigned)remaining_len) { glflags.gf_count_major_errors++; printf("\nERROR: expression length %" DW_PR_DUu " too large for section. " "DW_CFA_val_expression.\n", block_len); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_val_expression") != DW_DLV_OK) { return; } dump_block(" ", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; int pres = 0; Dwarf_Error cerr = 0; esb_constructor_fixed(&exprstring, exprstr_buf, sizeof(exprstr_buf)); pres = print_location_operations(dbg, die, /* indent */ 1, instp+1,block_len,addr_size, offset_size,version, &exprstring,&cerr); if ( pres == DW_DLV_OK) { printf(" %s\n", sanitized( esb_get_string(&exprstring))); } else if (pres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("\nERROR: Unable to get string " "from" " DW_CFA_def_cfa_val_expression " "block of length " " %" DW_PR_DUu " bytes.\n", block_len); } else { glflags.gf_count_major_errors++; printf("\nERROR: No string from" " DW_CFA_def_cfa_val_expression " "block of length " " %" DW_PR_DUu " bytes.\n" , block_len); printf("Error: %s\n",dwarf_errmsg(cerr)); } esb_destructor(&exprstring); } instp += block_len; remaining_len -= block_len; off += block_len; } break; /* Only in Metaware. Unknown meaning. */ case DW_CFA_METAWARE_info: { Dwarf_Unsigned val = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&val,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_METAWARE_info\n"); return; } printf(" %2u DW_CFA_METAWARE_info value: %" DW_PR_DUu "\n", loff, val); instp += uleblen; remaining_len -= uleblen; off += uleblen; } break; #ifdef DW_CFA_GNU_window_save case DW_CFA_GNU_window_save:{ /* no information: this just tells unwinder to restore the window registers from the previous frame's window save area */ printf(" %2u DW_CFA_GNU_window_save \n", loff); } break; #endif #ifdef DW_CFA_GNU_negative_offset_extended case DW_CFA_GNU_negative_offset_extended:{ printf(" %2u DW_CFA_GNU_negative_offset_extended \n", loff); } break; #endif #ifdef DW_CFA_GNU_args_size /* single uleb128 is the current arg area size in bytes. no register exists yet to save this in */ case DW_CFA_GNU_args_size:{ Dwarf_Unsigned lreg = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&lreg,endpoint); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("\nERROR: reading leb in " "DW_CFA_GNU_args_size\n"); return; } printf(" %2u DW_CFA_GNU_args_size arg size: %" DW_PR_DUu "\n", loff, lreg); instp += uleblen; remaining_len -= uleblen; off += uleblen; } break; #endif default: printf(" %u Unexpected op 0x%x: \n", loff, (unsigned int) bottom); remaining_len = 0; break; } } instp++; remaining_len--; off++; if ( remaining_len < 0) { glflags.gf_count_major_errors++; printf("\nERROR: reading frame instructions, " "remaining length negative: %" DW_PR_DSd "\n",remaining_len); return; } } if (lastop_pointless(lastop)) { printf( " Warning: Final FDE operator is useless " "but not an error. %s\n", get_CFA_name(lastop,true)); } } /* Print our register names for the cases we have a name. Delegate to the configure code to actually do the print. */ void printreg(Dwarf_Unsigned reg, struct dwconf_s *config_data) { print_reg_from_config_data(reg, config_data); } /* Actually does the printing of a rule in the table. This may print something or may print nothing! */ static void print_one_frame_reg_col(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned rule_id, Dwarf_Small value_type, Dwarf_Unsigned reg_used, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data, Dwarf_Signed offset_relevant, Dwarf_Signed offset, Dwarf_Ptr block_ptr) { char *type_title = ""; int print_type_title = 1; if (!glflags.gf_do_print_dwarf) { return; } if (reg_used == config_data->cf_initial_rule_value && (value_type == DW_EXPR_OFFSET || value_type == DW_EXPR_VAL_OFFSET) ) { /* This is really an empty column. Nothing to do. Would be great if we could tell the caller the *next* column used here or something. */ return; } if (config_data->cf_interface_number == 2) { print_type_title = 0; } switch (value_type) { case DW_EXPR_OFFSET: type_title = "off"; goto preg2; case DW_EXPR_VAL_OFFSET: type_title = "valoff"; preg2: if (print_type_title) printf("<%s ", type_title); printreg(rule_id, config_data); printf("="); if (offset_relevant == 0) { printreg(reg_used, config_data); printf(" "); } else { printf("%02" DW_PR_DSd , offset); printf("("); printreg(reg_used, config_data); printf(") "); } if (print_type_title) printf("> "); break; case DW_EXPR_EXPRESSION: type_title = "expr"; goto pexp2; case DW_EXPR_VAL_EXPRESSION: type_title = "valexpr"; pexp2: if (print_type_title) { printf("<%s ", type_title); } printreg(rule_id, config_data); printf("="); /* Here 'offset' is actually block length. */ printf("expr-block-len=%" DW_PR_DSd , offset); if (print_type_title) { printf("> "); } if (glflags.verbose) { printf("<"); printf("%s",type_title); printf("bytes:"); /* The data being dumped comes direct from libdwarf so libdwarf validated it. */ dump_block("", block_ptr, offset); printf("> "); if (glflags.verbose) { struct esb_s exprstring; char local_buf[300]; int gres = 0; Dwarf_Error cerr = 0; esb_constructor_fixed(&exprstring,local_buf, sizeof(local_buf)); /* Here 'offset' is actually block length. */ gres = print_location_operations(dbg, die, /* indent */ 1, block_ptr,offset,addr_size, offset_size,version, &exprstring,&cerr); if ( gres == DW_DLV_OK) { printf("",sanitized( esb_get_string(&exprstring))); } else if (gres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("\nERROR: Unable to get string from" " DW_EXPR_VAL_EXPRESSION block of length " " %" DW_PR_DSd " bytes.\n" ,offset); } else { glflags.gf_count_major_errors++; printf("\nERROR: No string from" " DW_EXPR_VAL_EXPRESSION block of length " " %" DW_PR_DSd " bytes.\n" ,offset); printf("Error: %s\n",dwarf_errmsg(cerr)); } esb_destructor(&exprstring); } } break; default: printf("Internal error in libdwarf, value type %d\n", value_type); exit(1); } return; } /* We do NOT want to free cie/fde data as we will use that in print_all_cies() */ static int print_all_fdes(Dwarf_Debug dbg, const char *frame_section_name, Dwarf_Fde *fde_data, Dwarf_Signed fde_element_count, Dwarf_Cie *cie_data, Dwarf_Signed cie_element_count, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Half version, int is_eh, struct dwconf_s *config_data, void **map_lowpc_to_name, void **lowpcSet, Dwarf_Die *cu_die_for_print_frames, Dwarf_Error*err) { Dwarf_Signed i = 0; int frame_count = 0; /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; const char *stdsecname = 0; if (!is_eh) { stdsecname=".debug_frame"; } else { stdsecname=".eh_frame"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,stdsecname, &truename,true); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); printf("\nfde:\n"); } for (i = 0; i < fde_element_count; i++) { int fdres = 0; fdres = print_one_fde(dbg, frame_section_name, fde_data[i], i, cie_data, cie_element_count, address_size, offset_size, version, is_eh, config_data, map_lowpc_to_name, lowpcSet, cu_die_for_print_frames, err); if (fdres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: Printing fde %" DW_PR_DSd " fails. Error %s\n", i,dwarf_errmsg(*err)); return fdres; } if (fdres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("ERROR: Printing fde %" DW_PR_DSd " fails saying 'no entry'. Impossible.\n", i); return fdres; } ++frame_count; if (frame_count >= glflags.break_after_n_units) { break; } } return DW_DLV_OK; } static int print_all_cies(Dwarf_Debug dbg, Dwarf_Cie *cie_data, Dwarf_Signed cie_element_count, Dwarf_Half address_size, struct dwconf_s *config_data, Dwarf_Die *cu_die_for_print_frames, Dwarf_Error*err) { /* Print the cie set. */ /* Do not print if in check mode */ Dwarf_Signed i = 0; Dwarf_Signed cie_count = 0; if (glflags.gf_do_print_dwarf) { printf("\ncie:\n"); } for (i = 0; i < cie_element_count; i++) { int cres = 0; cres = print_one_cie(dbg, *cu_die_for_print_frames, cie_data[i], i, address_size, config_data, err); if (cres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("\nERROR: Printing cie %" DW_PR_DSd " fails. Error %s\n", i,dwarf_errmsg(*err)); return cres; } else if (cres == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; printf("\nERROR: Printing cie %" DW_PR_DSd " fails. saying NO_ENTRY!\n", i); return cres; } else { ++cie_count; if (cie_count >= glflags.break_after_n_units) { break; } } } return DW_DLV_OK; } /* get all the data in .debug_frame (or .eh_frame). The '3' versions mean print using the dwarf3 new interfaces. The non-3 mean use the old interfaces. All combinations of requests are possible. */ int print_frames(Dwarf_Debug dbg, int want_eh, struct dwconf_s *config_data, /* Pass these next 3 so preserved from .eh_frame to .debug_frame */ Dwarf_Die * cu_die_for_print_frames, void ** map_lowpc_to_name, void ** lowpcSet, Dwarf_Error *err) { int fres = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; Dwarf_Half version = 0; /* We only get here if a flag says we want to process the section (want_eh is either 0 or 1). */ glflags.current_section_id = DEBUG_FRAME; /* Only in DWARF4 or later is there a real address size known in the frame data itself. If any DIE is known then a real address size can be gotten from dwarf_get_die_address_size(). */ fres = dwarf_get_address_size(dbg, &address_size, err); if (fres != DW_DLV_OK) { glflags.gf_count_major_errors++; printf("ERROR: Unable to print frame section as " " we cannot get the address size\n"); return fres; } { Dwarf_Cie *cie_data = NULL; Dwarf_Signed cie_element_count = 0; Dwarf_Fde *fde_data = NULL; Dwarf_Signed fde_element_count = 0; const char *frame_section_name = 0; int silent_if_missing = 0; int is_eh = 0; if (!want_eh) { Dwarf_Error localerr = 0; glflags.current_section_id = DEBUG_FRAME; /* Do not free frame_section_name. */ fres = dwarf_get_frame_section_name(dbg, &frame_section_name,&localerr); if (fres != DW_DLV_OK || !frame_section_name || !strlen(frame_section_name)) { frame_section_name = ".debug_frame"; if (fres == DW_DLV_ERROR) { dwarf_dealloc(dbg,localerr,DW_DLA_ERROR); localerr = 0; } } /* Big question here is how to print all the info? Can print the logical matrix, but that is huge, though could skip lines that don't change. Either that, or print the instruction statement program that describes the changes. */ fres = dwarf_get_fde_list(dbg, &cie_data, &cie_element_count, &fde_data, &fde_element_count, err); if (glflags.gf_check_harmless) { print_any_harmless_errors(dbg); } } else { /* want_eh */ Dwarf_Error localerr = 0; glflags.current_section_id = DEBUG_FRAME_EH_GNU; is_eh = 1; /* This is gnu g++ exceptions in a .eh_frame section. Which is just like .debug_frame except that the empty, or 'special' CIE_id is 0, not -1 (to distinguish fde from cie). And the augmentation is "eh". As of egcs-1.1.2 anyway. A non-zero cie_id is in a fde and is the difference between the fde address and the beginning of the cie it belongs to. This makes sense as this is intended to be referenced at run time, and is part of the running image. For more on augmentation strings, see libdwarf/dwarf_frame.c. */ /* Big question here is how to print all the info? Can print the logical matrix, but that is huge, though could skip lines that don't change. Either that, or print the instruction statement program that describes the changes. */ silent_if_missing = 1; /* Do not free frame_section_name. */ fres = dwarf_get_frame_section_name_eh_gnu(dbg, &frame_section_name,&localerr); if (fres != DW_DLV_OK || !frame_section_name || !strlen(frame_section_name)) { frame_section_name = ".eh_frame"; if (fres == DW_DLV_ERROR){ dwarf_dealloc(dbg,localerr,DW_DLA_ERROR); localerr = 0; } } fres = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_element_count, &fde_data, &fde_element_count, err); if (glflags.gf_check_harmless) { print_any_harmless_errors(dbg); } } if (fres == DW_DLV_ERROR) { const char *loc = "dwarf_get_fde_list"; if (is_eh) { loc = "dwarf_get_fde_list_eh"; } glflags.gf_count_major_errors++; printf("\nERROR: %s not loadable. %s %s\n", sanitized(frame_section_name),loc, dwarf_errmsg(*err)); return fres; } /* Do not print any frame info if in check mode */ if (glflags.gf_check_frames) { if (fres == DW_DLV_OK) { dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count, fde_data, fde_element_count); } return DW_DLV_OK; } if (fres == DW_DLV_NO_ENTRY) { if (!silent_if_missing) { printf("\n%s is not present\n", sanitized(frame_section_name)); } /* no frame information */ return fres; } else { /* DW_DLV_OK */ int res = 0; res = print_all_fdes(dbg,frame_section_name,fde_data, fde_element_count, cie_data, cie_element_count, address_size,offset_size,version,is_eh, config_data,map_lowpc_to_name, lowpcSet, cu_die_for_print_frames, err); if (res == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: printing fdes fails. %s " " Attempting to continue. \n", dwarf_errmsg(*err)); dwarf_dealloc_error(dbg,*err); *err = 0; } res = print_all_cies(dbg, /* frame_section_name, */ cie_data, cie_element_count, address_size, /* offset_size,version,is_eh, */ config_data, /* map_lowpc_to_name, lowpcSet, */ cu_die_for_print_frames, err); if (res == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: printing cies fails. %s " " Attempting to continue. \n", dwarf_errmsg(*err)); dwarf_dealloc_error(dbg,*err); *err = 0; } /* Here we do the free. Not earlier. */ dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count, fde_data, fde_element_count); } /* End inner scope, not a loop */ } /* End inner scope, not a loop */ return DW_DLV_OK; } libdwarf-20210528/dwarfdump/true_section_name.c0000664000175000017500000000652213764006205016344 00000000000000/* Copyright 2018-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "esb.h" #include "esb_using_functions.h" void get_true_section_name(Dwarf_Debug dbg, const char *standard_name, struct esb_s *name_out, Dwarf_Bool add_compr) { Dwarf_Small marked_compressed = 0; Dwarf_Small marked_zlib_compressed = 0; Dwarf_Small marked_shf_compressed = 0; Dwarf_Unsigned compressed_length = 0; Dwarf_Unsigned uncompressed_length = 0; const char *stdname = standard_name; const char *actualname = 0; int cres = 0; Dwarf_Error tnameerr = 0; cres = dwarf_get_real_section_name(dbg, stdname, &actualname, &marked_compressed, &marked_zlib_compressed, &marked_shf_compressed, &compressed_length,&uncompressed_length, &tnameerr); if (cres == DW_DLV_OK) { esb_append(name_out,actualname); if (add_compr) { Dwarf_Bool compr = FALSE; if (marked_compressed) { esb_append(name_out," .zdebug"); compr = TRUE; } if (marked_zlib_compressed) { esb_append(name_out," ZLIB-initial-bytes"); compr = TRUE; } if (marked_shf_compressed) { esb_append(name_out," SHF_COMPRESSED"); compr = TRUE; } if (compr) { char floatbuf[40]; double comprfactor = 0.0; if (compressed_length > 0) { comprfactor = (double)uncompressed_length / (double)compressed_length; } esb_append_printf_u(name_out," CompLen=%" DW_PR_DUu, compressed_length); esb_append_printf_u(name_out," Uncomp=%" DW_PR_DUu, uncompressed_length); sprintf(floatbuf," compression=%.1f",comprfactor); esb_append(name_out, floatbuf); } } return; } else if (cres == DW_DLV_NO_ENTRY) { esb_append(name_out,stdname); return; } /* DW_DLV_ERROR */ esb_append(name_out,stdname); /* avoid error leak */ dwarf_dealloc(dbg,tnameerr,DW_DLA_ERROR); tnameerr = 0; esb_append(name_out," (Error accessing section name)"); return; } libdwarf-20210528/dwarfdump/print_gdbindex.c0000664000175000017500000004233114003121771015630 00000000000000/* Copyright 2014-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" static const char * dw_dlv_string(int res) { if (res == DW_DLV_ERROR) { return "DW_DLV_ERROR"; } if (res == DW_DLV_NO_ENTRY) { return "DW_DLV_NO_ENTRY"; } if (res == DW_DLV_OK) { return "DW_DLV_OK"; } return "ERROR: Impossible libdwarf DW_DLV code"; } static int print_culist_array(UNUSEDARG Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned *cu_list_len, Dwarf_Error * err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_culist_array(gdbindex, &list_len,err); if (res == DW_DLV_NO_ENTRY) { return res; } if (res == DW_DLV_ERROR) { simple_err_return_msg_either_action(res, "ERROR: dwarf_gdbindex_culist_array failed."); return res; } printf(" CU list. array length: %" DW_PR_DUu " format: [entry#] cuoffset culength\n", list_len); for (i = 0; i < list_len; i++) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned culength = 0; res = dwarf_gdbindex_culist_entry(gdbindex,i, &cuoffset,&culength,err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_culist_entry " "got %s ",et); esb_append_printf_u(&msg, " on entry %u ",i); esb_append_printf_u(&msg," of %u entries.", list_len); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", i, cuoffset, culength); } printf("\n"); *cu_list_len = list_len; return DW_DLV_OK; } static int print_types_culist_array(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Error * cular_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = 0; res = dwarf_gdbindex_types_culist_array(gdbindex, &list_len,cular_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_types_culist_array call failed", res,*cular_err); return res; } printf(" TU list. array length: %" DW_PR_DUu " format: [entry#] cuoffset culength signature\n", list_len); for (i = 0; i < list_len; i++) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned culength = 0; Dwarf_Unsigned signature = 0; res = dwarf_gdbindex_types_culist_entry(gdbindex,i, &cuoffset,&culength, &signature, cular_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_culist_entry call " "got %s ",et); esb_append_printf_u(&msg, " on entry %u ",i); esb_append_printf_u(&msg," of %u entries.", list_len); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", i, cuoffset, culength, signature); } printf("\n"); return DW_DLV_OK; } static int print_addressarea(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Error * addra_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_addressarea(gdbindex, &list_len,addra_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_addressarea failed",res,*addra_err); return res; } printf(" Address table array length: %" DW_PR_DUu " format: [entry#] lowpc highpc cu-index\n", list_len); for (i = 0; i < list_len; i++) { Dwarf_Unsigned lowpc = 0; Dwarf_Unsigned highpc = 0; Dwarf_Unsigned cu_index = 0; res = dwarf_gdbindex_addressarea_entry(gdbindex,i, &lowpc,&highpc, &cu_index, addra_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_addressarea_entry call " "got %s ",et); esb_append_printf_u(&msg, " on entry %u ",i); esb_append_printf_u(&msg," of %u entries.", list_len); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %4" DW_PR_DUu "\n", i, lowpc, highpc, cu_index); } printf("\n"); return DW_DLV_OK; } const char *kind_list[] = { "unknown(0) ", "type(1) ", "var-enum(2) ", "function(3) ", "other-sym(4)", "reserved(5) ", "function(6) ", "reserved(7) ", }; static void get_kind_string(struct esb_s *out,unsigned k) { if (k <= 7) { esb_append(out,sanitized(kind_list[k])); return; } esb_append(out, "kind-erroneous"); } /* NOTE: Returns pointer to static local string. Use the returned pointer immediately or things will not work properly. */ static void get_cu_index_string(struct esb_s *out, Dwarf_Unsigned index, Dwarf_Unsigned culist_len) { Dwarf_Unsigned type_index = 0; if (index < culist_len) { esb_append_printf_u(out,"%4" DW_PR_DUu,index); return; } type_index = index-culist_len; esb_append_printf_u(out, "%4" DW_PR_DUu ,index); esb_append_printf_u(out, "(T%4" DW_PR_DUu ")",type_index); return; } static int print_symtab_entry(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned index, Dwarf_Unsigned symnameoffset, Dwarf_Unsigned cuvecoffset, Dwarf_Unsigned culist_len, Dwarf_Error *sym_err) { int res = 0; const char *name = 0; Dwarf_Unsigned cuvec_len = 0; Dwarf_Unsigned ii = 0; if (symnameoffset == 0 && cuvecoffset == 0) { if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "] " "\"empty-hash-entry\"\n", index); } return DW_DLV_OK; } res = dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset,&name,sym_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_string_by_offset call " "failed with %s ",et); esb_append_printf_u(&msg, " on offset 0x%lx",symnameoffset); esb_append_printf_u(&msg, " (%u).",symnameoffset); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } res = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset,&cuvec_len,sym_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_cuvector_length() call " "failed with %s ",et); esb_append_printf_u(&msg, " on cu vector offset 0x%lx",cuvecoffset); esb_append_printf_u(&msg, " (%u).",cuvecoffset); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "]" "stroff 0x%" DW_PR_XZEROS DW_PR_DUx " cuvecoff 0x%" DW_PR_XZEROS DW_PR_DUx " cuveclen 0x%" DW_PR_XZEROS DW_PR_DUx "\n", index,symnameoffset,cuvecoffset,cuvec_len); } for (ii = 0; ii < cuvec_len; ++ii ) { Dwarf_Unsigned attributes = 0; Dwarf_Unsigned cu_index = 0; Dwarf_Unsigned reserved1 = 0; Dwarf_Unsigned symbol_kind = 0; Dwarf_Unsigned is_static = 0; struct esb_s tmp_cuindx; struct esb_s tmp_kind; res = dwarf_gdbindex_cuvector_inner_attributes( gdbindex,cuvecoffset,ii, &attributes,sym_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_cuvector_inner_attributes failed", res,*sym_err); return res; } res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex, attributes, &cu_index,&reserved1,&symbol_kind, &is_static, sym_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_gdbindex_cuvector_instance_expand" "_value() call " "failed with %s ",et); esb_append_printf_u(&msg, " on cu vector index %d ",ii); esb_append_printf_u(&msg, " on of %d entries.",cuvec_len); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } /* if cu_index is > the cu-count, then it refers to a tu_index of 'cu_index - cu-count' */ esb_constructor(&tmp_cuindx); esb_constructor(&tmp_kind); get_kind_string(&tmp_kind,symbol_kind), get_cu_index_string(&tmp_cuindx,cu_index,culist_len); if (cuvec_len == 1) { printf(" [%4" DW_PR_DUu "]" "%s" " [%s %s] \"%s\"\n", index, esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind), sanitized(name)); } else if (ii == 0) { printf(" [%4" DW_PR_DUu "] \"%s\"\n" , index, sanitized(name)); printf(" %s [%s %s]\n", esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind)); }else{ printf(" %s [%s %s]\n", esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind)); } esb_destructor(&tmp_cuindx); esb_destructor(&tmp_kind); if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "]" "attr 0x%" DW_PR_XZEROS DW_PR_DUx " cuindx 0x%" DW_PR_XZEROS DW_PR_DUx " kind 0x%" DW_PR_XZEROS DW_PR_DUx " static 0x%" DW_PR_XZEROS DW_PR_DUx "\n", ii,attributes,cu_index,symbol_kind,is_static); } } return DW_DLV_OK; } static int print_symboltable(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned culist_len, Dwarf_Error * symt_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_symboltable_array(gdbindex, &list_len,symt_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_get_gdbindex_symboltable_array call " "failed with %s ",et); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } printf("\n Symbol table: length %" DW_PR_DUu " format: [entry#] symindex cuindex [type] \"name\" or \n", list_len); printf(" " " format: [entry#] \"name\" , list of cuindex [type]\n"); for (i = 0; i < list_len; i++) { Dwarf_Unsigned symnameoffset = 0; Dwarf_Unsigned cuvecoffset = 0; res = dwarf_gdbindex_symboltable_entry(gdbindex,i, &symnameoffset,&cuvecoffset, symt_err); if (res != DW_DLV_OK) { struct esb_s msg; const char * et= dw_dlv_string(res); esb_constructor(&msg); esb_append_printf_s(&msg, "ERROR: dwarf_gdbindex_symboltable_entry() call " "failed with %s ",et); esb_append_printf_u(&msg, " on symtab index %d ",i); esb_append_printf_u(&msg, " on of %d entries.",list_len); simple_err_return_action(res, esb_get_string(&msg)); esb_destructor(&msg); return res; } res = print_symtab_entry(dbg,gdbindex,i, symnameoffset,cuvecoffset, culist_len,symt_err); if (res != DW_DLV_OK) { return res; } } printf("\n"); return DW_DLV_OK; } int print_gdb_index(Dwarf_Debug dbg,Dwarf_Error *err) { Dwarf_Gdbindex gdbindex = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned cu_list_offset = 0; Dwarf_Unsigned types_cu_list_offset = 0; Dwarf_Unsigned address_area_offset = 0; Dwarf_Unsigned symbol_table_offset = 0; Dwarf_Unsigned constant_pool_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Unsigned unused = 0; const char *section_name = 0; /* unused */ Dwarf_Unsigned culist_len = 0; int res = 0; glflags.current_section_id = DEBUG_GDB_INDEX; if (!glflags.gf_do_print_dwarf) { return DW_DLV_OK; } res = dwarf_gdbindex_header(dbg, &gdbindex, &version, &cu_list_offset, &types_cu_list_offset, &address_area_offset, &symbol_table_offset, &constant_pool_offset, §ion_size, &unused, §ion_name, err); if (res == DW_DLV_NO_ENTRY) { /* Silently! The section is rare so lets say nothing. */ return res; } if (res == DW_DLV_ERROR) { simple_err_return_msg_either_action(res, "ERROR: .gdb_index not readable."); return res; } { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".gdb_index", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } printf(" Version : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", version); printf(" CU list offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", cu_list_offset); printf(" Address area offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", types_cu_list_offset); printf(" Symbol table offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", address_area_offset); printf(" Constant pool offset: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", constant_pool_offset); printf(" section size : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", section_size); res = print_culist_array(dbg,gdbindex,&culist_len,err); if (res != DW_DLV_OK) { dwarf_gdbindex_free(gdbindex); return res; } res = print_types_culist_array(dbg,gdbindex,err); if (res != DW_DLV_OK) { dwarf_gdbindex_free(gdbindex); return res; } res = print_addressarea(dbg,gdbindex,err); if (res != DW_DLV_OK) { dwarf_gdbindex_free(gdbindex); return res; } res = print_symboltable(dbg,gdbindex,culist_len,err); dwarf_gdbindex_free(gdbindex); return res; } libdwarf-20210528/dwarfdump/ChangeLog20070000664000175000017500000001323113644370703014557 000000000000002007-12-09 DavidAnderson * print_sections.c print_frames.c: Forgot to commit yesterday. yesterday's commit includes renaming _dwarf_fde_section_offset _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines to dwarf_* form while retaining support for the now obsolete _dwarf_* form. 2007-12-08 DavidAnderson * config.h.in, configure.in: Latest linux libelf.h requires _GNU_SOURCE to get off64_t defined so dwarfdump compiles. Only define _GNU_SOURCE if libelf.h defines off64_t. Regenerated configure. * config.guess, config.sub: Updated to 2.61 * acconfig.h: Deleted, removing autoconf complaint. 2007-10-15 DavidAnderson * print_die.c (clean_up_die_esb): New function cleans up malloc space. * print_reloc.c (clean_up_syms_malloc_data): New function cleans up malloc space. * dwarfdump.c (main): Call new cleanup functions at end. * globals.h: Declare new cleanup functions. 2007-09-04 DavidAnderson * print_die.c (print_attribute): For DWARF4: DW_AT_high_pc: add qualifier to value when the value is an offset from DW_AT_low_pc (thus not itself a address). Update the address of the FSF. * print_frames.h DWARFDUMPCOPYRIGHT print_sections.c print_reloc.c dwarfdump.c tag_tree.c tag_attr.c esb.c esb.h makename.c acconfig.h dwconf.c makename.h dwconf.h globals.h print_frames.c: Update the address of the FSF. 2007-07-03 DavidAnderson * print_sections.c (dump_block): Removed superfluous return byte from printed characters. Removed unused variables. * print_die.c: A little refactoring for clarity. * globals.h: dwarfdump_print_one_locdesc() is now a global-to-dwarfdump function. * print_frames.c: Now (with -v) prints dwarf expression bytes in frame expressions readably. 2007-07-02 DavidAnderson * dwarfdump.c: Add new -R option for 'generic' register sets. * dwarfdump.1: document -R, add new -x documentation. * dwconf.c: Set up -R configuration. Slight revision of register printing code. * dwconf.h: Interface to register name printing simplified. * print_frames.c: Use the simpler register name interface. * dwarfdump.conf: Add new 'generic' abi for up to 1000 registers. 2007-07-01 DavidAnderson * print_frames.c: For DW_CFA_def_cfa_sf & DW_CFA_def_cfa_offset_sf print a computed data alignment factor. 2007-06-29 DavidAnderson * dwarfdump.1: Corrected spelling error. 2007-05-25 DavidAnderson * dwconf.h dwconf.c: Changed field name to cf_named_regs_table_size as old name was less than clear. * dwarfdump.c: Call frame table setup with cf_table_entry_count not cf_named_regs_table_size. The newly renamed field makes it clearer the call was wrong. 2007-05-04 DavidAnderson * print_die.c: printing of global offset of DIEs with -G is now more in the style of previous output. 2007-04-18 Chris Quenelle * Makefile.in: - use $(srcdir) for files in source directory - support running rules in parallel by - use different tmp file names in different rules. - use more accurate target for dwarf_names.{c,h} * dwarf_names.awk: Enhance script to be able to generate either #define-style headers or enum-style headers * dwarfdump.c: dump most everything by default if no arguments are given to dwarfdump. This seems to be a more useful default than showing nothing at all. Also add a -G option to show the (G)lobal section offset for each die within an a.out. If you think you're seeing data corruption inside a .debug_info section, this is a useful option to have. * print_die.c: Support compressed integer blocks. This is an array (DW_FORM_block) of LEB numbers used as part of a Sun extension, DW_AT_SUN_func_offsets. Also add support for a new dwarf enum DW_ATCF_xxxx. This is used in DW_AT_SUN_cf_kind. Also, fix DW_AT_upper_bound so it can be a constant or a location list. DW_AT_count and DW_AT_data_member_location should also be fixed eventually. * print_sections.c: Changes to support zero-padding in the middle of section data. Change offset labels to be a little more clear. Not sure about the get_str failure. * tag_tree.list: DW_TAG_compile_unit can contain a DW_TAG_namespace 2007-04-10 David Anderson * print_reloc.c dwarfdump.c print_frames.c: Unified copyright to the SGI form. No copyright change. 2007-04-06 David Anderson * print_die.c (print_die_and_children): Increase static depth of die stack. Notice if it overflows and print error. 2007-02-23 David Anderson * print_reloc.c: 2 lines added (long) cast in printf and made %3ld instead of %3d to fix compiler warning. * print_frames.c: newline was missing from the output. Thanks to Chris Quenelle for noticing. 2007-02-20 David Anderson * print_frame.c (print_frame_inst_bytes): Fixed an off by one error (several places) when printing dwarf expressions and added commentary about it. Thanks to Julian Seward for pointing out it was off by one. * dwarfdump.c (print_error): added fflush of stdout, stderr where we are going to exit right away anyway. libdwarf-20210528/dwarfdump/warningcontrol.h0000644000175000017500000000234513743575426015726 00000000000000/* Copyright (C) 2016-201t David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef WARNINGCONTROL_H #define WARNINGCONTROL_H #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #endif /* WARNINGCONTROL_H */ libdwarf-20210528/dwarfdump/print_macinfo.c0000664000175000017500000002177713767710523015512 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "macrocheck.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" #include "print_frames.h" #define TRUE 1 #define FALSE 0 struct macro_counts_s { long mc_start_file; long mc_end_file; long mc_define; long mc_undef; long mc_extension; long mc_code_zero; long mc_unknown; }; static int print_one_macro_entry_detail(long i, char *type, struct Dwarf_Macro_Details_s *mdp, UNUSEDARG Dwarf_Error *err) { /* "DW_MACINFO_*: section-offset file-index [line] string\n" */ if (glflags.gf_do_print_dwarf) { if (mdp->dmd_macro) { printf("%3ld %s: %6" DW_PR_DUu " %4" DW_PR_DSd " [%4" DW_PR_DSd "] \"%s\" \n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno, sanitized(mdp->dmd_macro)); } else { printf("%3ld %s: %6" DW_PR_DUu " %4" DW_PR_DSd " [%4" DW_PR_DSd "] 0\n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno); } } return DW_DLV_OK; } /* Nothing in here can actually fail. Returns DW_DLV_OK */ static int print_one_macro_entry(long i, struct Dwarf_Macro_Details_s *mdp, struct macro_counts_s *counts, char ** srcfiles, Dwarf_Signed srcf_count, UNUSEDARG Dwarf_Error *error) { int res = 0; switch (mdp->dmd_type) { case 0: counts->mc_code_zero++; res = print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp,error); break; case DW_MACINFO_start_file: { counts->mc_start_file++; if (mdp->dmd_fileindex == 0) { mdp->dmd_macro = ""; } else if (srcf_count > 0 && mdp->dmd_fileindex <= srcf_count) { mdp->dmd_macro = srcfiles[mdp->dmd_fileindex-1]; } else { if (srcf_count == 0) { mdp->dmd_macro = ""; } else { mdp->dmd_macro = ""; } } res = print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp,error); break; } case DW_MACINFO_end_file: counts->mc_end_file++; res = print_one_macro_entry_detail(i, "DW_MACINFO_end_file ", mdp,error); break; case DW_MACINFO_vendor_ext: counts->mc_extension++; res = print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp,error); break; case DW_MACINFO_define: counts->mc_define++; res = print_one_macro_entry_detail(i, "DW_MACINFO_define ", mdp,error); break; case DW_MACINFO_undef: counts->mc_undef++; res = print_one_macro_entry_detail(i, "DW_MACINFO_undef ", mdp,error); break; default: { struct esb_s typeb; esb_constructor(&typeb); counts->mc_unknown++; esb_append_printf_u(&typeb, "DW_MACINFO_0x%x, of unknown type", mdp->dmd_type); print_one_macro_entry_detail(i, esb_get_string(&typeb), mdp,error); esb_destructor(&typeb); } res = DW_DLV_OK; break; } return res; } static void mac_dealloc_srcfiles_data(Dwarf_Debug dbg, char **srcfiles, Dwarf_Signed srcf_count) { Dwarf_Signed i = 0; if (!srcfiles) { return; } for ( ; i < srcf_count; ++i) { dwarf_dealloc(dbg,srcfiles[i],DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); } /* print data in .debug_macinfo */ /*ARGSUSED*/ int print_macinfo_by_offset(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Unsigned offset, Dwarf_Error *error) { Dwarf_Unsigned max = 0; Dwarf_Signed count = 0; Dwarf_Macro_Details *maclist = NULL; int lres = 0; long i = 0; struct macro_counts_s counts; Dwarf_Unsigned totallen = 0; Dwarf_Bool is_primary = TRUE; char ** srcfiles = 0; Dwarf_Signed srcf_count = 0; glflags.current_section_id = DEBUG_MACINFO; /* No real need to get the real section name, this section not used much in modern compilers as this definition of macro data (V2-V4) is obsolete -- it takes too much space to be much used. */ lres = dwarf_get_macro_details(dbg, offset, max, &count, &maclist, error); if (lres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_get_macro_details() fails on" " offset 0x%x from print_macinfo_by_offset().",offset); simple_err_only_return_action(lres, esb_get_string(&m)); esb_destructor(&m); return lres; } else if (lres == DW_DLV_NO_ENTRY) { return lres; } lres = dwarf_srcfiles(cu_die,&srcfiles,&srcf_count,error); if (lres == DW_DLV_ERROR) { /* This error will get found other places. No need to say anything here. */ dwarf_dealloc_error(dbg,*error); *error = 0; } memset(&counts, 0, sizeof(counts)); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_macinfo", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); printf("\n"); printf("compilation-unit .debug_macinfo offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n",offset); printf(" sec file\n"); printf("num name offset index [line] " "\"string\"\n"); } for (i = 0; i < count; i++) { struct Dwarf_Macro_Details_s *mdp = &maclist[i]; print_one_macro_entry(i, mdp, &counts, srcfiles,srcf_count,error); } if (counts.mc_start_file == 0) { printf("ERROR: DW_MACINFO file count of zero is " "invalid DWARF2/3/4\n"); glflags.gf_count_major_errors++; } if (counts.mc_start_file != counts.mc_end_file) { glflags.gf_count_major_errors++; printf("ERROR: Counts of DW_MACINFO start_file (%ld)" " end_file (%ld) " "do not match!. Incorrect DWARF2,3,4.\n", counts.mc_start_file, counts.mc_end_file); } if (counts.mc_code_zero < 1) { glflags.gf_count_major_errors++; printf("ERROR: Count of zeros in macro group " "should be non-zero " "(1 preferred), count is %ld\n", counts.mc_code_zero); } /* next byte is maclist[count - 1].dmd_offset + 1; */ totallen = (maclist[count - 1].dmd_offset + 1) - offset; add_macro_import(&macinfo_check_tree,is_primary, offset,0,0); add_macro_area_len(&macinfo_check_tree,offset,totallen); if (glflags.gf_do_print_dwarf) { printf("Macro counts: start file %ld, " "end file %ld, " "define %ld, " "undef %ld, " "ext %ld, " "code-zero %ld, " "unknown %ld\n", counts.mc_start_file, counts.mc_end_file, counts.mc_define, counts.mc_undef, counts.mc_extension, counts.mc_code_zero, counts.mc_unknown); } /* int type= maclist[count - 1].dmd_type; */ /* ASSERT: type is zero */ mac_dealloc_srcfiles_data(dbg,srcfiles,srcf_count); dwarf_dealloc(dbg, maclist, DW_DLA_STRING); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/sanitized.c0000664000175000017500000001540314003121635014621 00000000000000/* Copyright 2016-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Definitions for TRUE, FALSE, etc. */ #include "globals.h" #include "esb.h" #include "glflags.h" #include "sanitized.h" /* This does a uri-style conversion of control characters. So SOH prints as %01 for example. Which stops corrupted or crafted strings from doing things to the terminal the string is routed to. We do not translate an input % to %% (as in real uri) as that would be a bit confusing for most readers. The conversion makes it possble to print UTF-8 strings reproducibly, sort of (not showing the real glyph!). Only call this in a printf or sprintf, and only call it once in any single printf/sprintf. Othewise you will get bogus results and confusion. */ /* ASCII control codes: We leave newline as is, NUL is end of string, the others are translated. NUL Null 0 00 Ctrl-@ ^@ SOH Start of heading 1 01 Alt-1 Ctrl-A ^A STX Start of text 2 02 Alt-2 Ctrl-B ^B ETX End of text 3 03 Alt-3 Ctrl-C ^C EOT End of transmission 4 04 Alt-4 Ctrl-D ^D ENQ Enquiry 5 05 Alt-5 Ctrl-E ^E ACK Acknowledge 6 06 Alt-6 Ctrl-F ^F BEL Bell 7 07 Alt-7 Ctrl-G ^G BS Backspace 8 08 Alt-8 Ctrl-H ^H HT Horizontal tab 9 09 Alt-9 Ctrl-I ^I LF Line feed 10 0A Alt-10 Ctrl-J ^J VT Vertical tab 11 0B Alt-11 Ctrl-K ^K FF Form feed 12 0C Alt-12 Ctrl-L ^L CR Carriage return 13 0D Alt-13 Ctrl-M ^M SO Shift out 14 0E Alt-14 Ctrl-N ^N SI Shift in 15 0F Alt-15 Ctrl-O ^O DLE Data line escape 16 10 Alt-16 Ctrl-P ^P DC1 Device control 1 17 11 Alt-17 Ctrl-Q ^Q DC2 Device control 2 18 12 Alt-18 Ctrl-R ^R DC3 Device control 3 19 13 Alt-19 Ctrl-S ^S DC4 Device control 4 20 14 Alt-20 Ctrl-T ^T NAK Negative acknowledge 21 15 Alt-21 Ctrl-U ^U SYN Synchronous idle 22 16 Alt-22 Ctrl-V ^V ETB End transmission block 23 17 Alt-23 Ctrl-W ^W CAN Cancel 24 18 Alt-24 Ctrl-X ^X EM End of medium 25 19 Alt-25 Ctrl-Y ^Y SU Substitute 26 1A Alt-26 Ctrl-Z ^Z ES Escape 27 1B Alt-27 Ctrl-[ ^[ FS File separator 28 1C Alt-28 Ctrl-\ ^\ GS Group separator 29 1D Alt-29 Ctrl-] ^] RS Record separator 30 1E Alt-30 Ctrl-^ ^^ US Unit separator 31 1F Alt-31 Ctrl-_ ^_ In addition, characters decimal 141, 157, 127,128, 129 143,144,157 appear to be questionable too. Not in iso-8859-1 nor in html character entities list. We translate all strings with a % to do sanitizing and we change a literal ASCII '%' char to %27 so readers know any % is a sanitized char. We could double up a % into %% on output, but switching to %27 is simpler and for readers and prevents ambiguity. Since we do not handle utf-8 properly nor detect it we turn all non-ASCII to %xx below. */ static struct esb_s localesb = {0,0,0,0,0}; /* do_sanity_insert() and no_questionable_chars() absolutely must have the same idea of questionable characters. Be Careful. */ static void do_sanity_insert( const char *s,struct esb_s *mesb) { const char *cp = s; for ( ; *cp; cp++) { unsigned c = *cp & 0xff ; if (c == '%') { /* %xx for this too. Simple and unambiguous */ esb_append(mesb, "%"); esb_append_printf_u(mesb, "%02x",c & 0xff); continue; } if (c >= 0x20 && c <=0x7e) { /* Usual case, ASCII printable characters. */ esb_appendn(mesb,cp,1); continue; } #ifdef _WIN32 if (c == 0x0D) { esb_appendn(mesb,cp,1); continue; } #endif /* _WIN32 */ if (c < 0x20) { esb_append(mesb, "%"); esb_append_printf_u(mesb, "%02x",c & 0xff); continue; } /* ASSERT: (c >= 0x7f) */ /* ISO-8859 or UTF-8. Not handled well yet. */ esb_append(mesb, "%"); esb_append_printf_u(mesb, "%02x",c & 0xff); } } /* This routine improves overall dwarfdump run times a lot by separating strings that might print badly from strings that will print fine. In one large test case it reduces run time from 140 seconds to 13 seconds. */ static int no_questionable_chars(const char *s) { const char *cp = s; for ( ; *cp; cp++) { unsigned c = *cp & 0xff ; if (c == '%') { /* Always sanitize a % ASCII char. */ return FALSE; } if (c >= 0x20 && c <=0x7e) { /* Usual case, ASCII printable characters */ continue; } #ifdef _WIN32 if (c == 0x0D) { continue; } #endif /* _WIN32 */ if (c == 0x0A || c == 0x09 ) { continue; } if (c < 0x20) { return FALSE; } if (c >= 0x7f) { /* This notices iso-8859 and UTF-8 data as we don't deal with them properly in dwarfdump. */ return FALSE; } } return TRUE; } void sanitized_string_destructor(void) { esb_destructor(&localesb); } const char * sanitized(const char *s) { const char *sout = 0; if (glflags.gf_no_sanitize_strings) { return s; } if (no_questionable_chars(s)) { /* The original string is safe as is. */ return s; } /* Using esb_destructor is quite expensive in cpu time when we build the next sanitized string so we just empty the localesb. One reason it's expensive is that we do the appends in such small batches in do_sanity-insert(). */ esb_empty_string(&localesb); do_sanity_insert(s,&localesb); sout = esb_get_string(&localesb); return sout; } libdwarf-20210528/dwarfdump/print_tag_attributes_usage.c0000664000175000017500000002770614053210412020256 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2021 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "print_frames.h" /* for print_location_operations() . */ #include "macrocheck.h" #include "helpertree.h" #include "opscounttab.h" #include "tag_common.h" #include "attr_form.h" static int pd_dwarf_names_print_on_error = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Record TAGs usage */ static unsigned int tag_usage[DW_TAG_last] = {0}; void record_tag_usage(int tag) { if (tag < DW_TAG_last) { ++tag_usage[tag]; } } #endif /* HAVE_USAGE_TAG_ATTR */ #include "dwarfdump-ta-table.h" #include "dwarfdump-ta-ext-table.h" int legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr) { if (tag <= 0) { return FALSE; } if (tag < ATTR_TREE_ROW_COUNT) { int index = attr / BITS_PER_WORD; if (index < ATTR_TREE_COLUMN_COUNT) { unsigned bitflag = ((unsigned)1) << (attr % BITS_PER_WORD); int known = ((tag_attr_combination_table[tag][index] & bitflag) > 0 ? TRUE : FALSE); if (known) { #ifdef HAVE_USAGE_TAG_ATTR /* Record usage of pair (tag,attr) */ if ( glflags.gf_print_usage_tag_attr) { Usage_Tag_Attr *usage_ptr = usage_tag_attr[tag]; while (usage_ptr->attr) { if (attr == usage_ptr->attr) { ++usage_ptr->count; break; } ++usage_ptr; } } #endif /* HAVE_USAGE_TAG_ATTR */ return TRUE; } } } /* DW_AT_MIPS_fde used to return TRUE as that was convenient for SGI/MIPS users. */ if (!glflags.gf_suppress_check_extensions_tables) { int r = 0; for (; r < ATTR_TREE_EXT_ROW_COUNT; ++r ) { int c = 1; if (tag != tag_attr_combination_ext_table[r][0]) { continue; } for (; c < ATTR_TREE_EXT_COLUMN_COUNT ; ++c) { if (tag_attr_combination_ext_table[r][c] == attr) { return TRUE; } } } } return FALSE; } #include "dwarfdump-tt-table.h" #include "dwarfdump-tt-ext-table.h" /* Look only at valid table entries The check here must match the building-logic in tag_tree.c And must match the tags defined in dwarf.h The tag_tree_combination_table is a table of bit flags. */ int legal_tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child) { if (tag_parent <= 0) { return FALSE; } if (tag_parent < TAG_TREE_ROW_COUNT) { int index = tag_child / BITS_PER_WORD; if (index < TAG_TREE_COLUMN_COUNT) { unsigned bitflag = ((unsigned)1) << (tag_child % BITS_PER_WORD); int known = ((tag_tree_combination_table[tag_parent] [index] & bitflag) > 0 ? TRUE : FALSE); if (known) { #ifdef HAVE_USAGE_TAG_ATTR /* Record usage of pair (tag_parent,tag_child) */ if ( glflags.gf_print_usage_tag_attr) { Usage_Tag_Tree *usage_ptr = usage_tag_tree[tag_parent]; while (usage_ptr->tag) { if (tag_child == usage_ptr->tag) { ++usage_ptr->count; break; } ++usage_ptr; } } #endif /* HAVE_USAGE_TAG_ATTR */ return TRUE; } } } if (!glflags.gf_suppress_check_extensions_tables) { int r = 0; for (; r < TAG_TREE_EXT_ROW_COUNT; ++r ) { int c = 1; if (tag_parent != tag_tree_combination_ext_table[r][0]) { continue; } for (; c < TAG_TREE_EXT_COLUMN_COUNT ; ++c) { if (tag_tree_combination_ext_table[r][c] == tag_child) { return TRUE; } } } } return (FALSE); } /* Print a detailed tag and attributes usage */ int print_tag_attributes_usage(void) { #ifdef HAVE_USAGE_TAG_ATTR /* Traverse the tag-tree table to print its usage and then use the DW_TAG value as an index into the tag_attr table to print its associated usage all together. */ Dwarf_Bool print_header = TRUE; Rate_Tag_Tree *tag_rate; Rate_Tag_Attr *atr_rate; Usage_Tag_Tree *usage_tag_tree_ptr; Usage_Tag_Attr *usage_tag_attr_ptr; Dwarf_Unsigned total_tags = 0; Dwarf_Unsigned total_atrs = 0; Dwarf_Half total_found_tags = 0; Dwarf_Half total_found_atrs = 0; Dwarf_Half total_legal_tags = 0; Dwarf_Half total_legal_atrs = 0; float rate_1; float rate_2; int tag; printf("\n*** TAGS AND ATTRIBUTES USAGE ***\n"); for (tag = 1; tag < DW_TAG_last; ++tag) { /* Print usage of children TAGs */ if ( glflags.gf_print_usage_tag_attr_full || tag_usage[tag]) { usage_tag_tree_ptr = usage_tag_tree[tag]; if (usage_tag_tree_ptr && print_header) { total_tags += tag_usage[tag]; printf("%6d %s\n", tag_usage[tag], get_TAG_name(tag,pd_dwarf_names_print_on_error)); print_header = FALSE; } while (usage_tag_tree_ptr && usage_tag_tree_ptr->tag) { if ( glflags.gf_print_usage_tag_attr_full || usage_tag_tree_ptr->count) { total_tags += usage_tag_tree_ptr->count; printf("%6s %6d %s\n", " ", usage_tag_tree_ptr->count, get_TAG_name(usage_tag_tree_ptr->tag, pd_dwarf_names_print_on_error)); /* Record the tag as found */ if (usage_tag_tree_ptr->count) { ++rate_tag_tree[tag].found; } } ++usage_tag_tree_ptr; } } /* Print usage of attributes */ if ( glflags.gf_print_usage_tag_attr_full || tag_usage[tag]) { usage_tag_attr_ptr = usage_tag_attr[tag]; if (usage_tag_attr_ptr && print_header) { total_tags += tag_usage[tag]; printf("%6d %s\n", tag_usage[tag], get_TAG_name(tag,pd_dwarf_names_print_on_error)); } while (usage_tag_attr_ptr && usage_tag_attr_ptr->attr) { if ( glflags.gf_print_usage_tag_attr_full || usage_tag_attr_ptr->count) { total_atrs += usage_tag_attr_ptr->count; printf("%6s %6d %s\n", " ", usage_tag_attr_ptr->count, get_AT_name(usage_tag_attr_ptr->attr, pd_dwarf_names_print_on_error)); /* Record the attribute as found */ if (usage_tag_attr_ptr->count) { ++rate_tag_attr[tag].found; } } ++usage_tag_attr_ptr; } } print_header = TRUE; } printf("** Summary **\n" "Number of standard tags : %10" /*DW_PR_XZEROS*/ DW_PR_DUu "\n" /* TAGs */ "Number of standard attributes: %10" /*DW_PR_XZEROS*/ DW_PR_DUu "\n" /* ATRs */, total_tags, total_atrs); total_legal_tags = 0; total_found_tags = 0; total_legal_atrs = 0; total_found_atrs = 0; /* Print percentage of TAGs covered */ printf("\n*** STANDARD TAGS AND ATTRIBUTES USAGE RATE ***\n"); printf("%-32s %-16s %-16s\n"," ","Tags","Attributes"); printf("%-32s legal found rate legal found rate\n","TAG name"); for (tag = 1; tag < DW_TAG_last; ++tag) { tag_rate = &rate_tag_tree[tag]; atr_rate = &rate_tag_attr[tag]; if ( glflags.gf_print_usage_tag_attr_full || tag_rate->found || atr_rate->found) { rate_1 = tag_rate->legal ? (float)((tag_rate->found * 100) / tag_rate->legal):0; rate_2 = atr_rate->legal ? (float)((atr_rate->found * 100) / atr_rate->legal):0; /* Skip not defined DW_TAG values (See dwarf.h) */ if (usage_tag_tree[tag]) { total_legal_tags += tag_rate->legal; total_found_tags += tag_rate->found; total_legal_atrs += atr_rate->legal; total_found_atrs += atr_rate->found; printf("%-32s %5d %5d %3.0f%% %5d %5d %3.0f%%\n", get_TAG_name(tag,pd_dwarf_names_print_on_error), tag_rate->legal,tag_rate->found,rate_1, atr_rate->legal,atr_rate->found,rate_2); } } } /* Print a whole summary */ rate_1 = total_legal_tags ? (float)((total_found_tags * 100) / total_legal_tags) : 0; rate_2 = total_legal_atrs ? (float)((total_found_atrs * 100) / total_legal_atrs) : 0; printf("%-32s %5d %5d %3.0f%% %5d %5d %3.0f%%\n", "** Summary **", total_legal_tags,total_found_tags,rate_1, total_legal_atrs,total_found_atrs,rate_2); if (glflags.gf_check_tag_attr || glflags.gf_check_attr_encoding || glflags.gf_print_usage_tag_attr) { print_attr_form_usage(pd_dwarf_names_print_on_error); } #endif /* HAVE_USAGE_TAG_ATTR */ return DW_DLV_OK; } /* This is only needed when processing archives. There is no data to free, but there are counts to reset. usage_tag_tree has a count field. rate_tag_tree has a found field. Function created February 2021. The usage info printed by dwarfdump from Elf archives has been wrong for a few years due to the lack of this function.. */ void reset_usage_rate_tag_trees(void) { int i = 0; for (i = 0 ; i < DW_TAG_last; ++i) { tag_usage[i] = 0; } for (i = 0 ; i < DW_TAG_last; ++i) { Usage_Tag_Tree *usage_ptr = usage_tag_tree[i]; if (!usage_ptr) { continue; } for (; usage_ptr->tag; ++usage_ptr) { usage_ptr->count = 0; } } for (i = 0 ; i < DW_TAG_last; ++i) { rate_tag_tree[i].found = 0; } } libdwarf-20210528/dwarfdump/print_lines.c0000664000175000017500000013115213767716422015201 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. Portions Copyright 2015-2015 Google, Inc. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "uri.h" #include #include #include "print_sections.h" /* Print line number information: [line] [address] new basic-block filename */ #define DW_LINE_VERSION5 5 static void print_source_intro(Dwarf_Debug dbg,Dwarf_Die cu_die) { int ores = 0; Dwarf_Off off = 0; Dwarf_Error src_err = 0; ores = dwarf_dieoffset(cu_die, &off, &src_err); if (ores == DW_DLV_OK) { int lres = 0; const char *sec_name = 0; lres = dwarf_get_die_section_name_b(cu_die, &sec_name,&src_err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_info"; } printf("Source lines (from CU-DIE at %s offset 0x%" DW_PR_XZEROS DW_PR_DUx "):\n", sec_name, (Dwarf_Unsigned) off); DROP_ERROR_INSTANCE(dbg,lres,src_err); } else { DROP_ERROR_INSTANCE(dbg,ores,src_err); printf("Source lines (for the CU-DIE at unknown" " location):\n"); } } static void record_line_error(const char *where, Dwarf_Error line_err) { if (glflags.gf_check_lines && checking_this_compiler()) { struct esb_s tmp_buff; char buftmp[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&tmp_buff,buftmp,sizeof(buftmp)); esb_append_printf_s(&tmp_buff, "Error getting line details calling %s", where); esb_append_printf_s(&tmp_buff, " dwarf error is %s", dwarf_errmsg(line_err)); DWARF_CHECK_ERROR(lines_result,esb_get_string(&tmp_buff)); esb_destructor(&tmp_buff); } } static int process_line_table(Dwarf_Debug dbg, const char *sec_name, Dwarf_Line *linebuf, Dwarf_Signed linecount, Dwarf_Bool is_logicals_table, Dwarf_Bool is_actuals_table, Dwarf_Error *lt_err) { char *padding = 0; Dwarf_Signed i = 0; Dwarf_Addr pc = 0; Dwarf_Unsigned lineno = 0; Dwarf_Unsigned logicalno = 0; Dwarf_Unsigned column = 0; Dwarf_Unsigned call_context = 0; char* subprog_name = 0; char* subprog_filename = 0; Dwarf_Unsigned subprog_line = 0; Dwarf_Bool newstatement = 0; Dwarf_Bool lineendsequence = 0; Dwarf_Bool new_basic_block = 0; int sres = 0; int ares = 0; int lires = 0; int cores = 0; char lastsrc_tmp[ESB_FIXED_ALLOC_SIZE]; struct esb_s lastsrc; Dwarf_Addr elf_max_address = 0; Dwarf_Bool SkipRecord = FALSE; esb_constructor_fixed(&lastsrc,lastsrc_tmp,sizeof(lastsrc_tmp)); glflags.current_section_id = DEBUG_LINE; /* line_flag is TRUE */ get_address_size_and_max(dbg,0,&elf_max_address,lt_err); /* Padding for a nice layout */ padding = glflags.gf_line_print_pc ? " " : ""; if (glflags.gf_do_print_dwarf) { /* Check if print of address is needed. */ printf("\n"); if (is_logicals_table) { printf("Logicals Table:\n"); printf("%sNS new statement, PE prologue end, " "EB epilogue begin\n",padding); printf("%sDI=val discriminator value\n", padding); printf("%sCC=val context, SB=val subprogram\n", padding); } else if (is_actuals_table) { printf("Actuals Table:\n"); printf("%sBB new basic block, ET end of text sequence\n" "%sIS=val ISA number\n",padding,padding); } else { /* Standard DWARF line table. */ printf("%sNS new statement, BB new basic block, " "ET end of text sequence\n",padding); printf("%sPE prologue end, EB epilogue begin\n",padding); printf("%sIS=val ISA number, " "DI=val discriminator value\n", padding); } if (is_logicals_table || is_actuals_table) { printf("[ row] "); } if (glflags.gf_line_print_pc) { printf(" "); } if (is_logicals_table) { printf("[lno,col] NS PE EB DI= CC= SB= uri:" " \"filepath\"\n"); } else if (is_actuals_table) { printf("[logical] BB ET IS=\n"); } else { printf("[lno,col] NS BB ET PE EB IS= DI= uri:" " \"filepath\"\n"); } } for (i = 0; i < linecount; i++) { Dwarf_Line line = linebuf[i]; char* lsrc_filename = 0; int nsres = 0; Dwarf_Bool found_line_error = FALSE; Dwarf_Bool has_is_addr_set = FALSE; char *where = NULL; if (glflags.gf_check_decl_file && checking_this_compiler()) { /* A line record with addr=0 was detected */ if (SkipRecord) { /* Skip records that do not have is_addr_set */ ares = dwarf_line_is_addr_set(line, &has_is_addr_set, lt_err); if (ares == DW_DLV_OK && has_is_addr_set) { SkipRecord = FALSE; } else { /* Keep ignoring records until we have one with 'is_addr_set' */ continue; } } } if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } /* NO. lsrc_filename is a DW_DLA_STRING, do not assign a static string. lsrc_filename = ""; */ if (!is_actuals_table) { Dwarf_Error aterr = 0; sres = dwarf_linesrc(line, &lsrc_filename, &aterr); if (sres == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linesrc()"; record_line_error(where,aterr); found_line_error = TRUE; DROP_ERROR_INSTANCE(dbg,sres,aterr); } } pc = 0; ares = dwarf_lineaddr(line, &pc, lt_err); if (ares == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineaddr()"; record_line_error(where,*lt_err); found_line_error = TRUE; pc = 0; DROP_ERROR_INSTANCE(dbg,ares,*lt_err); } if (ares == DW_DLV_NO_ENTRY) { pc = 0; } if (is_actuals_table) { lires = dwarf_linelogical(line, &logicalno, lt_err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linelogical()"; record_line_error(where,*lt_err); found_line_error = TRUE; DROP_ERROR_INSTANCE(dbg,lires,*lt_err); } if (lires == DW_DLV_NO_ENTRY) { logicalno = 0; } column = 0; } else { lires = dwarf_lineno(line, &lineno, lt_err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineno()"; record_line_error(where,*lt_err); found_line_error = TRUE; DROP_ERROR_INSTANCE(dbg,lires,*lt_err); } if (lires == DW_DLV_NO_ENTRY) { lineno = 0; } cores = dwarf_lineoff_b(line, &column, lt_err); if (cores == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineoff()"; record_line_error(where,*lt_err); found_line_error = TRUE; DROP_ERROR_INSTANCE(dbg,cores,*lt_err); } if (cores == DW_DLV_NO_ENTRY) { /* Zero was always the correct default, meaning the left edge. DWARF2/3/4 spec sec 6.2.2 */ column = 0; } } /* Process any possible error condition, though we won't be at the first such error. */ if (glflags.gf_check_decl_file && checking_this_compiler()) { DWARF_CHECK_COUNT(decl_file_result,1); if (found_line_error) { DWARF_CHECK_ERROR2(decl_file_result,where, dwarf_errmsg(*lt_err)); } else if (glflags.gf_do_check_dwarf) { /* Check the address lies with a valid [lowPC:highPC] in the .text section*/ if (IsValidInBucketGroup(glflags.pRangesInfo,pc)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol. The problem we have here is we have consumed the deug_info section and we are dealing just with the records from the .debug_line, so no PU_name is available and no high_pc. Traverse the linkonce table if try to match the pc value with one of those ranges. */ if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } if (FindAddressInBucketGroup( glflags.pLinkonceInfo,pc)){ /* Valid values; do nothing */ } else { /* The SN Systems Linker generates line records with addr=0, when dealing with linkonce symbols and no stripping */ if (pc) { if (glflags.gf_check_lines && checking_this_compiler()) { char abuf[50]; struct esb_s atm; esb_constructor_fixed(&atm, abuf,sizeof(abuf)); esb_append_printf_s(&atm, "%s: Address", sanitized(sec_name)); esb_append_printf_u(&atm, " 0x%" DW_PR_XZEROS DW_PR_DUx " outside a valid .text range", pc); DWARF_CHECK_ERROR(lines_result, esb_get_string(&atm)); esb_destructor(&atm); } } else { SkipRecord = TRUE; } } } /* Check the last record for the .debug_line, the one created by DW_LNE_end_sequence, is the same as the high_pc address for the last known user program unit (PU). There is no real reason */ if ((i + 1 == linecount) && glflags.seen_PU_high_address && !is_logicals_table) { /* Ignore those PU that have been stripped by the linker; their low_pc values are set to -1 (snc linker only) */ /* It is perfectly sensible for a compiler to leave a few bytes of NOP or other stuff after the last instruction in a subprogram, for cache-alignment or other purposes, so a mismatch here is not necessarily an error. */ if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); if ((pc != glflags.PU_high_address) && (glflags.PU_base_address != elf_max_address)) { char addr_tmp[140]; struct esb_s cm; esb_constructor_fixed(&cm,addr_tmp, sizeof(addr_tmp)); esb_append_printf_s(&cm, "%s: Address",sanitized(sec_name)); esb_append_printf_u(&cm, " 0x%" DW_PR_XZEROS DW_PR_DUx " DW_LNE_end_sequence address" " does not exactly match",pc); esb_append_printf_u(&cm, " high function addr: " " 0x%" DW_PR_XZEROS DW_PR_DUx, glflags.PU_high_address); DWARF_CHECK_ERROR(lines_result, esb_get_string(&cm)); esb_destructor(&cm); } } } } } /* Display the error information */ if (found_line_error || glflags.gf_record_dwarf_error) { if (glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { /* Print the record number for better error description */ printf("Record = %" DW_PR_DUu " Addr = 0x%" DW_PR_XZEROS DW_PR_DUx " [%4" DW_PR_DUu ",%2" DW_PR_DUu "] '%s'\n", i, pc,lineno,column, lsrc_filename?sanitized(lsrc_filename):""); /* The compilation unit was already printed */ if (!glflags.gf_check_decl_file) { PRINT_CU_INFO(); } } glflags.gf_record_dwarf_error = FALSE; /* Due to a fatal error, skip current record */ if (found_line_error) { dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; continue; } } if (glflags.gf_do_print_dwarf) { if (is_logicals_table || is_actuals_table) { printf("[%4" DW_PR_DUu "] ", i + 1); } /* Check if print of address is needed. */ if (glflags.gf_line_print_pc) { printf("0x%" DW_PR_XZEROS DW_PR_DUx " ", pc); } if (is_actuals_table) { printf("[%7" DW_PR_DUu "]", logicalno); } else { printf("[%4" DW_PR_DUu ",%2" DW_PR_DUu "]", lineno, column); } } if (!is_actuals_table) { nsres = dwarf_linebeginstatement(line, &newstatement, lt_err); if (nsres == DW_DLV_OK) { if (newstatement && glflags.gf_do_print_dwarf) { printf(" %s","NS"); } } else if (nsres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_linebeginstatement failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return nsres; } } if (!is_logicals_table) { nsres = dwarf_lineblock(line, &new_basic_block, lt_err); if (nsres == DW_DLV_OK) { if (new_basic_block && glflags.gf_do_print_dwarf) { printf(" %s","BB"); } } else if (nsres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_lineblock failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return nsres; } nsres = dwarf_lineendsequence(line, &lineendsequence, lt_err); if (nsres == DW_DLV_OK) { if (lineendsequence && glflags.gf_do_print_dwarf) { printf(" %s", "ET"); } } else if (nsres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_lineendsequence failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return nsres; } } if (glflags.gf_do_print_dwarf) { Dwarf_Bool prologue_end = 0; Dwarf_Bool epilogue_begin = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; int disres = dwarf_prologue_end_etc(line, &prologue_end,&epilogue_begin, &isa,&discriminator,lt_err); if (disres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_prologue_end_etc() failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return disres; } if (prologue_end && !is_actuals_table) { printf(" PE"); } if (epilogue_begin && !is_actuals_table) { printf(" EB"); } if (isa && !is_logicals_table) { printf(" IS=0x%" DW_PR_DUx, isa); } if (discriminator && !is_actuals_table) { printf(" DI=0x%" DW_PR_DUx, discriminator); } if (is_logicals_table) { call_context = 0; disres = dwarf_linecontext(line, &call_context, lt_err); if (disres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_linecontext() failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return disres; } if (call_context) { printf(" CC=%" DW_PR_DUu, call_context); } subprog_name = 0; disres = dwarf_line_subprog(line, &subprog_name, &subprog_filename, &subprog_line, lt_err); if (disres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: dwarf_line_subprog() failed" " on linebuf index %u ",i); esb_append_printf_u(&m, "of %u line records in the linebuf.", linecount); simple_err_return_action(nsres, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; return disres; } if (subprog_name && strlen(subprog_name)) { /* We do not print an empty name. Clutters things up. */ printf(" SB=\"%s\"", sanitized(subprog_name)); } dwarf_dealloc(dbg,subprog_filename, DW_DLA_STRING); subprog_filename = 0; } } if (!is_actuals_table) { if (i == 0 || glflags.verbose > 2 || strcmp(lsrc_filename?lsrc_filename:"", esb_get_string(&lastsrc))) { struct esb_s urs; char atmp2[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&urs,atmp2,sizeof(atmp2)); esb_append(&urs, " uri: \""); translate_to_uri(lsrc_filename? lsrc_filename:"", &urs); esb_append(&urs,"\""); if (glflags.gf_do_print_dwarf) { printf("%s",esb_get_string(&urs)); } esb_destructor(&urs); esb_empty_string(&lastsrc); esb_append(&lastsrc, lsrc_filename?lsrc_filename:""); } else { /* Do not print name, it is the same as the last name printed. */ } } if (glflags.gf_do_print_dwarf) { printf("\n"); } dwarf_dealloc(dbg,lsrc_filename, DW_DLA_STRING); lsrc_filename = 0; } esb_destructor(&lastsrc); return DW_DLV_OK; } /* Here we test the interfaces into Dwarf_Line_Context. */ static int print_line_context_record(UNUSEDARG Dwarf_Debug dbg, Dwarf_Line_Context line_context, Dwarf_Error *err) { int vres = 0; Dwarf_Unsigned lsecoff = 0; Dwarf_Unsigned version = 0; Dwarf_Signed dir_count = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; Dwarf_Signed i = 0; Dwarf_Signed subprog_count = 0; const char *name = 0; Dwarf_Small table_count = 0; struct esb_s bufr; int include_dir_base = 1; /* DWARF2.3,4 */ int include_dir_limit = 0; /* set below */ char bufr_tmp[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&bufr,bufr_tmp,sizeof(bufr_tmp)); printf("Line Context data\n"); vres = dwarf_srclines_table_offset(line_context,&lsecoff, err); if (vres != DW_DLV_OK) { simple_err_return_action(vres, "\nERROR: dwarf_srclines_table_offset() failed" ". Something broken"); return vres; } printf(" Line Section Offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lsecoff); vres = dwarf_srclines_version(line_context,&version, &table_count, err); if (vres != DW_DLV_OK) { simple_err_return_action(vres, "\nERROR: dwarf_srclines_version() failed" ". Something broken"); return vres; } printf(" version number 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", version,version); printf(" number of line tables %d.\n", table_count); vres = dwarf_srclines_comp_dir(line_context,&name,err); if (vres != DW_DLV_OK) { simple_err_return_action(vres, "\nERROR: dwarf_srclines_comp_dir() failed" ". Something broken"); return vres; } if (name) { printf(" Compilation directory: %s\n",name); } else { printf(" Compilation directory: \n"); } vres = dwarf_srclines_include_dir_count(line_context, &dir_count,err); if (vres != DW_DLV_OK) { simple_err_return_action(vres, "\nERROR: dwarf_srclines_comp_dir() failed" ". Something broken"); return vres; } printf(" include directory count 0x%" DW_PR_DUx " %" DW_PR_DSd "\n", (Dwarf_Unsigned)dir_count,dir_count); if (version == DW_LINE_VERSION5) { include_dir_base = 0; include_dir_limit = dir_count; } else { include_dir_base = 1; include_dir_limit = dir_count+1; } for (i = include_dir_base; i < include_dir_limit; ++i) { vres = dwarf_srclines_include_dir_data(line_context,i, &name,err); if (vres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "\nERROR: Error accessing include directory " " %d ",i); esb_append_printf_i(&m, "(max allowed index is %d).",dir_count); simple_err_return_action(vres, esb_get_string(&m)); esb_destructor(&m); return vres; } printf(" [%2" DW_PR_DSd "] \"%s\"\n",i,name); } vres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,err); if (vres != DW_DLV_OK) { simple_err_return_action(vres, "\nERROR: Error accessing files indexes"); return vres; } printf( " files count 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", file_count,file_count); /* Set up so just one loop control needed for all versions of line tables. */ for (i = baseindex; i < endindex; ++i) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,err); if (vres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "\nERROR: Error accessing line_context " " calling dwarf_srclines_files_data_b() " "with index %d ",i); esb_append_printf_i(&m, "(end index is %d).",endindex); simple_err_return_action(vres, esb_get_string(&m)); esb_destructor(&m); return vres; } esb_empty_string(&bufr); if (name) { esb_empty_string(&bufr); esb_append(&bufr,"\""); esb_append(&bufr,name); esb_append(&bufr,"\""); } else { esb_append(&bufr,""); } printf(" [%2" DW_PR_DSd "] %-24s ,", i,esb_get_string(&bufr)); printf(" directory index %2" DW_PR_DUu ,dirindex); printf(", file length %2" DW_PR_DUu ,flength); if (md5data) { char *c = (char *)md5data; char *end = c+sizeof(*md5data); printf(", file md5 value 0x"); while(c < end) { printf("%02x",0xff&*c); ++c; } printf(" "); } if (modtime) { time_t tt3 = (time_t)modtime; /* ctime supplies newline */ printf( "file mod time 0x%x %s", (unsigned)tt3, ctime(&tt3)); } else { printf(" file mod time 0\n"); } } esb_destructor(&bufr); vres = dwarf_srclines_subprog_count(line_context,&subprog_count, err); if (vres != DW_DLV_OK) { simple_err_return_msg_either_action(vres, "ERROR: dwarf_srclines_subprog_count() on a " "line_context fails"); return vres; } if (subprog_count == 0) { return DW_DLV_OK; } /* The following is for the experimental table which is only DWARF4 so far, so no need for a dwarf_srclines_subprog_indexes() function. Yet. */ printf(" subprograms count (experimental) 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", subprog_count,subprog_count); for (i = 1; i <= subprog_count; ++i) { Dwarf_Unsigned decl_file = 0; Dwarf_Unsigned decl_line = 0; vres = dwarf_srclines_subprog_data(line_context,i, &name,&decl_file, &decl_line,err); if (vres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "\nERROR: Error accessing line_context " " calling dwarf_srclines_subprog_data() " "with index %d ",i); esb_append_printf_i(&m, "(end index is %d).",subprog_count); simple_err_return_action(vres, esb_get_string(&m)); esb_destructor(&m); return vres; } printf(" [%2" DW_PR_DSd "] \"%s\"" ", fileindex %2" DW_PR_DUu ", lineindex %2" DW_PR_DUu "\n", i,name,decl_file,decl_line); } return DW_DLV_OK; } int print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, char **srcfiles, Dwarf_Signed srcf_count, Dwarf_Error *err) { Dwarf_Unsigned lineversion = 0; Dwarf_Signed linecount = 0; Dwarf_Line *linebuf = NULL; Dwarf_Signed linecount_actuals = 0; Dwarf_Line *linebuf_actuals = NULL; Dwarf_Small table_count = 0; int lres = 0; int line_errs = 0; Dwarf_Line_Context line_context = 0; const char *sec_name = 0; Dwarf_Off cudie_local_offset = 0; Dwarf_Off dieprint_cu_goffset = 0; int atres = 0; glflags.current_section_id = DEBUG_LINE; /* line_flag is TRUE */ lres = dwarf_get_line_section_name_from_die(cu_die, &sec_name,err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_line"; } DROP_ERROR_INSTANCE(dbg,lres,*err); /* The offsets will be zero if it fails. Let it pass. */ atres = dwarf_die_offsets(cu_die,&dieprint_cu_goffset, &cudie_local_offset,err); DROP_ERROR_INSTANCE(dbg,atres,*err); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_line", &truename,FALSE); /* Ignore the COMPRESSED flags */ printf("\n%s: line number info for a single cu\n", sanitized(esb_get_string(&truename))); esb_destructor(&truename); } else { /* We are checking, not printing. */ Dwarf_Half tag = 0; int tres = dwarf_tag(cu_die, &tag, err); if (tres != DW_DLV_OK) { /* Something broken here. */ struct esb_s m; esb_constructor(&m); esb_append(&m, "\nERROR: Unable to get CU DIE dwarf tag " "attempting to print line numbers for a CU "); if (tres == DW_DLV_ERROR) { esb_append(&m,dwarf_errmsg(*err)); } simple_err_return_msg_either_action(tres, esb_get_string(&m)); esb_destructor(&m); return tres; } else if (tag == DW_TAG_type_unit) { /* Not checking since type units missing address or range in CU header. */ return DW_DLV_NO_ENTRY; } } if (glflags.verbose > 1) { int errcount = 0; Dwarf_Bool attr_dup = FALSE; int lresv = 0; print_source_intro(dbg,cu_die); lresv = print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ 1, /* indent level */0, srcfiles,srcf_count, &attr_dup, /* ignore_die_stack= */TRUE, err); if (lresv == DW_DLV_ERROR) { return lresv; } DWARF_CHECK_COUNT(lines_result,1); lresv = dwarf_print_lines(cu_die, err,&errcount); if (errcount > 0) { DWARF_ERROR_COUNT(lines_result,errcount); DWARF_CHECK_COUNT(lines_result,(errcount-1)); } if (lresv == DW_DLV_ERROR) { print_error_and_continue(dbg, "Failed to print CU lines", lresv, *err); } return lresv; } if (glflags.gf_check_lines && checking_this_compiler()) { int lres2 = 0; DWARF_CHECK_COUNT(lines_result,1); lres2 = dwarf_check_lineheader_b(cu_die,&line_errs, err); if (lres2 == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_check_lineheader_b found a serious error", lres2, *err); dwarf_dealloc(dbg,*err,DW_DLA_ERROR); *err = 0; } if (line_errs > 0) { DWARF_CHECK_ERROR_PRINT_CU(); DWARF_ERROR_COUNT(lines_result,line_errs); DWARF_CHECK_COUNT(lines_result,(line_errs-1)); } } /* The following is complicated by a desire to test various line table interface functions. Hence we test line_flag_selection. Normal code should pick an interface (for most the best choice is what we here call glflags.gf_line_flag_selection == singledw5) and use just that interface set. Sorry about the length of the code that results from having so many interfaces. */ if (glflags.gf_line_flag_selection == singledw5) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, err); if (lres == DW_DLV_OK) { lres = dwarf_srclines_from_linecontext(line_context, &linebuf, &linecount,err); } } else if (glflags.gf_line_flag_selection == orig) { /* DWARF2,3,4, ok for 5. */ /* Useless for experimental line tables */ lres = dwarf_srclines(cu_die, &linebuf, &linecount, err); if (lres == DW_DLV_OK && linecount ){ table_count++; } } else if (glflags.gf_line_flag_selection == orig2l) { lres = dwarf_srclines_two_level(cu_die, &lineversion, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, err); if (lres == DW_DLV_OK && linecount){ table_count++; } if (lres == DW_DLV_OK && linecount_actuals){ table_count++; } } else if (glflags.gf_line_flag_selection == s2l) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, err); if (lres == DW_DLV_OK) { lres = dwarf_srclines_two_level_from_linecontext( line_context, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, err); } } if (lres == DW_DLV_ERROR) { /* Do not terminate processing */ if (glflags.gf_check_decl_file) { DWARF_CHECK_COUNT(decl_file_result,1); DWARF_CHECK_ERROR2(decl_file_result,"dwarf_srclines", dwarf_errmsg(*err)); /* Clear error condition */ glflags.gf_record_dwarf_error = FALSE; } else { print_error_and_continue(dbg, "dwarf_srclines", lres, *err); } DROP_ERROR_INSTANCE(dbg,lres,*err); return DW_DLV_OK; } else if (lres == DW_DLV_NO_ENTRY) { /* no line information is included */ } else if (table_count > 0) { /* lres DW_DLV_OK */ if (glflags.gf_do_print_dwarf) { if (line_context && glflags.verbose) { lres = print_line_context_record(dbg, line_context,err); if (lres != DW_DLV_OK){ /* Should we issue message about this call? */ dwarf_srclines_dealloc_b(line_context); return lres; } } print_source_intro(dbg,cu_die); if (glflags.verbose) { int dres = 0; Dwarf_Bool attr_dup = FALSE; /* FIXME */ dres = print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, &attr_dup, /* ignore_die_stack= */TRUE,err); if (dres == DW_DLV_ERROR) { dwarf_srclines_dealloc_b(line_context); return dres; } } } if (glflags.gf_line_flag_selection == singledw5 || glflags.gf_line_flag_selection == s2l) { int ltres = 0; if (table_count == 0 || table_count == 1) { /* ASSERT: is_single_table == true */ Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; ltres = process_line_table(dbg,sec_name, linebuf, linecount, is_logicals,is_actuals,err); if (ltres == DW_DLV_ERROR) { /* what if NO_ENTRY? */ dwarf_srclines_dealloc_b(line_context); return ltres; } } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; ltres = process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals,err); if (ltres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return ltres; dwarf_srclines_dealloc_b(line_context); return ltres; } ltres = process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals,err); if (ltres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return ltres; } } dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; } else if (glflags.gf_line_flag_selection == orig) { int ltres = 0; Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; ltres= process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals,err); dwarf_srclines_dealloc(dbg,linebuf,linecount); linebuf = 0; if (ltres != DW_DLV_OK) { /* what if NO_ENTRY? */ return ltres; } } else if (glflags.gf_line_flag_selection == orig2l) { int ltres = 0; if (table_count == 1 || table_count == 0) { Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; ltres = process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals,err); dwarf_srclines_dealloc(dbg,linebuf,linecount); linebuf = 0; if (ltres != DW_DLV_OK) { return ltres; } } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; ltres = process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals,err); ltres = process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals,err); dwarf_srclines_dealloc(dbg,linebuf,linecount); linebuf = 0; if (ltres != DW_DLV_OK) { /* what if NO_ENTRY? */ return ltres; } } } /* end, table_count > 0 */ } else { /* lres DW_DLV_OK */ /* table_count == 0. no lines in table. Just a line table header. */ if (glflags.gf_do_print_dwarf) { int ores = 0; Dwarf_Unsigned off = 0; print_source_intro(dbg,cu_die); if (glflags.verbose) { int dpres = 0; Dwarf_Bool attr_dup = FALSE; /* FIXME */ dpres = print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, &attr_dup, /* ignore_die_stack= */TRUE, err); if (dpres == DW_DLV_ERROR) { dwarf_srclines_dealloc(dbg,linebuf,linecount); return dpres; } } if (line_context) { if (glflags.verbose > 2) { ores = print_line_context_record(dbg, line_context,err); if (ores != DW_DLV_OK) { simple_err_return_msg_either_action( ores, "ERROR: line context record " " where table count is 0 has a" " problem"); dwarf_srclines_dealloc(dbg,linebuf,linecount); return ores; } } ores = dwarf_srclines_table_offset( line_context, &off,err); if (ores != DW_DLV_OK) { simple_err_return_msg_either_action( ores, "ERROR: line context table_offset " " where table count is 0 has a" " problem"); dwarf_srclines_dealloc(dbg,linebuf,linecount); return ores; } else { printf(" Line table is present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no lines present\n", off); } } else { printf(" Line table is present but" " no lines present\n"); } } if (glflags.gf_line_flag_selection == singledw5 || glflags.gf_line_flag_selection == s2l) { /* also deletes the linebuf... */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; } else if (linebuf) { /* Original allocation. No context record. */ dwarf_srclines_dealloc(dbg,linebuf,linecount); linebuf = 0; } /* end, linecounttotal == 0 */ } if (line_context) { /* also deletes the linebuf... */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; } if (linebuf) { dwarf_srclines_dealloc(dbg,linebuf,linecount); linebuf = 0; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/section_bitmaps_test.c0000664000175000017500000000420213764006205017054 00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in command_options.c */ #include "section_bitmaps.h" int main() { unsigned i = 1; unsigned arraycount = section_bitmap_array_size(); if (arraycount != DW_HDR_ARRAY_SIZE) { printf("FAIL map_sections.c sections array wrong size " "%u vs %u\n", arraycount,DW_HDR_ARRAY_SIZE); exit(1); } for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { struct section_map_s * mp = map_sectnames+i; if (mp->value != i) { printf("FAIL map_sections.c at entry %s we have " "0x%x vs 0x%x" " mismatch\n", mp->name?mp->name:"value, i); exit(1); } if (!mp->name) { printf("FAIL map_sections.c at entry %u" " we have no name!\n",i); exit(1); } } printf("PASS section maps\n"); return 0; } libdwarf-20210528/dwarfdump/DWARFDUMPCOPYRIGHT0000664000175000017500000000750613644370703015251 00000000000000 ========The dwarfdump copyright======= The full text of the GPL version 2 is provided in the file GPL.txt. See the end of this file for January 2015 changes. Nearly all the files in this directory have contained a GPL copyright, not an LGPL copyright, for years. The following is an example of that copyright as used in the dwarfdump source, and is what SGI always intended (in David Anderson's opinion) to have present in the DWARFDUMPCOPYRIGHT file. (tag_tree.list tag_attr.list acconfig.h have long been marked LGPL and therefore the LGPL copyright, not GPL, applies to those three files.) This GPL copyright text added here to DWARFDUMPCOPYRIGHT Dec 4, 2006 Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan The following was the entire content of this file before December 24 2006, Being the LGPL text this is in conflict with the individual source files and I (David Anderson) believe the source file copyright was intended for dwarfdump not the LGPL source directly following this note. However the 3 files tag_tree.list tag_attr.list acconfig.h have long been marked LGPL and the following copyright applies to those three. Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan As of 31 January 2015 the lines with http://www.sgi.com and oss.sgi.com have been removed. sgi.com is readily found on the web and oss.sgi.com no longer exists. No one from SGI still contributes to dwarfdump. libdwarf-20210528/dwarfdump/defined_types.h0000644000175000017500000000244113767715500015472 00000000000000/* Copyright 2011-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DEFINED_TYPES_H #define DEFINED_TYPES_H #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FAILED #define FAILED 1 #endif #define OKAY 0 #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DEFINED_TYPES_H */ libdwarf-20210528/dwarfdump/ChangeLog20130000664000175000017500000001030613644370703014554 000000000000002013-10-17 David Anderson * print_types.c: Remove pointless blank line. 2013-08-15 David Anderson * dwarfdump.c: Now calls dwarf_register_printf_callback() so dwarf_print_lines() output is shown (if dwarfdump wants it shown). Update version string. * common.c: Update version string. 2013-08-13 David Anderson * esb.c: Add 1 so the esb_append_printf has room for the NUL byte. * print_die.c: Clarified a comment about DW_AT_high_pc and FORM class constant. Fixed indent error. * dwarfdump.c: Fixed indent error. 2013-08-08 David Anderson * print_reloc.c: Removed duplicated call to get_scndata(). 2013-08-07 David Anderson * dwarfdump.c: Changed non-fatal error messages to write to stdout instead of stderr. Making it much easier to have a usable output-with-errors in case of redirection. Updated version string. * checkutil.c: If a certain pointer not set, just do nothing, there is no reason to abort. Added in a missing [ in a debug printf. * common.c: Updated version string. 2013-07-30 David Anderson * common.c,dwarfdump.c: updated version string. 2013-02-05 David Anderson * dwarfdump.c: Update version string. get_producer_name() now uses struct esb_s; * common.c: Update version string. * print_die.c: Check DW_AT_sibling values for sanity, and when something quite wrong is found, print an error and stop. get_producer_name() now uses struct esb_s; Added sibling_die_global_offset_ to die_stack_data_s so we can check sibling attribute values. get_attr_value() now uses esb_s pointer. * globals.h: get_producer_name() now uses struct esb_s; * print_aranges.c, print_pubnames.c:get_producer_name() now uses struct esb_s; * dwconf.c: The use of esb_s means we need to consider an empty config-file-path as no path and look in default places. We cannot just test for null pointer. 2013-02-04 David Anderson * dwarfdump/addrmap.c: Forgot to remove the addr_map_destroy() implementation in #ifndef HAVE_TSEARCH. Now it is removed. 2013-02-03 David Anderson * dwarfdump/addrmap.c: Implement HAVE_TDESTROY. tdestroy() is GNU only. Now we allow tsearch without tdestroy even though that means leaking every tsearch map we build. dwarfdump2 has no such leak. * dwarfdump/config.h.in: Add HAVE_TDESTROY. * dwarfdump/configure: Regenerate. * dwarfdump/configure.in: Test for tdestroy() function. * dwarfdump/print_frames.c: Zero out the map pointer. 2013-02-01 David Anderson * print_die.c: Replaced use of makename (which did malloc) with use of struct esb_s, avoiding a serious memory leak. Completely removed static struct variables esb_base and esb_extra, ensuring die string print-data is not corrupted by recursive calls. * dwarfdump.c, common.c: Update version string. 2013-01-26 David Anderson * dwarfdump.c, common.c: Update version string. * print_die.c: Print DW_OP_GNU_const_type properly using the binary-compatibility version of Dwarf_Loc. 2013-01-25 David Anderson * dwarfdump.c, common.c: Update version string. * print_die.c: Print DW_OP_GNU_const_type properly. 2013-01-16 David Anderson * dwconf.c: Changed table size to unsigned to eliminate signed/unsigned comparison warnings. * dwconf.h: Changed struct fields to unsigned to eliminate signed/unsigned comparison warnings. * esb.c: Checked for negative vfprintf return to avoid (hopefully impossible) error from crashing the program, and fix comparison warnings. * print_die.c: Changed counts to unsigned to fix signed/unsigned comparison warnings. * print_frames.c: Changed counts to unsigned to fix signed/unsigned comparison warnings. * print_reloc.c: Changed table sizes to unsigned to fix signed/unsigned comparison warnings. * tag_tree.c, tag_attr.c: Changed table sizes to unsigned to fix signed/unsigned comparison warnings. 2013-01-16 David Anderson * dwarfdump.c, common.c: Update version string. libdwarf-20210528/dwarfdump/COPYING0000644000175000017500000000206513743575426013541 00000000000000 David Anderson: December 2006 The code in the dwarfdump directory is (if you look in each file) covered by the GPL (not the LGPL). The DWARFDUMPCOPYRIGHT file, though, said (before December 24, 2006) the copyright is LGPL. There is no doubt in my (David Anderson) mind that the intent was always that dwarfdump be GPL and the copyright markings in each file are correct. There are three files marked with the LGPL: tag_tree.list tag_attr.list acconfig.h. These markings are left as is and these are are therefore LGPL files. A few files are marked with the two-clause BSD license (FreeBSD license). The DWARFDUMPCOPYRIGHT file now (Dec 24 2006) has both copyrights and an explanation of where each applies. ------------------------------------------- The text present for years, thru Dec 23, 2006: The files: dwarfdump.c and all the .h and .c files in this implementation of dwarfdump are copyrighted according to the file DWARFDUMPCOPYRIGHT. $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/COPYING,v $ $Revision: 1.1 $ $Date: 2001/01/16 17:47:55 $ libdwarf-20210528/dwarfdump/testuriLE64ELf.base0000664000175000017500000012656414012575576016034 00000000000000 .debug_info CU_HEADER: cu_header_length = 0x0000133e 4926 version_stamp = 0x0004 4 abbrev_offset = 0x00000000 0 address_size = 0x08 8 offset_size = 0x04 4 cu_type = 0x01 DW_UT_compile COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit dwarf_srcfiles() returned strings. Count = 16. [ 0] /home/davea/dwarf/code/dwarfdump/uri.c [ 1] /usr/include/x86_64-linux-gnu/bits/stdio2.h [ 2] /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h [ 3] /usr/include/x86_64-linux-gnu/bits/types.h [ 4] /usr/include/x86_64-linux-gnu/bits/libio.h [ 5] /usr/include/x86_64-linux-gnu/bits/types/FILE.h [ 6] /usr/include/stdio.h [ 7] /usr/include/x86_64-linux-gnu/bits/sys_errlist.h [ 8] /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h [ 9] /usr/include/regex.h [10] /home/davea/dwarf/code/dwarfdump/checkutil.h [11] /home/davea/dwarf/code/dwarfdump/defined_types.h [12] /home/davea/dwarf/code/dwarfdump/glflags.h [13] /home/davea/dwarf/code/dwarfdump/esb.h [14] /home/davea/dwarf/code/dwarfdump/globals.h [15] /tmp/dwbld/dwarfdump/ DW_AT_producer GNU C11 7.4.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong DW_AT_language DW_LANG_C99 DW_AT_name /home/davea/dwarf/code/dwarfdump/uri.c DW_AT_comp_dir /tmp/dwbld/dwarfdump DW_AT_low_pc 0x00000000 DW_AT_high_pc 618 DW_AT_stmt_list 0x00000000 LOCAL_SYMBOLS: < 1><0x0000002d> DW_TAG_typedef DW_AT_name size_t DW_AT_decl_file 0x00000003 /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h DW_AT_decl_line 0x000000d8 DW_AT_type <0x00000038> < 1><0x00000038> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned DW_AT_name long unsigned int < 1><0x0000003f> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_unsigned_char DW_AT_name unsigned char < 1><0x00000046> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_unsigned DW_AT_name short unsigned int < 1><0x0000004d> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_unsigned DW_AT_name unsigned int < 1><0x00000054> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name signed char < 1><0x0000005b> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_signed DW_AT_name short int < 1><0x00000062> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name int < 1><0x00000069> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long int < 1><0x00000070> DW_TAG_typedef DW_AT_name __off_t DW_AT_decl_file 0x00000004 /usr/include/x86_64-linux-gnu/bits/types.h DW_AT_decl_line 0x0000008c DW_AT_type <0x00000069> < 1><0x0000007b> DW_TAG_typedef DW_AT_name __off64_t DW_AT_decl_file 0x00000004 /usr/include/x86_64-linux-gnu/bits/types.h DW_AT_decl_line 0x0000008d DW_AT_type <0x00000069> < 1><0x00000086> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 < 1><0x00000088> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000008e> < 1><0x0000008e> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name char < 1><0x00000095> DW_TAG_const_type DW_AT_type <0x0000008e> < 1><0x0000009a> DW_TAG_structure_type DW_AT_name _IO_FILE DW_AT_byte_size 0x000000d8 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000f5 DW_AT_sibling <0x0000021a> < 2><0x000000a6> DW_TAG_member DW_AT_name _flags DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000f6 DW_AT_type <0x00000062> DW_AT_data_member_location 0 < 2><0x000000b2> DW_TAG_member DW_AT_name _IO_read_ptr DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fb DW_AT_type <0x00000088> DW_AT_data_member_location 8 < 2><0x000000be> DW_TAG_member DW_AT_name _IO_read_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fc DW_AT_type <0x00000088> DW_AT_data_member_location 16 < 2><0x000000ca> DW_TAG_member DW_AT_name _IO_read_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fd DW_AT_type <0x00000088> DW_AT_data_member_location 24 < 2><0x000000d6> DW_TAG_member DW_AT_name _IO_write_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fe DW_AT_type <0x00000088> DW_AT_data_member_location 32 < 2><0x000000e2> DW_TAG_member DW_AT_name _IO_write_ptr DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000ff DW_AT_type <0x00000088> DW_AT_data_member_location 40 < 2><0x000000ee> DW_TAG_member DW_AT_name _IO_write_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000100 DW_AT_type <0x00000088> DW_AT_data_member_location 48 < 2><0x000000fb> DW_TAG_member DW_AT_name _IO_buf_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000101 DW_AT_type <0x00000088> DW_AT_data_member_location 56 < 2><0x00000108> DW_TAG_member DW_AT_name _IO_buf_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000102 DW_AT_type <0x00000088> DW_AT_data_member_location 64 < 2><0x00000115> DW_TAG_member DW_AT_name _IO_save_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000104 DW_AT_type <0x00000088> DW_AT_data_member_location 72 < 2><0x00000122> DW_TAG_member DW_AT_name _IO_backup_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000105 DW_AT_type <0x00000088> DW_AT_data_member_location 80 < 2><0x0000012f> DW_TAG_member DW_AT_name _IO_save_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000106 DW_AT_type <0x00000088> DW_AT_data_member_location 88 < 2><0x0000013c> DW_TAG_member DW_AT_name _markers DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000108 DW_AT_type <0x0000025d> DW_AT_data_member_location 96 < 2><0x00000149> DW_TAG_member DW_AT_name _chain DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000010a DW_AT_type <0x00000263> DW_AT_data_member_location 104 < 2><0x00000156> DW_TAG_member DW_AT_name _fileno DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000010c DW_AT_type <0x00000062> DW_AT_data_member_location 112 < 2><0x00000163> DW_TAG_member DW_AT_name _flags2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000110 DW_AT_type <0x00000062> DW_AT_data_member_location 116 < 2><0x00000170> DW_TAG_member DW_AT_name _old_offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000112 DW_AT_type <0x00000070> DW_AT_data_member_location 120 < 2><0x0000017d> DW_TAG_member DW_AT_name _cur_column DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000116 DW_AT_type <0x00000046> DW_AT_data_member_location 128 (-128) < 2><0x0000018a> DW_TAG_member DW_AT_name _vtable_offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000117 DW_AT_type <0x00000054> DW_AT_data_member_location 130 (-126) < 2><0x00000197> DW_TAG_member DW_AT_name _shortbuf DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000118 DW_AT_type <0x00000269> DW_AT_data_member_location 131 (-125) < 2><0x000001a4> DW_TAG_member DW_AT_name _lock DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000011c DW_AT_type <0x00000279> DW_AT_data_member_location 136 (-120) < 2><0x000001b1> DW_TAG_member DW_AT_name _offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000125 DW_AT_type <0x0000007b> DW_AT_data_member_location 144 (-112) < 2><0x000001be> DW_TAG_member DW_AT_name __pad1 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012d DW_AT_type <0x00000086> DW_AT_data_member_location 152 (-104) < 2><0x000001cb> DW_TAG_member DW_AT_name __pad2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012e DW_AT_type <0x00000086> DW_AT_data_member_location 160 (-96) < 2><0x000001d8> DW_TAG_member DW_AT_name __pad3 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012f DW_AT_type <0x00000086> DW_AT_data_member_location 168 (-88) < 2><0x000001e5> DW_TAG_member DW_AT_name __pad4 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000130 DW_AT_type <0x00000086> DW_AT_data_member_location 176 (-80) < 2><0x000001f2> DW_TAG_member DW_AT_name __pad5 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000132 DW_AT_type <0x0000002d> DW_AT_data_member_location 184 (-72) < 2><0x000001ff> DW_TAG_member DW_AT_name _mode DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000133 DW_AT_type <0x00000062> DW_AT_data_member_location 192 (-64) < 2><0x0000020c> DW_TAG_member DW_AT_name _unused2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000135 DW_AT_type <0x0000027f> DW_AT_data_member_location 196 (-60) < 1><0x0000021a> DW_TAG_typedef DW_AT_name FILE DW_AT_decl_file 0x00000006 /usr/include/x86_64-linux-gnu/bits/types/FILE.h DW_AT_decl_line 0x00000007 DW_AT_type <0x0000009a> < 1><0x00000225> DW_TAG_typedef DW_AT_name _IO_lock_t DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000009a < 1><0x0000022c> DW_TAG_structure_type DW_AT_name _IO_marker DW_AT_byte_size 0x00000018 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a0 DW_AT_sibling <0x0000025d> < 2><0x00000238> DW_TAG_member DW_AT_name _next DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a1 DW_AT_type <0x0000025d> DW_AT_data_member_location 0 < 2><0x00000244> DW_TAG_member DW_AT_name _sbuf DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a2 DW_AT_type <0x00000263> DW_AT_data_member_location 8 < 2><0x00000250> DW_TAG_member DW_AT_name _pos DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a6 DW_AT_type <0x00000062> DW_AT_data_member_location 16 < 1><0x0000025d> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000022c> < 1><0x00000263> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000009a> < 1><0x00000269> DW_TAG_array_type DW_AT_type <0x0000008e> DW_AT_sibling <0x00000279> < 2><0x00000272> DW_TAG_subrange_type DW_AT_type <0x00000038> DW_AT_upper_bound 0 < 1><0x00000279> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000225> < 1><0x0000027f> DW_TAG_array_type DW_AT_type <0x0000008e> DW_AT_sibling <0x0000028f> < 2><0x00000288> DW_TAG_subrange_type DW_AT_type <0x00000038> DW_AT_upper_bound 19 < 1><0x0000028f> DW_TAG_structure_type DW_AT_name _IO_FILE_plus DW_AT_declaration yes(1) < 1><0x00000294> DW_TAG_variable DW_AT_name _IO_2_1_stdin_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000013f DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002a0> DW_TAG_variable DW_AT_name _IO_2_1_stdout_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000140 DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002ac> DW_TAG_variable DW_AT_name _IO_2_1_stderr_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000141 DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002b8> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000095> < 1><0x000002be> DW_TAG_const_type DW_AT_type <0x000002b8> < 1><0x000002c3> DW_TAG_restrict_type DW_AT_type <0x000002b8> < 1><0x000002c8> DW_TAG_variable DW_AT_name stdin DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000087 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002d3> DW_TAG_variable DW_AT_name stdout DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000088 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002de> DW_TAG_variable DW_AT_name stderr DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000089 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002e9> DW_TAG_variable DW_AT_name sys_nerr DW_AT_decl_file 0x00000008 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h DW_AT_decl_line 0x0000001a DW_AT_type <0x00000062> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002f4> DW_TAG_array_type DW_AT_type <0x000002be> DW_AT_sibling <0x000002ff> < 2><0x000002fd> DW_TAG_subrange_type < 1><0x000002ff> DW_TAG_const_type DW_AT_type <0x000002f4> < 1><0x00000304> DW_TAG_variable DW_AT_name sys_errlist DW_AT_decl_file 0x00000008 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h DW_AT_decl_line 0x0000001b DW_AT_type <0x000002ff> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000030f> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long long int < 1><0x00000316> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned DW_AT_name long long unsigned int < 1><0x0000031d> DW_TAG_typedef DW_AT_name Dwarf_Unsigned DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004a DW_AT_type <0x00000316> < 1><0x00000328> DW_TAG_typedef DW_AT_name Dwarf_Off DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004c DW_AT_type <0x00000316> < 1><0x00000333> DW_TAG_typedef DW_AT_name Dwarf_Addr DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004d DW_AT_type <0x00000316> < 1><0x0000033e> DW_TAG_typedef DW_AT_name Dwarf_Bool DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004e DW_AT_type <0x00000062> < 1><0x00000349> DW_TAG_typedef DW_AT_name Dwarf_Die DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00000218 DW_AT_type <0x00000355> < 1><0x00000355> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000035b> < 1><0x0000035b> DW_TAG_structure_type DW_AT_name Dwarf_Die_s DW_AT_declaration yes(1) < 1><0x00000360> DW_TAG_structure_type DW_AT_byte_size 0x00000004 DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001391 DW_AT_sibling <0x00000377> < 2><0x00000369> DW_TAG_member DW_AT_name check_verbose_mode DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001392 DW_AT_type <0x0000033e> DW_AT_data_member_location 0 < 1><0x00000377> DW_TAG_typedef DW_AT_name Dwarf_Cmdline_Options DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001393 DW_AT_type <0x00000360> < 1><0x00000383> DW_TAG_variable DW_AT_name dwarf_cmdline_options DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001394 DW_AT_type <0x00000377> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000038f> DW_TAG_typedef DW_AT_name reg_syntax_t DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000002a DW_AT_type <0x00000038> < 1><0x0000039a> DW_TAG_variable DW_AT_name re_syntax_options DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x000000b5 DW_AT_type <0x0000038f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000003a5> DW_TAG_structure_type DW_AT_name re_pattern_buffer DW_AT_byte_size 0x00000040 DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000165 DW_AT_sibling <0x0000047e> < 2><0x000003b2> DW_TAG_member DW_AT_name __buffer DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000016a DW_AT_type <0x0000047e> DW_AT_data_member_location 0 < 2><0x000003bf> DW_TAG_member DW_AT_name __allocated DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000016d DW_AT_type <0x00000038> DW_AT_data_member_location 8 < 2><0x000003cc> DW_TAG_member DW_AT_name __used DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000170 DW_AT_type <0x00000038> DW_AT_data_member_location 16 < 2><0x000003d9> DW_TAG_member DW_AT_name __syntax DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000173 DW_AT_type <0x0000038f> DW_AT_data_member_location 24 < 2><0x000003e6> DW_TAG_member DW_AT_name __fastmap DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000178 DW_AT_type <0x00000088> DW_AT_data_member_location 32 < 2><0x000003f3> DW_TAG_member DW_AT_name __translate DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000017e DW_AT_type <0x0000047e> DW_AT_data_member_location 40 < 2><0x00000400> DW_TAG_member DW_AT_name re_nsub DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000181 DW_AT_type <0x0000002d> DW_AT_data_member_location 48 < 2><0x0000040d> DW_TAG_member DW_AT_name __can_be_null DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000187 DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x0000001f DW_AT_data_member_location 56 < 2><0x0000041d> DW_TAG_member DW_AT_name __regs_allocated DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000192 DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000002 DW_AT_bit_offset 0x0000001d DW_AT_data_member_location 56 < 2><0x0000042d> DW_TAG_member DW_AT_name __fastmap_accurate DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000196 DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x0000001c DW_AT_data_member_location 56 < 2><0x0000043d> DW_TAG_member DW_AT_name __no_sub DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000019a DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x0000001b DW_AT_data_member_location 56 < 2><0x0000044d> DW_TAG_member DW_AT_name __not_bol DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000019e DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x0000001a DW_AT_data_member_location 56 < 2><0x0000045d> DW_TAG_member DW_AT_name __not_eol DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x000001a1 DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x00000019 DW_AT_data_member_location 56 < 2><0x0000046d> DW_TAG_member DW_AT_name __newline_anchor DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x000001a4 DW_AT_type <0x0000004d> DW_AT_byte_size 0x00000004 DW_AT_bit_size 0x00000001 DW_AT_bit_offset 0x00000018 DW_AT_data_member_location 56 < 1><0x0000047e> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000003f> < 1><0x00000484> DW_TAG_typedef DW_AT_name regex_t DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x000001a7 DW_AT_type <0x000003a5> < 1><0x00000490> DW_TAG_structure_type DW_AT_byte_size 0x00000030 DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000026 DW_AT_sibling <0x000004e1> < 2><0x00000498> DW_TAG_member DW_AT_name bFlag DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000027 DW_AT_type <0x0000033e> DW_AT_data_member_location 0 < 2><0x000004a4> DW_TAG_member DW_AT_name name DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000028 DW_AT_type <0x000002b8> DW_AT_data_member_location 8 < 2><0x000004b0> DW_TAG_member DW_AT_name key DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000029 DW_AT_type <0x00000333> DW_AT_data_member_location 16 < 2><0x000004bc> DW_TAG_member DW_AT_name base DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000002c DW_AT_type <0x00000333> DW_AT_data_member_location 24 < 2><0x000004c8> DW_TAG_member DW_AT_name low DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000002d DW_AT_type <0x00000333> DW_AT_data_member_location 32 < 2><0x000004d4> DW_TAG_member DW_AT_name high DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000002e DW_AT_type <0x00000333> DW_AT_data_member_location 40 < 1><0x000004e1> DW_TAG_typedef DW_AT_name Bucket_Data DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000002f DW_AT_type <0x00000490> < 1><0x000004ec> DW_TAG_structure_type DW_AT_name bucket DW_AT_byte_size 0x00017e90 DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000003a DW_AT_sibling <0x00000523> < 2><0x000004fb> DW_TAG_member DW_AT_name nEntries DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000003b DW_AT_type <0x00000062> DW_AT_data_member_location 0 < 2><0x00000507> DW_TAG_member DW_AT_name Entries DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000003c DW_AT_type <0x00000523> DW_AT_data_member_location 8 < 2><0x00000513> DW_TAG_member DW_AT_name pNext DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000003d DW_AT_type <0x00000534> DW_AT_data_member_location 97928 < 1><0x00000523> DW_TAG_array_type DW_AT_type <0x000004e1> DW_AT_sibling <0x00000534> < 2><0x0000052c> DW_TAG_subrange_type DW_AT_type <0x00000038> DW_AT_upper_bound 2039 < 1><0x00000534> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x000004ec> < 1><0x0000053a> DW_TAG_typedef DW_AT_name Bucket DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x0000003e DW_AT_type <0x000004ec> < 1><0x00000545> DW_TAG_structure_type DW_AT_byte_size 0x00000038 DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000042 DW_AT_sibling <0x000005a2> < 2><0x0000054d> DW_TAG_member DW_AT_name kind DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000043 DW_AT_type <0x00000062> DW_AT_data_member_location 0 < 2><0x00000559> DW_TAG_member DW_AT_name lower DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h DW_AT_decl_line 0x00000044 DW_AT_type <0x00000333> DW_AT_data_member_location 8 < 2><0x00000565> DW_TAG_member DW_AT_name upper DW_AT_decl_file 0x0000000b /home/davea/dwarf/code/dwarfdump/checkutil.h libdwarf-20210528/dwarfdump/naming.h0000664000175000017500000000655314012575576014134 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* naming.h */ #ifndef NAMING_H_INCLUDED #define NAMING_H_INCLUDED #ifdef __cplusplus extern "C" { #endif extern const char * get_FORM_CLASS_name(unsigned int val_in, int printonerr); extern const char * get_TAG_name(unsigned int val_in,int printonerr); extern const char * get_children_name(unsigned int val_in, int printonerr); extern const char * get_FORM_name(unsigned int val_in, int printonerr); extern const char * get_AT_name(unsigned int val_in, int printonerr); extern const char * get_OP_name(unsigned int val_in, int printonerr); extern const char * get_ATE_name(unsigned int val_in, int printonerr); extern const char * get_DS_name(unsigned int val_in, int printonerr); extern const char * get_END_name(unsigned int val_in, int printonerr); extern const char * get_ATCF_name(unsigned int val_in, int printonerr); extern const char * get_ACCESS_name(unsigned int val_in, int printonerr); extern const char * get_VIS_name(unsigned int val_in, int printonerr); extern const char * get_VIRTUALITY_name(unsigned int val_in, int printonerr); extern const char * get_LANG_name(unsigned int val_in, int printonerr); extern const char * get_ID_name(unsigned int val_in, int printonerr); extern const char * get_CC_name(unsigned int val_in, int printonerr); extern const char * get_INL_name(unsigned int val_in, int printonerr); extern const char * get_ORD_name(unsigned int val_in, int printonerr); extern const char * get_DSC_name(unsigned int val_in, int printonerr); extern const char * get_LNS_name(unsigned int val_in, int printonerr); extern const char * get_LNE_name(unsigned int val_in, int printonerr); extern const char * get_MACINFO_name(unsigned int val_in, int printonerr); extern const char * get_MACRO_name(unsigned int val_in, int printonerr); extern const char * get_CFA_name(unsigned int val_in, int printonerr); extern const char * get_EH_name(unsigned int val_in, int printonerr); extern const char * get_FRAME_name(unsigned int val_in, int printonerr); extern const char * get_CHILDREN_name(unsigned int val_in, int printonerr); extern const char * get_ADDR_name(unsigned int val_in, int printonerr); #ifdef __cplusplus } #endif #endif /* NAMING_H_INCLUDED */ libdwarf-20210528/dwarfdump/print_hipc_lopc_attr.c0000664000175000017500000003220214005560003017027 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "print_frames.h" /* for print_location_operations() . */ #include "macrocheck.h" #include "helpertree.h" #include "tag_common.h" /* Is this a PU has been invalidated by the SN Systems linker? */ #define IsInvalidCode(low,high) \ ((low == max_address) || (low == 0 && high == 0)) /* Most types of CU can have highpc and/or lowpc. DW_TAG_type_unit will not. */ static Dwarf_Bool cu_tag_type_may_have_lopc_hipc(int tag) { if (tag == DW_TAG_compile_unit) { return TRUE; } if (tag == DW_TAG_partial_unit) { return TRUE; } if (tag == DW_TAG_skeleton_unit) { return TRUE; } return FALSE; } /* This updates values in glflags used for reporting in error cases. */ static void update_cu_base_addresses(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Half attr, Dwarf_Half tag, LoHiPc *lohipc, Dwarf_Error *err) { /* Update base address for CU */ if (attr == DW_AT_low_pc) { if (glflags.need_CU_base_address && cu_tag_type_may_have_lopc_hipc(tag)) { int lres = dwarf_formaddr(attrib, &glflags.CU_base_address, err); DROP_ERROR_INSTANCE(dbg,lres,*err); if (lres == DW_DLV_OK) { glflags.need_CU_base_address = FALSE; glflags.CU_low_address = glflags.CU_base_address; } } else if (!glflags.CU_low_address) { /* We take the first non-zero address as meaningful. Even if no such in CU DIE. */ int fres = dwarf_formaddr(attrib, &glflags.CU_low_address, err); DROP_ERROR_INSTANCE(dbg,fres,*err); if (fres == DW_DLV_OK) { /* Stop looking for base. Bogus, but there is none available, so stop. */ glflags.need_CU_base_address = FALSE; } } } /* Update high address for CU */ if (attr == DW_AT_high_pc) { if (glflags.need_CU_high_address ) { /* This is bogus in that it accepts the first high address in the CU, from any TAG */ if (lohipc->sawhi_flag == LOHIPC_SAWADDR) { glflags.need_CU_high_address = FALSE; glflags.CU_high_address = lohipc->hival; } else if (lohipc->havefinal_flag) { glflags.CU_high_address = lohipc->hifinal; glflags.need_CU_high_address = FALSE; } } } } #if 0 static void dumplohipc(LoHiPc *hilopc,char *msg, int line) { printf("LoHiPc %s line %d " "sawlo: %d 0x%" DW_PR_XZEROS DW_PR_DUx "\n", msg,line, hilopc->sawlo_flag,hilopc->lopc); printf( " sawhi: %d 0x%" DW_PR_XZEROS DW_PR_DUx "\n", hilopc->sawhi_flag,hilopc->hival); printf( " havefinal:%d 0x%" DW_PR_XZEROS DW_PR_DUx "\n", hilopc->havefinal_flag,hilopc->hifinal); } #endif /* ASSERT: attrnum == DW_AT_low_pc or DW_AT_high_pc This does not print errors as those checks will be redone by other related code. */ static void get_pc_value(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Half attrnum, Dwarf_Half theform, LoHiPc *lohipc, Dwarf_Error *err) { int bres = 0; int islowaddr =(attrnum == DW_AT_low_pc)?TRUE:FALSE; Dwarf_Unsigned uval = 0; Dwarf_Addr addr = 0; if (!islowaddr && (theform != DW_FORM_addr && !dwarf_addr_form_is_indexed(theform))) { /* New in DWARF4: other forms (of class constant) are not an address but are instead offset from pc. */ bres = dwarf_formudata(attrib,&uval,err); if (bres == DW_DLV_OK) { if (!lohipc->sawhi_flag) { lohipc->sawhi_flag = LOHIPC_SAWOFFSET; lohipc->hival = uval; if (lohipc->sawlo_flag && !lohipc->havefinal_flag ) { lohipc->havefinal_flag = TRUE; lohipc->hifinal = lohipc->lopc + uval; } } } else { if (bres == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,bres,*err); } } return; } bres = dwarf_formaddr(attrib, &addr, err); if (bres == DW_DLV_OK) { if (islowaddr) { lohipc->lopc = addr; lohipc->sawlo_flag = TRUE; if (lohipc->sawhi_flag == LOHIPC_SAWOFFSET && !lohipc->havefinal_flag) { lohipc->havefinal_flag = TRUE; lohipc->hifinal = addr + lohipc->hival; } } else { if (!lohipc->sawhi_flag ) { lohipc->hival = addr; lohipc->sawhi_flag = TRUE; lohipc->hifinal = addr; lohipc->havefinal_flag = TRUE; } } } else if (bres == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,bres,*err); } } int print_hipc_lopc_attribute(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, int die_indent_level, Dwarf_Unsigned dieprint_cu_goffset, char ** srcfiles, Dwarf_Signed cnt, Dwarf_Attribute attrib, Dwarf_Half attr, Dwarf_Unsigned max_address, LoHiPc *lohipc, struct esb_s *valname, Dwarf_Error *err) { Dwarf_Half theform =0; int rv = 0; /* For DWARF4, the high_pc offset from the low_pc */ Dwarf_Unsigned highpcOff = 0; char highpcstrbuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s highpcstr; esb_constructor_fixed(&highpcstr,highpcstrbuf, sizeof(highpcstrbuf)); rv = dwarf_whatform(attrib,&theform,err); /* Depending on the form and the attribute, process the form. */ if (rv == DW_DLV_ERROR) { print_error_and_continue(dbg, "in print_attribute " "dwarf_whatform cannot" " Find attr form", rv, *err); esb_destructor(&highpcstr); return rv; } else if (rv == DW_DLV_NO_ENTRY) { esb_destructor(&highpcstr); return rv; } get_pc_value(dbg, attrib, attr, theform,lohipc,err); /* Determine if the high pc is really an offset, set offset_detected flag if so. */ if (theform != DW_FORM_addr && !dwarf_addr_form_is_indexed(theform)) { /* New in DWARF4: other forms (of class constant) are not an address but are instead offset from pc. One could test for DWARF4 here before adding this string, but that seems unnecessary as this could not happen with DWARF3 or earlier. A normal consumer would have to add this value to DW_AT_low_pc to get a true pc. */ esb_append(&highpcstr," "); /* Update the high_pc value if we are checking the ranges */ if ( glflags.gf_check_ranges && attr == DW_AT_high_pc) { /* Get the offset value */ int show_form_here = 0; int ares = dd_get_integer_and_name(dbg, attrib, &highpcOff, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, err,show_form_here); if (ares != DW_DLV_OK) { if (ares == DW_DLV_NO_ENTRY) { print_error_and_continue(dbg, "dd_get_integer_and_name" " No Entry for DW_AT_high_pc/DW_AT_low_pc", ares, *err); } else { print_error_and_continue(dbg, "dd_get_integer_and_name" " Failed for DW_AT_high_pc/DW_AT_low_pc", ares, *err); } esb_destructor(&highpcstr); return ares; } } } rv = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, cnt, &highpcstr,glflags.show_form_used, glflags.verbose,err); if (rv == DW_DLV_ERROR) { return rv; } if (lohipc->sawhi_flag == LOHIPC_SAWOFFSET && lohipc->havefinal_flag) { esb_append_printf_u(&highpcstr, " ", lohipc->hifinal); } esb_empty_string(valname); esb_append(valname, esb_get_string(&highpcstr)); esb_destructor(&highpcstr); /* Update base and high addresses for CU */ if (glflags.seen_CU && (glflags.need_CU_base_address || glflags.need_CU_high_address)) { /* updating glflags data for checking/reporting later. */ update_cu_base_addresses(dbg,attrib, attr, tag, lohipc, err); } if ((glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations)) { if (glflags.seen_PU && !glflags.seen_PU_base_address && lohipc->sawlo_flag) { glflags.seen_PU_base_address = TRUE; glflags.PU_base_address = lohipc->lopc; } if (glflags.seen_PU && !glflags.seen_PU_high_address && lohipc->havefinal_flag) { glflags.seen_PU_high_address = TRUE; glflags.PU_high_address = lohipc->hifinal; } /* We have now both low_pc and high_pc values */ if (lohipc->havefinal_flag && lohipc->sawlo_flag) { /* We need to decide if this PU is valid, as the SN Linker marks a stripped function by setting lowpc to -1; also for discarded comdat, both lowpc and highpc are zero */ Dwarf_Unsigned lowaddr = lohipc->lopc; Dwarf_Unsigned highaddr = lohipc->hifinal; if (glflags.need_PU_valid_code) { glflags.need_PU_valid_code = FALSE; /* To ignore a PU as invalid code, only consider the lowpc and highpc values associated with the DW_TAG_subprogram; other instances of lowpc and highpc, must be ignored (lexical blocks) */ glflags.in_valid_code = TRUE; if (IsInvalidCode(lowaddr,highaddr) && tag == DW_TAG_subprogram) { glflags.in_valid_code = FALSE; } } /* We have a low_pc/high_pc pair; check if they are valid */ if (glflags.in_valid_code) { DWARF_CHECK_COUNT(ranges_result,1); if (lowaddr != max_address && lowaddr > highaddr ) { DWARF_CHECK_ERROR(ranges_result, ".debug_info: Incorrect values " "for low_pc/high_pc"); if (glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { printf("Low = 0x%" DW_PR_XZEROS DW_PR_DUx ", High = 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lowaddr,highaddr); } } if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations) { AddEntryIntoBucketGroup(glflags.pRangesInfo,0, lowaddr, lowaddr,highaddr,NULL,FALSE); } } } } esb_destructor(&highpcstr); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/print_static_funcs.c0000664000175000017500000000710213764006205016535 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_funcnames An SGI extension. (For a long time, erroneously called .debug_static_funcs here). On error, this allows some dwarf memory leaks. */ extern int print_static_funcs(Dwarf_Debug dbg,Dwarf_Error*err) { Dwarf_Func *globbuf = NULL; Dwarf_Signed count = 0; int gfres = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s truename; struct esb_s sanitname; glflags.current_section_id = DEBUG_STATIC_FUNC; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_funcnames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ dwarf_return_empty_pubnames(dbg,1,err); } gfres = dwarf_get_funcs(dbg, &globbuf, &count, err); if (gfres == DW_DLV_ERROR) { printf("\n%s\n",esb_get_string(&sanitname)); return gfres; } else if (gfres == DW_DLV_NO_ENTRY) { dwarf_return_empty_pubnames(dbg,0,err); esb_destructor(&sanitname); return gfres; } else { int pres = 0; int printed = FALSE; if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); printed= TRUE; } pres = print_all_pubnames_style_records(dbg, "static-func", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, err); dwarf_funcs_dealloc(dbg,globbuf,count); if (pres == DW_DLV_ERROR) { if (!printed) { printf("\n%s\n",esb_get_string(&sanitname)); } dwarf_return_empty_pubnames(dbg,0,err); esb_destructor(&sanitname); return pres; } } dwarf_return_empty_pubnames(dbg,0,err); esb_destructor(&sanitname); return DW_DLV_OK; } /* print_static_funcs() */ libdwarf-20210528/dwarfdump/section_bitmaps.c0000664000175000017500000001256214003121033016005 00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in command_options.c */ #include "section_bitmaps.h" struct section_map_s map_sectnames[DW_HDR_ARRAY_SIZE] = { {0,0}, {DW_SECTNAME_DEBUG_INFO, DW_HDR_DEBUG_INFO}, {DW_SECTNAME_DEBUG_INFO_DWO, DW_HDR_DEBUG_INFO_DWO}, {DW_SECTNAME_DEBUG_LINE, DW_HDR_DEBUG_LINE}, {DW_SECTNAME_DEBUG_LINE_DWO, DW_HDR_DEBUG_LINE_DWO}, {DW_SECTNAME_DEBUG_PUBNAMES, DW_HDR_DEBUG_PUBNAMES}, {DW_SECTNAME_DEBUG_ABBREV, DW_HDR_DEBUG_ABBREV}, {DW_SECTNAME_DEBUG_ABBREV_DWO, DW_HDR_DEBUG_ABBREV_DWO}, {DW_SECTNAME_DEBUG_ARANGES, DW_HDR_DEBUG_ARANGES}, {DW_SECTNAME_DEBUG_FRAME, DW_HDR_DEBUG_FRAME}, {DW_SECTNAME_DEBUG_LOC, DW_HDR_DEBUG_LOC}, {DW_SECTNAME_DEBUG_LOCLISTS, DW_HDR_DEBUG_LOCLISTS}, {DW_SECTNAME_DEBUG_LOCLISTS_DWO, DW_HDR_DEBUG_LOCLISTS_DWO}, {DW_SECTNAME_DEBUG_RANGES, DW_HDR_DEBUG_RANGES}, {DW_SECTNAME_DEBUG_RNGLISTS, DW_HDR_DEBUG_RNGLISTS}, {DW_SECTNAME_DEBUG_RNGLISTS_DWO, DW_HDR_DEBUG_RNGLISTS_DWO}, {DW_SECTNAME_DEBUG_STR, DW_HDR_DEBUG_STR}, {DW_SECTNAME_DEBUG_STR_DWO, DW_HDR_DEBUG_STR_DWO}, {DW_SECTNAME_DEBUG_STR_OFFSETS, DW_HDR_DEBUG_STR_OFFSETS}, {DW_SECTNAME_DEBUG_STR_OFFSETS_DWO, DW_HDR_DEBUG_STR_OFFSETS_DWO}, {DW_SECTNAME_DEBUG_PUBTYPES, DW_HDR_DEBUG_PUBTYPES}, {DW_SECTNAME_DEBUG_TYPES, DW_HDR_DEBUG_TYPES}, {DW_SECTNAME_TEXT, DW_HDR_TEXT}, {DW_SECTNAME_GDB_INDEX, DW_HDR_GDB_INDEX}, {DW_SECTNAME_EH_FRAME, DW_HDR_EH_FRAME}, {DW_SECTNAME_DEBUG_MACINFO, DW_HDR_DEBUG_MACINFO}, {DW_SECTNAME_DEBUG_MACRO, DW_HDR_DEBUG_MACRO}, {DW_SECTNAME_DEBUG_MACRO_DWO, DW_HDR_DEBUG_MACRO_DWO}, {DW_SECTNAME_DEBUG_NAMES, DW_HDR_DEBUG_NAMES}, {DW_SECTNAME_DEBUG_CU_INDEX, DW_HDR_DEBUG_CU_INDEX}, {DW_SECTNAME_DEBUG_TU_INDEX, DW_HDR_DEBUG_TU_INDEX}, {"Elf Header", DW_HDR_HEADER}, }; /* See section_bitmaps.c, .h Control section header printing. (not DWARF printing) */ static char reloc_map[DW_SECTION_REL_ARRAY_SIZE]; static char section_map[DW_HDR_ARRAY_SIZE]; static Dwarf_Bool all_sections_on; unsigned section_bitmap_array_size(void) { unsigned len = sizeof(map_sectnames)/sizeof(struct section_map_s); return len; } Dwarf_Bool section_name_is_debug_and_wanted(const char *section_name) { unsigned i = 1; if (all_sections_on) { return TRUE; } for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { if (!strcmp(section_name,map_sectnames[i].name) && section_map[map_sectnames[i].value]) { return TRUE; } } return FALSE; } /* For now defaults matches all but .text. */ void set_all_section_defaults(void) { unsigned i = 1; for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { section_map[i] = TRUE; } } void set_all_sections_on(void) { unsigned i = 1; all_sections_on = TRUE; for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { section_map[i] = TRUE; } } void set_all_reloc_sections_on(void) { unsigned i = 1; for ( ; i < DW_SECTION_REL_ARRAY_SIZE; ++i) { reloc_map[i] = TRUE; } } Dwarf_Bool any_section_header_to_print(void) { unsigned i = 1; for ( ; i < DW_HDR_HEADER; ++i) { if (section_map[i]) { return TRUE; } } return FALSE; } /* TRUE if the section map entry specified by the index has been enabled. */ Dwarf_Bool section_map_enabled(unsigned index) { if (index <= 0 || index >= DW_HDR_ARRAY_SIZE) return FALSE; return section_map[index]; } void enable_section_map_entry(unsigned index) { if (index > 0 && index < DW_HDR_ARRAY_SIZE) { section_map[index] = TRUE; } } /* TRUE if the reloc map entry specified by the index has been enabled. */ Dwarf_Bool reloc_map_enabled(unsigned index) { if (index <= 0 || index >= DW_SECTION_REL_ARRAY_SIZE) return FALSE; return reloc_map[index]; } void enable_reloc_map_entry(unsigned index) { if (index > 0 && index < DW_SECTION_REL_ARRAY_SIZE) { reloc_map[index] = TRUE; } } libdwarf-20210528/dwarfdump/print_sections.c0000664000175000017500000000625613764006205015710 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "print_sections.h" #include "print_frames.h" /* Print line number information: filename new basic-block [line] [address] */ int dwarf_names_print_on_error = 1; /* The April 2005 dwarf_get_section_max_offsets() in libdwarf returns all max-offsets, but we only want one of those offsets. This function returns the one we want from that set, making functions needing this offset as readable as possible. (avoiding code duplication). In case of error or missing section it returns a zero size, which seems appropriate. */ Dwarf_Unsigned get_info_max_offset(Dwarf_Debug dbg) { Dwarf_Unsigned debug_info_size = 0; Dwarf_Unsigned debug_abbrev_size = 0; Dwarf_Unsigned debug_line_size = 0; Dwarf_Unsigned debug_loc_size = 0; Dwarf_Unsigned debug_aranges_size = 0; Dwarf_Unsigned debug_macinfo_size = 0; Dwarf_Unsigned debug_pubnames_size = 0; Dwarf_Unsigned debug_str_size = 0; Dwarf_Unsigned debug_frame_size = 0; Dwarf_Unsigned debug_ranges_size = 0; Dwarf_Unsigned debug_pubtypes_size = 0; int res = 0; res = dwarf_get_section_max_offsets(dbg, &debug_info_size, &debug_abbrev_size, &debug_line_size, &debug_loc_size, &debug_aranges_size, &debug_macinfo_size, &debug_pubnames_size, &debug_str_size, &debug_frame_size, &debug_ranges_size, &debug_pubtypes_size); if (res != DW_DLV_OK) { return 0; } return debug_info_size; } /* Dumping a dwarf-expression as a byte stream. */ void dump_block(char *prefix, char *data, Dwarf_Signed len) { char *end_data = data + len; char *cur = data; int i = 0; printf("%s", prefix); for (; cur < end_data; ++cur, ++i) { if (i > 0 && i % 4 == 0) printf(" "); printf("%02x", 0xff & *cur); } } libdwarf-20210528/dwarfdump/print_macro.c0000664000175000017500000015233614003120375015153 00000000000000/* Copyright 2015-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "uri.h" #include "makename.h" #include "dwarf_tsearch.h" #include "print_sections.h" #include "macrocheck.h" #include "sanitized.h" #define TRUE 1 #define FALSE 0 /* See the comments at the beginning of macrocheck.c */ static int strcmp_for_macdef_tdel( const void *l,const void *r) { const char *ls = (const char *)l; const char *rs = (const char *)r; return strcmp(ls,rs); } /* Extensible array, of pointers to file records . */ #define MACFILE_ARRAY_START_LEN 100 unsigned macfile_array_len; unsigned macfile_array_next_to_use; /* Array of pointers to extended macfile_entry records... records with the file name string appended, so not all the same length. */ macfile_entry ** macfile_array; static int macdef_tree_compare_func(const void *l, const void *r); static void macdef_tree_insert(char *key, unsigned opnum, unsigned operator, Dwarf_Unsigned line, Dwarf_Unsigned offset, const char * string, Dwarf_Unsigned macro_unit_offset, void **map); static macdef_entry * macdef_tree_find(char *key, void **map); static macdef_entry * macdef_tree_create_entry(char *key, unsigned opnum, unsigned operator, Dwarf_Unsigned line, Dwarf_Unsigned offset, Dwarf_Unsigned macro_unit_offset, const char * string); static void macfile_array_destroy(void); void macdef_tree_run_checks(void); static void macdef_free_func(void *mx) { struct madef_entry *m = mx; /* frees both strings and the struct */ free(m); } macfile_entry * macfile_from_array_index( unsigned index) { macfile_entry *m = 0; m = macfile_array[index]; return m; } static void macdef_tree_destroy_inner( void *tree) { dwarf_tdestroy(tree,macdef_free_func); } static void destroy_macdef_tree() { macdef_tree_destroy_inner(macdefundeftree); macdefundeftree = 0; } static void destroy_macro_globals(void) { macfile_array_destroy(); destroy_macdef_tree(); /* The stack is static, not malloc, and only has unsigned vals, nothing to free. */ macfile_stack_next_to_use = 0; } static int print_macros_5style_this_cu_inner(Dwarf_Debug dbg, Dwarf_Die cu_die, char **dwarf_srcfiles, Dwarf_Signed srcfiles_count, int do_print_dwarf /* not relying on gf_do_print_dwarf here */, int descend_into_inport/* TRUE means follow imports */, int by_offset /* if TRUE is an imported macro unit so the offset is relevant. If false is the set for the CU itself. */, Dwarf_Unsigned offset, Dwarf_Unsigned lineno, unsigned fileno, int level, Dwarf_Error *err); static const char *nonameavail = ""; static const char *nofileseenyet = ""; static void print_stack_crash(void) { unsigned i = 0; printf("MACRONOTE: The start file operation just above" " exceeds the max allowed of %d. " "Possibly corrupt dwarf\n",MACFILE_STACK_DEPTH_MAX); glflags.gf_count_macronotes++; printf(" [] op# line filenum filename\n"); for (i = 0; i < macfile_stack_next_to_use; ++i) { macfile_entry * m = macfile_array[macfile_stack[i]]; printf(" [%u] %3u %4" DW_PR_DUu " %2" DW_PR_DUu " MOFF=0x%" DW_PR_DUx " %s\n", i, m->ms_operatornum,m->ms_line,m->ms_filenum, m->ms_macro_unit_offset, sanitized(m->ms_filename)); } } /* Return 0 if format is bogus */ static unsigned find_set_keyend(char *str) { char c = 0; char *cp = str; unsigned int len = 0; for ( ; *cp ; ++cp) { c=*cp; /* The following two returns are the norm for #define */ if (c == ' ') { *cp = 0; return len; } else if (c == '(') { *cp = 0; return len; } ++len; continue; } /* This is the normal return for #undef. If an incoming #define string is empty or has no spaces we get here too.*/ return len; } static int is_define_op(unsigned int operator) { switch(operator) { case DW_MACRO_define: case DW_MACRO_define_strx: case DW_MACRO_define_sup: case DW_MACRO_define_strp: return TRUE; } return FALSE; } static void add_def_undef(unsigned opnum, Dwarf_Unsigned offset, unsigned int operator, Dwarf_Unsigned line_number, const char * macro_string, Dwarf_Off macro_unit_offset, struct esb_s *mtext, Dwarf_Bool didprintdwarf) { unsigned int key_length = 0; macfile_entry *m = 0; macdef_entry *meb = 0; char * keystr = 0; int isdef = FALSE; if (!strcmp(esb_get_string(mtext),nonameavail)) { /* we have no string, just the fake we provide. hard to check much in this case. */ return; } keystr = strdup((const char *)macro_string); key_length = find_set_keyend(keystr); if (!key_length) { if (!didprintdwarf) { printf("%s",sanitized(esb_get_string(mtext))); } glflags.gf_count_major_errors++; printf("ERROR: the above define/undef " "macro op is missing its " "macro name. Corrupt DWARF.\n"); free(keystr); return; } isdef = is_define_op(operator); meb = macdef_tree_find(keystr,&macdefundeftree); if (!meb) { /* Unknown key. */ macdef_tree_insert(keystr,opnum,operator,line_number, offset,macro_string, macro_unit_offset, &macdefundeftree); meb = macdef_tree_find(keystr,&macdefundeftree); if (!meb) { printf("ERROR: Unable to find key \"%s\" " "in macdef tree though just created.\n", sanitized(keystr)); return; } if (isdef) { meb->md_defined = isdef; meb->md_defcount = 1; } else { meb->md_undefined = !isdef; meb->md_undefcount = 1; } free(keystr); return; } /* A key we have seen */ if (isdef) { if (meb->md_defined) { if (!strcmp(macro_string,meb->md_string)) { /* duplicate def. Legal C */ } else { /* Not duplicate def. Bogus. */ if (!didprintdwarf) { printf("%s",sanitized(esb_get_string(mtext))); } glflags.gf_count_macronotes++; printf("MACRONOTE: Duplicating the macro " "name \"%s\" but with a different spelling " "seems to be an error\n", sanitized(keystr)); printf(" Earlier spelling in operator %u is\n", meb->md_operatornum); m = macfile_from_array_index( meb->md_file_array_entry); printf(" MOFF=0x%" DW_PR_XZEROS DW_PR_DUx " from line %" DW_PR_DUu " file %s", meb->md_macro_unit_offset, meb->md_line, sanitized(m->ms_filename)); printf(" %s\n",sanitized(meb->md_string)); printf(" new spelling with operator %u is\n", opnum); m = macfile_from_array_index( macfile_array_next_to_use -1); printf(" MOFF=0x%" DW_PR_XZEROS DW_PR_DUx " from line %" DW_PR_DUu " file %s", macro_unit_offset, line_number, sanitized(m->ms_filename)); printf(" %s\n",sanitized(macro_string)); meb->md_defcount++; } } else { /* Now defining something new with this key. */ /* Should we print something? Warn or not? */ unsigned defcount = meb->md_defcount+1; unsigned undefcount = meb->md_undefcount; macdef_entry *mee = 0; dwarf_tdelete(keystr,&macdefundeftree, strcmp_for_macdef_tdel); macdef_tree_insert(keystr,opnum, operator,line_number,offset, macro_string, macro_unit_offset, &macdefundeftree); mee = macdef_tree_find(keystr,&macdefundeftree); if (!mee) { printf("ERROR: Unable to find key \"%s\" " "in macdef tree though just created..\n", sanitized(keystr)); return; } mee->md_defined = TRUE; mee->md_defcount = defcount; mee->md_undefcount = undefcount+1; } free(keystr); /* free(me); */ return; } /* We have seen it and we have an undef for it now */ if (meb->md_defined) { /* Was def of something with this key, now undefining with this key. */ unsigned defcount = meb->md_defcount; unsigned undefcount = meb->md_undefcount+1; macdef_entry *mec = 0; dwarf_tdelete(keystr,&macdefundeftree, strcmp_for_macdef_tdel); macdef_tree_insert(keystr,opnum, operator,line_number,offset,macro_string, macro_unit_offset, &macdefundeftree); mec = macdef_tree_find(keystr,&macdefundeftree); if (!mec) { printf("ERROR: Unable to find key \"%s\" " "in macdef tree though just created..\n", sanitized(keystr)); return; } mec->md_defined = FALSE; mec->md_undefined = TRUE; mec->md_defcount = defcount; mec->md_undefcount = undefcount+1; /* free(me); */ free(keystr); return; } if (!meb->md_undefined) { /* Simply a normal first undef of a defined thing. */ unsigned defcount = meb->md_defcount; unsigned undefcount = meb->md_undefcount+1; macdef_entry *med = 0; dwarf_tdelete(keystr,&macdefundeftree, strcmp_for_macdef_tdel); macdef_tree_insert(keystr,opnum, operator,line_number,offset,macro_string, macro_unit_offset, &macdefundeftree); med = macdef_tree_find(keystr,&macdefundeftree); if (!med) { printf("ERROR: Unable to find key \"%s\" " "in macdef tree though just created.3.\n", sanitized(keystr)); return; } med->md_defined = FALSE; med->md_undefined = TRUE; med->md_defcount = defcount; med->md_undefcount = undefcount+1; /* free(me); */ free(keystr); return; } /* ASSERT: meb->md_undefined TRUE */ /* In tree is marked undef. So undef again */ if (!didprintdwarf) { printf("%s",sanitized(esb_get_string(mtext))); } if (!glflags.gf_do_check_dwarf) { free(keystr); return; } glflags.gf_count_macronotes++; printf("MACRONOTE: Duplicating the undefine of macro " "name \"%s\" " "could possibly be an error.\n", sanitized(keystr)); printf(" Earlier in operator %u is\n", meb->md_operatornum); m = macfile_from_array_index(meb->md_file_array_entry); printf(" MOFF=0x%" DW_PR_XZEROS DW_PR_DUx " from line %" DW_PR_DUu " file %s", meb->md_macro_unit_offset, meb->md_line, sanitized(m->ms_filename)); printf(" %s\n",sanitized(meb->md_key)); printf(" new in operator %u is\n", opnum); m = macfile_from_array_index(macfile_array_next_to_use -1); printf(" MOFF=0x%" DW_PR_XZEROS DW_PR_DUx " from line %" DW_PR_DUu " file %s", macro_unit_offset, line_number, sanitized(m->ms_filename)); printf(" %s\n",sanitized(keystr)); free(keystr); /* free(me); */ return; } static void expand_array_file_if_required(void) { if (macfile_array_next_to_use >= macfile_array_len) { /* ASSERT: useme == macfile_array_len */ unsigned oldlen = macfile_array_len; unsigned newlen = 2*oldlen; macfile_entry ** newar = 0; if (!newlen) { /* We have seen nothing, make a fresh start. */ newlen = MACFILE_ARRAY_START_LEN; free(macfile_array); macfile_array = 0; macfile_array_next_to_use = 0; macfile_array_len = 0; } newar = (macfile_entry **)calloc(newlen, sizeof(macfile_entry *)); if (!newar) { /* Out of memory. */ printf("\nERROR: out of memory attempting " "allocation of %u " "entries on macfile_array. Skipping entry.\n",newlen); glflags.gf_count_major_errors++; return; } if (oldlen) { memcpy(newar,macfile_array, oldlen*sizeof(macfile_entry *)); free(macfile_array); macfile_array = 0; } macfile_array_next_to_use = oldlen; macfile_array_len = newlen; macfile_array = newar; } } static void add_array_file_entry(unsigned k, Dwarf_Unsigned offset, unsigned int operator, Dwarf_Unsigned line_number, Dwarf_Unsigned index, Dwarf_Off macro_unit_offset, const char * macro_string) { size_t namelen = strlen(macro_string) +1; unsigned alloclen = sizeof(macfile_entry) + namelen; unsigned stroff = sizeof(macfile_entry); macfile_entry *m = 0; expand_array_file_if_required(); m = (macfile_entry*) calloc(1,alloclen); if (!m) { return; } m->ms_operatornum = k; m->ms_operator = operator; m->ms_line = line_number; m->ms_filenum = index; m->ms_offset = offset; m->ms_macro_unit_offset = macro_unit_offset; m->ms_array_number = macfile_array_next_to_use; m->ms_filename = (char *)m + stroff; strcpy(m->ms_filename,macro_string); macfile_array[macfile_array_next_to_use] = m; macfile_stack[macfile_stack_next_to_use] = macfile_array_next_to_use; macfile_array_next_to_use++; macfile_stack_next_to_use++; if (macfile_stack_next_to_use > macfile_stack_max_seen) { macfile_stack_max_seen = macfile_stack_next_to_use; } } static void add_to_file_stack(unsigned k, Dwarf_Unsigned offset, unsigned int operator, Dwarf_Unsigned line_number, Dwarf_Unsigned index, Dwarf_Off macro_unit_offset, const char * macro_string, struct esb_s * mtext, Dwarf_Bool didprintdwarf) { if (operator == DW_MACRO_end_file) { unsigned stack_useme = 0; /* DW_MACRO_end_file */ if (!didprintdwarf && !glflags.gf_do_check_dwarf) { printf("%s",sanitized(esb_get_string(mtext))); } if (!glflags.gf_do_check_dwarf) { macfile_entry *m = 0; m = macfile_from_array_index( macfile_array_next_to_use -1); if (macfile_stack_next_to_use < 1) { printf("MACRONOTE: End file operation just above" " MOFF=0x%" DW_PR_XZEROS DW_PR_DUx " file %s" " has no applicable start file!" " Possibly corrupt dwarf.\n", macro_unit_offset, sanitized(m->ms_filename)); glflags.gf_count_macronotes++; return; } } /* Leave the file array untouched. */ stack_useme = macfile_stack_next_to_use -1; macfile_stack[stack_useme] = 0; macfile_stack_next_to_use = stack_useme; return; } if (macfile_stack_next_to_use >= MACFILE_STACK_DEPTH_MAX) { if (!didprintdwarf) { printf("%s",sanitized(esb_get_string(mtext))); } print_stack_crash(); return; } add_array_file_entry(k,offset,operator, line_number,index, macro_unit_offset,macro_string); return; } static void print_source_intro(Dwarf_Die cu_die) { Dwarf_Off off = 0; int ores = 0; Dwarf_Error err = 0; ores = dwarf_dieoffset(cu_die, &off, &err); if (ores == DW_DLV_OK) { int lres = 0; const char *sec_name = 0; lres = dwarf_get_die_section_name_b(cu_die, &sec_name,&err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_info"; } printf("Macro data from CU-DIE at %s offset 0x%" DW_PR_XZEROS DW_PR_DUx ":\n", sanitized(sec_name), (Dwarf_Unsigned) off); } else { printf("Macro data (for the CU-DIE at unknown location):\n"); } } static void derive_error_message(Dwarf_Debug dbg, unsigned k, Dwarf_Half macro_operator, Dwarf_Unsigned number_of_ops, int res,Dwarf_Error *err, const char *operator_string) { const char *name = 0; struct esb_s m; dwarf_get_MACRO_name(macro_operator,&name); esb_constructor(&m); if (res == DW_DLV_ERROR) { esb_append(&m, "ERROR from "); } else { esb_append(&m, "ERROR. NO_ENTRY from "); } esb_append(&m,operator_string); esb_append_printf_s(&m, " for operand %s ",sanitized(name)); esb_append_printf_u(&m, " operand %u ",k); esb_append_printf_u(&m, " of %u operands",number_of_ops); print_error_and_continue(dbg, esb_get_string(&m), res,*err); esb_destructor(&m); } static int print_macro_ops(Dwarf_Debug dbg, Dwarf_Die cu_die, char ** dwarf_srcfiles, Dwarf_Signed srcfiles_count, Dwarf_Macro_Context mcontext, Dwarf_Unsigned number_of_ops, int do_print_dwarf /* not relying on gf_do_print_dwarf here */, int descend_into_import /* TRUE means follow imports */, int by_offset /* if TRUE is an imported macro unit */, Dwarf_Unsigned macro_unit_offset /* of this set*/, Dwarf_Unsigned *macro_unit_length /* return val */, int level, Dwarf_Error *err) { unsigned k = 0; for (k = 0; k < number_of_ops; ++k) { Dwarf_Unsigned section_offset = 0; Dwarf_Half macro_operator = 0; Dwarf_Half forms_count = 0; const Dwarf_Small *formcode_array = 0; Dwarf_Unsigned line_number = 0; Dwarf_Unsigned index = 0; Dwarf_Unsigned offset =0; const char * macro_string =0; int lres = 0; static char mbuf[100]; struct esb_s mtext; esb_constructor_fixed(&mtext,mbuf,sizeof(mbuf)); lres = dwarf_get_macro_op(mcontext, k, §ion_offset,¯o_operator, &forms_count, &formcode_array,err); if (lres != DW_DLV_OK) { struct esb_s m; dwarf_dealloc_macro_context(mcontext); esb_constructor(&m); if (lres == DW_DLV_ERROR) { esb_append(&m, "ERROR from dwarf_get_macro_op()"); } else { esb_append(&m, "ERROR. NO_ENTRY from dwarf_get_macro_op()"); } esb_append_printf_u(&m, " for operand %u ",k); esb_append_printf_u(&m, " of %u operands",number_of_ops); print_error_and_continue(dbg, esb_get_string(&m), lres,*err); esb_destructor(&m); esb_destructor(&mtext); return lres; } esb_append_printf_i(&mtext," [%3d] ",k); if (by_offset && descend_into_import) { esb_append_printf_u(&mtext," ", macro_unit_offset); } esb_append_printf_u(&mtext,"0x%02x",macro_operator); esb_append_printf_s(&mtext," %-20s", (macro_operator? get_MACRO_name(macro_operator, dwarf_names_print_on_error): "end-of-macros")); if (glflags.gf_show_global_offsets) { esb_append_printf_u(&mtext," ", section_offset); } if (glflags.show_form_used && forms_count > 0) { unsigned l = 0; esb_append_printf_u(&mtext,"\n Forms count %2u:", forms_count); for (; l < forms_count;++l) { Dwarf_Small form = formcode_array[l]; esb_append_printf_u(&mtext," 0x%02x", form); esb_append_printf_s(&mtext," %-18s ", get_FORM_name(form,dwarf_names_print_on_error)); } esb_append(&mtext,"\n "); } switch(macro_operator) { case 0: { /* End of these DWARF_MACRO ops */ Dwarf_Unsigned macro_unit_len = section_offset +1 - macro_unit_offset; esb_append_printf_u(&mtext, " op offset 0x%" DW_PR_XZEROS DW_PR_DUx, section_offset); esb_append_printf_u(&mtext, " macro unit length %" DW_PR_DUu, macro_unit_len); esb_append_printf_u(&mtext, " next byte offset 0x%" DW_PR_XZEROS DW_PR_DUx, section_offset+1); *macro_unit_length = macro_unit_len; esb_append(&mtext,"\n"); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } } break; case DW_MACRO_end_file: if (do_print_dwarf) { esb_append(&mtext,"\n"); } if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } add_to_file_stack(k,offset,macro_operator, line_number,offset, macro_unit_offset,"", &mtext,do_print_dwarf); break; case DW_MACRO_define: case DW_MACRO_undef: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_defundef"); esb_destructor(&mtext); return lres; } esb_append_printf_u(&mtext," line %u",line_number); esb_append_printf_s(&mtext," %s\n", macro_string? sanitized(macro_string):nonameavail); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } add_def_undef(k,offset,macro_operator, line_number,macro_string, macro_unit_offset, &mtext,do_print_dwarf); break; } case DW_MACRO_define_strp: case DW_MACRO_undef_strp: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_defundef"); esb_destructor(&mtext); return lres; } esb_append_printf_u(&mtext, " line %" DW_PR_DUu,line_number); esb_append_printf_u(&mtext, " str offset 0x%" DW_PR_XZEROS DW_PR_DUx, offset); esb_append_printf_s(&mtext, " %s\n",macro_string? sanitized(macro_string):nonameavail); if (do_print_dwarf) { printf("%s",esb_get_string(&mtext)); } add_def_undef(k,offset,macro_operator, line_number,macro_string, macro_unit_offset, &mtext,do_print_dwarf); } break; case DW_MACRO_define_strx: case DW_MACRO_undef_strx: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_defundef"); esb_destructor(&mtext); return lres; } esb_append_printf_u(&mtext, " line %" DW_PR_DUu,line_number); esb_append_printf_u(&mtext, " str offset 0x%" DW_PR_XZEROS DW_PR_DUx, offset); esb_append_printf_s(&mtext, " %s\n",macro_string? sanitized(macro_string):nonameavail); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } add_def_undef(k,offset,macro_operator, line_number,macro_string, macro_unit_offset, &mtext,do_print_dwarf); break; } case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { /* The strings here are from a supplementary object file, not this object file. Until we have a way to find the supplementary object file those will show name "" */ /* We do not add these to the MacroCheck treer */ lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_defundef"); esb_destructor(&mtext); return lres; } esb_append_printf_u(&mtext, " line %" DW_PR_DUu,line_number); esb_append_printf_u(&mtext, " str offset 0x%" DW_PR_XZEROS DW_PR_DUx, offset); esb_append_printf_s(&mtext, " %s\n",macro_string? sanitized(macro_string):nonameavail); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } break; } case DW_MACRO_start_file: { lres = dwarf_get_macro_startend_file(mcontext, k,&line_number, &index, ¯o_string,err); /* The above call knows how to reference its one srcfiles data and has the .debug_macro version. So we do not need to worry about getting the file name here. */ if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_startend_file"); esb_destructor(&mtext); return lres; } esb_append_printf_u(&mtext," line %" DW_PR_DUu, line_number); esb_append_printf_u(&mtext," file number %" DW_PR_DUu " ", index); esb_append(&mtext,macro_string? macro_string: ""); esb_append(&mtext,"\n"); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } add_to_file_stack(k,offset,macro_operator, line_number,index, macro_unit_offset,macro_string, &mtext,do_print_dwarf); break; } case DW_MACRO_import: { int mres = 0; lres = dwarf_get_macro_import(mcontext, k,&offset,err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_import"); esb_destructor(&mtext); return lres; } if (do_print_dwarf) { esb_append_printf(&mtext, " offset 0x%" DW_PR_XZEROS DW_PR_DUx , offset); } esb_append(&mtext,"\n"); if (do_print_dwarf) { printf("%s",sanitized(esb_get_string(&mtext))); } if (descend_into_import) { macfile_entry *mac_e = 0; mac_e = macfile_from_array_index( macfile_array_next_to_use-1); mres = macro_import_stack_present(offset); if (mres == DW_DLV_OK) { printf("ERROR: While Printing DWARF5 macros " "we find a recursive nest of imports " " noted with offset 0x%" DW_PR_XZEROS DW_PR_DUx " so we stop now. \n", offset); print_macro_import_stack(); glflags.gf_count_major_errors++; return DW_DLV_NO_ENTRY; } mres = print_macros_5style_this_cu_inner(dbg, cu_die, dwarf_srcfiles,srcfiles_count, FALSE /* turns off do_print_dwarf */, descend_into_import, TRUE /* by offset */, offset, mac_e->ms_line, macfile_array_next_to_use-1, level+1, err); if (mres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "ERROR: Printing DWARF5 macros " " at offset 0x%x " "for the import CU failed. ", offset); print_error_and_continue(dbg, esb_get_string(&m), mres,*err); DROP_ERROR_INSTANCE(dbg,mres,*err); esb_destructor(&m); } } break; } case DW_MACRO_import_sup: { lres = dwarf_get_macro_import(mcontext, k,&offset,err); if (lres != DW_DLV_OK) { derive_error_message(dbg,k,macro_operator, number_of_ops, lres,err,"dwarf_get_macro_import"); esb_destructor(&mtext); return lres; } #if 0 add_macro_import_sup(¯o_check_tree,offset); /* The supplementary object file is not available, So we cannot check the import references or know the size. As of December 2020 */ #endif if (do_print_dwarf) { printf(" sup_offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n" ,offset); } break; } } /* End switch(macro_operator) */ esb_destructor(&mtext); } return DW_DLV_OK; } /* We follow imports if building_primary_tree and in that case following imports we turn do_print_dwarf FALSE. */ static int print_macros_5style_this_cu_inner(Dwarf_Debug dbg, Dwarf_Die cu_die, char **dwarf_srcfiles, Dwarf_Signed srcfiles_count, int do_print_dwarf /* not relying on gf_do_print_dwarf here */, int descend_into_import /* TRUE means follow imports */, int by_offset /* if TRUE is an imported macro unit so the offset is relevant. If false is the set for the CU itself. */, Dwarf_Unsigned offset, Dwarf_Unsigned lineno, unsigned filenum, int level, Dwarf_Error *err) { int lres = 0; Dwarf_Unsigned version = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Unsigned macro_unit_offset = 0; Dwarf_Unsigned number_of_ops = 0; Dwarf_Unsigned ops_total_byte_len = 0; Dwarf_Unsigned context_total_byte_len = 0; Dwarf_Off dieprint_cu_goffset = 0; Dwarf_Off cudie_local_offset = 0; int atres = 0; glflags.current_section_id = DEBUG_MACRO; if (!by_offset) { lres = dwarf_get_macro_context(cu_die, &version,¯o_context, ¯o_unit_offset, &number_of_ops, &ops_total_byte_len, err); offset = macro_unit_offset; } else { lres = dwarf_get_macro_context_by_offset(cu_die, offset, &version,¯o_context, &number_of_ops, &ops_total_byte_len, err); macro_unit_offset = offset; } if (lres == DW_DLV_NO_ENTRY) { return lres; } if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Unable to dwarf_get_macro_context()" " for the DWARF 5 style macro", lres,*err); return lres; } /* If we fail to get the offsets we won't worry about it. */ atres = dwarf_die_offsets(cu_die,&dieprint_cu_goffset, &cudie_local_offset,err); DROP_ERROR_INSTANCE(dbg,atres,*err); lres = dwarf_macro_context_total_length(macro_context, &context_total_byte_len,err); if (lres != DW_DLV_OK) { return lres; } add_macro_import(¯o_check_tree, (!level)? 1:0, offset,lineno,filenum); add_macro_area_len(¯o_check_tree,offset, context_total_byte_len); lres = macro_import_stack_push(offset); if (lres == DW_DLV_ERROR) { /* message printed. Give up. */ return DW_DLV_NO_ENTRY; } if (do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_macro", &truename,TRUE); /* This does not return */ if (!by_offset) { printf("\n%s: Macro info for a single cu at macro Offset" " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", sanitized(esb_get_string(&truename)), macro_unit_offset); print_source_intro(cu_die); } else { printf("\n%s: Macro info for imported macro unit " "at macro Offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", sanitized(esb_get_string(&truename)), offset); } esb_destructor(&truename); } else { /* We are checking, not printing. */ Dwarf_Half tag = 0; int tres = dwarf_tag(cu_die, &tag, err); if (tres != DW_DLV_OK) { /* Something broken here. */ dwarf_dealloc_macro_context(macro_context); print_error_and_continue(dbg, "Unable to get CU DIE tag " "though we could see it earlier. " "Something broken.", tres,*err); return tres; } else if (tag == DW_TAG_type_unit) { dwarf_dealloc_macro_context(macro_context); /* Not checking since type units missing address or range in CU header. */ return DW_DLV_OK; } } if (do_print_dwarf && glflags.verbose > 1) { Dwarf_Bool attr_dup = FALSE; int pdres = 0; pdres = print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ 1, /* indent level */0, dwarf_srcfiles,srcfiles_count, &attr_dup, /* ignore_die_stack= */TRUE,err); if (pdres == DW_DLV_ERROR) { dwarf_dealloc_macro_context(macro_context); return pdres; } } { Dwarf_Half lversion =0; Dwarf_Unsigned mac_offset =0; Dwarf_Unsigned mac_len =0; Dwarf_Unsigned mac_header_len =0; Dwarf_Unsigned line_offset =0; unsigned mflags = 0; Dwarf_Bool has_line_offset = FALSE; Dwarf_Bool has_offset_size_64 = FALSE; Dwarf_Bool has_operands_table = FALSE; Dwarf_Half opcode_count = 0; Dwarf_Half offset_size = 4; Dwarf_Unsigned macro_unit_length = 0; const char *prefix = ""; if (by_offset) { prefix = " "; } lres = dwarf_macro_context_head(macro_context, &lversion, &mac_offset,&mac_len, &mac_header_len,&mflags,&has_line_offset, &line_offset, &has_offset_size_64,&has_operands_table, &opcode_count,err); if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc_macro_context(macro_context); /* Impossible */ return lres; } if (lres == DW_DLV_ERROR) { dwarf_dealloc_macro_context(macro_context); print_error_and_continue(dbg, "ERROR: dwarf_macro_context_head failed", lres,*err); return lres; } if (has_offset_size_64) { offset_size = 8; } /* If pure checking we won't print this header info */ if (!glflags.gf_do_check_dwarf) { /* To understand imports we really need the basic data shown on all targeted macro offsets. This is a start, allowing us to track the imported tables. Add verbose to see the rest printed just below */ printf("%s Nested import level: %d\n",prefix,level); printf("%s Macro version : %d\n",prefix,lversion); printf("%s macro section offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n",prefix, mac_offset); } if (glflags.verbose && !glflags.gf_do_check_dwarf) { printf("%s flags: 0x%x, " "offsetsize64? %s, " "lineoffset? %s, " "operands_table? %s\n", prefix, mflags, has_offset_size_64?"yes":" no", has_line_offset ?"yes":" no", has_operands_table?"yes":" no"); printf("%s offset size 0x%x\n",prefix,offset_size); printf("%s header length: 0x%" DW_PR_XZEROS DW_PR_DUx " total length: 0x%" DW_PR_XZEROS DW_PR_DUx "\n", prefix, mac_header_len,mac_len); if (has_line_offset) { printf(" debug_line_offset: 0x%" DW_PR_XZEROS DW_PR_DUx "\n", line_offset); } if (has_operands_table) { Dwarf_Half i = 0; for (i = 0; i < opcode_count; ++i) { Dwarf_Half opcode_num = 0; Dwarf_Half operand_count = 0; const Dwarf_Small *operand_array = 0; Dwarf_Half j = 0; lres = dwarf_macro_operands_table(macro_context, i, &opcode_num, &operand_count, &operand_array,err); if (lres == DW_DLV_NO_ENTRY) { struct esb_s m; dwarf_dealloc_macro_context(macro_context); esb_constructor(&m); esb_append_printf_u(&m, "ERROR: dwarf_macro_operands_table()" " returns NO_ENTRY for index %u ", i); esb_append_printf_u(&m, " of %u indexes. ", opcode_count); print_error_and_continue(dbg, esb_get_string(&m), lres,*err); esb_destructor(&m); return lres; } if (lres == DW_DLV_ERROR) { struct esb_s m; dwarf_dealloc_macro_context(macro_context); esb_constructor(&m); esb_append_printf_u(&m, "ERROR: dwarf_macro_operands_table()" " returns ERROR for index %u ", i); esb_append_printf_u(&m, " of %u indexes. ", opcode_count); print_error_and_continue(dbg, esb_get_string(&m), lres,*err); esb_destructor(&m); return lres; } if (opcode_num == 0) { printf("%s [%3u] end of macro operands.", prefix,i); /* Continue just in case something is wrong and there are more operands! */ continue; } printf("%s [%3u] op: 0x%04x %20s " "operandcount: %u\n", prefix, i,opcode_num, get_MACRO_name(opcode_num, dwarf_names_print_on_error), operand_count); for (j = 0; j < operand_count; ++j) { Dwarf_Small opnd = operand_array[j]; printf("%s [%3u] 0x%04x %20s\n", prefix,j,opnd, get_FORM_name(opnd, dwarf_names_print_on_error)); } } } } if (do_print_dwarf) { printf(" MacroInformationEntries count: %" DW_PR_DUu ", bytes length: %" DW_PR_DUu "\n", number_of_ops,ops_total_byte_len); } lres = print_macro_ops(dbg, cu_die, dwarf_srcfiles, srcfiles_count, macro_context,number_of_ops, do_print_dwarf /*not relying on gf_do_print_dwarf here*/, descend_into_import /* TRUE means follow imports */, by_offset /* if TRUE is an imported macro set */, macro_unit_offset, ¯o_unit_length, level, err); if (lres != DW_DLV_OK) { struct esb_s m; dwarf_dealloc_macro_context(macro_context); esb_constructor(&m); if (lres == DW_DLV_ERROR){ esb_append(&m, "ERROR: print_macro_ops() failed" " returns ERROR "); } else { esb_append(&m, "ERROR: print_macro_ops() failed" " returns NO_ENTRY "); } print_error_and_continue(dbg, esb_get_string(&m), lres,*err); esb_destructor(&m); return lres; } /* macro_unit_offset for macro_unit_length bytes is a real macro unit. */ } #if 0 if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); dwarf_check_lineheader(cu_die,&line_errs); if (line_errs > 0) { DWARF_CHECK_ERROR_PRINT_CU(); DWARF_ERROR_COUNT(lines_result,line_errs); DWARF_CHECK_COUNT(lines_result,(line_errs-1)); } } #endif if (do_print_dwarf) { mark_macro_offset_printed(¯o_check_tree,offset); } lres = macro_import_stack_pop(); if (lres != DW_DLV_OK) { return DW_DLV_NO_ENTRY; } dwarf_dealloc_macro_context(macro_context); macro_context = 0; return DW_DLV_OK; } int print_macros_5style_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, char **dwarf_srcfiles, Dwarf_Signed srcfiles_count, int do_print_dwarf /* not relying on gf_do_print_dwarf here */, int descend_into_import /* TRUE means follow imports */, int by_offset /* if TRUE is an imported macro unit so the offset is relevant. If false is the set for the CU itself. */, Dwarf_Unsigned offset, Dwarf_Error *err) { int res = 0; if (macfile_array_next_to_use || macfile_stack_next_to_use || macdefundeftree || macfile_array) { printf("ERROR: dwarfdump internal files not properly " "initialized, internal dwarfdump bug. " "No macro access done. " "Pretending no macro section present\n"); glflags.gf_count_major_errors++; return DW_DLV_NO_ENTRY; } add_array_file_entry(0,0,DW_MACRO_start_file, 0,0,0,nofileseenyet); res =print_macros_5style_this_cu_inner(dbg,cu_die, dwarf_srcfiles, srcfiles_count, do_print_dwarf, descend_into_import, by_offset, offset, 0,0, 0, err); macdef_tree_run_checks(); destroy_macro_globals(); /* Do NOT clear macrocheck statistics here, wait till all CUs processed before clearing. */ return res; } static int macdef_tree_compare_func(const void *l, const void *r) { const macdef_entry *ml = l; const macdef_entry *mr = r; int res = 0; res = strcmp(ml->md_key,mr->md_key); return res; } static void macdef_tree_insert(char *key, unsigned opnum, unsigned operator, Dwarf_Unsigned line, Dwarf_Unsigned offset, const char * string, Dwarf_Unsigned macro_unit_offset, void **map) { void *retval = 0; macdef_entry *re = 0; macdef_entry *e = 0; e = macdef_tree_create_entry(key, opnum,operator,line,offset,macro_unit_offset,string); e->md_defcount = 0; e->md_undefcount = 0; e->md_undefined = FALSE; e->md_defined = FALSE; /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,map, macdef_tree_compare_func); if (retval) { re = *(macdef_entry **)retval; if (re != e) { /* We returned an existing record, e not needed. Increment refcounts. */ macdef_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } } } static macdef_entry * macdef_tree_create_entry(char *key, unsigned opnum, unsigned operator, Dwarf_Unsigned line, Dwarf_Unsigned offset, Dwarf_Unsigned macro_unit_offset, const char * string) { char *keyspace = 0; unsigned klen = strlen(key) +1; unsigned slen = strlen(string) +1; unsigned finallen = sizeof(macdef_entry) + klen + slen; macdef_entry *me = (macdef_entry*)calloc(1,finallen); if (!me) { return 0; } keyspace = sizeof(macdef_entry) + (char *)me; me->md_key = keyspace; strcpy(me->md_key,key); me->md_operatornum = opnum; /* We will set md_define, md_undefined, and the md_defcount and md_undefcount elsewhere. */ me->md_defined = FALSE; me->md_undefined = FALSE; me->md_operator = operator; me->md_line = line; me->md_offset = offset; me->md_macro_unit_offset = macro_unit_offset; me->md_string = keyspace + klen; me->md_file_array_entry = macfile_array_next_to_use-1; strcpy(me->md_string,string); return me; } static macdef_entry * macdef_tree_find(char *key, void**tree) { void *retval = 0; macdef_entry *re = 0; macdef_entry *e = 0; e = macdef_tree_create_entry(key, 0,0,0,0,0,""); retval = dwarf_tfind(e,tree, macdef_tree_compare_func); if (retval) { re = *(macdef_entry **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ macdef_free_func(e); return re; } static void macfile_array_destroy(void) { unsigned i = 0; for ( ; i < macfile_array_next_to_use; ++i ) { macfile_entry *m = macfile_array[i]; /* Frees the macfile_entry and the filename string attached to the end of the struct. */ free(m); macfile_array[i] = 0; } free(macfile_array); macfile_array_len = 0; macfile_array_next_to_use = 0; macfile_array = 0; } static Dwarf_Unsigned walk_reccount = 0; static void macro_walk_count_recs(UNUSEDARG const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { if (which == dwarf_postorder || which == dwarf_endorder) { return; } walk_reccount += 1; } static Dwarf_Unsigned macro_count_recs(void **base) { walk_reccount = 0; dwarf_twalk(*base,macro_walk_count_recs); return walk_reccount; } /* These are file-static, not local, as we need to access in a tree-walk. */ static macdef_entry **mac_as_array = 0; static unsigned mac_as_array_next = 0; static void macro_walk_to_array(const void *nodep,const DW_VISIT which, UNUSEDARG const int depth) { macdef_entry * re = *(macdef_entry**)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } mac_as_array[mac_as_array_next] = re; mac_as_array_next++; } static int macdef_qsort_compare(const void *lin, const void *rin) { const macdef_entry *l = *(const macdef_entry **)lin; const macdef_entry *r = *(const macdef_entry **)rin; int res = 0; res = strcmp(l->md_key,r->md_key); if (res) { return res; } if (l->md_operatornum < r->md_operatornum) { return -1; } if (l->md_operatornum > r->md_operatornum) { return 1; } /* No two can have the same md_operatornum, so this is impossible. */ return 0; } static void print_macdef_warn(unsigned i, macdef_entry *m,unsigned warncount) { if (!warncount) { printf(" macro " " defs undefs at-end\n"); } printf("[%2d] %-24s",i,m->md_key); printf(" %2u",m->md_defcount); printf(" %2u",m->md_undefcount); printf(" %s",m->md_defined?"defined":"undefined"); printf("\n"); } /* Check the macdefundef tree for the unusual Check the macfile_stack for leftovers. The tree starts with 0 and that entry is a fake for macro ops before a DW_MACRO_start_file encountered. */ void macdef_tree_run_checks(void) { unsigned i = 0; unsigned warncount = 0; Dwarf_Unsigned me_array_count = 0; free(mac_as_array); mac_as_array = 0; mac_as_array_next = 0; if (macfile_stack_next_to_use > 1) { printf("MACRONOTE: The DWARF5 macro start-file stack has" " %u entries left on the stack. Missing " " some end-file entries?\n", macfile_stack_next_to_use); glflags.gf_count_macronotes++; printf(" [] op# line filenum filename\n"); for (i = 0; i < macfile_stack_next_to_use; ++i) { macfile_entry * m = macfile_array[macfile_stack[i]]; printf(" [%u] %3u %4" DW_PR_DUu " %2" DW_PR_DUu " %s\n", i, m->ms_operatornum,m->ms_line,m->ms_filenum, sanitized(m->ms_filename)); } } /* Now check the def/undef tree left */ if (!glflags.gf_do_check_dwarf) { return; } if (!macdefundeftree) { return; } me_array_count = macro_count_recs(&macdefundeftree); if (me_array_count) { mac_as_array = (macdef_entry**) calloc(me_array_count, sizeof(macdef_entry*)); } if (!mac_as_array) { /* done */ return; } warncount = 0; mac_as_array_next = 0; dwarf_twalk(macdefundeftree, macro_walk_to_array); qsort(mac_as_array, me_array_count,sizeof(macdef_entry*), macdef_qsort_compare); for (i = 0; i < me_array_count; ++i) { macdef_entry *m = mac_as_array[i]; if (!m->md_defined && m->md_defcount == m->md_undefcount) { /* totally normal.*/ continue; } if (m->md_defined && m->md_defcount ==1 && m->md_undefcount == 0) { /* totally normal.*/ continue; } print_macdef_warn(i,m,warncount); ++warncount; } free(mac_as_array); mac_as_array = 0; mac_as_array_next = 0; } libdwarf-20210528/dwarfdump/ChangeLog20090000664000175000017500000003530013644370703014562 000000000000002009-12-30 DavidAnderson * configure: Regenerated with autoconf 2.64. * config.guess, config.sub: Delete these, best not to have them. 2009-11-24 DavidAnderson * tag_common.h: Updated 'standard tag table row' and tag table column maximums now the DWARF4 entries are in the .list files. Removed dos 'CR' characters at line ends. * tag_tree.list, tag_attr.list: Added various DWARF4 entries and added DW_TAG_enumeration_type under DW_TAG_union_type. 2009-11-17 DavidAnderson * dwarfdump.1: Document the -u option more fully. * print_die.c: Check for both info_flag and cu_name_flag to decide when to print DIEs. 2009-10-12 DavidAnderson * dwarfdump.c: Updated dwarfdump version string to today. 2009-09-30 DavidAnderson * dwarfdump.c: Added globals for aranges checking and to print the resulting error count. * print_aranges.c: Added checking that all 3 ways of computing a cu_die_offset from an arange get the same offset (checked with -r -ka). * print_frames.c: DW_CFA_cfa_offset_extended_sf corrected to DW_CFA_offset_extended_sf. 2009-09-01 DavidAnderson * tag_tree.list: We add DW_TAG_class_type as a valid child of a DW_TAG_union_type. 2009-08-05 DavidAnderson * gennames.c: Change include from getopt.h to unistd.h so the code is more universally compilable. 2009-07-24: David Anderson * tag_attr.c: Remove duplicate include of naming.h. 2009-06-23: David Anderson * strstrnocase.c: Corrected typo in TEST code and added a new test. 2009-06-22: David Anderson * Makefile.in: switched to personally written string comparison, strstrnocase.c. * stristr.c: deleted. * strstrnocase.c: New code, written by me so no license issues. * print_die.c: Call is_strstrnocase(), the new function. * dwarfdump.1: More fully document -S. * globals.h: Create extern for is_strstrnocase(). 2009-06-18: David Anderson * configure: Regenerated. * Makefile.in: Add stristr.o * stristr.c: public domain source added to dwarfdump * print_die.c: Add code and arguments to support -S. * print_lines.c: print_one_die argument list changed, added the require argument.. * dwarfdump.c: Added the -S option. * configure.in: Add test to set HAVE_REGEX for the -S option. * dwarfdump.1: Document the -S options. * config.h.in: Set the default HAVE_REGEX * globals.h: Add -S globals, change the print_one_die() prototype to support -S. * print_aranges.c: Alter the print_one_die calls added to support -S. 2009-06-06: David Anderson * naming.c,naming.h: New files that implement the ellipsis functionality of dwarfdump and defer to libdwarf to get the names of the TAGs, attributes, FORMs, etc. * gennames.c: This file has moved to libdwarf, no longer present in dwarfdump. * esb.h, esb.c: Change certain char* arguments to const char* to avoid compiler warnings. * print_static_vars.c,print_static_funcs.c, print_sections.c,print_strings.c, print_locs.c, print_lines.c, print_pubnames.c,print_ranges.c, print_macros.c,print_types.c,tag_common.c, print_weaknames.c, print_aranges.c: Include changed from dwarf_names.h to naming.h * tag_common.h: Removed the tag_name array, libdwarf provides the TAG, ATTR, etc name strings now. * dwarfdump.c: Updated DWARFDUMP_VERSION string. * tag_tree.c,tag_attr.c: Include changed from dwarf_names.h to naming.h. simplified long complicated lines, remove dbg argument to get_TAG_name. * print_die.c,print_abbrevs.c: Include changed from dwarf_names.h to naming.h. Calls to get_TAG_name (etc) no longer have a dbg argument. * Makefile.in: We no longer build generated file names.c, we build naming.c (hand coded, not generated). 2009-05-07: David Anderson * dwarfdump.cc: updated DWARF_VERSION string. * Makefile.in: dwarf_names* are now generated by C, so 'clean' now cleans them out. 2009-05-04: David Anderson * common.h, common.c: Extracted simple utility routines into their own files. * dwarf_names.awk, at_list.awk: deleted. gennames.c replaces these. * tag_common.c, tag_common.h: Removed the simple utility routines from these files to simplify dependencies. * tag_attr.c, tag_tree.c: Include new common.h. * print_frames.c: Adding address_size argument to call. * print_frames.h: Adding new address_size argument to get_string_from_locs() declaration. * print_locs.c: Gets and uses CU-specific address_size. * print_ranges.c: Adding commentary. * print_die.c: adding DIE argument to ensure correct address size used for the CU in question. * Makefile.in: Now handles common.* and gennames.c changes. * gennames.c: New code emitting string 'get name' source. Replaces awk source. 2009-04-04: David Anderson * Makefile.in: clean up 'clean' and 'distclean' so that distributed files are not cleaned out by 'clean' and all generated files (even those shipped in distribution) are cleaned out by distclean. * dwarfdump.c: Now calls the new libdwarf function dwarf_set_frame_cfa_value() and other such functions to specify all the values libdwarf needs. * dwarfdump.conf: Sets the cfa_reg: value to a new higher value (1436) to avoid conflict with largest known register count. * dwconf.h: Corrected commentary on DW_FRAME_CFA_COL3. * dwconf.c: Now uses DW_FRAME_CFA_COL3 as default for interface 3, rather than a directly typed number. Sets undefined-value and same-value pseudo-register numbers. 2009-04-03: David Anderson * dwarfdump.1: Amplified -R and -x abi= documentation. * dwarfdump.conf: Added generic500 generic100 abis. 2009-03-29: David Anderson * print_die.c: Moved print_infos() to here. * dwarfdump.c: Moved print_infos() out of here. * globals.h: Declarations changed to allow moving print_infos(). * dwarf_names.awk: Eliminate a pointless space before a newline in the generated code. * print_locs.c: Add -v section offset output to loclist printing of the debug_loc section so the entries can be matched to loclist printing initiated from .debug_info. 2009-03-24: David Anderson * README: Would be nice if all could use dwarfdump2, not this C dwarfdump. * dwconf.c: Initialize new frame regs configure data and parse it in the .conf file. Fixed old formatting mistakes. * dwconf.h: Add new fields to frame regs configure struct. Make -R be 1200 regs so that -R covers all the currently popular ABIs. * print_die.c, print_lines.c, print_frames.c: Change %# to 0x% so that zero prints with leading 0x consistently. * dwarfdump.c: -R is now 1200 registers. So config function changed and usage message needed update. * dwarfdump.1: Change -R to 1200 and document -C. * dwarfdump.conf: Add same_val_reg: and undefined_val_reg: initial values where needed or interesting. * print_macros.c: Fix old formatting mistake. 2009-03-23: David Anderson * print_sections.h: New file for print_*.c sources. * dwarfdump.1: Added -C documentation. * Makefile.in: updated 'mandir' so it works with current configure (so now make install properly installs the man page). * print_sections.c: Moved get_fde_proc_name() and related code to print_frames.c, where it is referenced. * dwarfdump.c: No longer turn on info_flag with -f or -F. Moved the Usage strings into a string table and loop through to print them. * globals.h: Removed get_fde_proc_name() declaration. * print_frames.c: Added get_fde_proc_name() here and removed the 'inlined:' from the abstract origin name. 2009-03-20: David Anderson * print_static_vars.c, print_static_funcs.c, print_strings.c, print_locs.c, print_pubnames.c, print_lines.c, print_ranges.c, print_abbrevs.c, print_macros.c, print_types.c, print_weaknames.c, print_aranges.c: Moved the print_* functions from print_sections.c into individual sourcefiles. * Makefile.in: Now lists the new sourcefiles. * print_sections.c: Deleted code moved to individual sourcefiles. Added code to try to find the name from a DW_AT_abstract_origin DIE when a subprogram DIE itself has no DW_AT_name; * dwarfdump.c: Remove unused local variables. Use DWARFDUMP_VERSION #define to set version string. * tag_tree.c: Fix && || problem with parentheses. * tag_attr.c: Fix && || problem with parentheses. * print_frames.c: Moved the 'print_frames' function itself from print_sections.c to here. 2009-03-17: David Anderson * globals.h: Created predicate function should_skip_this_cu() predicate function. Eliminating code duplication. * print_frames.c: Fix a hex value output to have a leading 0x as all hex values should (when printed). * print_sections.c: Call should_skip_this_cu(), which replaces duplicate code. Fix the arange print: now the hex value has a leading 0x as all hex values should. get_proc_name() had local variable funcnamefound initialized incorrectly, now is set to 0 as it should be. get_nested_proc_name() now initializes string buffers. get_fde_proc_name() now initializes its string buffer. Surprisingly things worked adequately before in spite of the errors. * dwarfdump.c: Call should_skip_this_cu(). Implementation of that new function is in this source file. 2009-03-16: David Anderson * print_frames.c:DW_CFA_restore output had a spurious newline. Removed 2 pointless blank lines an initialized 2 local variables. * print_sections.c: Removed a pointless redeclaration of a function in libdwarf.h. check_info_offset_sanity() was missing a return statement in one place, which could lead to spurious extra (and silly) error text. 2009-03-09: David Anderson * print_die.c: Make a comment easier to understand. 2009-02-28: David Anderson * Makefile.in: add tmp-*.tmp to the 'clean' rule. 2009-02-17: David Anderson * print_sections.c,print_die.c,tag_common.c,print_frames.c: C99 in-line declarations and // comments are not intended here, this removes a few that were introduced accidentally. 2009-02-16: David Anderson * Makefile.in: Removed some use of awk and simplified some shell scripting here. renamed temp files, no longer named with underbars, they uniformly start with 'tmp-'. * print_sections.c: Added the new argument required by the updated dwarf_names.c functions argument lists. * tag_tree_ext.list: List 'common extensions' of tag->tag relationships. * tag_attr_ext.list: List 'common extensions' of tag->attr relationships. * print_die.c: New 'common extension' tables used for checking tag->tag and tag->attr relationships unless turned off with -C. * dwarf_names.awk: Removed tabs so generated names.c not so spread out. Added argument to the generated functions so tag_tree.c, tag_attr.c can use these generated functions nicely. * dwarfdump.c: Adding -C option, which exposes some 'common extensions' of dwarf uses as DWARF CHECK (-ka) warnings. By default these extensions not reported as warnings. * tag_tree.c: Now generates base and extensions tables. Code in common with tag_attr.c is in tag_common* files. * tag_attr.c: Now generates base and extensions tables. Code in common with tag_tree.c is in tag_common* files. * tag_common.c, tag_common.h: New files with the common data extracted from tag_tree.c and tag_attr.c * globals.h: global flag added for -C. 2009-02-14: David Anderson * configure.in: Define --enable-nonstandardprintf * config.h.in: new #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT * configure: Regenerated. * config.guess, config.sub: Latest version from GNU. * Makefile.in: Referenced configure variable to avoid irritating message at configure time. * README: document --enable-nonstandardprintf * print_sections.c, print_die.c, print_reloc.c, dwarfdump.c, dwconf.c, print_frames.c: Use libdwarf.h DW_PR_ printf macros for for better portability. 2009-02-13: David Anderson * print_sections.c: Ensure we are checking line table header correctness whichever line-table-print code is being used. Allow ARM line header table (which has a bug) to be used. * dwarfdump.c: Print lines_result total with checking on. * globals.h: Add lines_result global to count line botches. 2009-02-11: David Anderson * print_sections.c, print_die.c: DWARF_CHECK_ERROR* macros now get the count struct passed in. * tag_tree.c, tag_attr.c: Add a comment in the output identifying the output as generated code and with the generation date/time inserted. * globals.h: Accept the struct in DWARF_CHECK_ERROR* macros so we can update the error count in the macro. 2009-01-31: David Anderson * Makefile.in: Remove compilation of _tag_attr_table.c and _tag_tree_table.c as those are #included in print_die.c, not separately compiled. * print_frames.c: A formerly-static function now called from another file, so declare it here. * print_sections.c: Improve the printing of the .debug_loc section. * print_die.c: A couple of errors were missing their error count increment. * tag_attr.list tag_tree.list: Some normal relationships were left out of the tables: fixed now. libdwarf-20210528/dwarfdump/attr_form.c0000664000175000017500000004173214053210267014635 00000000000000/* Copyright (C) 2021 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #define DW_TSHASHTYPE long /* this type not needed */ #include "dwarf_tsearch.h" #include "naming.h" #include "attr_form.h" #include "dwarfdump-af-table.h" const Three_Key_Entry threekeyzero; #if 0 static void print_3key_record(int num,Three_Key_Entry *e) { printf("3key %d 0x%x 0x%x 0x%x st %d%d ct %lu\n", num,e->key1,e->key2,e->key3, e->std_or_exten,e->from_tables, (unsigned long)e->count); } #endif /* 0 */ int make_3key(Dwarf_Half k1, Dwarf_Half k2, Dwarf_Half k3, Dwarf_Small std_or_exten, Dwarf_Small from_preset, Dwarf_Unsigned count, Three_Key_Entry ** out) { Three_Key_Entry *e = (Three_Key_Entry *)malloc(sizeof(Three_Key_Entry)); if (!e) { return DW_DLV_ERROR; /* out of memory */ } e->key1 = k1; e->key2 = k2; e->key3 = k3; e->std_or_exten = std_or_exten; e->from_tables = from_preset; e->count = count; *out = e; return DW_DLV_OK; } void free_func_3key_entry(void *keystructptr) { Three_Key_Entry *e = keystructptr; free(e); } int std_compare_3key_entry(const void *l_in, const void *r_in) { const Three_Key_Entry *l = l_in; const Three_Key_Entry *r = r_in; if (l->key1 < r->key1) { return -1; } if (l->key1 > r->key1) { return 1; } if (l->key2 < r->key2) { return -1; } if (l->key2 > r->key2) { return 1; } if (l->key3 < r->key3) { return -1; } if (l->key3 > r->key3) { return 1; } return 0; } static Dwarf_Unsigned counting_global; static void count_3key_entry(UNUSEDARG const void * vptr, DW_VISIT x, UNUSEDARG int level) { if (x == dwarf_preorder || x == dwarf_leaf) { ++counting_global; } } /* Tree argument expected is threekey_attr_form_base for example */ Dwarf_Unsigned three_key_entry_count(void *base) { Dwarf_Unsigned count = 0; counting_global = 0; dwarf_twalk(base,count_3key_entry); count = counting_global; counting_global = 0; return count; } /* tree argument expected is &threekey_attr_form_base for example */ static int insert_new_tab_entry(void *tree, struct af_table_s * tab, int *errnum) { Three_Key_Entry *e = 0; Three_Key_Entry *re = 0; void *ret = 0; int res = 0; res = make_3key(tab->attr,tab->formclass,0, tab->section, 1 /* is from preset data */, 0 /* count is zero during preset */, &e); if (res != DW_DLV_OK) { *errnum = DW_DLE_ALLOC_FAIL; return res; } ret = dwarf_tsearch(e,tree,std_compare_3key_entry); if (!ret) { *errnum = DW_DLE_ALLOC_FAIL; return res; } re = *(Three_Key_Entry **)ret; if (re == e) { /* Normal. Added. */ return DW_DLV_OK; } /* A full duplicate in the table. Oops. Not a great choice of error code. */ *errnum = DW_DLE_ATTR_FORM_BAD; return DW_DLV_ERROR; } /* This is for dwarfdump to call at runtime. Returns DW_DLV_OK on success */ int build_attr_form_base_tree(int*errnum) { struct af_table_s * tab = 0; int res; void *tree = &threekey_attr_form_base; if (threekey_attr_form_base) { /* Do not init again if a tied file */ return DW_DLV_OK; } for (tab = &attr_formclass_table[0]; ; tab++) { if (!tab->attr && !tab->formclass && !tab->section) { /* Done */ break; } res = insert_new_tab_entry(tree,tab,errnum); if (res != DW_DLV_OK) { return res; } } return DW_DLV_OK; } /* The standard main tree for attr_form data. Starting out as a simple global variable. In general, pass &threekey_attr_form_base (for example) to tsearch calls. */ void * threekey_attr_form_base; void destroy_attr_form_trees(void) { if (!threekey_attr_form_base) { return; } dwarf_tdestroy(threekey_attr_form_base, free_func_3key_entry); threekey_attr_form_base = 0; } /* SKIP_AF_CHECK defined means this is in scripts/ddbuild.sh and this checking makes no sense and will not compile. */ #ifndef SKIP_AF_CHECK static Dwarf_Bool legal_attr_formclass_combination(Dwarf_Half attr, Dwarf_Half fc) { Three_Key_Entry *e = 0; Three_Key_Entry *re = 0; void *ret = 0; int res = 0; res = make_3key(attr,fc,0,0,0,0,&e); if (res!= DW_DLV_OK) { /* Hiding some sort of botch/malloc issue */ return TRUE; } ret = dwarf_tfind(e,&threekey_attr_form_base, std_compare_3key_entry); if (!ret) { /* Surprising combo. */ free(e); return FALSE; } re = *(Three_Key_Entry **)ret; if (!glflags.gf_suppress_check_extensions_tables) { free(e); return TRUE; } if (re->std_or_exten == AF_STD) { free(e); return TRUE; } free(e); return FALSE; } static void check_attr_formclass_combination(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Half attrnum, Dwarf_Half fc, int pd_dwarf_names_print_on_error, int die_stack_indent_level) { const char *tagname = ""; const char *formclassname = ""; DWARF_CHECK_COUNT(attr_formclass_result,1); if (legal_attr_formclass_combination(attrnum,fc)) { /* OK */ } else { /* Report errors only if tag-attr check is on */ if (glflags.gf_check_tag_attr) { tagname = get_AT_name(attrnum, pd_dwarf_names_print_on_error); tag_specific_globals_setup(dbg,tag, die_stack_indent_level); formclassname = get_FORM_CLASS_name(fc, pd_dwarf_names_print_on_error); DWARF_CHECK_ERROR3(attr_formclass_result,tagname, formclassname, "check the attr-formclass combination"); } } } #endif /* SKIP_AF_CHECK */ void record_attr_form_use( #ifndef SKIP_AF_CHECK Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Half attr, Dwarf_Half fclass, Dwarf_Half form, int pd_dwarf_names_print_on_error, int die_stack_indent_level) #else UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Half tag, Dwarf_Half attr, Dwarf_Half fclass, Dwarf_Half form, UNUSEDARG int pd_dwarf_names_print_on_error, UNUSEDARG int die_stack_indent_level) #endif /* SKIP_AF_CHECK */ { Three_Key_Entry *e = 0; Three_Key_Entry *re = 0; void *ret = 0; Dwarf_Small std_or_exten = AF_STD; int res = 0; if (attr >= DW_AT_lo_user) { std_or_exten = AF_EXTEN; } else if (form > DW_FORM_addrx4) { /* There is no lo_user code for FORMs, they really are limited. */ std_or_exten = AF_EXTEN; } #ifndef SKIP_AF_CHECK check_attr_formclass_combination(dbg, tag,attr,fclass,pd_dwarf_names_print_on_error, die_stack_indent_level); #endif /* SKIP_AF_CHECK */ res = make_3key(attr,fclass,form,std_or_exten,0,1,&e); if (res!= DW_DLV_OK) { /* Could print something */ return; } ret = dwarf_tsearch(e,&threekey_attr_form_base, std_compare_3key_entry); if (!ret) { free_func_3key_entry(e); /* Could print something */ return; } re = *(Three_Key_Entry **)ret; if (re == e) { /* Brand new entry. Done. local malloc is in the tree. */ return; } /* Was already entered.*/ ++re->count; /* Clean out the local malloc */ free_func_3key_entry(e); return; } static Dwarf_Unsigned recordcount = 0; static Dwarf_Unsigned recordmax = 0; static Three_Key_Entry * tkarray = 0; static void extract_3key_entry(const void * vptr, DW_VISIT x, UNUSEDARG int level) { if (x == dwarf_preorder || x == dwarf_leaf) { Three_Key_Entry *m = *(Three_Key_Entry **)vptr; if (recordcount >= recordmax) { /* Should never happen */ return; } tkarray[recordcount] = *m; ++recordcount; } } static int qsortformclass(const void * e1in, const void * e2in) { Three_Key_Entry *e1 = (Three_Key_Entry *)e1in; Three_Key_Entry *e2 = (Three_Key_Entry *)e2in; if (e1->key2 < e2->key2) { return -1; } if (e1->key2 > e2->key2) { return 1; } return 0; } static int qsortform(const void * e1in, const void * e2in) { Three_Key_Entry *e1 = (Three_Key_Entry *)e1in; Three_Key_Entry *e2 = (Three_Key_Entry *)e2in; if (e1->key3 < e2->key3) { return -1; } if (e1->key3 > e2->key3) { return 1; } return 0; } static int qsortcountattr(const void * e1in, const void * e2in) { Three_Key_Entry *e1 = (Three_Key_Entry *)e1in; Three_Key_Entry *e2 = (Three_Key_Entry *)e2in; if (e1->count < e2->count) { return 1; } if (e1->count > e2->count) { return -1; } if (e1->key1 < e2->key1) { return -1; } if (e1->key1 > e2->key1) { return 1; } if (e1->key3 < e2->key3) { return -1; } if (e1->key3 > e2->key3) { return 1; } if (e1->key2 < e2->key2) { return -1; } if (e1->key2 > e2->key2) { return 1; } return 0; } void print_attr_form_usage(int pd_dwarf_names_print_on_error) { Three_Key_Entry * tk_l = 0; Dwarf_Unsigned i =0; float total = 0; unsigned curform = 0; Dwarf_Unsigned formtotal = 0; unsigned curattr = 0; Dwarf_Unsigned attrtotal = 0; Dwarf_Unsigned j = 0; float pct = 0; Dwarf_Bool startnoted = FALSE; const char *localformat= 0; Dwarf_Unsigned localsum = 0; recordmax = three_key_entry_count(threekey_attr_form_base); if (!recordmax) { return; } tk_l = (Three_Key_Entry *)calloc(recordmax+1, sizeof(Three_Key_Entry)); tkarray=tk_l; if (!tk_l) { printf("ERROR: unable to malloc attr/form array " " for a summary report \n"); glflags.gf_count_major_errors++; return; } /* Reset the file-global! */ recordcount = 0; dwarf_twalk(threekey_attr_form_base,extract_3key_entry); if (recordcount != recordmax) { printf("ERROR: unable to fill in attr/form array " " for a summary report, count %lu != walk %lu \n", (unsigned long)recordcount, (unsigned long)recordmax); glflags.gf_count_major_errors++; free(tk_l); tkarray = 0; return; } for (i = 0; i < recordmax; ++i) { Three_Key_Entry * tke = tk_l+i; if (!tke->key3) { /* Skip table building data */ continue; } total += (float)tke->count; } qsort(tk_l,recordmax,sizeof(Three_Key_Entry), qsortcountattr); printf("\n*** ATTRIBUTES AND FORMS USAGE ***\n"); printf("Full record count : %8" DW_PR_DUu "\n", recordmax); printf("Total number of objectfile attributes: %8.0f\n", total); printf("[] " " found rate\n"); localformat="[%3u] %-30s %-20s %7" DW_PR_DUu " %.0f%%\n"; localsum = 0; for (i = 0; i < recordmax; ++i) { Three_Key_Entry * tke = tk_l+i; if (!tke->key3) { /* Skip table building data */ continue; } pct = ( (float)tke->count / total)*100.0; printf(localformat, (unsigned)i, get_AT_name(tke->key1,pd_dwarf_names_print_on_error), get_FORM_name(tke->key3,pd_dwarf_names_print_on_error), tke->count,pct); localsum += tke->count; } printf(localformat, (unsigned)(recordmax), "Sum found:","",localsum,100.0); qsort(tk_l,recordmax,sizeof(Three_Key_Entry), qsortformclass); j = 0; /* Re-using the following two */ curform = 0; formtotal = 0; startnoted = FALSE; printf("\n*** COUNT BY FORMCLASS ***\n"); printf("[] found rate\n"); localsum = 0; localformat="[%2u] %-28s %6" DW_PR_DUu " %.0f%%\n"; for (i = 0; i < recordmax; ++i) { Three_Key_Entry * tke = tk_l+i; if (!tke->key3) { /* Skip table building data */ continue; } if (!startnoted) { curform = tke->key2; formtotal = tke->count; startnoted = TRUE; continue; } if (curform != tke->key2) { pct = ( (float)formtotal / total)*100.0; printf(localformat, (unsigned)j, get_FORM_CLASS_name(curform, pd_dwarf_names_print_on_error), formtotal,pct); localsum += formtotal; curform = tke->key2; formtotal = tke->count; ++j; continue; } formtotal += tke->count; } if (formtotal) { pct = ( (float)formtotal / total)*100.0; printf(localformat, (unsigned)j, get_FORM_CLASS_name(curform, pd_dwarf_names_print_on_error), formtotal,pct); localsum += formtotal; } printf(localformat, (unsigned)(j+1), "Sum found:",localsum,100.0); /* Re-using the following two */ curform = 0; formtotal = 0; startnoted = FALSE; qsort(tk_l,recordmax,sizeof(Three_Key_Entry), qsortform); j = 0; printf("\n*** COUNT BY FORM ***\n"); printf("[] found rate\n"); localformat="[%2u] %-20s %6" DW_PR_DUu " %.0f%%\n"; localsum = 0; for (i = 0; i < recordmax; ++i) { Three_Key_Entry * tke = tk_l+i; if (!tke->key3) { /* Skip table building data */ continue; } if (!startnoted) { curform = tke->key3; formtotal = tke->count; startnoted = TRUE; continue; } if (curform != tke->key3) { pct = ( (float)formtotal / total)*100.0; printf(localformat, (unsigned)j, get_FORM_name(curform, pd_dwarf_names_print_on_error), formtotal,pct); localsum += formtotal; curform = tke->key3; formtotal = tke->count; ++j; continue; } formtotal += tke->count; } if (formtotal) { pct = ( (float)formtotal / total)*100.0; printf(localformat, (unsigned)j, get_FORM_name(curform, pd_dwarf_names_print_on_error), formtotal,pct); localsum += formtotal; } printf(localformat, (unsigned)(j+1), "Sum found:",localsum,100.0); j = 0; curattr = 0; attrtotal = 0; startnoted = FALSE; printf("\n*** COUNT BY ATTRIBUTE ***\n"); printf("[] found rate\n"); localsum = 0; localformat="[%2u] %-30s %6" DW_PR_DUu " %.0f%%\n"; for (i = 0; i < recordmax; ++i) { Three_Key_Entry * tke = tk_l+i; if (!tke->key3) { /* Skip table building data */ continue; } if (!startnoted) { curattr = tke->key1; attrtotal = tke->count; startnoted = TRUE; continue; } if (curattr != tke->key1) { pct = ( (float)attrtotal / total)*100.0; printf(localformat, (unsigned)j, get_AT_name(curattr, pd_dwarf_names_print_on_error), attrtotal,pct); localsum += attrtotal; curattr = tke->key1; attrtotal = tke->count; ++j; continue; } formtotal += tke->count; } if (attrtotal) { pct = ( (float)attrtotal / total)*100.0; printf(localformat, (unsigned)j, get_AT_name(curattr,pd_dwarf_names_print_on_error), attrtotal,pct); localsum += attrtotal; } printf(localformat, (unsigned)(j+1), "Sum found:",localsum,100.0); free(tk_l); tkarray = 0; } libdwarf-20210528/dwarfdump/dwarfdump-tt-table.h0000664000175000017500000010761514054205620016351 00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #ifndef HAVE_USAGE_TAG_ATTR #define HAVE_USAGE_TAG_ATTR 1 #endif /* HAVE_USAGE_TAG_ATTR */ #ifdef HAVE_USAGE_TAG_ATTR #include "dwarf.h" #include "libdwarf.h" typedef struct { unsigned int count; /* Tag count */ Dwarf_Half tag; /* Tag value */ } Usage_Tag_Tree; /* 0x23 - DW_TAG_access_declaration */ static Usage_Tag_Tree tag_tree_23[2] = { {/* */ 0, 0} }; /* 0x01 - DW_TAG_array_type */ static Usage_Tag_Tree tag_tree_01[6] = { {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* */ 0, 0} }; /* 0x24 - DW_TAG_base_type */ static Usage_Tag_Tree tag_tree_24[2] = { {/* */ 0, 0} }; /* 0x48 - DW_TAG_call_site */ static Usage_Tag_Tree tag_tree_48[3] = { {/* 0x49 */ 0, DW_TAG_call_site_parameter}, {/* */ 0, 0} }; /* 0x49 - DW_TAG_call_site_parameter */ static Usage_Tag_Tree tag_tree_49[2] = { {/* */ 0, 0} }; /* 0x25 - DW_TAG_catch_block */ static Usage_Tag_Tree tag_tree_25[27] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x02 - DW_TAG_class_type */ static Usage_Tag_Tree tag_tree_02[23] = { {/* 0x0d */ 0, DW_TAG_member}, {/* 0x1c */ 0, DW_TAG_inheritance}, {/* 0x23 */ 0, DW_TAG_access_declaration}, {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* */ 0, 0} }; /* 0x44 - DW_TAG_coarray_type */ static Usage_Tag_Tree tag_tree_44[7] = { {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* */ 0, 0} }; /* 0x1a - DW_TAG_common_block */ static Usage_Tag_Tree tag_tree_1a[3] = { {/* 0x34 */ 0, DW_TAG_variable}, {/* */ 0, 0} }; /* 0x1b - DW_TAG_common_inclusion */ static Usage_Tag_Tree tag_tree_1b[2] = { {/* */ 0, 0} }; /* 0x4a - DW_TAG_skeleton_unit */ static Usage_Tag_Tree tag_tree_4a[6] = { {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* */ 0, 0} }; /* 0x11 - DW_TAG_compile_unit */ static Usage_Tag_Tree tag_tree_11[39] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x36 */ 0, DW_TAG_dwarf_procedure}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* 0x3b */ 0, DW_TAG_unspecified_type}, {/* */ 0, 0} }; /* 0x41 - DW_TAG_type_unit */ static Usage_Tag_Tree tag_tree_41[35] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* */ 0, 0} }; /* 0x3f - DW_TAG_condition */ static Usage_Tag_Tree tag_tree_3f[4] = { {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* */ 0, 0} }; /* 0x47 - DW_TAG_atomic_type */ static Usage_Tag_Tree tag_tree_47[2] = { {/* */ 0, 0} }; /* 0x26 - DW_TAG_const_type */ static Usage_Tag_Tree tag_tree_26[2] = { {/* */ 0, 0} }; /* 0x27 - DW_TAG_constant */ static Usage_Tag_Tree tag_tree_27[2] = { {/* */ 0, 0} }; /* 0x36 - DW_TAG_dwarf_procedure */ static Usage_Tag_Tree tag_tree_36[2] = { {/* */ 0, 0} }; /* 0x03 - DW_TAG_entry_point */ static Usage_Tag_Tree tag_tree_03[5] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x1b */ 0, DW_TAG_common_inclusion}, {/* */ 0, 0} }; /* 0x04 - DW_TAG_enumeration_type */ static Usage_Tag_Tree tag_tree_04[3] = { {/* 0x28 */ 0, DW_TAG_enumerator}, {/* */ 0, 0} }; /* 0x28 - DW_TAG_enumerator */ static Usage_Tag_Tree tag_tree_28[2] = { {/* */ 0, 0} }; /* 0x29 - DW_TAG_file_type */ static Usage_Tag_Tree tag_tree_29[2] = { {/* */ 0, 0} }; /* 0x05 - DW_TAG_formal_parameter */ static Usage_Tag_Tree tag_tree_05[2] = { {/* */ 0, 0} }; /* 0x2a - DW_TAG_friend */ static Usage_Tag_Tree tag_tree_2a[2] = { {/* */ 0, 0} }; /* 0x08 - DW_TAG_imported_declaration */ static Usage_Tag_Tree tag_tree_08[2] = { {/* */ 0, 0} }; /* 0x3a - DW_TAG_imported_module */ static Usage_Tag_Tree tag_tree_3a[2] = { {/* */ 0, 0} }; /* 0x3d - DW_TAG_imported_unit */ static Usage_Tag_Tree tag_tree_3d[2] = { {/* */ 0, 0} }; /* 0x1c - DW_TAG_inheritance */ static Usage_Tag_Tree tag_tree_1c[2] = { {/* */ 0, 0} }; /* 0x1d - DW_TAG_inlined_subroutine */ static Usage_Tag_Tree tag_tree_1d[33] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x48 */ 0, DW_TAG_call_site}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x38 - DW_TAG_interface_type */ static Usage_Tag_Tree tag_tree_38[4] = { {/* 0x0d */ 0, DW_TAG_member}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* */ 0, 0} }; /* 0x0a - DW_TAG_label */ static Usage_Tag_Tree tag_tree_0a[2] = { {/* */ 0, 0} }; /* 0x0b - DW_TAG_lexical_block */ static Usage_Tag_Tree tag_tree_0b[35] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x48 */ 0, DW_TAG_call_site}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x0a */ 0, DW_TAG_label}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x0d - DW_TAG_member */ static Usage_Tag_Tree tag_tree_0d[2] = { {/* */ 0, 0} }; /* 0x1e - DW_TAG_module */ static Usage_Tag_Tree tag_tree_1e[2] = { {/* */ 0, 0} }; /* 0x2b - DW_TAG_namelist */ static Usage_Tag_Tree tag_tree_2b[3] = { {/* 0x2c */ 0, DW_TAG_namelist_item}, {/* */ 0, 0} }; /* 0x2c - DW_TAG_namelist_item */ static Usage_Tag_Tree tag_tree_2c[2] = { {/* */ 0, 0} }; /* 0x39 - DW_TAG_namespace */ static Usage_Tag_Tree tag_tree_39[33] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x2d - DW_TAG_packed_type */ static Usage_Tag_Tree tag_tree_2d[2] = { {/* */ 0, 0} }; /* 0x3c - DW_TAG_partial_unit */ static Usage_Tag_Tree tag_tree_3c[32] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x0f - DW_TAG_pointer_type */ static Usage_Tag_Tree tag_tree_0f[10] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x1f - DW_TAG_ptr_to_member_type */ static Usage_Tag_Tree tag_tree_1f[2] = { {/* */ 0, 0} }; /* 0x10 - DW_TAG_reference_type */ static Usage_Tag_Tree tag_tree_10[10] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x42 - DW_TAG_rvalue_reference_type */ static Usage_Tag_Tree tag_tree_42[10] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x37 - DW_TAG_restrict_type */ static Usage_Tag_Tree tag_tree_37[10] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x20 - DW_TAG_set_type */ static Usage_Tag_Tree tag_tree_20[2] = { {/* */ 0, 0} }; /* 0x40 - DW_TAG_shared_type */ static Usage_Tag_Tree tag_tree_40[11] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x12 - DW_TAG_string_type */ static Usage_Tag_Tree tag_tree_12[2] = { {/* */ 0, 0} }; /* 0x13 - DW_TAG_structure_type */ static Usage_Tag_Tree tag_tree_13[24] = { {/* 0x23 */ 0, DW_TAG_access_declaration}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x1c */ 0, DW_TAG_inheritance}, {/* 0x0d */ 0, DW_TAG_member}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x33 */ 0, DW_TAG_variant_part}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x2e - DW_TAG_subprogram */ static Usage_Tag_Tree tag_tree_2e[40] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x48 */ 0, DW_TAG_call_site}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1b */ 0, DW_TAG_common_inclusion}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x0a */ 0, DW_TAG_label}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x31 */ 0, DW_TAG_thrown_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x21 - DW_TAG_subrange_type */ static Usage_Tag_Tree tag_tree_21[2] = { {/* */ 0, 0} }; /* 0x45 - DW_TAG_generic_subrange */ static Usage_Tag_Tree tag_tree_45[2] = { {/* */ 0, 0} }; /* 0x15 - DW_TAG_subroutine_type */ static Usage_Tag_Tree tag_tree_15[5] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* */ 0, 0} }; /* 0x2f - DW_TAG_template_type_parameter */ static Usage_Tag_Tree tag_tree_2f[2] = { {/* */ 0, 0} }; /* 0x30 - DW_TAG_template_value_parameter */ static Usage_Tag_Tree tag_tree_30[2] = { {/* */ 0, 0} }; /* 0x31 - DW_TAG_thrown_type */ static Usage_Tag_Tree tag_tree_31[2] = { {/* */ 0, 0} }; /* 0x32 - DW_TAG_try_block */ static Usage_Tag_Tree tag_tree_32[2] = { {/* */ 0, 0} }; /* 0x16 - DW_TAG_typedef */ static Usage_Tag_Tree tag_tree_16[2] = { {/* */ 0, 0} }; /* 0x17 - DW_TAG_union_type */ static Usage_Tag_Tree tag_tree_17[12] = { {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x0d */ 0, DW_TAG_member}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* */ 0, 0} }; /* 0x43 - DW_TAG_template_alias */ static Usage_Tag_Tree tag_tree_43[4] = { {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* */ 0, 0} }; /* 0x18 - DW_TAG_unspecified_parameters */ static Usage_Tag_Tree tag_tree_18[2] = { {/* */ 0, 0} }; /* 0x3b - DW_TAG_unspecified_type */ static Usage_Tag_Tree tag_tree_3b[2] = { {/* */ 0, 0} }; /* 0x34 - DW_TAG_variable */ static Usage_Tag_Tree tag_tree_34[2] = { {/* */ 0, 0} }; /* 0x19 - DW_TAG_variant */ static Usage_Tag_Tree tag_tree_19[3] = { {/* 0x33 */ 0, DW_TAG_variant_part}, {/* */ 0, 0} }; /* 0x33 - DW_TAG_variant_part */ static Usage_Tag_Tree tag_tree_33[2] = { {/* */ 0, 0} }; /* 0x35 - DW_TAG_volatile_type */ static Usage_Tag_Tree tag_tree_35[2] = { {/* */ 0, 0} }; /* 0x22 - DW_TAG_with_stmt */ static Usage_Tag_Tree tag_tree_22[2] = { {/* */ 0, 0} }; static Usage_Tag_Tree *usage_tag_tree[0x4d] = { 0, tag_tree_01, /* 0x01 - DW_TAG_array_type */ tag_tree_02, /* 0x02 - DW_TAG_class_type */ tag_tree_03, /* 0x03 - DW_TAG_entry_point */ tag_tree_04, /* 0x04 - DW_TAG_enumeration_type */ tag_tree_05, /* 0x05 - DW_TAG_formal_parameter */ 0, 0, tag_tree_08, /* 0x08 - DW_TAG_imported_declaration */ 0, tag_tree_0a, /* 0x0a - DW_TAG_label */ tag_tree_0b, /* 0x0b - DW_TAG_lexical_block */ 0, tag_tree_0d, /* 0x0d - DW_TAG_member */ 0, tag_tree_0f, /* 0x0f - DW_TAG_pointer_type */ tag_tree_10, /* 0x10 - DW_TAG_reference_type */ tag_tree_11, /* 0x11 - DW_TAG_compile_unit */ tag_tree_12, /* 0x12 - DW_TAG_string_type */ tag_tree_13, /* 0x13 - DW_TAG_structure_type */ 0, tag_tree_15, /* 0x15 - DW_TAG_subroutine_type */ tag_tree_16, /* 0x16 - DW_TAG_typedef */ tag_tree_17, /* 0x17 - DW_TAG_union_type */ tag_tree_18, /* 0x18 - DW_TAG_unspecified_parameters */ tag_tree_19, /* 0x19 - DW_TAG_variant */ tag_tree_1a, /* 0x1a - DW_TAG_common_block */ tag_tree_1b, /* 0x1b - DW_TAG_common_inclusion */ tag_tree_1c, /* 0x1c - DW_TAG_inheritance */ tag_tree_1d, /* 0x1d - DW_TAG_inlined_subroutine */ tag_tree_1e, /* 0x1e - DW_TAG_module */ tag_tree_1f, /* 0x1f - DW_TAG_ptr_to_member_type */ tag_tree_20, /* 0x20 - DW_TAG_set_type */ tag_tree_21, /* 0x21 - DW_TAG_subrange_type */ tag_tree_22, /* 0x22 - DW_TAG_with_stmt */ tag_tree_23, /* 0x23 - DW_TAG_access_declaration */ tag_tree_24, /* 0x24 - DW_TAG_base_type */ tag_tree_25, /* 0x25 - DW_TAG_catch_block */ tag_tree_26, /* 0x26 - DW_TAG_const_type */ tag_tree_27, /* 0x27 - DW_TAG_constant */ tag_tree_28, /* 0x28 - DW_TAG_enumerator */ tag_tree_29, /* 0x29 - DW_TAG_file_type */ tag_tree_2a, /* 0x2a - DW_TAG_friend */ tag_tree_2b, /* 0x2b - DW_TAG_namelist */ tag_tree_2c, /* 0x2c - DW_TAG_namelist_item */ tag_tree_2d, /* 0x2d - DW_TAG_packed_type */ tag_tree_2e, /* 0x2e - DW_TAG_subprogram */ tag_tree_2f, /* 0x2f - DW_TAG_template_type_parameter */ tag_tree_30, /* 0x30 - DW_TAG_template_value_parameter */ tag_tree_31, /* 0x31 - DW_TAG_thrown_type */ tag_tree_32, /* 0x32 - DW_TAG_try_block */ tag_tree_33, /* 0x33 - DW_TAG_variant_part */ tag_tree_34, /* 0x34 - DW_TAG_variable */ tag_tree_35, /* 0x35 - DW_TAG_volatile_type */ tag_tree_36, /* 0x36 - DW_TAG_dwarf_procedure */ tag_tree_37, /* 0x37 - DW_TAG_restrict_type */ tag_tree_38, /* 0x38 - DW_TAG_interface_type */ tag_tree_39, /* 0x39 - DW_TAG_namespace */ tag_tree_3a, /* 0x3a - DW_TAG_imported_module */ tag_tree_3b, /* 0x3b - DW_TAG_unspecified_type */ tag_tree_3c, /* 0x3c - DW_TAG_partial_unit */ tag_tree_3d, /* 0x3d - DW_TAG_imported_unit */ 0, tag_tree_3f, /* 0x3f - DW_TAG_condition */ tag_tree_40, /* 0x40 - DW_TAG_shared_type */ tag_tree_41, /* 0x41 - DW_TAG_type_unit */ tag_tree_42, /* 0x42 - DW_TAG_rvalue_reference_type */ tag_tree_43, /* 0x43 - DW_TAG_template_alias */ tag_tree_44, /* 0x44 - DW_TAG_coarray_type */ tag_tree_45, /* 0x45 - DW_TAG_generic_subrange */ 0, tag_tree_47, /* 0x47 - DW_TAG_atomic_type */ tag_tree_48, /* 0x48 - DW_TAG_call_site */ tag_tree_49, /* 0x49 - DW_TAG_call_site_parameter */ tag_tree_4a, /* 0x4a - DW_TAG_skeleton_unit */ 0, 0 }; typedef struct { Dwarf_Small legal; /* Legal tags */ Dwarf_Small found; /* Found tags */ } Rate_Tag_Tree; static Rate_Tag_Tree rate_tag_tree[0x4d] = { {0, 0}, { 4, 0 /* 0x01 - DW_TAG_array_type */}, {21, 0 /* 0x02 - DW_TAG_class_type */}, { 3, 0 /* 0x03 - DW_TAG_entry_point */}, { 1, 0 /* 0x04 - DW_TAG_enumeration_type */}, { 0, 0 /* 0x05 - DW_TAG_formal_parameter */}, {0, 0}, {0, 0}, { 0, 0 /* 0x08 - DW_TAG_imported_declaration */}, {0, 0}, { 0, 0 /* 0x0a - DW_TAG_label */}, {33, 0 /* 0x0b - DW_TAG_lexical_block */}, {0, 0}, { 0, 0 /* 0x0d - DW_TAG_member */}, {0, 0}, { 8, 0 /* 0x0f - DW_TAG_pointer_type */}, { 8, 0 /* 0x10 - DW_TAG_reference_type */}, {37, 0 /* 0x11 - DW_TAG_compile_unit */}, { 0, 0 /* 0x12 - DW_TAG_string_type */}, {22, 0 /* 0x13 - DW_TAG_structure_type */}, {0, 0}, { 3, 0 /* 0x15 - DW_TAG_subroutine_type */}, { 0, 0 /* 0x16 - DW_TAG_typedef */}, {10, 0 /* 0x17 - DW_TAG_union_type */}, { 0, 0 /* 0x18 - DW_TAG_unspecified_parameters */}, { 1, 0 /* 0x19 - DW_TAG_variant */}, { 1, 0 /* 0x1a - DW_TAG_common_block */}, { 0, 0 /* 0x1b - DW_TAG_common_inclusion */}, { 0, 0 /* 0x1c - DW_TAG_inheritance */}, {31, 0 /* 0x1d - DW_TAG_inlined_subroutine */}, { 0, 0 /* 0x1e - DW_TAG_module */}, { 0, 0 /* 0x1f - DW_TAG_ptr_to_member_type */}, { 0, 0 /* 0x20 - DW_TAG_set_type */}, { 0, 0 /* 0x21 - DW_TAG_subrange_type */}, { 0, 0 /* 0x22 - DW_TAG_with_stmt */}, { 0, 0 /* 0x23 - DW_TAG_access_declaration */}, { 0, 0 /* 0x24 - DW_TAG_base_type */}, {25, 0 /* 0x25 - DW_TAG_catch_block */}, { 0, 0 /* 0x26 - DW_TAG_const_type */}, { 0, 0 /* 0x27 - DW_TAG_constant */}, { 0, 0 /* 0x28 - DW_TAG_enumerator */}, { 0, 0 /* 0x29 - DW_TAG_file_type */}, { 0, 0 /* 0x2a - DW_TAG_friend */}, { 1, 0 /* 0x2b - DW_TAG_namelist */}, { 0, 0 /* 0x2c - DW_TAG_namelist_item */}, { 0, 0 /* 0x2d - DW_TAG_packed_type */}, {38, 0 /* 0x2e - DW_TAG_subprogram */}, { 0, 0 /* 0x2f - DW_TAG_template_type_parameter */}, { 0, 0 /* 0x30 - DW_TAG_template_value_parameter */}, { 0, 0 /* 0x31 - DW_TAG_thrown_type */}, { 0, 0 /* 0x32 - DW_TAG_try_block */}, { 0, 0 /* 0x33 - DW_TAG_variant_part */}, { 0, 0 /* 0x34 - DW_TAG_variable */}, { 0, 0 /* 0x35 - DW_TAG_volatile_type */}, { 0, 0 /* 0x36 - DW_TAG_dwarf_procedure */}, { 8, 0 /* 0x37 - DW_TAG_restrict_type */}, { 2, 0 /* 0x38 - DW_TAG_interface_type */}, {31, 0 /* 0x39 - DW_TAG_namespace */}, { 0, 0 /* 0x3a - DW_TAG_imported_module */}, { 0, 0 /* 0x3b - DW_TAG_unspecified_type */}, {30, 0 /* 0x3c - DW_TAG_partial_unit */}, { 0, 0 /* 0x3d - DW_TAG_imported_unit */}, {0, 0}, { 2, 0 /* 0x3f - DW_TAG_condition */}, { 9, 0 /* 0x40 - DW_TAG_shared_type */}, {33, 0 /* 0x41 - DW_TAG_type_unit */}, { 8, 0 /* 0x42 - DW_TAG_rvalue_reference_type */}, { 2, 0 /* 0x43 - DW_TAG_template_alias */}, { 5, 0 /* 0x44 - DW_TAG_coarray_type */}, { 0, 0 /* 0x45 - DW_TAG_generic_subrange */}, {0, 0}, { 0, 0 /* 0x47 - DW_TAG_atomic_type */}, { 1, 0 /* 0x48 - DW_TAG_call_site */}, { 0, 0 /* 0x49 - DW_TAG_call_site_parameter */}, { 4, 0 /* 0x4a - DW_TAG_skeleton_unit */}, {0, 0}, {0, 0} }; #endif /* HAVE_USAGE_TAG_ATTR */ #define TAG_TREE_COLUMN_COUNT 3 #define TAG_TREE_ROW_COUNT 75 static unsigned int tag_tree_combination_table [TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = { /* 0x00 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00000010,0x00000002,0x00000060,}, /* 0x02 - DW_TAG_class_type */ { 0x90c8a114,0x0001c458,0x000000d8,}, /* 0x03 - DW_TAG_entry_point */ { 0x09000020,0x00000000,0x00000000,}, /* 0x04 - DW_TAG_enumeration_type */ { 0x00000000,0x00000100,0x00000000,}, /* 0x05 - DW_TAG_formal_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x06 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x07 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x08 - DW_TAG_imported_declaration */ { 0x00000000,0x00000000,0x00000000,}, /* 0x09 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0a - DW_TAG_label */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0xe0ed8d36,0x043068d3,0x000001f0,}, /* 0x0c - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0e - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0f - DW_TAG_pointer_type */ { 0x00010000,0x00a02040,0x00000085,}, /* 0x10 - DW_TAG_reference_type */ { 0x00008000,0x00a02040,0x00000085,}, /* 0x11 - DW_TAG_compile_unit */ { 0xe4ed8116,0x0ef06ad3,0x000000fc,}, /* 0x12 - DW_TAG_string_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x13 - DW_TAG_structure_type */ { 0x90c8a114,0x0029c458,0x00000098,}, /* 0x14 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x15 - DW_TAG_subroutine_type */ { 0x01400020,0x00000000,0x00000000,}, /* 0x16 - DW_TAG_typedef */ { 0x00000000,0x00000000,0x00000000,}, /* 0x17 - DW_TAG_union_type */ { 0x00c82014,0x0001c400,0x00000000,}, /* 0x18 - DW_TAG_unspecified_parameters */ { 0x00000000,0x00000000,0x00000000,}, /* 0x19 - DW_TAG_variant */ { 0x00000000,0x00080000,0x00000000,}, /* 0x1a - DW_TAG_common_block */ { 0x00000000,0x00100000,0x00000000,}, /* 0x1b - DW_TAG_common_inclusion */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1c - DW_TAG_inheritance */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0xa1ed8836,0x00306ad3,0x000001f0,}, /* 0x1e - DW_TAG_module */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1f - DW_TAG_ptr_to_member_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x20 - DW_TAG_set_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x21 - DW_TAG_subrange_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x22 - DW_TAG_with_stmt */ { 0x00000000,0x00000000,0x00000000,}, /* 0x23 - DW_TAG_access_declaration */ { 0x00000000,0x00000000,0x00000000,}, /* 0x24 - DW_TAG_base_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x25 - DW_TAG_catch_block */ { 0x81ed8036,0x003062d3,0x00000080,}, /* 0x26 - DW_TAG_const_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x27 - DW_TAG_constant */ { 0x00000000,0x00000000,0x00000000,}, /* 0x28 - DW_TAG_enumerator */ { 0x00000000,0x00000000,0x00000000,}, /* 0x29 - DW_TAG_file_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2a - DW_TAG_friend */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2b - DW_TAG_namelist */ { 0x00000000,0x00001000,0x00000000,}, /* 0x2c - DW_TAG_namelist_item */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2d - DW_TAG_packed_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0xaded8d36,0x0433ead3,0x000001b0,}, /* 0x2f - DW_TAG_template_type_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x30 - DW_TAG_template_value_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x31 - DW_TAG_thrown_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x32 - DW_TAG_try_block */ { 0x00000000,0x00000000,0x00000000,}, /* 0x33 - DW_TAG_variant_part */ { 0x00000000,0x00000000,0x00000000,}, /* 0x34 - DW_TAG_variable */ { 0x00000000,0x00000000,0x00000000,}, /* 0x35 - DW_TAG_volatile_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x36 - DW_TAG_dwarf_procedure */ { 0x00000000,0x00000000,0x00000000,}, /* 0x37 - DW_TAG_restrict_type */ { 0x00018000,0x00202040,0x00000085,}, /* 0x38 - DW_TAG_interface_type */ { 0x00002000,0x00004000,0x00000000,}, /* 0x39 - DW_TAG_namespace */ { 0xe4ed8116,0x063068d3,0x000000f0,}, /* 0x3a - DW_TAG_imported_module */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3b - DW_TAG_unspecified_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3c - DW_TAG_partial_unit */ { 0xe4ed8116,0x00306ad3,0x000000f0,}, /* 0x3d - DW_TAG_imported_unit */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3e - DW_TAG_mutable_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3f - DW_TAG_condition */ { 0x00000000,0x00000082,0x00000000,}, /* 0x40 - DW_TAG_shared_type */ { 0x00018000,0x00a02040,0x00000085,}, /* 0x41 - DW_TAG_type_unit */ { 0xe4ed8116,0x06306ad3,0x000000f8,}, /* 0x42 - DW_TAG_rvalue_reference_type */ { 0x00018000,0x00a02040,0x00000081,}, /* 0x43 - DW_TAG_template_alias */ { 0x00000000,0x00018000,0x00000000,}, /* 0x44 - DW_TAG_coarray_type */ { 0x00000002,0x00000012,0x00000060,}, /* 0x45 - DW_TAG_generic_subrange */ { 0x00000000,0x00000000,0x00000000,}, /* 0x46 - DW_TAG_dynamic_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x47 - DW_TAG_atomic_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x48 - DW_TAG_call_site */ { 0x00000000,0x00000000,0x00000200,}, /* 0x49 - DW_TAG_call_site_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x4a - DW_TAG_skeleton_unit */ { 0x00880014,0x00000000,0x00000000,}, }; /* END FILE */ libdwarf-20210528/dwarfdump/print_static_vars.c0000664000175000017500000000704713764006205016402 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_varnames (an SGI extension) For a long time erroneously called .debug_static_vars bere. */ int print_static_vars(Dwarf_Debug dbg,Dwarf_Error *err) { Dwarf_Var *globbuf = NULL; Dwarf_Signed count = 0; int res = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s sanitname; glflags.current_section_id = DEBUG_STATIC_VARS; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_varnames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ dwarf_return_empty_pubnames(dbg,1,err); } res = dwarf_get_vars(dbg, &globbuf, &count, err); if (res == DW_DLV_ERROR) { esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); return res; } else if (res == DW_DLV_NO_ENTRY) { /* no static vars */ esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); return res; } else { int pres = 0; int printed = FALSE; if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); printed = TRUE; } pres = print_all_pubnames_style_records(dbg, "static-var", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, err); if (pres == DW_DLV_ERROR) { if (!printed){ printf("\n%s\n",esb_get_string(&sanitname)); } } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); dwarf_vars_dealloc(dbg, globbuf, count); return pres; } dwarf_return_empty_pubnames(dbg,0,err); esb_destructor(&sanitname); return DW_DLV_OK; } /* print_static_vars */ libdwarf-20210528/dwarfdump/command_options.c0000664000175000017500000027514514053210340016030 00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "dwconf.h" #include "dwgetopt.h" #include "common.h" #include "makename.h" #include "uri.h" #include "esb.h" /* For flexible string buffer. */ #include "sanitized.h" #include "tag_common.h" #include "section_bitmaps.h" #include "command_options.h" #include "compiler_info.h" static const char *remove_quotes_pair(const char *text); static char *special_program_name(char *n); static void suppress_check_dwarf(void); extern char *dwoptarg; /* These configure items are for the frame data. We're flexible in the path to dwarfdump.conf . The HOME strings here are transformed in dwconf.c to reference the environment variable $HOME . As of August 2018 CONFPREFIX is always set as it comes from autoconf --prefix, aka $prefix which defaults to /usr/local The install puts the .conf file in CONFPREFIX/dwarfdump/ */ static char *config_file_defaults[] = { "dwarfdump.conf", "./dwarfdump.conf", "HOME/.dwarfdump.conf", "HOME/dwarfdump.conf", #ifdef CONFPREFIX /* See Makefile.am dwarfdump_CFLAGS. This prefix is the --prefix option (defaults to /usr/local and Makefile.am adds /share/dwarfdump ) */ /* We need 2 levels of macro to get the name turned into the string we want. */ #define STR2(s) # s #define STR(s) STR2(s) STR(CONFPREFIX) "/dwarfdump.conf", #else /* This no longer used as of August 2018. */ "/usr/lib/dwarfdump.conf", #endif 0 }; static const char *config_file_abi = 0; /* Do printing of most sections. Do not do detailed checking. */ static void do_all(void) { glflags.gf_frame_flag = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* .debug_types */ glflags.gf_line_flag = TRUE; glflags.gf_no_follow_debuglink = FALSE; glflags.gf_global_debuglink_paths = 0; glflags.gf_global_debuglink_count = 0; glflags.gf_pubnames_flag = TRUE; glflags.gf_macinfo_flag = TRUE; glflags.gf_macro_flag = TRUE; glflags.gf_aranges_flag = TRUE; /* Do not do glflags.gf_loc_flag = TRUE glflags.gf_abbrev_flag = TRUE; glflags.gf_ranges_flag = TRUE; because nothing in the DWARF spec guarantees the sections are free of random bytes in areas not referenced by .debug_info. though for DWARF5 .debug_loclists is free of random bytes. See --print_raw_loclists */ glflags.gf_string_flag = TRUE; /* Do not do glflags.gf_reloc_flag = TRUE; as print_relocs makes no sense for non-elf dwarfdump users.*/ glflags.gf_static_func_flag = TRUE; /* SGI only*/ glflags.gf_static_var_flag = TRUE; /* SGI only*/ glflags.gf_pubtypes_flag = TRUE; /* both SGI typenames and dwarf_pubtypes. */ glflags.gf_weakname_flag = TRUE; /* SGI only*/ glflags.gf_gnu_debuglink_flag = FALSE; glflags.gf_debug_names_flag = TRUE; glflags.gf_debug_sup_flag = TRUE; } static int get_number_value(char *v_in,long int *v_out) { long int v= 0; size_t len = strlen(v_in); char *endptr = 0; if (len < 1) { return DW_DLV_ERROR; } v = strtol(v_in,&endptr,10); if (endptr == v_in) { return DW_DLV_NO_ENTRY; } if (*endptr != '\0') { return DW_DLV_ERROR; } *v_out = v; return DW_DLV_OK; } static void suppress_print_dwarf(void) { glflags.gf_do_print_dwarf = FALSE; glflags.gf_do_check_dwarf = TRUE; } /* Remove matching leading/trailing quotes. Does not alter the passed in string. If quotes removed does a makename on a modified string. */ static const char * remove_quotes_pair(const char *text) { static char single_quote = '\''; static char double_quote = '\"'; char quote = 0; const char *p = text; int len = strlen(text); if (len < 2) { return p; } /* Compare first character with ' or " */ if (p[0] == single_quote) { quote = single_quote; } else { if (p[0] == double_quote) { quote = double_quote; } else { return p; } } { if (p[len - 1] == quote) { char *altered = calloc(1,len+1); const char *str2 = 0; strcpy(altered,p+1); altered[len - 2] = '\0'; str2 = makename(altered); free(altered); return str2; } } return p; } /* By trimming a /dwarfdump.O down to /dwarfdump (keeping any prefix or suffix) we can avoid a sed command in regressiontests/DWARFTEST.sh and save 12 minutes run time of a regression test. The effect is, when nothing has changed in the normal output, that the program_name matches too. Because we don't want a different name of dwarfdump to cause a mismatch. */ static char * special_program_name(char *n) { char * mp = "/dwarfdump.O"; char * revstr = "/dwarfdump"; char *cp = n; size_t mslen = strlen(mp); for ( ; *cp; ++cp) { if (*cp == *mp) { if (!strncmp(cp,mp,mslen)){ esb_append(glflags.newprogname,revstr); cp += mslen-1; } else { esb_appendn(glflags.newprogname,cp,1); } } else { esb_appendn(glflags.newprogname,cp,1); } } return esb_get_string(glflags.newprogname); } static void suppress_check_dwarf(void) { glflags.gf_do_print_dwarf = TRUE; if (glflags.gf_do_check_dwarf) { printf("Warning: check flag turned off, " "checking and printing are separate.\n"); } glflags.gf_do_check_dwarf = FALSE; set_checks_off(); } static struct esb_s uri_esb_data; void uri_data_constructor(void) { esb_constructor(&uri_esb_data); } void uri_data_destructor(void) { esb_destructor(&uri_esb_data); } /* The strings whose pointers are returned here from makename are never destructed, but that is ok since there are only about 10 created at most. */ const char * do_uri_translation(const char *s,const char *context) { struct esb_s str; char *finalstr = 0; if (!glflags.gf_uri_options_translation) { return makename(s); } esb_constructor(&str); translate_from_uri(s,&str); if (glflags.gf_do_print_uri_in_input) { if (strcmp(s,esb_get_string(&str))) { printf("Uri Translation on option %s\n",context); printf(" \'%s\'\n",s); printf(" \'%s\'\n",esb_get_string(&str)); } } finalstr = makename(esb_get_string(&str)); esb_destructor(&str); return finalstr; } /* Support for short (-option) and long (--option) names options. These functions implement the individual options. They are called from short names and long names options. Implementation code is shared for both types of formats. */ /* Handlers for the short/long names options. */ static void arg_check_abbrev(void); static void arg_check_all(void); static void arg_check_aranges(void); static void arg_check_attr_dup(void); static void arg_check_attr_encodings(void); static void arg_check_attr_names(void); static void arg_check_constants(void); static void arg_check_files_lines(void); static void arg_check_forward_refs(void); static void arg_check_frame_basic(void); static void arg_check_frame_extended(void); static void arg_check_frame_info(void); static void arg_check_gaps(void); static void arg_check_loc(void); static void arg_check_macros(void); static void arg_check_pubnames(void); static void arg_check_ranges(void); static void arg_check_self_refs(void); static void arg_check_show(void); static void arg_check_silent(void); static void arg_check_summary(void); static void arg_check_tag_attr(void); static void arg_check_tag_tag(void); static void arg_check_type(void); static void arg_check_unique(void); #ifdef HAVE_USAGE_TAG_ATTR static void arg_check_usage(void); static void arg_check_usage_extended(void); #endif /* HAVE_USAGE_TAG_ATTR */ static void arg_elf(void); static void arg_elf_abbrev(void); static void arg_elf_aranges(void); static void arg_elf_default(void); static void arg_elf_fission(void); static void arg_elf_frames(void); static void arg_elf_header(void); static void arg_elf_info(void); static void arg_elf_line(void); static void arg_elf_loc(void); static void arg_elf_macinfo(void); static void arg_elf_pubnames(void); static void arg_elf_pubtypes(void); static void arg_elf_ranges(void); static void arg_elf_strings(void); static void arg_elf_text(void); static void arg_file_abi(void); static void arg_file_line5(void); static void arg_file_name(void); static void arg_file_output(void); static void arg_file_tied(void); static void arg_file_use_no_libelf(void); static void arg_format_attr_name(void); static void arg_format_dense(void); static void arg_format_ellipsis(void); static void arg_format_expr_ops_joined(void); static void arg_format_extensions(void); static void arg_format_global_offsets(void); static void arg_format_loc(void); static void arg_format_registers(void); static void arg_format_suppress_data(void); static void arg_format_suppress_group(void); static void arg_format_suppress_lookup(void); static void arg_format_suppress_offsets(void); static void arg_format_suppress_sanitize(void); static void arg_format_suppress_uri(void); static void arg_format_suppress_uri_msg(void); static void arg_format_file(void); static void arg_format_gcc(void); static void arg_format_groupnumber(void); static void arg_format_limit(void); static void arg_format_producer(void); static void arg_format_snc(void); static void arg_print_all(void); static void arg_print_abbrev(void); static void arg_print_aranges(void); static void arg_print_debug_frame(void); static void arg_print_debug_names(void); static void arg_print_gnu_debuglink(void); static void arg_print_debug_gnu(void); static void arg_print_debug_sup(void); static void arg_print_fission(void); static void arg_print_gnu_frame(void); static void arg_print_info(void); static void arg_print_lines(void); static void arg_print_lines_short(void); static void arg_print_loc(void); static void arg_print_macinfo(void); static void arg_print_pubnames(void); static void arg_print_producers(void); static void arg_print_ranges(void); static void arg_print_raw_loclists(void); static void arg_print_raw_rnglists(void); static void arg_print_static(void); static void arg_print_static_func(void); static void arg_print_static_var(void); static void arg_print_str_offsets(void); static void arg_print_strings(void); static void arg_print_types(void); static void arg_print_weaknames(void); static void arg_reloc(void); static void arg_reloc_abbrev(void); static void arg_reloc_aranges(void); static void arg_reloc_frames(void); static void arg_reloc_info(void); static void arg_reloc_line(void); static void arg_reloc_loc(void); static void arg_reloc_pubnames(void); static void arg_reloc_ranges(void); static void arg_no_follow_debuglink(void); static void arg_add_debuglink_path(void); static void arg_debuglink_path_invalid(void); static void arg_search_any(void); static void arg_search_any_count(void); static void arg_search_match(void); static void arg_search_match_count(void); #ifdef HAVE_REGEX static void arg_search_regex(void); static void arg_search_regex_count(void); #endif /* HAVE_REGEX */ static void arg_search_count(void); static void arg_search_invalid(void); static void arg_search_print_children(void); static void arg_search_print_parent(void); static void arg_search_print_tree(void); static void arg_help(void); static void arg_trace(void); static void arg_verbose(void); static void arg_version(void); static void arg_show_dwarfdump_conf(void); static void arg_c_multiple_selection(void); static void arg_E_multiple_selection(void); static void arg_h_multiple_selection(void); static void arg_l_multiple_selection(void); static void arg_k_multiple_selection(void); static void arg_kx_multiple_selection(void); #ifdef HAVE_USAGE_TAG_ATTR static void arg_ku_multiple_selection(void); #endif /* HAVE_USAGE_TAG_ATTR */ static void arg_o_multiple_selection(void); static void arg_O_multiple_selection(void); static void arg_S_multiple_selection(void); static void arg_t_multiple_selection(void); static void arg_W_multiple_selection(void); static void arg_x_multiple_selection(void); static void arg_not_supported(void); static void arg_x_invalid(void); /* Extracted from 'process_args', as they are used by option handlers. */ static Dwarf_Bool arg_usage_error = FALSE; static int arg_option = 0; static const char *usage_debug_text[] = { "Usage: DwarfDump ", "options:\t-0\tprint this information", "\t\t-1\tDump RangesInfo Table", "\t\t-2\tDump Location (.debug_loc) Info", "\t\t-3\tDump Ranges (.debug_ranges) Info", "\t\t-4\tDump Linkonce Table", "\t\t-5\tDump Visited Info", "" }; static const char *usage_long_text[] = { "Usage: DwarfDump ", " ", "-------------------------------------------------------------------", "Print Debug Sections", "-------------------------------------------------------------------", "-b --print-abbrev Print abbrev section", "-a --print-all Print all debug_* sections", "-r --print-aranges Print aranges section", "-F --print-eh-frame Print gnu .eh_frame section", "-I --print-fission Print fission sections:", " .gdb_index, .debug_cu_index,", " .debug_tu_index, .gnu.debuglink,", " .note.gnu.build-id", " --print-gnu-debuglink Print .gnu_debuglink,", " .note.gnu.build-id sections", " --print-debug-gnu Print .debug_gnu_pubtypes and", " .debug_gnu_pubnames sections", " --print-debug-names Print .debug_names section", " --print-debug-sup Print .debug_sup section", "-i --print-info Print info section", "-l --print-lines Print line section", "-ls --print-lines-short Print line section, but do not", " print address", "-c --print-loc Print loc section", "-m --print-macinfo Print DWARF5 style .debug_macro section", " and DWARF2,3,4 .debug_macinfo section.", "-P --print-producers Print list of compile units per producer", "-p --print-pubnames Print pubnames section", "-N --print-ranges Print ranges section", " --print-raw-rnglists Print entire .debug_rnglists section", " --print-raw-loclists Print entire .debug_loclists section", "-ta --print-static Print both static sections", "-tf --print-static-func Print static func section", "-tv --print-static-var Print static var section", "-s --print-strings Print string section", " --print-str-offsets Print the .debug_str_offsets section", "-y --print-type Print pubtypes section", "-w --print-weakname Print weakname section", " ", "-------------------------------------------------------------------", "Print Elf Relocation Data", "-------------------------------------------------------------------", #ifdef DWARF_WITH_LIBELF "-o --reloc Print relocation info [afiloprR]", "-oa --reloc-abbrev Print relocation .debug_abbrev section", "-or --reloc-aranges Print relocation .debug_aranges section", "-of --reloc-frames Print relocation .debug_frame section", "-oi --reloc-info Print relocation .debug_info section", "-ol --reloc-line Print relocation .debug_line section", "-oo --reloc-loc Print relocation .debug_loc section", "-op --reloc-pubnames Print relocation .debug_pubnames section", "-oR --reloc-ranges Print relocation .debug_ranges section", #else " libelf not present, use GNU readelf or readelfobj", " to see relocations", #endif /* DWARF_WITH_LIBELF */ " ", "-------------------------------------------------------------------", "Print Elf Section Headers", "-------------------------------------------------------------------", #ifdef DWARF_WITH_LIBELF "-E --elf Print object Header and/or section information", " Same as -E[adfhiIlmoprRstx]", "-Ea --elf-abbrev Print .debug_abbrev header", "-Er --elf-aranges Print .debug_aranges header", "-Ed --elf-default Same as -E and {liaprfoRstx}", "-EI --elf-fission Print fission headers,", " .gdb_index, .debug_cu_index, .debug_tu_index", "-Ef --elf-frames Print .debug_frame header", "-Eh --elf-header Print ELF header", "-Ei --elf-info Print .debug_info header", "-El --elf-line Print .debug_line header", "-Eo --elf-loc Print .debug_loc header", "-Em --elf-macinfo Print old macinfo and dwarf5 macro header", "-Ep --elf-pubnames Print .debug_pubnames header", "-Et --elf-pubtypes Print .debug_types header", "-ER --elf-ranges Print .debug_ranges header", "-Es --elf-strings Print .debug_string header", "-Ex --elf-text Print .text header", #else " libelf not present, use GNU readelf or readelfobj", " to see elf file details", #endif /* DWARF_WITH_LIBELF */ " ", "-------------------------------------------------------------------", "Check DWARF Integrity", "-------------------------------------------------------------------", "-kb --check-abbrev Check abbreviations", "-ka --check-all Do all checks", "-kM --check-aranges Check ranges list (.debug_aranges)", "-kD --check-attr-dup Check duplicated attributes", "-kE --check-attr-encodings Examine attributes encodings", "-kn --check-attr-names Examine names in attributes", "-kc --check-constants Examine DWARF constants", "-kF --check-files-lines Examine integrity of files-lines", " attributes", "-kR --check-forward-refs Check forward references to DIEs", " (declarations)", "-kx --check-frame-basic Basic frames check (.eh_frame,", " .debug_frame)", "-kxe --check-frame-extended Extensive frames check (.eh_frame,", " .debug_frame)", "-kf --check-frame-info Examine frame information (use with", " -f or -F)", "-kg --check-gaps Check debug info gaps", "-kl --check-loc Check location list (.debug_loc)", "-kw --check-macros Check macros", "-ke --check-pubnames Examine attributes of pubnames", "-km --check-ranges Check ranges list (.debug_ranges)", "-kS --check-self-refs Check self references to DIEs", "-kd --check-show Show check results", "-ks --check-silent Perform checks in silent mode", "-ki --check-summary Display summary for all compilers", "-kr --check-tag-attr Examine tag-attr relation", "-kt --check-tag-tag Examine tag-tag relations", " Unless -C option given certain common", " tag-attr and tag-tag extensions are", " assumed to be ok (not reported).", "-ky --check-type Examine type info", "-kG --check-unique Print only unique errors", #ifdef HAVE_USAGE_TAG_ATTR "-ku --check-usage Print tag-tree & tag-attr usage", " (basic format)", "-kuf --check-usage-extended Modifies -ku to add summary detail.", #endif /* HAVE_USAGE_TAG_ATTR */ " ", "-------------------------------------------------------------------", "Print Output Qualifiers", "-------------------------------------------------------------------", "-M --format-attr-name Print the form name for each", " attribute", "-d --format-dense One line per entry (info section)", "-e --format-ellipsis Short names for tags, attrs etc.", "-G --format-global-offsets Show global die offsets", "-g --format-loc (Was loclist support. Do not use.)", " --format-expr-ops-joined Print each group of DWARF DW_OPs", " on one line rather than one", " per line.", "-R --format-registers Print frame register names as", " r33 etc and allow up to 1200", " registers using a generic", " register set.", "-Q --format-suppress-data Suppress printing section data", "-x noprintsectiongroups", " --format-suppress-group Do not print section groups", "-n --format-suppress-lookup Suppress frame information function", " name lookup(when printing frame", " information from multi-gigabyte", " object files this", " option may save significant time).", "-D --format-suppress-offsets Do not show offsets", "-x nosanitizestrings", " --format-suppress-sanitize Arbitrary string characters", " come thru printf", "-U --format-suppress-uri Suppress uri-translate", "-q --format-suppress-uri-msg Suppress uri-did-translate", " notification", "-C --format-extensions Print (with -ki) warnings", " for some common DWARF extensions", " (by default extensions accepted", " as standard).", " ", "-------------------------------------------------------------------", "Print Output Limiters", "-------------------------------------------------------------------", "-u --format-file= Print only specified file (CU name)", "-cg --format-gcc Check only GCC compiler objects", "-x groupnumber= ", " --format-group-number= Groupnumber to print", "-H --format-limit= Limit output to the first ", " major units.", " Stop after compilation units", "-c --format-producer= Check only specific compiler", " objects is described by", " 'DW_AT_producer' -c'350.1' ", " check only compiler objects", " with 350.1 in the CU name", "-cs --format-snc Check only SNC compiler objects", " ", "-------------------------------------------------------------------", "File Specifications", "-------------------------------------------------------------------", "-x abi= --file-abi= Name abi in dwarfdump.conf", "-x name= --file-name= Name dwarfdump.conf", "-x line5= --file-line5= Table DWARF5 new interfaces", " where is:", " std, s2l, orig or orig2l", "-O file= --file-output= Name the output file", "-x tied= --file-tied= Name the Split Dwarf", " skeleton object file", " --file-use-no-libelf Use non-libelf to", " read objects", " (as much as possible)", " ", "-------------------------------------------------------------------", "GNU debuglink options", "-------------------------------------------------------------------", " --no-follow-debuglink Do not follow GNU debuglink, ", " just use the file directly so,", " debuglink global paths are ignored.", " --add-debuglink_path= Add the path to the list of", " global paths debuglink searches", "-------------------------------------------------------------------", "Search text in attributes", "-------------------------------------------------------------------", "-S any= --search-any= Search any ", "-Svany= --search-any-count= print number of", " occurrences", "-S match= --search-match= Search matching ", "-Svmatch= --search-match-count print number of", " occurrences", #ifdef HAVE_REGEX "-S regex= --search-regex= Use regular expression", " matching", "-Svregex= --search-regex-count print number of", " occurrences", #endif /* HAVE_REGEX */ " only one -S option allowed, any= and", " regex= only usable if the functions", " required are found at configure time", " ", "-Wc --search-print-children Print children tree", " (wide format) with -S", "-Wp --search-print-parent Print parent tree ", " (wide format) with -S", "-W --search-print-tree Print parent/children tree ", " (wide format) with -S", " ", "-------------------------------------------------------------------", "Help & Version", "-------------------------------------------------------------------", "-h --help Print this dwarfdump help message.", "-v --verbose Show more information.", "-vv --verbose-more Show even more information.", "-V --version Print version information.", " --show-dwarfdump-conf Show what dwarfdump.conf is being used", "", }; enum longopts_vals { OPT_BEGIN = 999, /* Check DWARF Integrity */ OPT_CHECK_ABBREV, /* -kb --check-abbrev */ OPT_CHECK_ALL, /* -ka --check-all */ OPT_CHECK_ARANGES, /* -kM --check-aranges */ OPT_CHECK_ATTR_DUP, /* -kD --check-attr-dup */ OPT_CHECK_ATTR_ENCODINGS, /* -kE --check-attr-encodings*/ OPT_CHECK_ATTR_NAMES, /* -kn --check-attr-names */ OPT_CHECK_CONSTANTS, /* -kc --check-constants */ OPT_CHECK_FILES_LINES, /* -kF --check-files-lines */ OPT_CHECK_FORWARD_REFS, /* -kR --check-forward-refs */ OPT_CHECK_FRAME_BASIC, /* -kx --check-frame-basic */ OPT_CHECK_FRAME_EXTENDED, /* -kxe --check-frame-extended*/ OPT_CHECK_FRAME_INFO, /* -kf --check-frame-info */ OPT_CHECK_GAPS, /* -kg --check-gaps */ OPT_CHECK_LOC, /* -kl --check-loc */ OPT_CHECK_MACROS, /* -kw --check-macros */ OPT_CHECK_PUBNAMES, /* -ke --check-pubnames */ OPT_CHECK_RANGES, /* -km --check-ranges */ OPT_CHECK_SELF_REFS, /* -kS --check-self-refs */ OPT_CHECK_SHOW, /* -kd --check-show */ OPT_CHECK_SILENT, /* -ks --check-silent */ OPT_CHECK_SUMMARY, /* -ki --check-summary */ OPT_CHECK_TAG_ATTR, /* -kr --check-tag-attr */ OPT_CHECK_TAG_TAG, /* -kt --check-tag-tag */ OPT_CHECK_TYPE, /* -ky --check-type */ OPT_CHECK_UNIQUE, /* -kG --check-unique */ #ifdef HAVE_USAGE_TAG_ATTR OPT_CHECK_USAGE, /* -ku --check-usage */ OPT_CHECK_USAGE_EXTENDED, /* -kuf --check-usage-extended*/ #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header */ OPT_ELF, /* -E --elf */ OPT_ELF_ABBREV, /* -Ea --elf-abbrev */ OPT_ELF_ARANGES, /* -Er --elf-aranges */ OPT_ELF_DEFAULT, /* -Ed --elf-default */ OPT_ELF_FISSION, /* -EI --elf-fission */ OPT_ELF_FRAMES, /* -Ef --elf-frames */ OPT_ELF_HEADER, /* -Eh --elf-header */ OPT_ELF_INFO, /* -Ei --elf-info */ OPT_ELF_LINE, /* -El --elf-line */ OPT_ELF_LOC, /* -Eo --elf-loc */ OPT_ELF_MACINFO, /* -Em --elf-macinfo */ OPT_ELF_PUBNAMES, /* -Ep --elf-pubnames */ OPT_ELF_PUBTYPES, /* -Et --elf-pubtypes */ OPT_ELF_RANGES, /* -ER --elf-ranges */ OPT_ELF_STRINGS, /* -Es --elf-strings */ OPT_ELF_TEXT, /* -Ex --elf-text */ /* File Specifications */ OPT_FILE_ABI, /* -x abi= --file-abi= */ OPT_FILE_LINE5, /* -x line5= --file-line5= */ OPT_FILE_NAME, /* -x name= --file-name= */ OPT_FILE_OUTPUT, /* -O file= --file-output= */ OPT_FILE_TIED, /* -x tied= --file-tied= */ OPT_FILE_USE_NO_LIBELF,/* --file-use-no-libelf= */ /* Print Output Qualifiers */ OPT_FORMAT_ATTR_NAME, /* -M --format-attr-name */ OPT_FORMAT_DENSE, /* -d --format-dense */ OPT_FORMAT_ELLIPSIS, /* -e --format-ellipsis */ OPT_FORMAT_EXPR_OPS_JOINED, /* --format-expr-ops-joined */ OPT_FORMAT_EXTENSIONS, /* -C --format-extensions */ OPT_FORMAT_GLOBAL_OFFSETS, /* -G --format-global-offsets */ OPT_FORMAT_LOC, /* -g --format-loc */ OPT_FORMAT_REGISTERS, /* -R --format-registers */ OPT_FORMAT_SUPPRESS_DATA, /* -Q --format-suppress-data */ OPT_FORMAT_SUPPRESS_GROUP , /* -x --format-suppress-group */ OPT_FORMAT_SUPPRESS_LOOKUP, /* -n --format-suppress-lookup */ OPT_FORMAT_SUPPRESS_OFFSETS, /* -D --format-suppress-offsets */ OPT_FORMAT_SUPPRESS_SANITIZE, /* -x no-sanitize-strings --format-suppress-sanitize */ OPT_FORMAT_SUPPRESS_URI, /* -U --format-suppress-uri */ OPT_FORMAT_SUPPRESS_URI_MSG, /* -q --format-suppress-uri-msg */ /* Print Output Limiters */ OPT_FORMAT_FILE, /* -u --format-file= */ OPT_FORMAT_GCC, /* -cg --format-gcc */ OPT_FORMAT_GROUP_NUMBER, /* -x --format-group-number=*/ OPT_FORMAT_LIMIT, /* -H --format-limit= */ OPT_FORMAT_PRODUCER, /* -c --format-producer= */ OPT_FORMAT_SNC, /* -cs --format-snc */ /* Print Debug Sections */ OPT_PRINT_ABBREV, /* -b --print-abbrev */ OPT_PRINT_ALL, /* -a --print-all */ OPT_PRINT_ARANGES, /* -r --print-aranges */ OPT_PRINT_DEBUG_NAMES, /* --print-debug-names */ OPT_PRINT_GNU_DEBUGLINK, /* --print-gnu-debuglink */ OPT_PRINT_DEBUG_GNU, /* --print-debug-gnu */ OPT_PRINT_DEBUG_SUP, /* --print-debug-sup */ OPT_PRINT_EH_FRAME, /* -F --print-eh-frame */ OPT_PRINT_FISSION, /* -I --print-fission */ OPT_PRINT_FRAME, /* -f --print-frame */ OPT_PRINT_INFO, /* -i --print-info */ OPT_PRINT_LINES, /* -l --print-lines */ OPT_PRINT_LINES_SHORT, /* -ls --print-lines-short */ OPT_PRINT_LOC, /* -c --print-loc */ OPT_PRINT_MACINFO, /* -m --print-macinfo */ OPT_PRINT_PRODUCERS, /* -P --print-producers */ OPT_PRINT_PUBNAMES, /* -p --print-pubnames */ OPT_PRINT_RANGES, /* -N --print-ranges */ OPT_PRINT_RAW_LOCLISTS, /* --print-raw-loclists */ OPT_PRINT_RAW_RNGLISTS, /* --print-raw-rnglists */ OPT_PRINT_STATIC, /* -ta --print-static */ OPT_PRINT_STATIC_FUNC, /* -tf --print-static-func */ OPT_PRINT_STATIC_VAR, /* -tv --print-static-var */ OPT_PRINT_STRINGS, /* -s --print-strings */ OPT_PRINT_STR_OFFSETS, /* --print-str-offsets */ OPT_PRINT_TYPE, /* -y --print-type */ OPT_PRINT_WEAKNAME, /* -w --print-weakname */ /* Print Relocations Info */ OPT_RELOC, /* -o --reloc */ OPT_RELOC_ABBREV, /* -oa --reloc-abbrev */ OPT_RELOC_ARANGES, /* -or --reloc-aranges */ OPT_RELOC_FRAMES, /* -of --reloc-frames */ OPT_RELOC_INFO, /* -oi --reloc-info */ OPT_RELOC_LINE, /* -ol --reloc-line */ OPT_RELOC_LOC, /* -oo --reloc-loc */ OPT_RELOC_PUBNAMES, /* -op --reloc-pubnames */ OPT_RELOC_RANGES, /* -oR --reloc-ranges */ /* debuglink options */ OPT_NO_FOLLOW_DEBUGLINK, /* --no-follow-debuglink */ OPT_ADD_DEBUGLINK_PATH, /* --add-debuglink-path= */ /* Search text in attributes */ OPT_SEARCH_ANY, /* -S any= --search-any= */ OPT_SEARCH_ANY_COUNT, /* -Svany= --search-any-count= */ OPT_SEARCH_MATCH, /* -S match= --search-match= */ OPT_SEARCH_MATCH_COUNT, /* -Svmatch= --search-match-count*/ OPT_SEARCH_PRINT_CHILDREN, /* -Wc --search-print-children */ OPT_SEARCH_PRINT_PARENT, /* -Wp --search-print-parent */ OPT_SEARCH_PRINT_TREE, /* -W --search-print-tree */ #ifdef HAVE_REGEX OPT_SEARCH_REGEX, /* -S regex= --search-regex= */ OPT_SEARCH_REGEX_COUNT, /* -Svregex= --search-regex-count*/ #endif /* HAVE_REGEX */ /* Help & Version */ OPT_HELP, /* -h --help */ OPT_VERBOSE, /* -v --verbose */ OPT_VERBOSE_MORE, /* -vv --verbose-more */ OPT_VERSION, /* -V --version */ OPT_SHOW_DWARFDUMP_CONF, /* --show-dwarfdump-conf */ /* Trace */ OPT_TRACE, /* -# --trace= */ /* allocation statistics */ OPT_ALLOC_PRINT_SUMS, /* --print-alloc-sums */ OPT_ALLOC_TREE_OFF, /* --suppress-de-alloc-tree */ OPT_END }; static struct dwoption longopts[] = { /* Check DWARF Integrity. */ {"check-abbrev", dwno_argument, 0, OPT_CHECK_ABBREV }, {"check-all", dwno_argument, 0, OPT_CHECK_ALL }, {"check-aranges", dwno_argument, 0, OPT_CHECK_ARANGES }, {"check-attr-dup", dwno_argument, 0, OPT_CHECK_ATTR_DUP }, {"check-attr-encodings", dwno_argument, 0, OPT_CHECK_ATTR_ENCODINGS}, {"check-attr-names", dwno_argument, 0, OPT_CHECK_ATTR_NAMES }, {"check-constants", dwno_argument, 0, OPT_CHECK_CONSTANTS }, {"check-files-lines", dwno_argument, 0, OPT_CHECK_FILES_LINES }, {"check-forward-refs", dwno_argument, 0, OPT_CHECK_FORWARD_REFS }, {"check-frame-basic", dwno_argument, 0, OPT_CHECK_FRAME_BASIC }, {"check-frame-extended", dwno_argument, 0, OPT_CHECK_FRAME_EXTENDED}, {"check-frame-info", dwno_argument, 0, OPT_CHECK_FRAME_INFO }, {"check-gaps", dwno_argument, 0, OPT_CHECK_GAPS }, {"check-loc", dwno_argument, 0, OPT_CHECK_LOC }, {"check-macros", dwno_argument, 0, OPT_CHECK_MACROS }, {"check-pubnames", dwno_argument, 0, OPT_CHECK_PUBNAMES }, {"check-ranges", dwno_argument, 0, OPT_CHECK_RANGES }, {"check-self-refs", dwno_argument, 0, OPT_CHECK_SELF_REFS }, {"check-show", dwno_argument, 0, OPT_CHECK_SHOW }, {"check-silent", dwno_argument, 0, OPT_CHECK_SILENT }, {"check-summary", dwno_argument, 0, OPT_CHECK_SUMMARY }, {"check-tag-attr", dwno_argument, 0, OPT_CHECK_TAG_ATTR }, {"check-tag-tag", dwno_argument, 0, OPT_CHECK_TAG_TAG }, {"check-type", dwno_argument, 0, OPT_CHECK_TYPE }, {"check-unique", dwno_argument, 0, OPT_CHECK_UNIQUE }, #ifdef HAVE_USAGE_TAG_ATTR {"check-usage", dwno_argument, 0, OPT_CHECK_USAGE }, {"check-usage-extended", dwno_argument, 0, OPT_CHECK_USAGE_EXTENDED}, #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header. */ {"elf", dwno_argument, 0, OPT_ELF }, {"elf-abbrev", dwno_argument, 0, OPT_ELF_ABBREV }, {"elf-aranges", dwno_argument, 0, OPT_ELF_ARANGES }, {"elf-default", dwno_argument, 0, OPT_ELF_DEFAULT }, {"elf-fission", dwno_argument, 0, OPT_ELF_FISSION }, {"elf-frames", dwno_argument, 0, OPT_ELF_FRAMES }, {"elf-header", dwno_argument, 0, OPT_ELF_HEADER }, {"elf-info", dwno_argument, 0, OPT_ELF_INFO }, {"elf-line", dwno_argument, 0, OPT_ELF_LINE }, {"elf-loc", dwno_argument, 0, OPT_ELF_LOC }, {"elf-macinfo", dwno_argument, 0, OPT_ELF_MACINFO }, {"elf-pubnames", dwno_argument, 0, OPT_ELF_PUBNAMES}, {"elf-pubtypes", dwno_argument, 0, OPT_ELF_PUBTYPES}, {"elf-ranges", dwno_argument, 0, OPT_ELF_RANGES }, {"elf-strings", dwno_argument, 0, OPT_ELF_STRINGS }, {"elf-text", dwno_argument, 0, OPT_ELF_TEXT }, /* File Specifications. */ {"file-abi", dwrequired_argument, 0, OPT_FILE_ABI }, {"file-line5", dwrequired_argument, 0, OPT_FILE_LINE5 }, {"file-name", dwrequired_argument, 0, OPT_FILE_NAME }, {"file-output", dwrequired_argument, 0, OPT_FILE_OUTPUT}, {"file-tied", dwrequired_argument, 0, OPT_FILE_TIED }, {"file-use-no-libelf", dwno_argument, 0, OPT_FILE_USE_NO_LIBELF }, /* Print Output Qualifiers. */ {"format-attr-name", dwno_argument, 0, OPT_FORMAT_ATTR_NAME }, {"format-dense", dwno_argument, 0, OPT_FORMAT_DENSE }, {"format-ellipsis", dwno_argument, 0, OPT_FORMAT_ELLIPSIS }, {"format-expr-ops-joined", dwno_argument, 0, OPT_FORMAT_EXPR_OPS_JOINED }, {"format-extensions", dwno_argument, 0, OPT_FORMAT_EXTENSIONS }, {"format-global-offsets", dwno_argument, 0, OPT_FORMAT_GLOBAL_OFFSETS }, {"format-loc", dwno_argument, 0, OPT_FORMAT_LOC }, {"format-registers", dwno_argument, 0, OPT_FORMAT_REGISTERS }, {"format-suppress-data", dwno_argument, 0, OPT_FORMAT_SUPPRESS_DATA }, {"format-suppress-group", dwno_argument, 0, OPT_FORMAT_SUPPRESS_GROUP }, {"format-suppress-lookup", dwno_argument, 0, OPT_FORMAT_SUPPRESS_LOOKUP }, {"format-suppress-offsets", dwno_argument, 0, OPT_FORMAT_SUPPRESS_OFFSETS }, {"format-suppress-sanitize", dwno_argument, 0, OPT_FORMAT_SUPPRESS_SANITIZE}, {"format-suppress-uri", dwno_argument, 0, OPT_FORMAT_SUPPRESS_URI }, {"format-suppress-uri-msg", dwno_argument, 0, OPT_FORMAT_SUPPRESS_URI_MSG }, /* Print Output Limiters. */ {"format-file", dwrequired_argument, 0, OPT_FORMAT_FILE }, {"format-gcc", dwno_argument, 0, OPT_FORMAT_GCC }, {"format-group-number", dwrequired_argument, 0, OPT_FORMAT_GROUP_NUMBER}, {"format-limit", dwrequired_argument, 0, OPT_FORMAT_LIMIT }, {"format-producer", dwrequired_argument, 0, OPT_FORMAT_PRODUCER}, {"format-snc", dwno_argument, 0, OPT_FORMAT_SNC }, /* Print Debug Sections. */ {"print-abbrev", dwno_argument, 0, OPT_PRINT_ABBREV }, {"print-all", dwno_argument, 0, OPT_PRINT_ALL }, {"print-aranges", dwno_argument, 0, OPT_PRINT_ARANGES }, {"print-debug-names", dwno_argument, 0, OPT_PRINT_DEBUG_NAMES}, {"print-gnu-debuglink", dwno_argument,0,OPT_PRINT_GNU_DEBUGLINK}, {"print-debug-gnu", dwno_argument, 0, OPT_PRINT_DEBUG_GNU }, {"print-debug-sup", dwno_argument, 0, OPT_PRINT_DEBUG_SUP }, {"print-eh-frame", dwno_argument, 0, OPT_PRINT_EH_FRAME }, {"print-fission", dwno_argument, 0, OPT_PRINT_FISSION }, {"print-frame", dwno_argument, 0, OPT_PRINT_FRAME }, {"print-info", dwno_argument, 0, OPT_PRINT_INFO }, {"print-lines", dwno_argument, 0, OPT_PRINT_LINES }, {"print-lines-short", dwno_argument, 0, OPT_PRINT_LINES_SHORT}, {"print-loc", dwno_argument, 0, OPT_PRINT_LOC }, {"print-macinfo", dwno_argument, 0, OPT_PRINT_MACINFO }, {"print-producers", dwno_argument, 0, OPT_PRINT_PRODUCERS }, {"print-pubnames", dwno_argument, 0, OPT_PRINT_PUBNAMES }, {"print-ranges", dwno_argument, 0, OPT_PRINT_RANGES }, {"print-raw-loclists",dwno_argument, 0, OPT_PRINT_RAW_LOCLISTS}, {"print-raw-rnglists",dwno_argument, 0, OPT_PRINT_RAW_RNGLISTS}, {"print-static", dwno_argument, 0, OPT_PRINT_STATIC }, {"print-static-func", dwno_argument, 0, OPT_PRINT_STATIC_FUNC}, {"print-static-var", dwno_argument, 0, OPT_PRINT_STATIC_VAR }, {"print-strings", dwno_argument, 0, OPT_PRINT_STRINGS }, {"print-str-offsets", dwno_argument, 0, OPT_PRINT_STR_OFFSETS}, {"print-type", dwno_argument, 0, OPT_PRINT_TYPE }, {"print-weakname", dwno_argument, 0, OPT_PRINT_WEAKNAME }, /* Print Relocations Info. */ {"reloc", dwno_argument, 0, OPT_RELOC }, {"reloc-abbrev", dwno_argument, 0, OPT_RELOC_ABBREV }, {"reloc-aranges", dwno_argument, 0, OPT_RELOC_ARANGES }, {"reloc-frames", dwno_argument, 0, OPT_RELOC_FRAMES }, {"reloc-info", dwno_argument, 0, OPT_RELOC_INFO }, {"reloc-line", dwno_argument, 0, OPT_RELOC_LINE }, {"reloc-loc", dwno_argument, 0, OPT_RELOC_LOC }, {"reloc-pubnames", dwno_argument, 0, OPT_RELOC_PUBNAMES}, {"reloc-ranges", dwno_argument, 0, OPT_RELOC_RANGES }, /* GNU debuglink options */ {"no-follow-debuglink", dwno_argument, 0,OPT_NO_FOLLOW_DEBUGLINK}, {"add-debuglink-path", dwrequired_argument, 0,OPT_ADD_DEBUGLINK_PATH}, /* Search text in attributes. */ {"search-any", dwrequired_argument, 0,OPT_SEARCH_ANY }, {"search-any-count", dwrequired_argument, 0, OPT_SEARCH_ANY_COUNT }, {"search-match", dwrequired_argument, 0, OPT_SEARCH_MATCH }, {"search-match-count", dwrequired_argument, 0, OPT_SEARCH_MATCH_COUNT }, {"search-print-children", dwno_argument, 0, OPT_SEARCH_PRINT_CHILDREN}, {"search-print-parent", dwno_argument, 0, OPT_SEARCH_PRINT_PARENT }, {"search-print-tree", dwno_argument, 0, OPT_SEARCH_PRINT_TREE }, #ifdef HAVE_REGEX {"search-regex", dwrequired_argument, 0, OPT_SEARCH_REGEX }, {"search-regex-count", dwrequired_argument, 0, OPT_SEARCH_REGEX_COUNT }, #endif /* HAVE_REGEX */ /* Help & Version. */ {"help", dwno_argument, 0, OPT_HELP }, {"verbose", dwno_argument, 0, OPT_VERBOSE }, {"verbose-more", dwno_argument, 0, OPT_VERBOSE_MORE }, {"version", dwno_argument, 0, OPT_VERSION }, {"show-dwarfdump-conf",dwno_argument, 0, OPT_SHOW_DWARFDUMP_CONF }, /* Trace. */ {"trace", dwrequired_argument, 0, OPT_TRACE}, /* alloc sums. */ {"print-alloc-sums", dwno_argument, 0, OPT_ALLOC_PRINT_SUMS}, {"suppress-de-alloc-tree",dwno_argument,0,OPT_ALLOC_TREE_OFF}, {0,0,0,0} }; /* Handlers for the command line options. */ /* Option '--print-debug-names' */ void arg_print_debug_names(void) { glflags.gf_debug_names_flag = TRUE; } /* Option '--print-gnu-debuglink' */ void arg_print_gnu_debuglink(void) { glflags.gf_gnu_debuglink_flag = TRUE; } /* Option '--print-debug-gnu' */ void arg_print_debug_gnu(void) { glflags.gf_debug_gnu_flag = TRUE; } /* Option '--print-debug-sup' */ void arg_print_debug_sup(void) { glflags.gf_debug_sup_flag = TRUE; } /* Option '--print-str-offsets' */ void arg_print_str_offsets(void) { glflags.gf_print_str_offsets = TRUE; } void arg_trace(void) { int nTraceLevel = atoi(dwoptarg); if (nTraceLevel >= 0 && nTraceLevel <= MAX_TRACE_LEVEL) { glflags.nTrace[nTraceLevel] = 1; } /* Display dwarfdump debug options. */ if (dump_options) { print_usage_message(glflags.program_name,usage_debug_text); exit(OKAY); } } /* Option '-a' */ void arg_print_all(void) { suppress_check_dwarf(); do_all(); } /* Option '-b' */ void arg_print_abbrev(void) { glflags.gf_abbrev_flag = TRUE; suppress_check_dwarf(); } /* Option '-c[...]' */ void arg_c_multiple_selection(void) { /* Specify compiler name. */ if (dwoptarg) { switch (dwoptarg[0]) { case 's': arg_format_snc(); break; case 'g': arg_format_gcc(); break; default: arg_format_producer(); break; } } else { arg_print_loc(); } } /* Option '-c' */ void arg_print_loc(void) { glflags.gf_loc_flag = TRUE; suppress_check_dwarf(); } /* Option '-cs' */ void arg_format_snc(void) { /* -cs : Check SNC compiler */ glflags.gf_check_snc_compiler = TRUE; glflags.gf_check_all_compilers = FALSE; } /* Option '-cg' */ void arg_format_gcc(void) { /* -cg : Check GCC compiler */ glflags.gf_check_gcc_compiler = TRUE; glflags.gf_check_all_compilers = FALSE; } /* Option '-c' */ void arg_format_producer(void) { /* Assume a compiler version to check, most likely a substring of a compiler name. */ if (!record_producer(dwoptarg)) { fprintf(stderr, "Compiler table max %d exceeded, " "limiting the tracked compilers to %d\n", COMPILER_TABLE_MAX,COMPILER_TABLE_MAX); } } /* Option '--format-expr-ops-joined' restoring pre- December 2020 expression block printing */ void arg_format_expr_ops_joined(void) { glflags.gf_expr_ops_joined = TRUE; } /* Option '-C' */ void arg_format_extensions(void) { glflags.gf_suppress_check_extensions_tables = TRUE; } /* Option '-d' */ void arg_format_dense(void) { glflags.gf_do_print_dwarf = TRUE; /* This is sort of useless unless printing, but harmless, so we do not insist we are printing with suppress_check_dwarf(). */ glflags.dense = TRUE; } /* Option '-D' */ void arg_format_suppress_offsets(void) { /* Do not emit offset in output */ glflags.gf_display_offsets = FALSE; } /* Option '-e' */ void arg_format_ellipsis(void) { suppress_check_dwarf(); glflags.ellipsis = TRUE; } /* Option '-E[...]' */ void arg_E_multiple_selection(void) { /* Object Header information (but maybe really print) */ /* Selected printing of section info */ if (dwoptarg) { switch (dwoptarg[0]) { case 'a': arg_elf_abbrev(); break; case 'd': arg_elf_default(); break; case 'f': arg_elf_frames(); break; case 'h': arg_elf_header(); break; case 'i': arg_elf_info(); break; case 'I': arg_elf_fission(); break; case 'l': arg_elf_line(); break; case 'm': arg_elf_macinfo(); break; case 'o': arg_elf_loc(); break; case 'p': arg_elf_pubnames(); break; case 'r': arg_elf_aranges(); break; case 'R': arg_elf_ranges(); break; case 's': arg_elf_strings(); break; case 't': arg_elf_pubtypes(); break; case 'x': arg_elf_text(); break; default: arg_usage_error = TRUE; break; } } else { arg_elf(); } } /* Option '-E' */ void arg_elf(void) { /* Display header and all sections info */ glflags.gf_header_flag = TRUE; set_all_sections_on(); } /* Option '-Ea' */ void arg_elf_abbrev(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_ABBREV); } /* Option '-Ed' */ void arg_elf_default(void) { /* case 'd', use the default section set */ glflags.gf_header_flag = TRUE; set_all_section_defaults(); } /* Option '-Ef' */ void arg_elf_frames(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_FRAME); } /* Option '-Eh' */ void arg_elf_header(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_HEADER); } /* Option '-Ei' */ void arg_elf_info(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_INFO); enable_section_map_entry(DW_HDR_DEBUG_TYPES); } /* Option '-EI' */ void arg_elf_fission(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_GDB_INDEX); enable_section_map_entry(DW_HDR_DEBUG_CU_INDEX); enable_section_map_entry(DW_HDR_DEBUG_TU_INDEX); enable_section_map_entry(DW_HDR_DEBUG_NAMES); } /* Option '-El' */ void arg_elf_line(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_LINE); } /* Option '-Em' */ void arg_elf_macinfo(void) { /* For both old macinfo and dwarf5 macro */ glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_MACINFO); } /* Option '-Eo' */ void arg_elf_loc(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_LOC); } /* Option '-Ep' */ void arg_elf_pubnames(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_PUBNAMES); } /* Option '-Er' */ void arg_elf_aranges(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_ARANGES); } /* Option '-ER' */ void arg_elf_ranges(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_RANGES); enable_section_map_entry(DW_HDR_DEBUG_RNGLISTS); } /* Option '-Es' */ void arg_elf_strings(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_STR); } /* Option '-Et' */ void arg_elf_pubtypes(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_PUBTYPES); } /* Option '-Ex' */ void arg_elf_text(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_TEXT); } /* Option '-f' */ void arg_print_debug_frame(void) { glflags.gf_frame_flag = TRUE; suppress_check_dwarf(); } /* Option '-F' */ void arg_print_gnu_frame(void) { glflags.gf_eh_frame_flag = TRUE; suppress_check_dwarf(); } /* Option '-g' */ void arg_format_loc(void) { /*info_flag = TRUE; removed from -g. Nov 2015 */ glflags.gf_use_old_dwarf_loclist = TRUE; suppress_check_dwarf(); } /* Option '-G' */ void arg_format_global_offsets(void) { glflags.gf_show_global_offsets = TRUE; } /* Option '-h' */ void arg_h_multiple_selection(void) { if (dwoptarg) { arg_usage_error = TRUE; } else { arg_help(); } } /* Option '-h' */ void arg_help(void) { print_usage_message(glflags.program_name,usage_long_text); exit(OKAY); } /* Option '-H' */ void arg_format_limit(void) { int break_val = atoi(dwoptarg); if (break_val > 0) { glflags.break_after_n_units = break_val; } } /* Option '-i' */ void arg_print_info(void) { glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; suppress_check_dwarf(); } /* Option '-I' */ void arg_print_fission(void) { glflags.gf_gdbindex_flag = TRUE; glflags.gf_gnu_debuglink_flag = TRUE; suppress_check_dwarf(); } /* Option '-k[...]' */ void arg_k_multiple_selection(void) { switch (dwoptarg[0]) { case 'a': arg_check_all(); break; case 'b': arg_check_abbrev(); break; case 'c': arg_check_constants(); break; case 'd': arg_check_show(); break; case 'D': arg_check_attr_dup(); break; case 'e': arg_check_pubnames(); break; case 'E': arg_check_attr_encodings(); break; case 'f': arg_check_frame_info(); break; case 'F': arg_check_files_lines(); break; case 'g': arg_check_gaps(); break; case 'G': arg_check_unique(); break; case 'i': arg_check_summary(); break; case 'l': arg_check_loc(); break; case 'm': arg_check_ranges(); break; case 'M': arg_check_aranges(); break; case 'n': arg_check_attr_names(); break; case 'r': arg_check_tag_attr(); break; case 'R': arg_check_forward_refs(); break; case 's': arg_check_silent(); break; case 'S': arg_check_self_refs(); break; case 't': arg_check_tag_tag(); break; #ifdef HAVE_USAGE_TAG_ATTR case 'u': arg_ku_multiple_selection(); break; #endif /* HAVE_USAGE_TAG_ATTR */ case 'w': arg_check_macros(); break; case 'x': arg_kx_multiple_selection(); break; case 'y': arg_check_type(); break; default: arg_usage_error = TRUE; break; } } /* Option '-ka' */ void arg_check_all(void) { suppress_print_dwarf(); glflags.gf_check_pubname_attr = TRUE; glflags.gf_check_tag_attr = TRUE; glflags.gf_check_tag_tree = TRUE; glflags.gf_check_type_offset = TRUE; glflags.gf_gnu_debuglink_flag = FALSE; glflags.gf_check_names = TRUE; glflags.gf_pubnames_flag = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_gdbindex_flag = TRUE; glflags.gf_check_decl_file = TRUE; glflags.gf_check_macros = TRUE; glflags.gf_check_frames = TRUE; glflags.gf_check_frames_extended = FALSE; glflags.gf_check_locations = TRUE; glflags.gf_frame_flag = TRUE; glflags.gf_eh_frame_flag = TRUE; glflags.gf_check_ranges = TRUE; glflags.gf_check_lines = TRUE; glflags.gf_check_fdes = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_aranges = TRUE; glflags.gf_aranges_flag = TRUE; /* Aranges section */ glflags.gf_check_abbreviations = TRUE; glflags.gf_check_dwarf_constants = TRUE; glflags.gf_check_di_gaps = TRUE; glflags.gf_check_forward_decl = TRUE; glflags.gf_check_self_references = TRUE; glflags.gf_check_attr_encoding = TRUE; glflags.gf_print_usage_tag_attr = TRUE; glflags.gf_check_duplicated_attributes = TRUE; } /* Option '-kb' --check-abbrev */ void arg_check_abbrev(void) { /* Abbreviations */ suppress_print_dwarf(); glflags.gf_check_abbreviations = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* For some checks is worth trying the plain .debug_abbrev section on its own. */ glflags.gf_abbrev_flag = TRUE; } /* Option '-kc' --check-constants */ void arg_check_constants(void) { /* DWARF constants */ suppress_print_dwarf(); glflags.gf_check_dwarf_constants = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kd' --check-show */ void arg_check_show(void) { /* Display check results */ suppress_print_dwarf(); glflags.gf_check_show_results = TRUE; } /* Option '-kD' --check-attr-dup */ void arg_check_attr_dup(void) { /* Check duplicated attributes */ suppress_print_dwarf(); glflags.gf_check_duplicated_attributes = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* For some checks is worth trying the plain .debug_abbrev section on its own. */ glflags.gf_abbrev_flag = TRUE; } /* Option '-ke' --check-pubnames */ void arg_check_pubnames(void) { suppress_print_dwarf(); glflags.gf_check_pubname_attr = TRUE; glflags.gf_pubnames_flag = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_fdes = TRUE; } /* Option '-kE' --check-attr-encodings */ void arg_check_attr_encodings(void) { /* Attributes encoding usage */ suppress_print_dwarf(); glflags.gf_check_attr_encoding = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kf' --check-frame-info */ void arg_check_frame_info(void) { suppress_print_dwarf(); glflags.gf_check_harmless = TRUE; glflags.gf_check_fdes = TRUE; } /* Option '-kF' --check-files-lines */ void arg_check_files_lines(void) { /* files-lines */ suppress_print_dwarf(); glflags.gf_check_decl_file = TRUE; glflags.gf_check_lines = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kg' */ void arg_check_gaps(void) { /* Check debug info gaps */ suppress_print_dwarf(); glflags.gf_check_di_gaps = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kG' */ void arg_check_unique(void) { /* Print just global (unique) errors */ suppress_print_dwarf(); glflags.gf_print_unique_errors = TRUE; } /* Option '-ki' */ void arg_check_summary(void) { /* Summary for each compiler */ suppress_print_dwarf(); glflags.gf_print_summary_all = TRUE; } /* Option '-kl' */ void arg_check_loc(void) { /* Locations list */ suppress_print_dwarf(); glflags.gf_check_locations = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_loc_flag = TRUE; } /* Option '-km' */ void arg_check_ranges(void) { /* Ranges */ suppress_print_dwarf(); glflags.gf_check_ranges = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kM' */ void arg_check_aranges(void) { /* Aranges */ suppress_print_dwarf(); glflags.gf_check_aranges = TRUE; glflags.gf_aranges_flag = TRUE; } /* Option '-kn' */ void arg_check_attr_names(void) { /* invalid names */ suppress_print_dwarf(); glflags.gf_check_names = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kr' */ void arg_check_tag_attr(void) { suppress_print_dwarf(); glflags.gf_check_tag_attr = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_check_harmless = TRUE; } /* Option '-kR' */ void arg_check_forward_refs(void) { /* forward declarations in DW_AT_specification */ suppress_print_dwarf(); glflags.gf_check_forward_decl = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-ks' */ void arg_check_silent(void) { /* Check verbose mode */ suppress_print_dwarf(); glflags.gf_check_verbose_mode = FALSE; } /* Option '-kS' */ void arg_check_self_refs(void) { /* self references in: DW_AT_specification, DW_AT_type, DW_AT_abstract_origin */ suppress_print_dwarf(); glflags.gf_check_self_references = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kt' */ void arg_check_tag_tag(void) { suppress_print_dwarf(); glflags.gf_check_tag_tree = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } #ifdef HAVE_USAGE_TAG_ATTR /* Option '-ku[...]' */ void arg_ku_multiple_selection(void) { /* Tag-Tree and Tag-Attr usage */ if (dwoptarg[1]) { switch (dwoptarg[1]) { case 'f': arg_check_usage_extended(); break; default: arg_usage_error = TRUE; break; } } else { arg_check_usage(); } } /* Option '-ku' --check-usage */ void arg_check_usage(void) { suppress_print_dwarf(); glflags.gf_print_usage_tag_attr = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kuf' --check-usage-extended, a modifier to -ku or -kr to add details to the summary report */ void arg_check_usage_extended(void) { arg_check_usage(); /* -kuf : Full report */ glflags.gf_print_usage_tag_attr_full = TRUE; } #endif /* HAVE_USAGE_TAG_ATTR */ /* Option '-kw' --check-macros */ void arg_check_macros(void) { suppress_print_dwarf(); glflags.gf_check_macros = TRUE; glflags.gf_macro_flag = TRUE; glflags.gf_macinfo_flag = TRUE; } /* Option '-kx[...]' */ void arg_kx_multiple_selection(void) { /* Frames check */ if (dwoptarg[1]) { switch (dwoptarg[1]) { case 'e': arg_check_frame_extended(); break; default: arg_usage_error = TRUE; break; } } else { arg_check_frame_basic(); } } /* Option '-kx' --check-frame-basic */ void arg_check_frame_basic(void) { suppress_print_dwarf(); glflags.gf_check_frames = TRUE; glflags.gf_frame_flag = TRUE; glflags.gf_eh_frame_flag = TRUE; } /* Option '-kxe' --check-frame-extended */ void arg_check_frame_extended(void) { arg_check_frame_basic(); /* -xe : Extended frames check */ glflags.gf_check_frames = FALSE; glflags.gf_check_frames_extended = TRUE; } /* Option '-ky' */ void arg_check_type(void) { suppress_print_dwarf(); glflags.gf_check_type_offset = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_decl_file = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_pubtypes_flag = TRUE; glflags.gf_check_ranges = TRUE; glflags.gf_check_aranges = TRUE; } /* Option '-l[...]' */ void arg_l_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 's': arg_print_lines_short(); break; default: arg_usage_error = TRUE; break; } } else { arg_print_lines(); } } /* Option '-l' */ void arg_print_lines(void) { /* Enable to suppress offsets printing */ glflags.gf_line_flag = TRUE; suppress_check_dwarf(); } /* Option '-ls' */ void arg_print_lines_short(void) { /* -ls : suppress addresses */ glflags.gf_line_print_pc = FALSE; arg_print_lines(); } /* Option '-m' */ void arg_print_macinfo(void) { glflags.gf_macinfo_flag = TRUE; /* DWARF2,3,4 */ glflags.gf_macro_flag = TRUE; /* DWARF5 */ suppress_check_dwarf(); } /* Option '-M' */ void arg_format_attr_name(void) { glflags.show_form_used = TRUE; } /* Option '-n' */ void arg_format_suppress_lookup(void) { glflags.gf_suppress_nested_name_search = TRUE; } /* Option '-N' */ void arg_print_ranges(void) { glflags.gf_ranges_flag = TRUE; suppress_check_dwarf(); } /* Option '--print-raw-rnglists' */ void arg_print_raw_rnglists(void) { glflags.gf_print_raw_rnglists = TRUE; suppress_check_dwarf(); } /* Option '--print-raw-loclists' */ void arg_print_raw_loclists(void) { glflags.gf_print_raw_loclists = TRUE; suppress_check_dwarf(); } /* Option '-o[...]' */ void arg_o_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 'a': arg_reloc_abbrev(); break; case 'i': arg_reloc_info(); break; case 'l': arg_reloc_line(); break; case 'p': arg_reloc_pubnames(); break; case 'r': arg_reloc_aranges(); break; case 'f': arg_reloc_frames(); break; case 'o': arg_reloc_loc(); break; case 'R': arg_reloc_ranges(); break; default: arg_usage_error = TRUE; break; } } else { arg_reloc(); } } /* Option '-o' */ void arg_reloc(void) { glflags.gf_reloc_flag = TRUE; set_all_reloc_sections_on(); } /* Option '-oa' */ void arg_reloc_abbrev(void) { /* Case a has no effect, no relocations can point out of the abbrev section. */ glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_ABBREV); } /* Option '-of' */ void arg_reloc_frames(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_FRAME); } /* Option '-oi' */ void arg_reloc_info(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_INFO); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_TYPES); } /* Option '-ol' */ void arg_reloc_line(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LINE); } /* Option '-oo' */ void arg_reloc_loc(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LOC); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LOCLISTS); } /* Option '-op' */ void arg_reloc_pubnames(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_PUBNAMES); } /* Option '-or' */ void arg_reloc_aranges(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_ARANGES); } /* Option '-oR' */ void arg_reloc_ranges(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_RANGES); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_RNGLISTS); } /* Option '-O' */ void arg_O_multiple_selection(void) { /* Output filename */ /* -O file= */ if (strncmp(dwoptarg,"file=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_output(); } else { arg_usage_error = TRUE; } } /* Option '-O file=' */ void arg_file_output(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-output=" : "-O file="; const char *path = do_uri_translation(dwoptarg,ctx); if (strlen(path) > 0) { glflags.output_file = path; } else { arg_usage_error = TRUE; } } /* Option '-p' */ void arg_print_pubnames(void) { glflags.gf_pubnames_flag = TRUE; suppress_check_dwarf(); } /* Option '-P' */ void arg_print_producers(void) { /* List of CUs per compiler */ glflags.gf_producer_children_flag = TRUE; } /* Option '-q' */ void arg_format_suppress_uri_msg(void) { /* Suppress uri-did-translate notification */ glflags.gf_do_print_uri_in_input = FALSE; } /* Option '-Q' */ void arg_format_suppress_data(void) { /* Q suppresses section data printing. */ glflags.gf_do_print_dwarf = FALSE; } /* Option '-r' */ void arg_print_aranges(void) { glflags.gf_aranges_flag = TRUE; suppress_check_dwarf(); } /* Option '-R' */ void arg_format_registers(void) { glflags.gf_generic_1200_regs = TRUE; } /* Option '-s' */ void arg_print_strings(void) { glflags.gf_string_flag = TRUE; suppress_check_dwarf(); } /* Option '-S' */ void arg_S_multiple_selection(void) { /* 'v' option, to print number of occurrences */ /* -S[v]match|any|regex=text*/ if (dwoptarg[0] == 'v') { ++dwoptarg; arg_search_count(); } if (strncmp(dwoptarg,"match=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_search_match(); } else if (strncmp(dwoptarg,"any=",4) == 0) { dwoptarg = &dwoptarg[4]; arg_search_any(); } #ifdef HAVE_REGEX else if (strncmp(dwoptarg,"regex=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_search_regex(); } #endif /* HAVE_REGEX */ else { arg_search_invalid(); } } /* Option --no-follow-debuglink */ void arg_no_follow_debuglink(void) { glflags.gf_no_follow_debuglink = TRUE; } static int insert_debuglink_path(char *p) { char ** newarray = 0; unsigned int curcount = glflags.gf_global_debuglink_count; unsigned newcount = curcount+1; unsigned u = 0; char * pstr = 0; newarray = (char **)malloc(newcount * sizeof(char *)); if (!newarray) { fprintf(stderr,"ERROR Unable to malloc space for" " debuglink paths. " " malloc %u pointers failed.\n",newcount); fprintf(stderr,"Global debuglink path ignored: %s\n", sanitized(p)); return DW_DLV_ERROR; } pstr = strdup(p); if (!pstr) { fprintf(stderr,"ERROR Unable to malloc space" " for debuglink path: " "count stays at %u\n",curcount); fprintf(stderr,"Global debuglink path ignored: %s\n", sanitized(p)); free(newarray); return DW_DLV_ERROR; } for ( u = 0; u < curcount; ++u) { newarray[u] = glflags.gf_global_debuglink_paths[u]; } newarray[curcount] = pstr; free(glflags.gf_global_debuglink_paths); glflags.gf_global_debuglink_paths = newarray; glflags.gf_global_debuglink_count = newcount; return DW_DLV_OK; } /* Option --add-debuglink-path= */ void arg_add_debuglink_path(void) { int res = 0; if (strncmp(dwoptarg,"add-debuglink-path=",21) == 0) { dwoptarg = &dwoptarg[21]; if (strlen(dwoptarg)) { /* dosomething debuglink FIXME */ res = insert_debuglink_path(dwoptarg); if (res == DW_DLV_OK) { return; } } } arg_debuglink_path_invalid(); } /* Option '-S any=' */ void arg_search_any(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-any=" : "-S any="; /* -S any= */ glflags.gf_search_is_on = TRUE; glflags.search_any_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_any_text); glflags.search_any_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_any_text) <= 0) { arg_search_invalid(); } } /* Option '-Sv any=' */ void arg_search_any_count(void) { arg_search_count(); arg_search_any(); } /* Option '-S match=' */ void arg_search_match(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-match=" : "-S match="; /* -S match= */ glflags.gf_search_is_on = TRUE; glflags.search_match_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_match_text); glflags.search_match_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_match_text) <= 0) { arg_search_invalid(); } } /* Option '-Sv match=' */ void arg_search_match_count(void) { arg_search_count(); arg_search_match(); } #ifdef HAVE_REGEX /* Option '-S regex=' */ void arg_search_regex(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-regex=" : "-S regex="; /* -S regex= */ glflags.gf_search_is_on = TRUE; glflags.search_regex_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_regex_text); glflags.search_regex_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_regex_text) > 0) { if (regcomp(glflags.search_re, glflags.search_regex_text, REG_EXTENDED)) { fprintf(stderr, "regcomp: unable to compile " " search regular expression %s\n", glflags.search_regex_text); } } else { arg_search_invalid(); } } /* Option '-Sv regex=' */ void arg_search_regex_count(void) { arg_search_count(); arg_search_regex(); } #endif /* HAVE_REGEX */ /* Option '-Sv' */ void arg_search_count(void) { glflags.gf_search_print_results = TRUE; } /* Option '-t' */ void arg_t_multiple_selection(void) { switch (dwoptarg[0]) { case 'a': arg_print_static(); break; case 'f': arg_print_static_func(); break; case 'v': arg_print_static_var(); break; default: arg_usage_error = TRUE; break; } } /* Option '-ta' */ void arg_print_static(void) { /* all */ glflags.gf_static_func_flag = TRUE; glflags.gf_static_var_flag = TRUE; suppress_check_dwarf(); } /* Option '-tf' */ void arg_print_static_func(void) { /* .debug_static_func */ glflags.gf_static_func_flag = TRUE; suppress_check_dwarf(); } /* Option '-tv' */ void arg_print_static_var(void) { /* .debug_static_var */ glflags.gf_static_var_flag = TRUE; suppress_check_dwarf(); } /* Option '-u' */ void arg_format_file(void) { const char *ctx = arg_option > OPT_BEGIN ? "--format-file=" : "-u"; /* compile unit */ const char *tstr = 0; glflags.gf_cu_name_flag = TRUE; tstr = do_uri_translation(dwoptarg,ctx); esb_append(glflags.cu_name,tstr); } /* Option '-U' */ void arg_format_suppress_uri(void) { glflags.gf_uri_options_translation = FALSE; } /* Option '-v' --verbose */ void arg_verbose(void) { glflags.verbose++; } /* Option '--show-dwarfdump-conf' */ void arg_show_dwarfdump_conf(void) { glflags.gf_show_dwarfdump_conf++; } /* Option '-V' */ void arg_version(void) { /* Display dwarfdump compilation date and time */ print_version_details(glflags.program_fullname,TRUE); exit(OKAY); } /* Option '-w' */ void arg_print_weaknames(void) { /* .debug_weaknames */ glflags.gf_weakname_flag = TRUE; suppress_check_dwarf(); } /* Option '-W[...]' */ void arg_W_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 'c': arg_search_print_children(); break; case 'p': arg_search_print_parent(); break; default: arg_usage_error = TRUE; break; } } else { arg_search_print_tree(); } } /* Option '-W' */ void arg_search_print_tree(void) { /* Search results in wide format */ glflags.gf_search_wide_format = TRUE; /* -W : Display parent and children tree */ glflags.gf_display_children_tree = TRUE; glflags.gf_display_parent_tree = TRUE; } /* Option '-Wc' */ void arg_search_print_children(void) { /* -Wc : Display children tree */ arg_search_print_tree(); glflags.gf_display_children_tree = TRUE; glflags.gf_display_parent_tree = FALSE; } /* Option '-Wp' */ void arg_search_print_parent(void) { /* -Wp : Display parent tree */ arg_search_print_tree(); glflags.gf_display_children_tree = FALSE; glflags.gf_display_parent_tree = TRUE; } /* Option '-x[...]' */ void arg_x_multiple_selection(void) { if (strncmp(dwoptarg,"name=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_name(); } else if (strncmp(dwoptarg,"abi=",4) == 0) { dwoptarg = &dwoptarg[4]; arg_file_abi(); } else if (strncmp(dwoptarg,"groupnumber=",12) == 0) { dwoptarg = &dwoptarg[12]; arg_format_groupnumber(); } else if (strncmp(dwoptarg,"tied=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_tied(); } else if (strncmp(dwoptarg,"line5=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_file_line5(); } else if (strcmp(dwoptarg,"nosanitizestrings") == 0) { arg_format_suppress_sanitize(); } else if (strcmp(dwoptarg,"noprintsectiongroups") == 0) { arg_format_suppress_group(); } else { arg_x_invalid(); } } /* Option '-x abi=' */ static void arg_file_abi(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-abi=" : "-x abi="; /* -x abi= meaning select abi from dwarfdump.conf file. Must always select abi to use dwarfdump.conf */ const char *abi = do_uri_translation(dwoptarg,ctx); if (strlen(abi) > 0) { config_file_abi = abi; } else { arg_x_invalid(); } } /* Option '-x groupnumber=' */ static void arg_format_groupnumber(void) { /* By default prints the lowest groupnumber in the object. Default is -x groupnumber=0 For group 1 (standard base dwarfdata) -x groupnumber=1 For group 1 (DWARF5 .dwo sections and dwp data) -x groupnumber=2 */ long int gnum = 0; int res = get_number_value(dwoptarg,&gnum); if (res == DW_DLV_OK) { glflags.group_number = gnum; } else { arg_x_invalid(); } } /* Option '-x line5=' */ static void arg_file_line5(void) { if (!strcmp(dwoptarg,"std")) { glflags.gf_line_flag_selection = singledw5; } else if (!strcmp(dwoptarg,"s2l")) { glflags.gf_line_flag_selection= s2l; } else if (!strcmp(dwoptarg,"orig")) { glflags.gf_line_flag_selection= orig; } else if (!strcmp(dwoptarg,"orig2l")) { glflags.gf_line_flag_selection= orig2l; } else { arg_x_invalid(); } } /* Option '-x name=' */ static void arg_file_name(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-name=" : "-x name="; /* -x name= meaning name dwarfdump.conf file. */ const char *path = do_uri_translation(dwoptarg,ctx); if (strlen(path) > 0) { esb_empty_string(glflags.config_file_path); esb_append(glflags.config_file_path,path); } else { arg_x_invalid(); } } /* Option '-x noprintsectiongroups' */ static void arg_format_suppress_group(void) { glflags.gf_section_groups_flag = FALSE; } /* Option '-x nosanitizestrings' '--format-suppress-sanitize' */ static void arg_format_suppress_sanitize(void) { glflags.gf_no_sanitize_strings = TRUE; } /* Option '-x tied=' */ static void arg_file_tied(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-tied=" : "-x tied="; const char *tiedpath = do_uri_translation(dwoptarg,ctx); if (strlen(tiedpath) > 0) { esb_empty_string(glflags.config_file_tiedpath); esb_append(glflags.config_file_tiedpath,tiedpath); } else { arg_x_invalid(); } } /* Option '--file-use-no-libelf' */ static void arg_file_use_no_libelf(void) { glflags.gf_file_use_no_libelf = TRUE; } /* -y */ static void arg_print_types(void) { /* .debug_pubtypes */ /* Also for SGI-only, and obsolete, .debug_typenames */ suppress_check_dwarf(); glflags.gf_pubtypes_flag = TRUE; } /* Option not supported */ static void arg_not_supported(void) { fprintf(stderr, "-%c is no longer supported:ignored\n", arg_option); } /* Error message for --add-debuglink-path=path */ static void arg_debuglink_path_invalid(void) { fprintf(stderr, "--add-debuglink-path=\n"); fprintf(stderr, "is allowed, not %s\n",dwoptarg); arg_usage_error = TRUE; } /* Error message for invalid '-S' option. */ static void arg_search_invalid(void) { fprintf(stderr, "-S any= or -S match= or" " -S regex=\n"); fprintf(stderr, "is allowed, not -S %s\n",dwoptarg); arg_usage_error = TRUE; } /* Error message for invalid '-x' option. */ static void arg_x_invalid(void) { fprintf(stderr, "-x name= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x abi= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x tied= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x line5={std,s2l,orig,orig2l} \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x nosanitizestrings \n"); fprintf(stderr, "are legal, not -x %s\n", dwoptarg); arg_usage_error = TRUE; } /* Process the command line arguments and set the appropriate options. All the options are within the global flags structure. */ static void set_command_options(int argc, char *argv[]) { int longindex = 0; /* j unused */ while ((arg_option = dwgetopt_long(argc, argv, "#:abc::CdDeE::fFgGhH:iIk:l::mMnNo::O:pPqQrRsS:t:" "u:UvVwW::x:yz", longopts,&longindex)) != EOF) { switch (arg_option) { case '#': arg_trace(); break; case 'a': arg_print_all(); break; case 'b': arg_print_abbrev(); break; case 'c': arg_c_multiple_selection(); break; case 'C': arg_format_extensions(); break; case 'd': arg_format_dense(); break; case 'D': arg_format_suppress_offsets(); break; case 'e': arg_format_ellipsis(); break; case 'E': arg_E_multiple_selection(); break; case 'f': arg_print_debug_frame(); break; case 'F': arg_print_gnu_frame(); break; case 'g': arg_format_loc(); break; case 'G': arg_format_global_offsets(); break; case 'h': arg_h_multiple_selection(); break; case 'H': arg_format_limit(); break; case 'i': arg_print_info(); break; case 'I': arg_print_fission(); break; case 'k': arg_k_multiple_selection(); break; case 'l': arg_l_multiple_selection(); break; case 'm': arg_print_macinfo(); break; case 'M': arg_format_attr_name(); break; case 'n': arg_format_suppress_lookup(); break; case 'N': arg_print_ranges(); break; case 'o': arg_o_multiple_selection(); break; case 'O': arg_O_multiple_selection(); break; case 'p': arg_print_pubnames(); break; case 'P': arg_print_producers(); break; case 'q': arg_format_suppress_uri_msg(); break; case 'Q': arg_format_suppress_data(); break; case 'r': arg_print_aranges(); break; case 'R': arg_format_registers(); break; case 's': arg_print_strings(); break; case 'S': arg_S_multiple_selection(); break; case 't': arg_t_multiple_selection(); break; case 'u': arg_format_file(); break; case 'U': arg_format_suppress_uri(); break; case 'v': arg_verbose(); break; case 'V': arg_version(); break; case 'w': arg_print_weaknames(); break; case 'W': arg_W_multiple_selection(); break; case 'x': arg_x_multiple_selection(); break; case 'y': arg_print_types(); break; case 'z': arg_not_supported(); break; /* Check DWARF Integrity. */ case OPT_CHECK_ABBREV: arg_check_abbrev(); break; case OPT_CHECK_ALL: arg_check_all(); break; case OPT_CHECK_ARANGES: arg_check_aranges(); break; case OPT_CHECK_ATTR_DUP: arg_check_attr_dup(); break; case OPT_CHECK_ATTR_ENCODINGS: arg_check_attr_encodings(); break; case OPT_CHECK_ATTR_NAMES: arg_check_attr_names();break; case OPT_CHECK_CONSTANTS: arg_check_constants(); break; case OPT_CHECK_FILES_LINES: arg_check_files_lines(); break; case OPT_CHECK_FORWARD_REFS: arg_check_forward_refs(); break; case OPT_CHECK_FRAME_BASIC: arg_check_frame_basic(); break; case OPT_CHECK_FRAME_EXTENDED: arg_check_frame_extended(); break; case OPT_CHECK_FRAME_INFO: arg_check_frame_info();break; case OPT_CHECK_GAPS: arg_check_gaps(); break; case OPT_CHECK_LOC: arg_check_loc(); break; case OPT_CHECK_MACROS: arg_check_macros(); break; case OPT_CHECK_PUBNAMES: arg_check_pubnames(); break; case OPT_CHECK_RANGES: arg_check_ranges(); break; case OPT_CHECK_SELF_REFS: arg_check_self_refs();break; case OPT_CHECK_SHOW: arg_check_show(); break; case OPT_CHECK_SILENT: arg_check_silent(); break; case OPT_CHECK_SUMMARY: arg_check_summary(); break; case OPT_CHECK_TAG_ATTR: arg_check_tag_attr(); break; case OPT_CHECK_TAG_TAG: arg_check_tag_tag(); break; case OPT_CHECK_TYPE: arg_check_type(); break; case OPT_CHECK_UNIQUE: arg_check_unique(); break; #ifdef HAVE_USAGE_TAG_ATTR case OPT_CHECK_USAGE: arg_check_usage();break; case OPT_CHECK_USAGE_EXTENDED: arg_check_usage_extended(); break; #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header. */ case OPT_ELF: arg_elf(); break; case OPT_ELF_ABBREV: arg_elf_abbrev(); break; case OPT_ELF_ARANGES: arg_elf_aranges(); break; case OPT_ELF_DEFAULT: arg_elf_default(); break; case OPT_ELF_FISSION: arg_elf_fission(); break; case OPT_ELF_FRAMES: arg_elf_frames(); break; case OPT_ELF_HEADER: arg_elf_header(); break; case OPT_ELF_INFO: arg_elf_info(); break; case OPT_ELF_LINE: arg_elf_line(); break; case OPT_ELF_LOC: arg_elf_loc(); break; case OPT_ELF_MACINFO: arg_elf_macinfo(); break; case OPT_ELF_PUBNAMES: arg_elf_pubnames(); break; case OPT_ELF_PUBTYPES: arg_elf_pubtypes(); break; case OPT_ELF_RANGES: arg_elf_ranges(); break; case OPT_ELF_STRINGS: arg_elf_strings(); break; case OPT_ELF_TEXT: arg_elf_text(); break; /* File Specifications. */ case OPT_FILE_ABI: arg_file_abi(); break; case OPT_FILE_LINE5: arg_file_line5(); break; case OPT_FILE_NAME: arg_file_name(); break; case OPT_FILE_OUTPUT: arg_file_output(); break; case OPT_FILE_TIED: arg_file_tied(); break; case OPT_FILE_USE_NO_LIBELF: arg_file_use_no_libelf(); break; /* Print Output Qualifiers. */ case OPT_FORMAT_ATTR_NAME: arg_format_attr_name(); break; case OPT_FORMAT_DENSE: arg_format_dense(); break; case OPT_FORMAT_ELLIPSIS: arg_format_ellipsis(); break; case OPT_FORMAT_EXPR_OPS_JOINED: arg_format_expr_ops_joined(); break; case OPT_FORMAT_EXTENSIONS: arg_format_extensions(); break; case OPT_FORMAT_GLOBAL_OFFSETS: arg_format_global_offsets(); break; case OPT_FORMAT_LOC: arg_format_loc(); break; case OPT_FORMAT_REGISTERS: arg_format_registers(); break; case OPT_FORMAT_SUPPRESS_DATA: arg_format_suppress_data(); break; case OPT_FORMAT_SUPPRESS_GROUP: arg_format_suppress_group(); break; case OPT_FORMAT_SUPPRESS_OFFSETS: arg_format_suppress_offsets(); break; case OPT_FORMAT_SUPPRESS_LOOKUP: arg_format_suppress_lookup(); break; case OPT_FORMAT_SUPPRESS_SANITIZE: arg_format_suppress_sanitize();break; case OPT_FORMAT_SUPPRESS_URI: arg_format_suppress_uri(); break; case OPT_FORMAT_SUPPRESS_URI_MSG: arg_format_suppress_uri_msg(); break; /* Print Output Limiters. */ case OPT_FORMAT_FILE: arg_format_file(); break; case OPT_FORMAT_GCC: arg_format_gcc(); break; case OPT_FORMAT_GROUP_NUMBER: arg_format_groupnumber(); break; case OPT_FORMAT_LIMIT: arg_format_limit(); break; case OPT_FORMAT_PRODUCER: arg_format_producer(); break; case OPT_FORMAT_SNC: arg_format_snc(); break; /* Print Debug Sections. */ case OPT_PRINT_ABBREV: arg_print_abbrev(); break; case OPT_PRINT_ALL: arg_print_all(); break; case OPT_PRINT_ARANGES: arg_print_aranges(); break; case OPT_PRINT_DEBUG_NAMES: arg_print_debug_names(); break; case OPT_PRINT_GNU_DEBUGLINK: arg_print_gnu_debuglink(); break; case OPT_PRINT_DEBUG_GNU: arg_print_debug_gnu(); break; case OPT_PRINT_DEBUG_SUP: arg_print_debug_sup(); break; case OPT_PRINT_EH_FRAME: arg_print_gnu_frame(); break; case OPT_PRINT_FISSION: arg_print_fission(); break; case OPT_PRINT_FRAME: arg_print_debug_frame(); break; case OPT_PRINT_INFO: arg_print_info(); break; case OPT_PRINT_LINES: arg_print_lines(); break; case OPT_PRINT_LINES_SHORT: arg_print_lines_short(); break; case OPT_PRINT_LOC: arg_print_loc(); break; case OPT_PRINT_MACINFO: arg_print_macinfo(); break; case OPT_PRINT_PRODUCERS: arg_print_producers(); break; case OPT_PRINT_PUBNAMES: arg_print_pubnames(); break; case OPT_PRINT_RANGES: arg_print_ranges(); break; case OPT_PRINT_RAW_LOCLISTS:arg_print_raw_loclists();break; case OPT_PRINT_RAW_RNGLISTS:arg_print_raw_rnglists();break; case OPT_PRINT_STATIC: arg_print_static(); break; case OPT_PRINT_STATIC_FUNC: arg_print_static_func(); break; case OPT_PRINT_STATIC_VAR: arg_print_static_var(); break; case OPT_PRINT_STRINGS: arg_print_strings(); break; case OPT_PRINT_STR_OFFSETS: arg_print_str_offsets(); break; case OPT_PRINT_TYPE: arg_print_types(); break; case OPT_PRINT_WEAKNAME: arg_print_weaknames(); break; /* Print Relocations Info (only with libelf). */ case OPT_RELOC: arg_reloc(); break; case OPT_RELOC_ABBREV: arg_reloc_abbrev(); break; case OPT_RELOC_ARANGES: arg_reloc_aranges(); break; case OPT_RELOC_FRAMES: arg_reloc_frames(); break; case OPT_RELOC_INFO: arg_reloc_info(); break; case OPT_RELOC_LINE: arg_reloc_line(); break; case OPT_RELOC_LOC: arg_reloc_loc(); break; case OPT_RELOC_PUBNAMES: arg_reloc_pubnames(); break; case OPT_RELOC_RANGES: arg_reloc_ranges(); break; /* debuglink attributes */ case OPT_NO_FOLLOW_DEBUGLINK: arg_no_follow_debuglink();break; case OPT_ADD_DEBUGLINK_PATH: arg_add_debuglink_path(); break; /* Search text in attributes. */ case OPT_SEARCH_ANY: arg_search_any(); break; case OPT_SEARCH_ANY_COUNT: arg_search_any_count(); break; case OPT_SEARCH_MATCH: arg_search_match(); break; case OPT_SEARCH_MATCH_COUNT: arg_search_match_count(); break; case OPT_SEARCH_PRINT_CHILDREN: arg_search_print_children(); break; case OPT_SEARCH_PRINT_PARENT: arg_search_print_parent(); break; case OPT_SEARCH_PRINT_TREE: arg_search_print_tree();break; #ifdef HAVE_REGEX case OPT_SEARCH_REGEX: arg_search_regex();break; case OPT_SEARCH_REGEX_COUNT: arg_search_regex_count(); break; #endif /* HAVE_REGEX */ /* Help & Version. */ case OPT_HELP: arg_help(); break; case OPT_VERBOSE: arg_verbose(); break; case OPT_VERBOSE_MORE: arg_verbose(); break; case OPT_VERSION: arg_version(); break; case OPT_SHOW_DWARFDUMP_CONF: arg_show_dwarfdump_conf();break; /* Trace. */ case OPT_TRACE: arg_trace(); break; case OPT_ALLOC_PRINT_SUMS: glflags.gf_print_alloc_sums = TRUE; break; case OPT_ALLOC_TREE_OFF: /* Suppress nearly all libdwarf de_alloc_tree record keeping. */ dwarf_set_de_alloc_flag(FALSE); break; default: arg_usage_error = TRUE; break; } } } /* This is a hack allowing us to pretend that dwarfdump --print-alloc-sums --suppress-de-alloc-tree foo.o has no arguments. Because the args here really are special for use by dwarfdump developers and even with these special args we want do_all() to be called by process_args() below if there are no 'normal' - or -- args. And of course -v --verbose are special too. So regression testing can behave identically with or without the specials. Function new March 6, 2020 */ static const char *simplestdargs[] ={ "-v", "-vv", "-vvv", "-vvvv", "-vvvvv", "-vvvvvv", "--verbose", "--show-dwarfdump-conf", "--verbose-more", "--print-alloc-sums", "--suppress-de-alloc-tree", 0 }; static int lacking_normal_args (int argct,char **args) { char * curarg = 0; int i = 0; for ( i = 0; i < argct ; ++i) { int k = 0; int simple = FALSE; curarg = args[i]; if (curarg[0] != '-') { /* Standard case. */ return TRUE; } for (k = 0; simplestdargs[k]; ++k) { if (!strcmp(curarg,simplestdargs[k])) { simple = TRUE; break; } } if (simple) { continue; } /* Not one of the specials, a normal argument, so we have some 'real' args. */ return FALSE; } /* Never found any non-simple argument, let regular arg processing deal with it. */ return TRUE; } /* process arguments and return object filename */ const char * process_args(int argc, char *argv[]) { glflags.program_name = special_program_name(argv[0]); glflags.program_fullname = argv[0]; suppress_check_dwarf(); if (argv[1] && lacking_normal_args(argc-1,argv+1)) { /* The default setting of what to print or do */ do_all(); } glflags.gf_section_groups_flag = TRUE; /* Process the arguments and set the appropriate options. */ set_command_options(argc, argv); if (config_file_abi && glflags.gf_generic_1200_regs) { printf("Specifying both -R and -x abi= is not " "allowed. Use one " "or the other. -x abi= ignored.\n"); config_file_abi = 0; } { /* even with no abi we look as there may be a dwarfdump option there we know about. */ int res = 0; res = find_conf_file_and_read_config( esb_get_string(glflags.config_file_path), config_file_abi, config_file_defaults, glflags.config_file_data); if (res == FOUND_ERROR) { if (!glflags.gf_do_print_dwarf && !glflags.gf_do_check_dwarf) { printf("Frame not configured due to " "configure error(s).\n"); printf("(Since no print or check options provided " "dwarfdump may now silently exit)\n"); } else { printf("Frame not configured due to " "configure error(s), " "using generic 100 registers.\n" "Frame section access suppressed.\n"); glflags.gf_eh_frame_flag = FALSE; glflags.gf_frame_flag = FALSE; } } else if (res == FOUND_DONE || res == FOUND_OPTION) { if (glflags.gf_generic_1200_regs) { init_generic_config_1200_regs( glflags.config_file_data); } } else { /* FOUND_ABI_START nothing to do. */ } } if (arg_usage_error ) { printf("%s option error.\n",glflags.program_name); printf("To see the options list: %s -h\n", glflags.program_name); exit(FAILED); } if (dwoptind < (argc - 1)) { printf("Multiple apparent object file names " "provided to %s\n",glflags.program_name); printf("Only a single object name is allowed\n"); printf("To see the options list: %s -h\n", glflags.program_name); exit(FAILED); } if (dwoptind > (argc - 1)) { printf("No object file name provided to %s\n", glflags.program_name); printf("To see the options list: %s -h\n", glflags.program_name); exit(FAILED); } /* FIXME: it seems silly to be printing section names where the section does not exist in the object file. However we continue the long-standard practice of printing such by default in most cases. For now. */ if (glflags.group_number == DW_GROUPNUMBER_DWO) { /* For split-dwarf/DWO some sections make no sense. This prevents printing of meaningless headers where no data can exist. */ glflags.gf_pubnames_flag = FALSE; glflags.gf_eh_frame_flag = FALSE; glflags.gf_frame_flag = FALSE; glflags.gf_macinfo_flag = FALSE; glflags.gf_aranges_flag = FALSE; glflags.gf_ranges_flag = FALSE; glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_weakname_flag = FALSE; } if (glflags.group_number > DW_GROUPNUMBER_BASE) { /* These no longer apply, no one uses. */ glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_weakname_flag = FALSE; glflags.gf_pubnames_flag = FALSE; } if (glflags.gf_do_check_dwarf) { /* Reduce verbosity when checking (checking means checking-only). */ glflags.verbose = 1; } return do_uri_translation(argv[dwoptind],"file-to-process"); } libdwarf-20210528/dwarfdump/GPL.txt0000664000175000017500000004310313644370703013660 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. libdwarf-20210528/dwarfdump/print_abbrevs.c0000664000175000017500000007251414012575576015516 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "naming.h" #include "sanitized.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #define TRUE 1 #define FALSE 0 /* The following relevent for one specific Linker. */ #define SNLINKER_MAX_ATTRIB_COUNT 16 /* a warning limit which is arbitrary but leaves a bit more flexibility. */ #define GENERAL_MAX_ATTRIB_COUNT 32 /* Print data in .debug_abbrev This is inherently unsafe as it assumes there are no byte sequences in .debug_abbrev other than legal abbrev sequences. But the Dwarf spec does not promise that. The spec only promises that any bytes at an offset referred to from .debug_info are legal sequences. */ struct abbrev_entry_s { Dwarf_Unsigned ae_number; Dwarf_Unsigned ae_offset; Dwarf_Unsigned ae_attr; Dwarf_Unsigned ae_form; Dwarf_Unsigned ae_impl_const; unsigned ae_dupcount; }; static int ab_compare(const void *lin, const void *rin) { const struct abbrev_entry_s *l = (const struct abbrev_entry_s *)lin; const struct abbrev_entry_s *r = (const struct abbrev_entry_s *)rin; if (l->ae_attr < r->ae_attr) { return -1; } if (l->ae_attr > r->ae_attr) { return 1; } if (l->ae_form < r->ae_form) { return -1; } if (l->ae_form > r->ae_form) { return 1; } if (l->ae_number < r->ae_number) { return -1; } if (l->ae_number > r->ae_number) { return 1; } return 0; } static int attr_unknown(Dwarf_Unsigned attr) { const char *n = 0; int res = 0; if (!attr) { return TRUE; } if (attr <= DW_AT_loclists_base) { return FALSE; } if (attr > DW_AT_hi_user) { return TRUE; } res = dwarf_get_AT_name(attr,&n); if (res == DW_DLV_NO_ENTRY) { return TRUE; } return FALSE; } static int is_valid_form_we_know(Dwarf_Unsigned form) { int res = 0; const char *n = 0; res = dwarf_get_FORM_name(form,&n); if (res == DW_DLV_NO_ENTRY) { return FALSE; } return TRUE; } static void printdupab(struct abbrev_entry_s * lastaep) { struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Attribute " "0x%" DW_PR_XZEROS DW_PR_DUx , lastaep->ae_attr); esb_append_printf_s(&msg, " (%s)", get_AT_name(lastaep->ae_attr, dwarf_names_print_on_error)); esb_append_printf_u(&msg, " %u times", lastaep->ae_dupcount); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx ".", lastaep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&msg), "Duplicated attribute in abbrevs "); esb_destructor(&msg); } static int print_one_abbrev_for_cu(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned abbrev_num_in, Dwarf_Unsigned *length_out, Dwarf_Unsigned *abbrev_num_out, Dwarf_Error * error) { const char *tagname = ""; struct abbrev_entry_s *entryarray =0; unsigned entryarray_size = 0; Dwarf_Unsigned abbrev_entry_count = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Half tag = 0; Dwarf_Unsigned length = 0; int acres = 0; Dwarf_Abbrev ab = 0; int tres = 0; Dwarf_Unsigned abbrev_num = abbrev_num_in; Dwarf_Signed child_flag = 0; int abres = 0; Dwarf_Unsigned i = 0; abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, error); if (abres == DW_DLV_ERROR) { return abres; } if (abres == DW_DLV_NO_ENTRY) { return abres; } /* Here offset is the global offset in .debug_abbrev. The abbrev_num is a relatively worthless counter of all abbreviations. */ tres = dwarf_get_abbrev_tag(ab, &tag, error); if (tres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error_and_continue(dbg, "Error reading abbreviation Tag", tres, *error); return tres; } tres = dwarf_get_abbrev_code(ab, &abbrev_code, error); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error_and_continue(dbg, "Error reading abbreviation code", tres, *error); return tres; } if (!tag) { /* This means we are done with this abbrev set, abbrev for entire CU. */ tagname = "Abbrev 0: null abbrev entry"; } else { tagname = get_TAG_name(tag,dwarf_names_print_on_error); } if ( glflags.gf_do_print_dwarf) { if (glflags.dense) { printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx ">", abbrev_num, offset,abbrev_code); if (glflags.verbose) { printf("", length); } printf(" %s", tagname); } else { printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx ">", abbrev_num, offset, abbrev_code); if (glflags.verbose) { printf("", length); } printf(" %-27s", tagname); } } /* Process specific TAGs specially. */ tag_specific_globals_setup(dbg,tag,0); ++abbrev_num; acres = dwarf_get_abbrev_children_flag(ab, &child_flag, error); if (acres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error_and_continue(dbg, "Error reading abbreviation children flag", acres, *error); return acres; } if (acres == DW_DLV_NO_ENTRY) { child_flag = 0; } /* If tag is zero, it is a null byte, not a real abbreviation, so there is no 'children' flag to print. */ if (tag && glflags.gf_do_print_dwarf) { const char * child_name = 0; child_name = get_children_name(child_flag, dwarf_names_print_on_error); printf(" %s", child_name); } if (!glflags.dense) { if ( glflags.gf_do_print_dwarf) { printf("\n"); } } if (abbrev_entry_count < 1) { if (tag && glflags.gf_do_print_dwarf) { printf(" This abbreviation code has no entries\n"); } if (length == 0 || length == 1 ) { if ( glflags.gf_do_print_dwarf && glflags.dense ) { printf("\n"); } *length_out = length; *abbrev_num_out = abbrev_num; /* printed null abrev name above */ dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); return DW_DLV_OK; } } /* Abbrev contains the format of a die, which debug_info then points to with the real data. So here we just print the given format. */ entryarray_size = abbrev_entry_count; entryarray = calloc(entryarray_size, sizeof(struct abbrev_entry_s)); if (!entryarray) { printf( "%s ERROR: Malloc of %u abbrev_entry_s" " structs failed. Near section global offset 0x%" DW_PR_DUx " .\n", glflags.program_name,entryarray_size,offset); entryarray_size = 0; } for (i = 0; i < abbrev_entry_count ; i++) { int aeres = 0; Dwarf_Bool dofilter = FALSE; Dwarf_Unsigned form = 0; struct abbrev_entry_s *aep = entryarray+i; Dwarf_Unsigned attr = 0; Dwarf_Signed impl_const = 0; Dwarf_Off off = 0; aeres = dwarf_get_abbrev_entry_b(ab, i, dofilter,&attr, &form,&impl_const, &off, error); if (aeres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); free(entryarray); print_error_and_continue(dbg, "Error reading abbreviation entry", aeres, *error); return aeres; } aep->ae_number = i; aep->ae_attr = attr; aep->ae_form = form; aep->ae_offset = off; aep->ae_impl_const = impl_const; if (glflags.gf_do_print_dwarf) { char buf [80]; struct esb_s m; buf[0] = 0; esb_constructor_fixed(&m,buf,sizeof(buf)); if (form == DW_FORM_implicit_const) { esb_append_printf_i(&m, " <%d",impl_const); esb_append_printf_u(&m, " (0x%x)>", impl_const); } if (glflags.dense) { printf(" <%ld>%s<%s>%s", (unsigned long) off, get_AT_name(attr,dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error), esb_get_string(&m)); } else if (!esb_string_len(&m)) { printf(" <0x%08lx> %-28s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } else { printf(" <0x%08lx>" " %-28s%-20s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error), esb_get_string(&m)); } esb_destructor(&m); } } if (glflags.gf_check_abbreviations && entryarray_size > 0) { unsigned l = 0; struct abbrev_entry_s *lastaep = 0; DWARF_CHECK_COUNT(abbreviations_result,1); qsort((void *)entryarray,entryarray_size, sizeof(struct abbrev_entry_s),ab_compare); for (l = 0; l < entryarray_size ; ++l) { struct abbrev_entry_s *aep = entryarray+l; if (attr_unknown(aep->ae_attr) ) { struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Attribute " "0x%" DW_PR_XZEROS DW_PR_DUx , aep->ae_attr); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx "." , aep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, "Attr number unknown", esb_get_string(&msg)); esb_destructor(&msg); } if (!is_valid_form_we_know(aep->ae_form)){ struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Form " "0x%" DW_PR_XZEROS DW_PR_DUx, aep->ae_form); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx ".", aep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, "Form number unknown", esb_get_string(&msg)); esb_destructor(&msg); } if (l == 0) { lastaep = aep; } else if (lastaep->ae_attr == aep->ae_attr) { lastaep->ae_dupcount++; } else { if (lastaep->ae_dupcount) { printdupab(lastaep); } lastaep = aep; } } if (lastaep->ae_dupcount) { printdupab(lastaep); } } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); free(entryarray); entryarray = 0; entryarray_size = 0; *length_out = length; *abbrev_num_out = abbrev_num; if (glflags.gf_do_print_dwarf && glflags.dense) { printf("\n"); } return DW_DLV_OK; } int print_all_abbrevs_for_cu(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned abbrev_num_in, Dwarf_Unsigned *length_out, Dwarf_Unsigned *abbrev_num_out, Dwarf_Error *error) { Dwarf_Unsigned total_len = 0; int pres = 0; Dwarf_Unsigned loopcount = 0; /* We have always printed the abbrev_num starting with 1. Unclear why. */ Dwarf_Unsigned abbrev_num = abbrev_num_in; Dwarf_Unsigned abbrev_num_ret = abbrev_num_in; for ( ; ;++loopcount ) { Dwarf_Unsigned local_len = 0; abbrev_num = abbrev_num_ret; pres = print_one_abbrev_for_cu(dbg,offset, abbrev_num, &local_len,&abbrev_num_ret,error); if (pres == DW_DLV_ERROR) { return pres; } if (pres == DW_DLV_NO_ENTRY) { if (loopcount) { /* This is an incomplete final entry, the trailing NUL byte for a CU abbrev set is missing as of end of section. */ printf("ERROR: The final .debug_abbrev " "abbreviation ends without its required " "final NUL byte. A harmless error at " "section offset 0x%" DW_PR_XZEROS DW_PR_DUx ".",offset); glflags.gf_count_major_errors++; return pres; } return pres; } total_len += local_len; if (local_len == 1) { /* last of a CU data printed */ *abbrev_num_out = abbrev_num_ret; *length_out = total_len; return DW_DLV_OK; } offset += local_len; } *abbrev_num_out = abbrev_num_ret; *length_out = total_len; return DW_DLV_OK; } int print_abbrevs(Dwarf_Debug dbg,Dwarf_Error* paerr) { Dwarf_Abbrev ab = 0; Dwarf_Unsigned offset = 0; int abres = 0; int tres = 0; unsigned loopct = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned unused_entry_count = 0; Dwarf_Unsigned abbrev_num = 1; Dwarf_Unsigned abbrev_num_ret = 1; glflags.current_section_id = DEBUG_ABBREV; /* Doing this just to print the section name */ abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &unused_entry_count, paerr); { /* Do this after a dwarf_get_abbrev() so the section is loaded and uncompressed if necessary. We get information printed about the compression (if any) this way. */ print_secname(dbg,".debug_abbrev"); } if (abres == DW_DLV_OK) { /* discard what we got. */ dwarf_dealloc(dbg,ab, DW_DLA_ABBREV); ab = 0; } else if (abres == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*paerr); *paerr = 0; } for (loopct = 0; ; ++loopct) { tres = print_all_abbrevs_for_cu(dbg,offset, abbrev_num,&length,&abbrev_num_ret,paerr); if (tres == DW_DLV_NO_ENTRY) { if (loopct > 0) { return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } if (tres == DW_DLV_ERROR) { return tres; } offset = offset+length; abbrev_num = abbrev_num_ret; } } /* Abbreviations array info for checking abbrev tags. The [zero] entry is not used. We never shrink the array, but it never grows beyond the largest abbreviation count of all the CUs. It is set up when we start a new CU and used to validate abbreviations on each DIE in the CU. See print_die.c */ static Dwarf_Unsigned *abbrev_array = NULL; /* Size of the array, the same as the abbrev tag count of the CU with the most of them. Be careful as abbrev_array[abbrev_array_size] is outside the high bound. */ static Dwarf_Unsigned abbrev_array_size = 0; #define ABBREV_ARRAY_INITIAL_SIZE 64 void destruct_abbrev_array(void) { free(abbrev_array); abbrev_array = 0; abbrev_array_size = 0; } /* Normally abbreviation numbers are allocated in sequence from 1 and increase by 1 but in case of a compiler bug or a damaged object file one can see strange things. This looks for surprises and reports them. Returns the abbrev_code unless the value looks very wrong, and then it returns zero as we do not want a gigantic abbrev code to cause trouble. */ static Dwarf_Unsigned check_abbrev_num_sequence(Dwarf_Unsigned abbrev_code, Dwarf_Unsigned last_abbrev_code, UNUSEDARG Dwarf_Unsigned l_abbrev_array_size, UNUSEDARG Dwarf_Unsigned ev_entry_count, UNUSEDARG Dwarf_Unsigned total_abbrevs_counted) { char buf[128]; DWARF_CHECK_COUNT(abbreviations_result,1); if (abbrev_code > last_abbrev_code) { if ((abbrev_code-last_abbrev_code) > 100 ) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, " skips up by %" DW_PR_DUu, (abbrev_code-last_abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code! " "Not checking reuse."); esb_destructor(&ar); return 0; } else if ((abbrev_code-last_abbrev_code) > 1 ) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " skips up by %" DW_PR_DUu, (abbrev_code-last_abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); } } else if (abbrev_code < last_abbrev_code) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, " skips down by %" DW_PR_DUu, (last_abbrev_code - abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); } else { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu " unchanged from last abbrev code!.", abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); } return abbrev_code; } static void check_reused_code(Dwarf_Unsigned abbrev_code, Dwarf_Unsigned abbrev_entry_count) { char buf[128]; if (abbrev_code >= abbrev_array_size) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " entry_count unchecked: %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); return; } if (abbrev_array[abbrev_code]) { DWARF_CHECK_COUNT(abbreviations_result,1); /* This abbrev code slot was used before. */ if (abbrev_array[abbrev_code] == abbrev_entry_count) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " reused for same entry_count: %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); } else { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " reused for different entry_count. " " %" DW_PR_DUu , abbrev_array[abbrev_code]); esb_append_printf_u(&ar, " now %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Invalid abbreviation code."); esb_destructor(&ar); } } } /* Calculate the number of abbreviations for the current CU and set up basic abbreviations array info, storing the number of attributes per abbreviation */ void get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset_in) { Dwarf_Unsigned offset = offset_in; if (glflags.gf_check_abbreviations) { Dwarf_Unsigned length = 0; Dwarf_Unsigned last_abbrev_code = 0; Dwarf_Bool bMore = TRUE; Dwarf_Unsigned CU_abbrev_count = 0; if (abbrev_array == NULL) { /* Allocate initial abbreviation array info */ abbrev_array_size = ABBREV_ARRAY_INITIAL_SIZE; abbrev_array = (Dwarf_Unsigned *) calloc(abbrev_array_size,sizeof(Dwarf_Unsigned)); } else { /* Clear out values from previous CU */ memset((void *)abbrev_array,0, (abbrev_array_size) * sizeof(Dwarf_Unsigned)); } while (bMore) { Dwarf_Abbrev ab = 0; int abres = DW_DLV_OK; Dwarf_Unsigned abbrev_entry_count = 0; Dwarf_Unsigned abbrev_code; Dwarf_Error aberr = 0; abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, &aberr); if (abres == DW_DLV_ERROR) { destruct_abbrev_array(); print_error_and_continue(dbg, "Error reading abbreviations", abres, aberr); dwarf_dealloc(dbg,aberr,DW_DLA_ERROR); bMore = FALSE; break; } if (abres == DW_DLV_NO_ENTRY) { destruct_abbrev_array(); bMore = FALSE; break; } /* Will not error unless ab is NULL! */ dwarf_get_abbrev_code(ab,&abbrev_code,&aberr); if (abbrev_code == 0) { /* End of abbreviation table for this CU */ ++offset; /* Skip abbreviation code */ bMore = FALSE; } else { /* Valid abbreviation code. We hope. */ Dwarf_Unsigned abhigh = check_abbrev_num_sequence( abbrev_code, last_abbrev_code, abbrev_array_size,abbrev_entry_count, CU_abbrev_count); if (abhigh >= abbrev_array_size) { /* It is a new high, but is not outrageous. */ while (abbrev_code >= abbrev_array_size) { Dwarf_Unsigned old_size = abbrev_array_size; size_t addl_size_bytes = old_size * sizeof(Dwarf_Unsigned); /* Resize abbreviation array. Only a bogus abbreviation number will iterate more than once. The abhigh check. prevents a runaway. */ abbrev_array_size *= 2; abbrev_array = (Dwarf_Unsigned *) realloc(abbrev_array, abbrev_array_size * sizeof(Dwarf_Unsigned)); /* Zero out the new bytes. */ memset(abbrev_array + old_size,0, addl_size_bytes); } last_abbrev_code = abbrev_code; check_reused_code(abbrev_code, abbrev_entry_count); abbrev_array[abbrev_code] = abbrev_entry_count; } else { /* Zero is the case of 'too high' abbrev_code. */ if (abhigh > 0) { /* More or less normal abbrev_code. */ last_abbrev_code = abbrev_code; check_reused_code(abbrev_code, abbrev_entry_count); abbrev_array[abbrev_code] = abbrev_entry_count; } } ++CU_abbrev_count; offset += length; } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); ab = 0; } } } /* Validate an abbreviation for the current CU. In case of bogus abbrev input the CU_abbrev_count might not be as large as abbrev_array_size says the array is. This should catch that case. This just checks and reports errors. */ void validate_abbrev_code(UNUSEDARG Dwarf_Debug dbg, Dwarf_Unsigned abbrev_code) { char buf[128]; DWARF_CHECK_COUNT(abbreviations_result,1); if (abbrev_code && abbrev_code >= abbrev_array_size) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " outside valid range of [0-%" DW_PR_DUu "]", abbrev_array_size); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Invalid abbreviation code."); esb_destructor(&ar); } else { Dwarf_Unsigned abbrev_entry_count = abbrev_array[abbrev_code]; if (abbrev_entry_count > SNLINKER_MAX_ATTRIB_COUNT) { if (abbrev_entry_count > GENERAL_MAX_ATTRIB_COUNT) { struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, ", with %" DW_PR_DUu " attributes: ", abbrev_entry_count); esb_append_printf_i(&ar, "outside a sanity-check maximum of %d.", GENERAL_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Number of attributes exceeds sanity check"); esb_destructor(&ar); } else { /* These apply only to one compiliation environment, and are not generally applicable. */ struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, ", with %" DW_PR_DUu " attributes: ", abbrev_entry_count); esb_append_printf_i(&ar, "outside an SN-LINKER expected-maximum of %d.", SNLINKER_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Number of attributes exceeds " "SN-LINKER-specific sanity check."); esb_destructor(&ar); } } } } libdwarf-20210528/dwarfdump/opscounttab.h0000664000175000017500000000052514003122722015172 00000000000000/* Copyright (c) 2020, David Anderson All rights reserved. This software file is hereby placed in the public domain. For use by anyone for any purpose. */ /* opscounttab.h */ struct dwarf_opscounttab_s { signed char oc_opcount; }; #define DWOPS_ARRAY_SIZE 256 extern struct dwarf_opscounttab_s dwarf_opscounttab[DWOPS_ARRAY_SIZE]; libdwarf-20210528/dwarfdump/print_types.c0000664000175000017500000001017213764006205015215 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_typenames or debug_pubtypes. */ int print_types(Dwarf_Debug dbg, enum type_type_e type_type, Dwarf_Error *err) { Dwarf_Type *globbuf = 0; Dwarf_Signed count = 0; char *name = 0; int gtres = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s sanitname; int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, Dwarf_Error *) = 0; void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) = NULL; const char *linetitle = 0; /* We will, now only list either section when there is content. */ if (type_type == DWARF_PUBTYPES) { name = ".debug_pubtypes"; get_types = dwarf_get_pubtypes; dealloctype = dwarf_pubtypes_dealloc; linetitle = "pubtype"; } else { /* SGI_TYPENAME */ /* No need to get the real section name, this section not used in modern compilers. */ name = ".debug_typenames"; get_types = dwarf_get_types; dealloctype = dwarf_types_dealloc; linetitle = "type"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,name, &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused, there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { dwarf_return_empty_pubnames(dbg,1,err); } gtres = get_types(dbg, &globbuf, &count, err); if (gtres == DW_DLV_ERROR) { printf("\n%s\n",esb_get_string(&sanitname)); esb_destructor(&sanitname); return gtres; } else if (gtres == DW_DLV_NO_ENTRY) { /* no types */ esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); return gtres; } else { int wkres = 0; int printed = FALSE; if (glflags.gf_do_print_dwarf && count > 0) { printf("\n%s\n",esb_get_string(&sanitname)); printed = TRUE; } wkres = print_all_pubnames_style_records(dbg, linetitle, esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, err); dealloctype(dbg, globbuf, count); if (wkres == DW_DLV_ERROR) { if (!printed) { printf("\n%s\n",esb_get_string(&sanitname)); } dwarf_return_empty_pubnames(dbg,0,err); esb_destructor(&sanitname); return wkres; } } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); return DW_DLV_OK; } /* print_types() */ libdwarf-20210528/dwarfdump/tag_tree.list0000644000175000017500000003151513743575426015177 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-tree. 0xffffffff is a "punctuation." The final line of this file must be 0xffffffff. The next line after each 0xffffffff (except the final line) stands for "parent-tag." The lines after this line before the next 0xffffffff are the tags that can be children of the "parent-tag." For example, 0xffffffff DW_TAG_array_type DW_TAG_subrange_type DW_TAG_enumeration_type 0xffffffff means "only DW_TAG_subrange_type and DW_TAG_enumeration_type can be children of DW_TAG_array_type. Since DWARF is generally descriptive, not prescriptive, this list is at best a current understanding of appropriate practice. Moreover the the dwarf standard does not actually list the tag-tag dependencies. So mistakes in the list below is certainly possible. Corrections and small-ish sample object files with unusual or interesting tag tree layouts are welcome. Any sample object files should not be proprietary as we may wish to include the object files in the regression test base. This file is applied to the preprocessor, thus any C comment and preprocessor control line is available. */ 0xffffffff DW_TAG_access_declaration 0xffffffff DW_TAG_array_type DW_TAG_subrange_type DW_TAG_dynamic_type DW_TAG_generic_subrange DW_TAG_enumeration_type 0xffffffff DW_TAG_base_type 0xffffffff DW_TAG_call_site DW_TAG_call_site_parameter 0xffffffff DW_TAG_call_site_parameter 0xffffffff DW_TAG_catch_block DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_array_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_base_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_class_type DW_TAG_member DW_TAG_inheritance DW_TAG_access_declaration DW_TAG_friend DW_TAG_ptr_to_member_type DW_TAG_subprogram DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_typedef DW_TAG_base_type DW_TAG_pointer_type DW_TAG_union_type DW_TAG_coarray_type DW_TAG_dynamic_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_class_type /* Nested classes */ DW_TAG_structure_type /* Nested structures */ DW_TAG_enumeration_type /* Nested enums */ DW_TAG_imported_declaration DW_TAG_template_alias /* C++ 2010 template alias */ 0xffffffff DW_TAG_coarray_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_dynamic_type DW_TAG_array_type DW_TAG_base_type 0xffffffff DW_TAG_common_block DW_TAG_variable 0xffffffff DW_TAG_common_inclusion 0xffffffff DW_TAG_skeleton_unit DW_TAG_structure_type DW_TAG_union_type DW_TAG_class_type DW_TAG_enumeration_type 0xffffffff DW_TAG_compile_unit DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_dwarf_procedure DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_rvalue_reference_type DW_TAG_restrict_type /* Used by LLVM */ DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_namespace DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_imported_module DW_TAG_template_alias /* C++ 2010 template alias */ DW_TAG_unspecified_type 0xffffffff DW_TAG_type_unit DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_namespace DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_imported_module DW_TAG_template_alias /* C++ 2010 template alias */ 0xffffffff DW_TAG_condition /* COBOL */ DW_TAG_constant DW_TAG_subrange_type 0xffffffff DW_TAG_atomic_type 0xffffffff DW_TAG_const_type 0xffffffff DW_TAG_constant 0xffffffff DW_TAG_dwarf_procedure 0xffffffff DW_TAG_entry_point DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_common_inclusion 0xffffffff DW_TAG_enumeration_type DW_TAG_enumerator 0xffffffff DW_TAG_enumerator 0xffffffff DW_TAG_file_type 0xffffffff DW_TAG_formal_parameter 0xffffffff DW_TAG_friend 0xffffffff DW_TAG_imported_declaration 0xffffffff DW_TAG_imported_module 0xffffffff DW_TAG_imported_unit 0xffffffff DW_TAG_inheritance 0xffffffff DW_TAG_inlined_subroutine DW_TAG_array_type DW_TAG_atomic_type DW_TAG_base_type DW_TAG_call_site DW_TAG_class_type DW_TAG_coarray_type DW_TAG_constant DW_TAG_const_type DW_TAG_dynamic_type DW_TAG_enumeration_type DW_TAG_file_type DW_TAG_formal_parameter DW_TAG_generic_subrange DW_TAG_inlined_subroutine DW_TAG_lexical_block DW_TAG_namelist DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_reference_type DW_TAG_set_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subprogram DW_TAG_subrange_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_unspecified_parameters DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_interface_type DW_TAG_member DW_TAG_subprogram 0xffffffff DW_TAG_label 0xffffffff DW_TAG_lexical_block DW_TAG_array_type DW_TAG_atomic_type DW_TAG_base_type DW_TAG_call_site DW_TAG_class_type DW_TAG_coarray_type DW_TAG_constant DW_TAG_const_type DW_TAG_dynamic_type DW_TAG_enumeration_type DW_TAG_formal_parameter DW_TAG_generic_subrange DW_TAG_imported_declaration DW_TAG_imported_module DW_TAG_inlined_subroutine DW_TAG_label DW_TAG_lexical_block DW_TAG_module DW_TAG_namelist DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_reference_type DW_TAG_set_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subprogram DW_TAG_subrange_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_member 0xffffffff DW_TAG_module 0xffffffff DW_TAG_namelist DW_TAG_namelist_item 0xffffffff DW_TAG_namelist_item 0xffffffff DW_TAG_namespace DW_TAG_array_type DW_TAG_atomic_type DW_TAG_base_type DW_TAG_class_type DW_TAG_coarray_type DW_TAG_common_block DW_TAG_constant DW_TAG_const_type DW_TAG_dynamic_type DW_TAG_enumeration_type DW_TAG_generic_subrange DW_TAG_imported_declaration DW_TAG_imported_module /* Allow imported module */ DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_namelist DW_TAG_namespace /* Allow a nested namespace */ DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_reference_type DW_TAG_set_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subprogram DW_TAG_subrange_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_packed_type 0xffffffff DW_TAG_partial_unit DW_TAG_array_type DW_TAG_atomic_type DW_TAG_base_type DW_TAG_class_type DW_TAG_coarray_type DW_TAG_common_block DW_TAG_constant DW_TAG_const_type DW_TAG_dynamic_type DW_TAG_enumeration_type DW_TAG_file_type DW_TAG_generic_subrange DW_TAG_imported_declaration DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_namelist DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_reference_type DW_TAG_set_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subprogram DW_TAG_subrange_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_pointer_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_ptr_to_member_type 0xffffffff DW_TAG_reference_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_rvalue_reference_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_restrict_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_set_type 0xffffffff DW_TAG_shared_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_string_type 0xffffffff DW_TAG_structure_type DW_TAG_access_declaration DW_TAG_atomic_type DW_TAG_base_type DW_TAG_class_type /* nested classes */ DW_TAG_coarray_type DW_TAG_const_type DW_TAG_enumeration_type /* nested enums */ DW_TAG_friend DW_TAG_imported_declaration /* References to namespaces */ DW_TAG_inheritance DW_TAG_member DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_structure_type /* nested structures */ DW_TAG_subprogram DW_TAG_template_alias /* C++ 2010 template alias */ DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_typedef DW_TAG_union_type DW_TAG_variant_part DW_TAG_volatile_type 0xffffffff DW_TAG_subprogram DW_TAG_array_type DW_TAG_atomic_type DW_TAG_base_type DW_TAG_call_site DW_TAG_class_type DW_TAG_coarray_type DW_TAG_common_block DW_TAG_common_inclusion DW_TAG_constant DW_TAG_const_type DW_TAG_enumeration_type DW_TAG_file_type DW_TAG_formal_parameter DW_TAG_generic_subrange DW_TAG_imported_declaration /* References to namespaces */ DW_TAG_imported_module /* References to namespaces */ DW_TAG_inlined_subroutine DW_TAG_label DW_TAG_lexical_block DW_TAG_namelist DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_ptr_to_member_type DW_TAG_reference_type DW_TAG_set_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subprogram DW_TAG_subrange_type DW_TAG_subroutine_type DW_TAG_template_type_parameter DW_TAG_template_value_parameter DW_TAG_thrown_type DW_TAG_typedef DW_TAG_union_type DW_TAG_unspecified_parameters DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_subrange_type 0xffffffff DW_TAG_generic_subrange 0xffffffff DW_TAG_subroutine_type DW_TAG_formal_parameter DW_TAG_typedef DW_TAG_unspecified_parameters 0xffffffff DW_TAG_template_type_parameter 0xffffffff DW_TAG_template_value_parameter 0xffffffff DW_TAG_thrown_type 0xffffffff DW_TAG_try_block 0xffffffff DW_TAG_typedef 0xffffffff DW_TAG_union_type DW_TAG_class_type /* Nested classes */ DW_TAG_enumeration_type /* Nested enums */ DW_TAG_friend DW_TAG_member DW_TAG_structure_type /* Nested structures */ DW_TAG_subprogram DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_typedef /* Nested typedef */ DW_TAG_union_type /* Nested unions */ 0xffffffff DW_TAG_template_alias DW_TAG_template_type_parameter DW_TAG_template_value_parameter 0xffffffff DW_TAG_unspecified_parameters 0xffffffff DW_TAG_unspecified_type 0xffffffff DW_TAG_variable 0xffffffff DW_TAG_variant DW_TAG_variant_part 0xffffffff DW_TAG_variant_part 0xffffffff DW_TAG_volatile_type 0xffffffff DW_TAG_with_stmt 0xffffffff libdwarf-20210528/dwarfdump/ChangeLog20140000664000175000017500000001661213644370703014563 000000000000002014-12-31 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-12-28 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-08-15 David Anderson * print_die.c(print_one_die_section): A c99-ism of declarations mixed with statements was present. Moved declaration of 'res' up a few lines. 2014-08-05 David Anderson * print_gdbindex.c: A couple places: Fixed indents on a comment. 2014-08-05 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-08-04 David Anderson * dwarfdump.1: Mention -I option. * dwarfdump.c: Add -I to help output. * print_gdbindex.c: Add cu_list_len argument to print_culist_array so it can pass back the culist length for use by symboltable code. So symboltable code can know what indexes are type units and which compilation units. 2014-08-03 David Anderson * dwarfdump.c: Corrected typo in comment. * print_debugfission.c: Removed trailing whitespace. Fixed some small mistakes in the output. * print_die.c: Removed trailing whitespace. Fixed the section name. It was showing .debug_types when not wanted. 2014-08-02 David Anderson * print_debugfission.c, print_gdbindex.c: Use the section name strings returned by section-open for object files that have them (like Elf). 2014-07-12 David Anderson * print_die.c: Using a new interface to print the actual section name, not just .debug_info or .debug_types. dwarf_get_die_section_name(); * dwarfdump.c: Corrected a comment relating to .gdb_index and .debug_[ct]u_index sections * debugfission.c: Fix indentation mistakes. 2014-07-11 David Anderson * print_debugfission.c: Prints the offset and size tables. 2014-07-10 David Anderson * print_debugfission.c: Prints the hash table values of the .debug_tu_index and .debug_cu_index sections. 2014-07-09 David Anderson * print_debugfission.c: Removed trailing whitespace characters. 2014-07-09 David Anderson * Makefile.n: Add print_debugfission.o to the list. * globals.h: Add print_debugfission_index() interface. * print_debugfission.c: New file beginning to support print of .debug_tu_index and .debug_cu_index sections (DWARF5). 2014-07-02 David Anderson * dwarfdump.c: A missing comma after DW_SECTNAME_GDB_INDEX lead to a core dump. * print_die.c: The printf format for a warning message was messed up. Fixed. 2014-07-01 David Anderson * dwarfdump.c, print_gdbindex.c: Fixed indentation and trailing whitespaces. 2014-07-01 David Anderson * print_gdbindex.c: Now prints gdb_index symboltable. 2014-06-30 David Anderson * print_gdbindex.c: Add types printing. Add addressarea printing. 2014-06-29 David Anderson * print_gdbindex.c: Call latest libdwarf interfaces. Fix the formatting a bit. 2014-06-28 David Anderson * Makefile.in: Add print_dgbindex.o to objects list. * dwarfdump.1: Add -I to options list (for gdb_index section). * dwarfdump.c: Add gdbindex_flag and a call to print_gdb_index(). * globals.h: Add DW_HDR_GDB_INDEX to flags. * print_gdbindex.c: New file, prints .gdb_index section if the section is present in an object. 2014-05-20 David Anderson * dwarfdump.c, common.c: Updated version string. * print_die.c: now the dwo_id value prints as hex. 2014-05-19 David Anderson * dwarfdump.cc, common.cc: Updated version string. 2014-05-19 David Anderson * print_die.c: Removed two unused local variables. 2014-05-18 David Anderson * dwarfdump.c,print_die.c: Fixed indent errors and removed trailing whitespace. 2014-05-14 David Anderson * print_die.c: Complete printing of DW_FORM_GNU_str_index, DW_FORM_GNU_addr_index, DW_FORM_addrx, DW_FORM_constx. * print_frames.c: Now supports DW_FORM_GNU_addr_index, DW_FORM_addrx, DW_FORM_constx. * dwarfdump.c: Update version string. Trivial text realignment of argument strings in print_error() and print_error_and_continue(). * common.c: Update version string. 2014-05-11 David Anderson * print_die.c: Add printing of DW_FORM_GNU_str_index, partial of DW_FORM_GNU_addr_index. Support for DW_OP_GNU_const_index too. * dwarfdump.c: Trivial change to error strings so each is unique. Update version string. * common.c: Update version string. 2014-04-15 David Anderson * uri.c(hexdig): was testing 0, fixed to be '0'. 2014-04-14 David Anderson * dwarfdump.c,common.c: Update version string. 2014-04-12 David Anderson * dwarfdump.c,common.c: Update version string. 2014-02-13 David Anderson * dwarfdump.cc: Minor changes in the commentary relating to the search paths for dwarfdump.conf. No code changed. 2014-02-08 David Anderson * dwarfdump.c,common.c: Update version string. 2014-02-08 David Anderson * Makefile.in: Having a single rule build two independent things interacted badly with make -j 2 , so now each rule just builds a single target (see tag*.list builds). 2014-02-02 David Anderson * tag_attr.list,tag_attr_ext.list,tag_tree.list,tag_tree_ext.list: Removed trailing whitespace. 2014-01-31 David Anderson * addrmap.c: Forgot to add include of dwarf_tsearch.h here. Added. * dwarfdump.c, common.c: Updated version string. 2014-01-30 David Anderson * print_die.c: Add limited support for DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. 2014-01-29 David Anderson * addrmap.c addrmap.h checkutil.c,checkutil.h, common.c common.h,dwarf_tsearch.h,dwarfdump.c,dwconf.c, dwconf.h,esb.c,esb.h,globals.h,makename.h,naming.c,naming.h: Remove trailing whitespace. * print_abbrevs.c,print_aranges.c,print_die.c,print_frames.c, print_frames.h, print_lines.c,print_locs.c,print_macros.c,print_pubnames.c, print_ranges.c, print_reloc.c,print_reloc.h,print_sections.c,print_sections.h, print_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c, print_weaknames.c,strstrnocase.c, tag_attr.c,tag_common.c,tag_common.h,tag_tree.c, testesb.c,uri.c,uri.h,uritablebuild.c: Remove trailing whitespace. 2014-01-29 David Anderson * dwarf_tsearchbal.c,dwarf_tsearch.h: New source files. * print_frames.c: dwarf_tsearch now built in, we are no longer using libc tsearch. * addrmap.c: Now uses dwarf_tsearch. * configure.in, config.h.in: No longer need HAVE_TSEARCH or HAVE_TDESTROY * configure: regenerated 2014-01-10 David Anderson * dwarfdump.c: Change // comments to /* */ comments. * makename.c: Delete blank line and trailing space. Add cast so gcc -ansi compiles without complaint. * print_die.c, uri.c: Change // comments to /* */ comments. * tag_attr.c: Add getopt.h include so gcc -ansi compiles without complaint. * tag_tree.c: Add getopt.h and string.h include so gcc -ansi compiles without complaint. Add cast so strdup call to avoid warning. * addr_map.c: Add cast so strdup call does not cause warning gcc -ansi. 2014-01-04 David Anderson * dwarfdump.c: Initialize a local variable to zero and move a declaration (avoiding a c99-ism, the code is not supposed to be using c99 features). libdwarf-20210528/dwarfdump/CMakeLists.txt0000664000175000017500000001677114012575576015255 00000000000000 set_source_group(SOURCES "Source Files" addrmap.c checkutil.c dwarfdump.c dwconf.c helpertree.c glflags.c command_options.c compiler_info.c dwarf_names.c macrocheck.c opscounttab.c print_abbrevs.c print_aranges.c attr_form.c print_debugfission.c print_die.c print_debug_gnu.c print_debug_names.c print_debug_sup.c print_frames.c print_gdbindex.c print_hipc_lopc_attr.c print_lines.c print_llex_codes.c print_origloclist_codes.c print_loclists_codes.c print_locs.c print_loclists.c print_macro.c print_macinfo.c print_pubnames.c print_ranges.c print_rnglists.c print_reloc.c print_str_offsets.c print_sections.c print_section_groups.c print_static_funcs.c print_static_vars.c print_strings.c print_tag_attributes_usage.c print_types.c print_weaknames.c sanitized.c section_bitmaps.c strstrnocase.c true_section_name.c uri.c dwgetopt.c makename.c naming.c common.c esb.c dwarf_tsearchbal.c) set_source_group(HEADERS "Header Files" addrmap.h attr_form.h checkutil.h common.h dwconf.h command_options.h compiler_info.h dwarf_names.h opscounttab.h print_debug_gnu.h dwconf_using_functions.h esb_using_functions.h dwarfdump-af-table.h dwarfdump-ta-ext-table.h dwarfdump-ta-table.h dwarfdump-tt-ext-table.h dwarfdump-tt-table.h dwgetopt.h esb.h glflags.h globals.h macrocheck.h defined_types.h makename.h dwarf_tsearch.h print_frames.h print_reloc.h print_reloc_decls.h section_bitmaps.h uri.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(dwarfdump ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) set_folder(dwarfdump dwarfdump) target_compile_definitions(dwarfdump PRIVATE "CONFPREFIX=${CMAKE_INSTALL_PREFIX}/lib") target_compile_options(dwarfdump PRIVATE ${DW_FWALL}) target_link_libraries(dwarfdump PRIVATE ${dwarf-target} ${DW_FZLIB}) # Plain GNU C dash E does not work on a .list, # so copy to a .c name to run # the following four table creations. set(SELFTEST "-DSELFTEST") if (DO_TESTING) set_source_group(GETOPTEST_SOURCES "Source Files" getopttest.c dwgetopt.c) add_executable(selfgetopttest ${GETOPTEST_SOURCES}) target_compile_options(selfgetopttest PRIVATE ${DW_FWALL}) add_test(NAME selfgetopttest COMMAND selfgetopttest) endif() if (DO_TESTING) set_source_group(TESTESB_SOURCES "Source Files" esb.c testesb.c dwarf_tsearchbal.c) add_executable(selftestesb ${TESTESB_SOURCES}) target_compile_options(selftestesb PRIVATE ${SELFTEST} ) target_compile_options(selftestesb PRIVATE ${DW_FWALL}) add_test(NAME selftestesb COMMAND selftestesb) endif() if (DO_TESTING) set_source_group(TESTESB_SOURCES "Source Files" getopttest.c dwgetopt.c) add_executable(selfgetopttestnat ${GETOPTEST_SOURCES}) target_compile_options(selfgetopttestnat PRIVATE ${DW_FWALL}) if(UNIX) target_compile_definitions(selfgetopttestnat PRIVATE GETOPT_FROM_SYSTEM) endif() foreach(i 1 2 3 5 6 7 8 9 10) add_test(NAME selfgetopttestnat${i} COMMAND selfgetopttestnat -c ${i}) endforeach() endif() if (DO_TESTING) set_source_group(MAKENAME_SOURCES "Source Files" makename_test.c esb.c dwarf_tsearchbal.c makename.c) add_executable(selfmakename ${MAKENAME_SOURCES}) target_compile_options(selfmakename PRIVATE ${DW_FWALL}) target_compile_options(selfmakename PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmakename PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfmakename COMMAND selfmakename) endif() if (DO_TESTING) set_source_group(HELPERTREE_SOURCES "Source Files" helpertree_test.c helpertree.c dwarf_tsearchbal.c) add_executable(selfhelpertree ${HELPERTREE_SOURCES}) target_compile_options(selfhelpertree PRIVATE ${DW_FWALL}) target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_SOURCE_DIR}/dwarfdump") target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfhelpertree COMMAND selfhelpertree) endif() if (DO_TESTING) set_source_group(SELFMC_SOURCES "Source Files" macrocheck.c esb.c dwarf_tsearchbal.c) add_executable(selfmc ${SELFMC_SOURCES} ) target_compile_options(selfmc PRIVATE ${SELFTEST} ) target_compile_options(selfmc PRIVATE ${DW_FWALL}) target_compile_options(selfmc PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmc PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfmc COMMAND selfmc) endif() if (DO_TESTING) set_source_group(SELFESB_SOURCES "Source Files" testesb.c esb.c) add_executable(selfesb ${SELFESB_SOURCES}) target_compile_options(selfesb PRIVATE ${SELFTEST} ) target_compile_options(selfesb PRIVATE ${DW_FWALL}) target_compile_options(selfmakename PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmakename PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfesb COMMAND selfesb) endif() if (DO_TESTING) set_source_group(SECTIONBITMAPS_SOURCES "Source Files" section_bitmaps.c section_bitmaps_test.c ) add_executable(selfsectionbitmaps ${SECTIONBITMAPS_SOURCES}) target_compile_options(selfsectionbitmaps PRIVATE ${SELFTEST} ) target_compile_options(selfsectionbitmaps PRIVATE ${DW_FWALL}) target_compile_options(selfsectionbitmaps PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfsectionbitmaps PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfsectionbitmaps COMMAND selfsectionbitmaps) endif() if (DO_TESTING) set_source_group(SELFPRINTRELOC_SOURCES "Source Files" esb.c print_reloc_test.c) add_executable(selfprintreloc ${SELFPRINTRELOC_SOURCES}) # We need access to a few relocation-data libdwarf headers target_compile_options(selfprintreloc PRIVATE ${SELFTEST} ) target_compile_options(selfprintreloc PRIVATE ${DW_FWALL}) target_compile_options(selfprintreloc PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfprintreloc PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfprintreloc COMMAND selfprintreloc) endif() if (DO_TESTING) set(peobj "${CMAKE_SOURCE_DIR}/dwarfdump/testobjLE32PE.exe") set(pebase "${CMAKE_SOURCE_DIR}/dwarfdump/testobjLE32PE.base") set(execpedd "${CMAKE_BINARY_DIR}/dwarfdump/dwarfdump") add_test(NAME selfdwarfdumppe COMMAND sh -c "${execpedd} -vvv -a ${peobj} | head -700 | sed 's/last time 0x.*/last time 0x0/' >junk.testoutpe ; diff ${pebase} junk.testoutpe" ) endif() if (DO_TESTING) set(elfobj "${CMAKE_SOURCE_DIR}/dwarfdump/testuriLE64ELf.obj") set(elfbase "${CMAKE_SOURCE_DIR}/dwarfdump/testuriLE64ELf.base") set(execelfdd "${CMAKE_BINARY_DIR}/dwarfdump/dwarfdump") add_test(NAME selfdwarfdumpelf COMMAND sh -c "${execelfdd} -vvv -a ${elfobj} | head -700 > junk.testoutelf ; diff ${elfbase} junk.testoutelf" ) endif() if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set(SUFFIX 64) endif() set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS dwarfdump DESTINATION RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) install(FILES dwarfdump.conf DESTINATION ${LIBDIR}) install(FILES dwarfdump.1 DESTINATION share/man/man1) libdwarf-20210528/dwarfdump/print_debugfission.c0000664000175000017500000002575513764006205016547 00000000000000/* Copyright 2014-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" #define TRUE 1 #define FALSE 0 static const char * dw_dlv_string(int res) { if (res == DW_DLV_ERROR) { return "DW_DLV_ERROR"; } if (res == DW_DLV_NO_ENTRY) { return "DW_DLV_NO_ENTRY"; } if (res == DW_DLV_OK) { return "DW_DLV_OK"; } return "ERROR: Impossible libdwarf DW_DLV code"; } static int hashval_zero(Dwarf_Sig8 *val) { unsigned u = 0; for (u=0 ; u < sizeof(Dwarf_Sig8);++u) { if (val->signature[u]) { return FALSE; } } return TRUE; } int print_debugfission_index(Dwarf_Debug dbg,const char *type, Dwarf_Error *err) { int res = 0; Dwarf_Xu_Index_Header xuhdr = 0; Dwarf_Unsigned version_number = 0; Dwarf_Unsigned offsets_count = 0; Dwarf_Unsigned units_count = 0; Dwarf_Unsigned hash_slots_count = 0; const char * section_name = 0; const char * section_type2 = 0; const char * section_name2 = 0; int is_cu = !strcmp(type,"cu")?TRUE:FALSE; res = dwarf_get_xu_index_header(dbg, type, &xuhdr, &version_number, &offsets_count, &units_count, &hash_slots_count, §ion_name, err); if (res == DW_DLV_NO_ENTRY) { /* This applies to most object files. */ return res; } if (res == DW_DLV_ERROR) { simple_err_return_msg_either_action(res, "ERROR: Call to dwarf_get_xu_index_header() failed."); return res; } res = dwarf_get_xu_index_section_type(xuhdr, §ion_type2, §ion_name2, err); if (res == DW_DLV_NO_ENTRY) { struct esb_s tmsg; esb_constructor(&tmsg); esb_append(&tmsg, "ERROR: dwarf_get_xu_index_section_type() " " returned DW_DLV_NO_ENTRY " " which should be impossible."); esb_append(&tmsg," Something is corrupted."); simple_err_return_action(DW_DLV_ERROR, esb_get_string(&tmsg)); dwarf_xu_header_free(xuhdr); esb_destructor(&tmsg); /* We have no way to return a DW_DLV_ERROR. as we cannot manufacture a Dwarf_Error */ return res; } if (res == DW_DLV_ERROR) { simple_err_return_msg_either_action(res, "ERROR: Call to dwarf_get_xu_index_section_type() " "failed."); dwarf_xu_header_free(xuhdr); return res; } if (strcmp(section_type2,type)) { struct esb_s tmsg; esb_constructor(&tmsg); esb_append_printf_s(&tmsg, "ERROR: dwarf_get_xu_index_section_type() " " returned section type %s ", sanitized(section_type2)); esb_append_printf_s(&tmsg, "whereas the call was for section type %s. ", sanitized(type)); esb_append(&tmsg," Something is corrupted."); simple_err_return_action(DW_DLV_ERROR, esb_get_string(&tmsg)); esb_destructor(&tmsg); dwarf_xu_header_free(xuhdr); /* We have no way to return a DW_DLV_ERROR. as we cannot manufacture a Dwarf_Error */ return DW_DLV_OK; } if (!section_name || !*section_name) { section_name = (is_cu?".debug_cu_index":".debug_tu_index"); } { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } printf(" Version: : %" DW_PR_DUu "\n", version_number); printf(" Number of columns N: %" DW_PR_DUu "\n", offsets_count); printf(" number of entries U: %" DW_PR_DUu "\n", units_count); printf(" Number of slots S: %" DW_PR_DUu "\n", hash_slots_count); { unsigned n = 0; Dwarf_Unsigned sect_num; const char *name = 0; printf("\n"); printf("Columns index to section id and name \n"); printf(" [ ] id name\n"); for ( ; n < offsets_count; ++n) { res = dwarf_get_xu_section_names(xuhdr, n,§_num,&name,err); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { printf(" [%u] unused\n",n); } else { printf(" [%u] %" DW_PR_DUu " %s\n",n, sect_num,name); } } } if (hash_slots_count > 0) { printf("\n"); printf(" slot hash index\n"); } { /* For h < S */ Dwarf_Unsigned h = 0; for ( h = 0; h < hash_slots_count; h++) { Dwarf_Sig8 hashval; Dwarf_Unsigned index = 0; Dwarf_Unsigned col = 0; memset(&hashval,0,sizeof(hashval)); res = dwarf_get_xu_hash_entry(xuhdr,h, &hashval,&index,err); if (res == DW_DLV_ERROR) { struct esb_s hmsg; esb_constructor(&hmsg); esb_append_printf_u(&hmsg, "ERROR: dwarf_get_xu_hash_entry failed " " on slot number %u ",h); esb_append_printf_u(&hmsg," of %u slots.", hash_slots_count); simple_err_return_action(res, esb_get_string(&hmsg)); dwarf_xu_header_free(xuhdr); esb_destructor(&hmsg); return res; } else if (res == DW_DLV_NO_ENTRY) { /* Impossible */ struct esb_s hmsg; esb_constructor(&hmsg); esb_append_printf_u(&hmsg, "ERROR: dwarf_get_xu_hash_entry got NO_ENTRY " " on slot number %u ",h); esb_append_printf_u(&hmsg," of %u slots." " That should be impossible.", hash_slots_count); dwarf_xu_header_free(xuhdr); esb_destructor(&hmsg); return res; } else if (!index) { if (hashval_zero(&hashval)) { /* An unused hash slot, we do not print them */ } else { struct esb_s hashhexstring; esb_constructor(&hashhexstring); format_sig8_string(&hashval,&hashhexstring); printf(" [%4" DW_PR_DUu "] %s" " %8" DW_PR_DUu " %s\n", h, esb_get_string(&hashhexstring), index, "Index 0 means the hash gets ignored"); esb_destructor(&hashhexstring); } continue; } { struct esb_s hashhexstring; esb_constructor(&hashhexstring); format_sig8_string(&hashval,&hashhexstring); printf(" [%4" DW_PR_DUu "] %s" " %8" DW_PR_DUu "\n", h, esb_get_string(&hashhexstring), index); esb_destructor(&hashhexstring); } printf(" [r,c] section " " offset size\n"); for (col = 0; col < offsets_count; col++) { Dwarf_Unsigned off = 0; Dwarf_Unsigned len = 0; const char * name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr, col,&num,&name,err); if (res != DW_DLV_OK) { struct esb_s hmsg; const char * et= dw_dlv_string(res); esb_constructor(&hmsg); esb_append_printf_s(&hmsg, "ERROR: dwarf_get_xu_section_names " "got %s ",et); esb_append_printf_u(&hmsg, " on column number %u ",col); esb_append_printf_u(&hmsg," of %u columns.", offsets_count); simple_err_return_action(res, esb_get_string(&hmsg)); esb_destructor(&hmsg); dwarf_xu_header_free(xuhdr); return res; } /* index is 1-origin. We use it that way. */ res = dwarf_get_xu_section_offset(xuhdr, index,col,&off,&len,err); if (res != DW_DLV_OK) { struct esb_s hmsg; const char * et= dw_dlv_string(res); esb_constructor(&hmsg); esb_append_printf_s(&hmsg, "ERROR: dwarf_get_xu_section_offset " "got %s ",et); esb_append_printf_u(&hmsg, " on index number %u ",index); esb_append_printf_u(&hmsg, " on column number %u ",col); esb_append_printf_u(&hmsg," of %u columns.", offsets_count); simple_err_return_action(res, esb_get_string(&hmsg)); esb_destructor(&hmsg); dwarf_xu_header_free(xuhdr); return res; } printf(" [%1" DW_PR_DUu ",%1" DW_PR_DUu "] %20s " "0x%" DW_PR_XZEROS DW_PR_DUx " (%8" DW_PR_DUu ") " "0x%" DW_PR_XZEROS DW_PR_DUx " (%8" DW_PR_DUu ")\n", index, col,name, off,off, len,len); } } } dwarf_xu_header_free(xuhdr); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/uri.h0000644000175000017500000000247713743575426013465 00000000000000/* Copyright 2011-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef URI_H #define URI_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void translate_to_uri(const char * filename, struct esb_s *out); void translate_from_uri(const char * input, struct esb_s *out); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* URI_H */ libdwarf-20210528/dwarfdump/print_reloc_test.c0000664000175000017500000000425413764006205016220 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #ifndef SELFTEST #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #include "print_reloc.h" #endif /* SELFTEST */ #include "print_reloc_decls.h" #include "section_bitmaps.h" #include "esb.h" #include "sanitized.h" int main() { int failcount = 0; unsigned long i = 1; for ( ; i < DW_SECTION_REL_ARRAY_SIZE; ++i) { if (rel_info[i].index != i) { printf(" FAIL rel_info check, i = %lu vs %lu\n", i, (unsigned long)rel_info[i].index); ++failcount; } } if (failcount) { printf("FAIL print_reloc selftest\n"); exit(1); } printf("PASS print_reloc selftest\n"); return 0; } #else /* Without libelf we don't care about this as we will not try to print relocation data. Pretend ok. */ int main() { return 0; } #endif /* DWARF_WITH_LIBELF */ libdwarf-20210528/dwarfdump/testobjLE32PE.base0000664000175000017500000012247214012575576015632 00000000000000 .debug_info CU_HEADER: cu_header_length = 0x00000223 547 version_stamp = 0x0004 4 abbrev_offset = 0x00000000 0 address_size = 0x04 4 offset_size = 0x04 4 cu_type = 0x01 DW_UT_compile COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit dwarf_srcfiles() returned strings. Count = 9. [0] c:/Users/dandelot/test.c [1] c:/mingw/include/stdio.h [2] c:/mingw/include/_mingw.h [3] c:/mingw/include/msvcrtver.h [4] c:/mingw/include/w32api.h [5] c:/mingw/include/sdkddkver.h [6] c:/mingw/lib/gcc/mingw32/6.3.0/include/stddef.h [7] c:/mingw/include/sys/types.h [8] c:/mingw/lib/gcc/mingw32/6.3.0/include/stdarg.h DW_AT_producer GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 DW_AT_language DW_LANG_C99 DW_AT_name c:/Users/dandelot/test.c DW_AT_low_pc 0x00401460 DW_AT_high_pc 87 DW_AT_stmt_list 0x00000000 DW_AT_GNU_macros 0x00000000 LOCAL_SYMBOLS: < 1><0x0000006a> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_unsigned DW_AT_name unsigned int < 1><0x0000007a> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_unsigned DW_AT_name short unsigned int < 1><0x00000090> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name long int < 1><0x0000009c> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long long int < 1><0x000000ad> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name int < 1><0x000000b4> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name char < 1><0x000000bc> DW_TAG_structure_type DW_AT_name _iobuf DW_AT_byte_size 0x00000020 DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d2 DW_AT_sibling <0x00000143> < 2><0x000000cb> DW_TAG_member DW_AT_name _ptr DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d4 DW_AT_type <0x00000143> DW_AT_data_member_location 0 < 2><0x000000d8> DW_TAG_member DW_AT_name _cnt DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d5 DW_AT_type <0x000000ad> DW_AT_data_member_location 4 < 2><0x000000e5> DW_TAG_member DW_AT_name _base DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d6 DW_AT_type <0x00000143> DW_AT_data_member_location 8 < 2><0x000000f3> DW_TAG_member DW_AT_name _flag DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d7 DW_AT_type <0x000000ad> DW_AT_data_member_location 12 < 2><0x00000101> DW_TAG_member DW_AT_name _file DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d8 DW_AT_type <0x000000ad> DW_AT_data_member_location 16 < 2><0x0000010f> DW_TAG_member DW_AT_name _charbuf DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d9 DW_AT_type <0x000000ad> DW_AT_data_member_location 20 < 2><0x00000120> DW_TAG_member DW_AT_name _bufsiz DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000da DW_AT_type <0x000000ad> DW_AT_data_member_location 24 < 2><0x00000130> DW_TAG_member DW_AT_name _tmpfname DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000db DW_AT_type <0x00000143> DW_AT_data_member_location 28 < 1><0x00000143> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x000000b4> < 1><0x00000149> DW_TAG_typedef DW_AT_name FILE DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000dc DW_AT_type <0x000000bc> < 1><0x00000155> DW_TAG_array_type DW_AT_type <0x00000149> DW_AT_sibling <0x00000160> < 2><0x0000015e> DW_TAG_subrange_type < 1><0x00000160> DW_TAG_variable DW_AT_name _iob DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000ef DW_AT_type <0x00000155> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000016c> DW_TAG_structure_type DW_AT_name something DW_AT_byte_size 0x00000008 DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000004 DW_AT_sibling <0x00000193> < 2><0x0000017e> DW_TAG_member DW_AT_name a DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000005 DW_AT_type <0x000000ad> DW_AT_data_member_location 0 < 2><0x00000188> DW_TAG_member DW_AT_name b DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000006 DW_AT_type <0x0000006a> DW_AT_data_member_location 4 < 1><0x00000193> DW_TAG_subprogram DW_AT_external yes(1) DW_AT_name main DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_prototyped yes(1) DW_AT_type <0x000000ad> DW_AT_low_pc 0x0040146d DW_AT_high_pc 74 DW_AT_frame_base len 0x0001: 0x9c: DW_OP_call_frame_cfa DW_AT_GNU_all_tail_call_sites yes(1) DW_AT_sibling <0x000001f1> < 2><0x000001ad> DW_TAG_formal_parameter DW_AT_name argc DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 0x9100: DW_OP_fbreg 0 < 2><0x000001bc> DW_TAG_formal_parameter DW_AT_name argv DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_type <0x000001f1> DW_AT_location len 0x0002: 0x9104: DW_OP_fbreg 4 < 2><0x000001cb> DW_TAG_variable DW_AT_name x DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000013 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 0x741c: DW_OP_breg4+28 < 2><0x000001d7> DW_TAG_variable DW_AT_name y DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000014 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 0x7418: DW_OP_breg4+24 < 2><0x000001e3> DW_TAG_variable DW_AT_name so DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000015 DW_AT_type <0x0000016c> DW_AT_location len 0x0002: 0x7410: DW_OP_breg4+16 < 1><0x000001f1> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x00000143> < 1><0x000001f7> DW_TAG_subprogram DW_AT_external yes(1) DW_AT_name buffle DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x0000000a DW_AT_prototyped yes(1) DW_AT_type <0x000000ad> DW_AT_low_pc 0x00401460 DW_AT_high_pc 13 DW_AT_frame_base len 0x0001: 0x9c: DW_OP_call_frame_cfa DW_AT_GNU_all_call_sites yes(1) DW_AT_sibling <0x00000220> < 2><0x00000213> DW_TAG_formal_parameter DW_AT_name v DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x0000000a DW_AT_type <0x00000220> DW_AT_location len 0x0002: 0x9100: DW_OP_fbreg 0 < 1><0x00000220> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x0000016c> .debug_line: line number info for a single cu Source lines (from CU-DIE at .debug_info offset 0x0000000b): COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit dwarf_srcfiles() returned strings. Count = 9. [0] c:/Users/dandelot/test.c [1] c:/mingw/include/stdio.h [2] c:/mingw/include/_mingw.h [3] c:/mingw/include/msvcrtver.h [4] c:/mingw/include/w32api.h [5] c:/mingw/include/sdkddkver.h [6] c:/mingw/lib/gcc/mingw32/6.3.0/include/stddef.h [7] c:/mingw/include/sys/types.h [8] c:/mingw/lib/gcc/mingw32/6.3.0/include/stdarg.h DW_AT_producer GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 DW_AT_language DW_LANG_C99 DW_AT_name c:/Users/dandelot/test.c DW_AT_low_pc 0x00401460 DW_AT_high_pc 87 DW_AT_stmt_list 0x00000000 DW_AT_GNU_macros 0x00000000 *** DWARF CHECK: .debug_line: standard DWARF3 operands matched, but is DWARF2 linetable: count 12 at offset 0x00000000 ( 0 ) *** total line info length 256 bytes, line offset 0x00000000 0 line table version 2 line table length field length 4 prologue length 224 compilation_directory min instruction length 1 default is stmt 1 line base -5 line_range 14 opcode base 13 standard opcode count 12 opcode[ 1] length 0 opcode[ 2] length 1 opcode[ 3] length 1 opcode[ 4] length 1 opcode[ 5] length 1 opcode[ 6] length 0 opcode[ 7] length 0 opcode[ 8] length 0 opcode[ 9] length 1 opcode[10] length 0 opcode[11] length 0 opcode[12] length 1 include directories count 4 (index starts at 1) include dir[1] c:/Users/dandelot include dir[2] c:/mingw/include include dir[3] c:/mingw/lib/gcc/mingw32/6.3.0/include include dir[4] c:/mingw/include/sys file names count 9 file[0] test.c (file-number: 1) dir index 1 last time 0x0 file length 0 0x0 file[1] stdio.h (file-number: 2) dir index 2 last time 0x0 file length 0 0x0 file[2] _mingw.h (file-number: 3) dir index 2 last time 0x0 file length 0 0x0 file[3] msvcrtver.h (file-number: 4) dir index 2 last time 0x0 file length 0 0x0 file[4] w32api.h (file-number: 5) dir index 2 last time 0x0 file length 0 0x0 file[5] sdkddkver.h (file-number: 6) dir index 2 last time 0x0 file length 0 0x0 file[6] stddef.h (file-number: 7) dir index 3 last time 0x0 file length 0 0x0 file[7] types.h (file-number: 8) dir index 4 last time 0x0 file length 0 0x0 file[8] stdarg.h (file-number: 9) dir index 3 last time 0x0 file length 0 0x0 statement prog offset in section: 0x000000ea (234) s b e p e i d t l s r p s i m c e o i a s section op col t k q l l c offset code address file line umn ? ? ? ? ? [0x0000ea] DW_LNE_set_address address 0x00401460 [0x0000f1] DW_LNS_advance_line val 10 0x0000000a [0x0000f3] DW_LNS_copy 1 0x00401460 1 11 0 1 0 0 [0x0000f4] Specialop 61 48 0x00401463 1 12 0 1 0 0 [0x0000f5] Specialop 132 119 0x0040146b 1 14 0 1 0 0 [0x0000f6] Specialop 49 36 0x0040146d 1 17 0 1 0 0 [0x0000f7] Specialop 144 131 0x00401476 1 17 0 1 0 0 [0x0000f8] Specialop 90 77 0x0040147b 1 19 0 1 0 0 [0x0000f9] Specialop 131 118 0x00401483 1 20 0 1 0 0 [0x0000fa] Specialop 133 120 0x0040148b 1 23 0 1 0 0 [0x0000fb] Specialop 131 118 0x00401493 1 24 0 1 0 0 [0x0000fc] Specialop 243 230 0x004014a3 1 25 0 1 0 0 [0x0000fd] DW_LNS_const_add_pc new address 0x004014b4 [0x0000fe] Specialop 33 20 0x004014b5 1 26 0 1 0 0 [0x0000ff] DW_LNS_advance_pc val 2 0x00000002 [0x000101] DW_LNE_end_sequence extended 1 0x004014b7 1 26 0 1 0 1 .debug_macro: Macro info for a single cu at macro Offset 0x00000000 Macro data from CU-DIE at .debug_info offset 0x0000000b: COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit dwarf_srcfiles() returned strings. Count = 9. [0] c:/Users/dandelot/test.c [1] c:/mingw/include/stdio.h [2] c:/mingw/include/_mingw.h [3] c:/mingw/include/msvcrtver.h [4] c:/mingw/include/w32api.h [5] c:/mingw/include/sdkddkver.h [6] c:/mingw/lib/gcc/mingw32/6.3.0/include/stddef.h [7] c:/mingw/include/sys/types.h [8] c:/mingw/lib/gcc/mingw32/6.3.0/include/stdarg.h DW_AT_producer GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 DW_AT_language DW_LANG_C99 DW_AT_name c:/Users/dandelot/test.c DW_AT_low_pc 0x00401460 DW_AT_high_pc 87 DW_AT_stmt_list 0x00000000 DW_AT_GNU_macros 0x00000000 Nested import level: 0 Macro version : 4 macro section offset 0x00000000 flags: 0x2, offsetsize64? no, lineoffset? yes, operands_table? no offset size 0x4 header length: 0x00000007 total length: 0x00003f19 debug_line_offset: 0x00000000 MacroInformationEntries count: 565, bytes length: 16146 [ 0] 0x01 DW_MACRO_define line 0 __STDC__ 1 [ 1] 0x01 DW_MACRO_define line 0 __STDC_VERSION__ 201112L [ 2] 0x01 DW_MACRO_define line 0 __STDC_UTF_16__ 1 [ 3] 0x01 DW_MACRO_define line 0 __STDC_UTF_32__ 1 [ 4] 0x01 DW_MACRO_define line 0 __STDC_HOSTED__ 1 [ 5] 0x01 DW_MACRO_define line 0 __GNUC__ 6 [ 6] 0x01 DW_MACRO_define line 0 __GNUC_MINOR__ 3 [ 7] 0x01 DW_MACRO_define line 0 __GNUC_PATCHLEVEL__ 0 [ 8] 0x01 DW_MACRO_define line 0 __VERSION__ "6.3.0" [ 9] 0x01 DW_MACRO_define line 0 __ATOMIC_RELAXED 0 [ 10] 0x01 DW_MACRO_define line 0 __ATOMIC_SEQ_CST 5 [ 11] 0x01 DW_MACRO_define line 0 __ATOMIC_ACQUIRE 2 [ 12] 0x01 DW_MACRO_define line 0 __ATOMIC_RELEASE 3 [ 13] 0x01 DW_MACRO_define line 0 __ATOMIC_ACQ_REL 4 [ 14] 0x01 DW_MACRO_define line 0 __ATOMIC_CONSUME 1 [ 15] 0x01 DW_MACRO_define line 0 __FINITE_MATH_ONLY__ 0 [ 16] 0x01 DW_MACRO_define line 0 __SIZEOF_INT__ 4 [ 17] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG__ 4 [ 18] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG_LONG__ 8 [ 19] 0x01 DW_MACRO_define line 0 __SIZEOF_SHORT__ 2 [ 20] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT__ 4 [ 21] 0x01 DW_MACRO_define line 0 __SIZEOF_DOUBLE__ 8 [ 22] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG_DOUBLE__ 12 [ 23] 0x01 DW_MACRO_define line 0 __SIZEOF_SIZE_T__ 4 [ 24] 0x01 DW_MACRO_define line 0 __CHAR_BIT__ 8 [ 25] 0x01 DW_MACRO_define line 0 __BIGGEST_ALIGNMENT__ 16 [ 26] 0x01 DW_MACRO_define line 0 __ORDER_LITTLE_ENDIAN__ 1234 [ 27] 0x01 DW_MACRO_define line 0 __ORDER_BIG_ENDIAN__ 4321 [ 28] 0x01 DW_MACRO_define line 0 __ORDER_PDP_ENDIAN__ 3412 [ 29] 0x01 DW_MACRO_define line 0 __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ [ 30] 0x01 DW_MACRO_define line 0 __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ [ 31] 0x01 DW_MACRO_define line 0 __SIZEOF_POINTER__ 4 [ 32] 0x01 DW_MACRO_define line 0 __SIZE_TYPE__ unsigned int [ 33] 0x01 DW_MACRO_define line 0 __PTRDIFF_TYPE__ int [ 34] 0x01 DW_MACRO_define line 0 __WCHAR_TYPE__ short unsigned int [ 35] 0x01 DW_MACRO_define line 0 __WINT_TYPE__ short unsigned int [ 36] 0x01 DW_MACRO_define line 0 __INTMAX_TYPE__ long long int [ 37] 0x01 DW_MACRO_define line 0 __UINTMAX_TYPE__ long long unsigned int [ 38] 0x01 DW_MACRO_define line 0 __CHAR16_TYPE__ short unsigned int [ 39] 0x01 DW_MACRO_define line 0 __CHAR32_TYPE__ unsigned int [ 40] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_TYPE__ int [ 41] 0x01 DW_MACRO_define line 0 __INT8_TYPE__ signed char [ 42] 0x01 DW_MACRO_define line 0 __INT16_TYPE__ short int [ 43] 0x01 DW_MACRO_define line 0 __INT32_TYPE__ int [ 44] 0x01 DW_MACRO_define line 0 __INT64_TYPE__ long long int [ 45] 0x01 DW_MACRO_define line 0 __UINT8_TYPE__ unsigned char [ 46] 0x01 DW_MACRO_define line 0 __UINT16_TYPE__ short unsigned int [ 47] 0x01 DW_MACRO_define line 0 __UINT32_TYPE__ unsigned int [ 48] 0x01 DW_MACRO_define line 0 __UINT64_TYPE__ long long unsigned int [ 49] 0x01 DW_MACRO_define line 0 __INT_LEAST8_TYPE__ signed char [ 50] 0x01 DW_MACRO_define line 0 __INT_LEAST16_TYPE__ short int [ 51] 0x01 DW_MACRO_define line 0 __INT_LEAST32_TYPE__ int [ 52] 0x01 DW_MACRO_define line 0 __INT_LEAST64_TYPE__ long long int [ 53] 0x01 DW_MACRO_define line 0 __UINT_LEAST8_TYPE__ unsigned char [ 54] 0x01 DW_MACRO_define line 0 __UINT_LEAST16_TYPE__ short unsigned int [ 55] 0x01 DW_MACRO_define line 0 __UINT_LEAST32_TYPE__ unsigned int [ 56] 0x01 DW_MACRO_define line 0 __UINT_LEAST64_TYPE__ long long unsigned int [ 57] 0x01 DW_MACRO_define line 0 __INT_FAST8_TYPE__ signed char [ 58] 0x01 DW_MACRO_define line 0 __INT_FAST16_TYPE__ short int [ 59] 0x01 DW_MACRO_define line 0 __INT_FAST32_TYPE__ int [ 60] 0x01 DW_MACRO_define line 0 __INT_FAST64_TYPE__ long long int [ 61] 0x01 DW_MACRO_define line 0 __UINT_FAST8_TYPE__ unsigned char [ 62] 0x01 DW_MACRO_define line 0 __UINT_FAST16_TYPE__ short unsigned int [ 63] 0x01 DW_MACRO_define line 0 __UINT_FAST32_TYPE__ unsigned int [ 64] 0x01 DW_MACRO_define line 0 __UINT_FAST64_TYPE__ long long unsigned int [ 65] 0x01 DW_MACRO_define line 0 __INTPTR_TYPE__ int [ 66] 0x01 DW_MACRO_define line 0 __UINTPTR_TYPE__ unsigned int [ 67] 0x01 DW_MACRO_define line 0 __has_include(STR) __has_include__(STR) [ 68] 0x01 DW_MACRO_define line 0 __has_include_next(STR) __has_include_next__(STR) [ 69] 0x01 DW_MACRO_define line 0 __GXX_ABI_VERSION 1010 [ 70] 0x01 DW_MACRO_define line 0 __SCHAR_MAX__ 0x7f [ 71] 0x01 DW_MACRO_define line 0 __SHRT_MAX__ 0x7fff [ 72] 0x01 DW_MACRO_define line 0 __INT_MAX__ 0x7fffffff [ 73] 0x01 DW_MACRO_define line 0 __LONG_MAX__ 0x7fffffffL [ 74] 0x01 DW_MACRO_define line 0 __LONG_LONG_MAX__ 0x7fffffffffffffffLL [ 75] 0x01 DW_MACRO_define line 0 __WCHAR_MAX__ 0xffff [ 76] 0x01 DW_MACRO_define line 0 __WCHAR_MIN__ 0 [ 77] 0x01 DW_MACRO_define line 0 __WINT_MAX__ 0xffff [ 78] 0x01 DW_MACRO_define line 0 __WINT_MIN__ 0 [ 79] 0x01 DW_MACRO_define line 0 __PTRDIFF_MAX__ 0x7fffffff [ 80] 0x01 DW_MACRO_define line 0 __SIZE_MAX__ 0xffffffffU [ 81] 0x01 DW_MACRO_define line 0 __INTMAX_MAX__ 0x7fffffffffffffffLL [ 82] 0x01 DW_MACRO_define line 0 __INTMAX_C(c) c ## LL [ 83] 0x01 DW_MACRO_define line 0 __UINTMAX_MAX__ 0xffffffffffffffffULL [ 84] 0x01 DW_MACRO_define line 0 __UINTMAX_C(c) c ## ULL [ 85] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_MAX__ 0x7fffffff [ 86] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) [ 87] 0x01 DW_MACRO_define line 0 __INT8_MAX__ 0x7f [ 88] 0x01 DW_MACRO_define line 0 __INT16_MAX__ 0x7fff [ 89] 0x01 DW_MACRO_define line 0 __INT32_MAX__ 0x7fffffff [ 90] 0x01 DW_MACRO_define line 0 __INT64_MAX__ 0x7fffffffffffffffLL [ 91] 0x01 DW_MACRO_define line 0 __UINT8_MAX__ 0xff [ 92] 0x01 DW_MACRO_define line 0 __UINT16_MAX__ 0xffff [ 93] 0x01 DW_MACRO_define line 0 __UINT32_MAX__ 0xffffffffU [ 94] 0x01 DW_MACRO_define line 0 __UINT64_MAX__ 0xffffffffffffffffULL [ 95] 0x01 DW_MACRO_define line 0 __INT_LEAST8_MAX__ 0x7f [ 96] 0x01 DW_MACRO_define line 0 __INT8_C(c) c [ 97] 0x01 DW_MACRO_define line 0 __INT_LEAST16_MAX__ 0x7fff [ 98] 0x01 DW_MACRO_define line 0 __INT16_C(c) c [ 99] 0x01 DW_MACRO_define line 0 __INT_LEAST32_MAX__ 0x7fffffff [100] 0x01 DW_MACRO_define line 0 __INT32_C(c) c [101] 0x01 DW_MACRO_define line 0 __INT_LEAST64_MAX__ 0x7fffffffffffffffLL [102] 0x01 DW_MACRO_define line 0 __INT64_C(c) c ## LL [103] 0x01 DW_MACRO_define line 0 __UINT_LEAST8_MAX__ 0xff [104] 0x01 DW_MACRO_define line 0 __UINT8_C(c) c [105] 0x01 DW_MACRO_define line 0 __UINT_LEAST16_MAX__ 0xffff [106] 0x01 DW_MACRO_define line 0 __UINT16_C(c) c [107] 0x01 DW_MACRO_define line 0 __UINT_LEAST32_MAX__ 0xffffffffU [108] 0x01 DW_MACRO_define line 0 __UINT32_C(c) c ## U [109] 0x01 DW_MACRO_define line 0 __UINT_LEAST64_MAX__ 0xffffffffffffffffULL [110] 0x01 DW_MACRO_define line 0 __UINT64_C(c) c ## ULL [111] 0x01 DW_MACRO_define line 0 __INT_FAST8_MAX__ 0x7f [112] 0x01 DW_MACRO_define line 0 __INT_FAST16_MAX__ 0x7fff [113] 0x01 DW_MACRO_define line 0 __INT_FAST32_MAX__ 0x7fffffff [114] 0x01 DW_MACRO_define line 0 __INT_FAST64_MAX__ 0x7fffffffffffffffLL [115] 0x01 DW_MACRO_define line 0 __UINT_FAST8_MAX__ 0xff [116] 0x01 DW_MACRO_define line 0 __UINT_FAST16_MAX__ 0xffff [117] 0x01 DW_MACRO_define line 0 __UINT_FAST32_MAX__ 0xffffffffU [118] 0x01 DW_MACRO_define line 0 __UINT_FAST64_MAX__ 0xffffffffffffffffULL [119] 0x01 DW_MACRO_define line 0 __INTPTR_MAX__ 0x7fffffff [120] 0x01 DW_MACRO_define line 0 __UINTPTR_MAX__ 0xffffffffU [121] 0x01 DW_MACRO_define line 0 __GCC_IEC_559 2 [122] 0x01 DW_MACRO_define line 0 __GCC_IEC_559_COMPLEX 2 [123] 0x01 DW_MACRO_define line 0 __FLT_EVAL_METHOD__ 2 [124] 0x01 DW_MACRO_define line 0 __DEC_EVAL_METHOD__ 2 [125] 0x01 DW_MACRO_define line 0 __FLT_RADIX__ 2 [126] 0x01 DW_MACRO_define line 0 __FLT_MANT_DIG__ 24 [127] 0x01 DW_MACRO_define line 0 __FLT_DIG__ 6 [128] 0x01 DW_MACRO_define line 0 __FLT_MIN_EXP__ (-125) [129] 0x01 DW_MACRO_define line 0 __FLT_MIN_10_EXP__ (-37) [130] 0x01 DW_MACRO_define line 0 __FLT_MAX_EXP__ 128 [131] 0x01 DW_MACRO_define line 0 __FLT_MAX_10_EXP__ 38 [132] 0x01 DW_MACRO_define line 0 __FLT_DECIMAL_DIG__ 9 [133] 0x01 DW_MACRO_define line 0 __FLT_MAX__ 3.40282346638528859812e+38F [134] 0x01 DW_MACRO_define line 0 __FLT_MIN__ 1.17549435082228750797e-38F [135] 0x01 DW_MACRO_define line 0 __FLT_EPSILON__ 1.19209289550781250000e-7F [136] 0x01 DW_MACRO_define line 0 __FLT_DENORM_MIN__ 1.40129846432481707092e-45F [137] 0x01 DW_MACRO_define line 0 __FLT_HAS_DENORM__ 1 [138] 0x01 DW_MACRO_define line 0 __FLT_HAS_INFINITY__ 1 [139] 0x01 DW_MACRO_define line 0 __FLT_HAS_QUIET_NAN__ 1 [140] 0x01 DW_MACRO_define line 0 __DBL_MANT_DIG__ 53 [141] 0x01 DW_MACRO_define line 0 __DBL_DIG__ 15 [142] 0x01 DW_MACRO_define line 0 __DBL_MIN_EXP__ (-1021) [143] 0x01 DW_MACRO_define line 0 __DBL_MIN_10_EXP__ (-307) [144] 0x01 DW_MACRO_define line 0 __DBL_MAX_EXP__ 1024 [145] 0x01 DW_MACRO_define line 0 __DBL_MAX_10_EXP__ 308 [146] 0x01 DW_MACRO_define line 0 __DBL_DECIMAL_DIG__ 17 [147] 0x01 DW_MACRO_define line 0 __DBL_MAX__ ((double)1.79769313486231570815e+308L) [148] 0x01 DW_MACRO_define line 0 __DBL_MIN__ ((double)2.22507385850720138309e-308L) [149] 0x01 DW_MACRO_define line 0 __DBL_EPSILON__ ((double)2.22044604925031308085e-16L) [150] 0x01 DW_MACRO_define line 0 __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L) [151] 0x01 DW_MACRO_define line 0 __DBL_HAS_DENORM__ 1 [152] 0x01 DW_MACRO_define line 0 __DBL_HAS_INFINITY__ 1 [153] 0x01 DW_MACRO_define line 0 __DBL_HAS_QUIET_NAN__ 1 [154] 0x01 DW_MACRO_define line 0 __LDBL_MANT_DIG__ 64 [155] 0x01 DW_MACRO_define line 0 __LDBL_DIG__ 18 [156] 0x01 DW_MACRO_define line 0 __LDBL_MIN_EXP__ (-16381) [157] 0x01 DW_MACRO_define line 0 __LDBL_MIN_10_EXP__ (-4931) [158] 0x01 DW_MACRO_define line 0 __LDBL_MAX_EXP__ 16384 [159] 0x01 DW_MACRO_define line 0 __LDBL_MAX_10_EXP__ 4932 [160] 0x01 DW_MACRO_define line 0 __DECIMAL_DIG__ 21 [161] 0x01 DW_MACRO_define line 0 __LDBL_MAX__ 1.18973149535723176502e+4932L [162] 0x01 DW_MACRO_define line 0 __LDBL_MIN__ 3.36210314311209350626e-4932L [163] 0x01 DW_MACRO_define line 0 __LDBL_EPSILON__ 1.08420217248550443401e-19L [164] 0x01 DW_MACRO_define line 0 __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L [165] 0x01 DW_MACRO_define line 0 __LDBL_HAS_DENORM__ 1 [166] 0x01 DW_MACRO_define line 0 __LDBL_HAS_INFINITY__ 1 [167] 0x01 DW_MACRO_define line 0 __LDBL_HAS_QUIET_NAN__ 1 [168] 0x01 DW_MACRO_define line 0 __DEC32_MANT_DIG__ 7 [169] 0x01 DW_MACRO_define line 0 __DEC32_MIN_EXP__ (-94) [170] 0x01 DW_MACRO_define line 0 __DEC32_MAX_EXP__ 97 [171] 0x01 DW_MACRO_define line 0 __DEC32_MIN__ 1E-95DF [172] 0x01 DW_MACRO_define line 0 __DEC32_MAX__ 9.999999E96DF [173] 0x01 DW_MACRO_define line 0 __DEC32_EPSILON__ 1E-6DF [174] 0x01 DW_MACRO_define line 0 __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF [175] 0x01 DW_MACRO_define line 0 __DEC64_MANT_DIG__ 16 [176] 0x01 DW_MACRO_define line 0 __DEC64_MIN_EXP__ (-382) [177] 0x01 DW_MACRO_define line 0 __DEC64_MAX_EXP__ 385 [178] 0x01 DW_MACRO_define line 0 __DEC64_MIN__ 1E-383DD [179] 0x01 DW_MACRO_define line 0 __DEC64_MAX__ 9.999999999999999E384DD [180] 0x01 DW_MACRO_define line 0 __DEC64_EPSILON__ 1E-15DD [181] 0x01 DW_MACRO_define line 0 __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD [182] 0x01 DW_MACRO_define line 0 __DEC128_MANT_DIG__ 34 [183] 0x01 DW_MACRO_define line 0 __DEC128_MIN_EXP__ (-6142) [184] 0x01 DW_MACRO_define line 0 __DEC128_MAX_EXP__ 6145 [185] 0x01 DW_MACRO_define line 0 __DEC128_MIN__ 1E-6143DL [186] 0x01 DW_MACRO_define line 0 __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL [187] 0x01 DW_MACRO_define line 0 __DEC128_EPSILON__ 1E-33DL [188] 0x01 DW_MACRO_define line 0 __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL [189] 0x01 DW_MACRO_define line 0 __REGISTER_PREFIX__ [190] 0x01 DW_MACRO_define line 0 __USER_LABEL_PREFIX__ _ [191] 0x01 DW_MACRO_define line 0 __GNUC_STDC_INLINE__ 1 [192] 0x01 DW_MACRO_define line 0 __NO_INLINE__ 1 [193] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 [194] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 [195] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 [196] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 [197] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_BOOL_LOCK_FREE 2 [198] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR_LOCK_FREE 2 [199] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 [200] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 [201] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 [202] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_SHORT_LOCK_FREE 2 [203] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_INT_LOCK_FREE 2 [204] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_LONG_LOCK_FREE 2 [205] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_LLONG_LOCK_FREE 2 [206] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 [207] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_POINTER_LOCK_FREE 2 [208] 0x01 DW_MACRO_define line 0 __GCC_HAVE_DWARF2_CFI_ASM 1 [209] 0x01 DW_MACRO_define line 0 __PRAGMA_REDEFINE_EXTNAME 1 [210] 0x01 DW_MACRO_define line 0 __SIZEOF_WCHAR_T__ 2 [211] 0x01 DW_MACRO_define line 0 __SIZEOF_WINT_T__ 2 [212] 0x01 DW_MACRO_define line 0 __SIZEOF_PTRDIFF_T__ 4 [213] 0x01 DW_MACRO_define line 0 __i386 1 [214] 0x01 DW_MACRO_define line 0 __i386__ 1 [215] 0x01 DW_MACRO_define line 0 i386 1 [216] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT80__ 12 [217] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT128__ 16 [218] 0x01 DW_MACRO_define line 0 __ATOMIC_HLE_ACQUIRE 65536 [219] 0x01 DW_MACRO_define line 0 __ATOMIC_HLE_RELEASE 131072 [220] 0x01 DW_MACRO_define line 0 __GCC_ASM_FLAG_OUTPUTS__ 1 [221] 0x01 DW_MACRO_define line 0 __i586 1 [222] 0x01 DW_MACRO_define line 0 __i586__ 1 [223] 0x01 DW_MACRO_define line 0 __pentium 1 [224] 0x01 DW_MACRO_define line 0 __pentium__ 1 [225] 0x01 DW_MACRO_define line 0 __code_model_32__ 1 [226] 0x01 DW_MACRO_define line 0 __SEG_FS 1 [227] 0x01 DW_MACRO_define line 0 __SEG_GS 1 [228] 0x01 DW_MACRO_define line 0 _X86_ 1 [229] 0x01 DW_MACRO_define line 0 __stdcall __attribute__((__stdcall__)) [230] 0x01 DW_MACRO_define line 0 __fastcall __attribute__((__fastcall__)) [231] 0x01 DW_MACRO_define line 0 __thiscall __attribute__((__thiscall__)) [232] 0x01 DW_MACRO_define line 0 __cdecl __attribute__((__cdecl__)) [233] 0x01 DW_MACRO_define line 0 _stdcall __attribute__((__stdcall__)) [234] 0x01 DW_MACRO_define line 0 _fastcall __attribute__((__fastcall__)) [235] 0x01 DW_MACRO_define line 0 _thiscall __attribute__((__thiscall__)) [236] 0x01 DW_MACRO_define line 0 _cdecl __attribute__((__cdecl__)) [237] 0x01 DW_MACRO_define line 0 __GXX_MERGED_TYPEINFO_NAMES 0 [238] 0x01 DW_MACRO_define line 0 __GXX_TYPEINFO_EQUALITY_INLINE 0 [239] 0x01 DW_MACRO_define line 0 __MSVCRT__ 1 [240] 0x01 DW_MACRO_define line 0 __MINGW32__ 1 [241] 0x01 DW_MACRO_define line 0 _WIN32 1 [242] 0x01 DW_MACRO_define line 0 __WIN32 1 [243] 0x01 DW_MACRO_define line 0 __WIN32__ 1 [244] 0x01 DW_MACRO_define line 0 WIN32 1 [245] 0x01 DW_MACRO_define line 0 __WINNT 1 [246] 0x01 DW_MACRO_define line 0 __WINNT__ 1 [247] 0x01 DW_MACRO_define line 0 WINNT 1 [248] 0x01 DW_MACRO_define line 0 _INTEGRAL_MAX_BITS 64 [249] 0x01 DW_MACRO_define line 0 __declspec(x) __attribute__((x)) [250] 0x01 DW_MACRO_define line 0 __DECIMAL_BID_FORMAT__ 1 [251] 0x03 DW_MACRO_start_file line 0 file number 1 c:/Users/dandelot/test.c [252] 0x03 DW_MACRO_start_file line 1 file number 2 c:/mingw/include/stdio.h [253] 0x01 DW_MACRO_define line 51 _STDIO_H [254] 0x03 DW_MACRO_start_file line 56 file number 3 c:/mingw/include/_mingw.h [255] 0x01 DW_MACRO_define line 34 __MINGW_H [256] 0x01 DW_MACRO_define line 49 __MINGW32_VERSION 5000001L [257] 0x01 DW_MACRO_define line 50 __MINGW32_MAJOR_VERSION 5 [258] 0x01 DW_MACRO_define line 51 __MINGW32_MINOR_VERSION 0 [259] 0x01 DW_MACRO_define line 52 __MINGW32_PATCHLEVEL 1 [260] 0x03 DW_MACRO_start_file line 66 file number 4 c:/mingw/include/msvcrtver.h [261] 0x01 DW_MACRO_define line 34 _MSVCRTVER_H [262] 0x01 DW_MACRO_define line 42 __MSVCR60_DLL 0x0600 [263] 0x01 DW_MACRO_define line 43 __MSVCR61_DLL 0x0601 [264] 0x01 DW_MACRO_define line 44 __MSVCR70_DLL 0x0700 [265] 0x01 DW_MACRO_define line 45 __MSVCR71_DLL 0x0701 [266] 0x01 DW_MACRO_define line 46 __MSVCR80_DLL 0x0800 [267] 0x01 DW_MACRO_define line 47 __MSVCR90_DLL 0x0900 [268] 0x01 DW_MACRO_define line 48 __MSVCR100_DLL 0x1000 [269] 0x01 DW_MACRO_define line 49 __MSVCR110_DLL 0x1100 [270] 0x01 DW_MACRO_define line 50 __MSVCR120_DLL 0x1200 [271] 0x01 DW_MACRO_define line 68 __MSVCRT_VERSION__ __MSVCR60_DLL [272] 0x04 DW_MACRO_end_file [273] 0x03 DW_MACRO_start_file line 73 file number 5 c:/mingw/include/w32api.h [274] 0x01 DW_MACRO_define line 34 _W32API_H [275] 0x01 DW_MACRO_define line 51 __W32API_VERSION 5000001L [276] 0x01 DW_MACRO_define line 52 __W32API_MAJOR_VERSION 5 [277] 0x01 DW_MACRO_define line 53 __W32API_MINOR_VERSION 0 [278] 0x01 DW_MACRO_define line 54 __W32API_PATCHLEVEL 1 [279] 0x03 DW_MACRO_start_file line 59 file number 6 c:/mingw/include/sdkddkver.h [280] 0x01 DW_MACRO_define line 34 _SDKDDKVER_H [281] 0x01 DW_MACRO_define line 41 OSVERSION_MASK 0xFFFF0000 [282] 0x01 DW_MACRO_define line 42 SPVERSION_MASK 0x0000FF00 [283] 0x01 DW_MACRO_define line 43 SUBVERSION_MASK 0x000000FF [284] 0x01 DW_MACRO_define line 48 OSVER(ver) ((ver) & OSVERSION_MASK) [285] 0x01 DW_MACRO_define line 49 SPVER(ver) (((ver) & SPVERSION_MASK) >> 8) [286] 0x01 DW_MACRO_define line 50 SUBVER(ver) ((ver) & SUBVERSION_MASK) [287] 0x01 DW_MACRO_define line 51 WINNTVER(ver) ((ver) >> 16) [288] 0x01 DW_MACRO_define line 55 NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT(ver) [289] 0x01 DW_MACRO_define line 56 _NTDDI_VERSION_FROM_WIN32_WINNT(ver) ver ##0000 [290] 0x01 DW_MACRO_define line 62 _WIN32_WINNT_NT4 0x0400 [291] 0x01 DW_MACRO_define line 63 _WIN32_WINNT_NT4E 0x0401 [292] 0x01 DW_MACRO_define line 64 _WIN32_WINNT_NT4SP3 0x0403 [293] 0x01 DW_MACRO_define line 65 _WIN32_WINDOWS_95 0x0400 [294] 0x01 DW_MACRO_define line 66 _WIN32_WINDOWS_98 0x0410 [295] 0x01 DW_MACRO_define line 67 _WIN32_WINDOWS_ME 0x0490 [296] 0x01 DW_MACRO_define line 68 _WIN32_WINNT_WIN2K 0x0500 [297] 0x01 DW_MACRO_define line 69 _WIN32_WINNT_WINXP 0x0501 [298] 0x01 DW_MACRO_define line 70 _WIN32_WINNT_WS03 0x0502 [299] 0x01 DW_MACRO_define line 71 _WIN32_WINNT_WIN6 0x0600 [300] 0x01 DW_MACRO_define line 72 _WIN32_WINNT_VISTA 0x0600 [301] 0x01 DW_MACRO_define line 73 _WIN32_WINNT_WS08 0x0600 [302] 0x01 DW_MACRO_define line 74 _WIN32_WINNT_LONGHORN 0x0600 [303] 0x01 DW_MACRO_define line 75 _WIN32_WINNT_WIN7 0x0601 [304] 0x01 DW_MACRO_define line 76 _WIN32_WINNT_WIN8 0x0602 [305] 0x01 DW_MACRO_define line 77 _WIN32_WINNT_WINBLUE 0x0603 [306] 0x01 DW_MACRO_define line 82 _WIN32_IE_IE50 0x0500 [307] 0x01 DW_MACRO_define line 83 _WIN32_IE_IE501 0x0501 [308] 0x01 DW_MACRO_define line 84 _WIN32_IE_IE55 0x0550 [309] 0x01 DW_MACRO_define line 85 _WIN32_IE_IE56 0x0560 [310] 0x01 DW_MACRO_define line 86 _WIN32_IE_IE60 0x0600 [311] 0x01 DW_MACRO_define line 87 _WIN32_IE_IE60SP1 0x0601 [312] 0x01 DW_MACRO_define line 88 _WIN32_IE_IE60SP2 0x0603 [313] 0x01 DW_MACRO_define line 89 _WIN32_IE_IE70 0x0700 [314] 0x01 DW_MACRO_define line 90 _WIN32_IE_IE80 0x0800 [315] 0x01 DW_MACRO_define line 92 _WIN32_IE_IE30 0x0300 [316] 0x01 DW_MACRO_define line 93 _WIN32_IE_IE301 0x0301 [317] 0x01 DW_MACRO_define line 94 _WIN32_IE_IE302 0x0302 [318] 0x01 DW_MACRO_define line 95 _WIN32_IE_IE40 0x0400 [319] 0x01 DW_MACRO_define line 96 _WIN32_IE_IE401 0x0401 [320] 0x01 DW_MACRO_define line 101 __NTDDI_WIN5 0x05000000 [321] 0x01 DW_MACRO_define line 102 __NTDDI_WIN51 0x05010000 [322] 0x01 DW_MACRO_define line 103 __NTDDI_WIN52 0x05020000 [323] 0x01 DW_MACRO_define line 104 __NTDDI_WIN6 0x06000000 [324] 0x01 DW_MACRO_define line 105 __NTDDI_WIN61 0x06010000 [325] 0x01 DW_MACRO_define line 106 __NTDDI_WIN62 0x06020000 [326] 0x01 DW_MACRO_define line 107 __NTDDI_WIN63 0x06030000 [327] 0x01 DW_MACRO_define line 108 __NTDDI_SP0 0x00000000 [328] 0x01 DW_MACRO_define line 109 __NTDDI_SP1 0x00000100 [329] 0x01 DW_MACRO_define line 110 __NTDDI_SP2 0x00000200 [330] 0x01 DW_MACRO_define line 111 __NTDDI_SP3 0x00000300 [331] 0x01 DW_MACRO_define line 112 __NTDDI_SP4 0x00000400 [332] 0x01 DW_MACRO_define line 114 NTDDI_WIN2K __NTDDI_WIN5 + __NTDDI_SP0 [333] 0x01 DW_MACRO_define line 115 NTDDI_WIN2KSP1 __NTDDI_WIN5 + __NTDDI_SP1 [334] 0x01 DW_MACRO_define line 116 NTDDI_WIN2KSP2 __NTDDI_WIN5 + __NTDDI_SP2 [335] 0x01 DW_MACRO_define line 117 NTDDI_WIN2KSP3 __NTDDI_WIN5 + __NTDDI_SP3 libdwarf-20210528/dwarfdump/esb.h0000644000175000017500000001220414003123100013364 00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* esb.h Extensible string buffer. A simple vaguely object oriented extensible string buffer. The struct could be opaque here, but it seems ok to expose the contents: simplifies debugging. */ #ifndef ESB_H #define ESB_H #include "config.h" #include #include /* For va_start va_arg va_list */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If esb_allocated_size > 0 then esb_string points to esb_allocated_size bytes and esb_used bytes <= (esb_allocated_size -1) All operations that insert or return strings ensure, first, that esb_allocated_size is non-zero and the requirements here are met. In esb_constructor esb_allocated_size and esb_used_bytes and esb_string are set 0. No malloc done. Default init alloc sets esb_allocated_size=alloc_size and mallocs alloc_size bytes. and esb_used_bytes = 0 and esb_string[0] = NUL. */ struct esb_s { char * esb_string; /* pointer to the data itself, or NULL. */ size_t esb_allocated_size; /* Size of allocated data or 0 The allocated size must include the trailing NUL as we do insert a NUL. */ size_t esb_used_bytes; /* Amount of space used or 0, which does not include the trailing NUL. Matches what strlen(esb_string) would return. */ /* rigid means never do malloc. fixed means the size is a user buffer but if we run out of room feel free to malloc space (and then unset esb_fixed). An esb can be (fixed and rigid), (fixed and not rigid), or (not fixed and not rigid). */ char esb_fixed; char esb_rigid; }; /* Mirroring the broken code in libdwarf.h.in */ typedef long long esb_int; typedef unsigned long long esb_unsigned; /* Open/close the null device used during formatting printing */ FILE *esb_open_null_device(void); void esb_close_null_device(void); /* string length taken from string itself. */ void esb_append(struct esb_s *data, const char * in_string); /* The 'len' is believed. Do not pass in strings < len bytes long. */ void esb_appendn(struct esb_s *data, const char * in_string, size_t len); /* Always returns an empty string or a non-empty string. Never 0. */ char * esb_get_string(struct esb_s *data); /* Sets esb_used_bytes to zero. The string is not freed and esb_allocated_size is unchanged. */ void esb_empty_string(struct esb_s *data); /* Return esb_used_bytes. */ size_t esb_string_len(struct esb_s *data); /* The following are for testing esb, not use by dwarfdump. */ /* *data is presumed to contain garbage, not values, and is properly initialized. */ void esb_constructor(struct esb_s *data); void esb_constructor_rigid(struct esb_s *data, char *buf,size_t buflen); void esb_constructor_fixed(struct esb_s *data, char *buf,size_t buflen); void esb_force_allocation(struct esb_s *data, size_t minlen); /* The string is freed, contents of *data set to zeroes. */ void esb_destructor(struct esb_s *data); /* To get all paths in the code tested, this sets the allocation/reallocation to the given value, which can be quite small but must not be zero. */ void esb_alloc_size(size_t size); size_t esb_get_allocated_size(struct esb_s *data); /* Append a formatted string */ void esb_append_printf(struct esb_s *data,const char *format, ...); void esb_append_printf_s(struct esb_s *data, const char *format,const char *s); void esb_append_printf_i(struct esb_s *data, const char *format,esb_int); void esb_append_printf_u(struct esb_s *data, const char *format,esb_unsigned); /* Get a copy of the internal data buffer */ char * esb_get_copy(struct esb_s *data); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ESB_H */ libdwarf-20210528/dwarfdump/ChangeLog20180000664000175000017500000006412313644370703014567 000000000000002018-12-24 David Anderson * dwarfdump.1: Clarifying the effect of any - or -- option on the output of dwarfdump. 2018-12-21 David Anderson * command_options.c: Reformat a few lines of the usage text so it all prints in around 70 characters without overlap. 2018-12-20 David Anderson * dwarfdump.1: Clarifying: the abi=ppc etc options are only made use of if -a, -F, or -f (or the long versions of these) are used. 2018-12-20 David Anderson * dwarfdump.c,dwconf_using_functions.h,esb_using_functions.h: Removing trailing whitespace,empty last lines. 2018-12-20 David Anderson * globals.h: Removed include of * esb.c: Now includes 2018-12-20 David Anderson * print_frames.c: Now properly deals with endian mismatch in printing frame instruction details and avoids requiring we have a precise definiion of type lengths. * CMakeLists.txt,Makefile.am: Adding memcpy_swap.h. New header. 2018-12-19 David Anderson * CMakeLists.txt: Now has dwconf_using_functions.h and esb_using_functions.h listed so cmake works. * Makefile.am: Added new header dwconf_using_functions.h * dwarfdump.c: Includes new header. * globals.h: Remove dwconf_s forward decl, remove dwconf-using functions. * dwconf_using_functions.h: New, has the function declarations removed from globals.h * print_abbrevs.c,print_aranges.c, print_dnames.c, print_lines.c,print_locs.c,print_macro.c, print_macros.c,print_pubnames.c,print_section_groups.c, print_sections.c,print_static_funcs.c, print_static_vars.c,print_str_offsets.c, print_strings.c,print_types.c,print_weaknames.c: Removed include of "dwconf.h" * print_frames.c: Includes new header dwconf_using_functions.h. 2018-12-19 David Anderson * Makefile.am: Added new header esb_using_functions.h with content extracted from globals.h. * globals.h: Remove forward decl of esb_s and remove functions using that to esb_using_functions.h * dwarfdump.c,print_abbrevs.c,print_aranges.c, print_debugfission.c,print_die.c,print_dnames.c, print_frames.c,print_gdbindex.c,print_lines.c, print_locs.c,print_macro.c,print_macros.c,print_pubnames.c, print_ranges.c,print_static_funcs.c,print_static_vars.c, print_str_offsets.c,print_strings.c,print_types.c, print_weaknames.c,print_true_section_name.c: Include esb_using_functions.h 2018-12-19 David Anderson * globals.h: Removed an include of section_bitmaps.h and duplicate lines about UNUSEDARG. * command_options.c: Now includes section_bitmaps.h. * section_bitmaps.c: Now includes section_bitmaps.h. 2018-12-19 David Anderson * dwarfdump.c: Moved elf-header printing to print_reloc.c (print_object_header()). Removed elf argument from print_object_header(). * globals.h: Removed elf argument from print_object_header(). * print_reloc.c: Now all the elf header/sym/reloc printing is in this one file. 2018-12-19 David Anderson * dwarfdump.c: Now uses the new libdwarf function dwarf_errmsg_by_number() so we get more specific messages about problems when all we have is an errorcode. 2018-12-07 David Anderson * dwarfdump.1: -E missed its long-form (--elf) and -h (--help) was improperly documented. 2018-11-26 David Anderson * dwarfdump.c: Now dumps DWARF from PE objects. 2018-11-01 David Anderson * strstrnocase.c had include which is now "globals.h" as it was always supposed to be. 2018-10-30 David Anderson * dwarfdump.1: Now shows long and short options. For a few options it references the help file. * command_options.c: The available help options are now -h and --help, and both report the new options list with both short and long options shown. 2018-10-26 David Anderson * dwarfdump.c: A single instance of a malloc in main() had no associated free(). Memory Leak of a couple hundred bytes exactly once per run of dwarfdump. Now we free(). 2018-10-19 David Anderson * command_options.c,glflags.c,glflags.h: New option --file-use-no-libelf, function arg_file_use_no_libelf(), glflags.gf_file_use_no_libelf now exist. * dwarfdump.c: process_one_file() and main() are refactored to allow additional object files. 2018-09-29 David Anderson * command_options.c: Fixed indent issues. 2018-09-26 Carlos Alberto Enciso * command_options.c: At this point, the regression test pass, with the exception of 2 test cases, that verify the output from the '-h' option, which fails due to missing options in the usage data. 2018-09-25 Carlos Alberto Enciso * command_options.c: Add support for long name options that expect an argument by using the same code from the short options. 2018-09-25 Carlos Alberto Enciso * command_options.c: Add -he and --help-extended to display usage for the long name options. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add support for long name options. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add missing desriptions in the usage message for -q, -U, -x line5 and -x noprintsettinggroups. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add missing desriptions in the usage message for -EI, -Em and -kw. 2018-09-20 Carlos Alberto Enciso * command_options.c: Move the code associated with each sub-option, to an individual function. Preliminary work for the implementation of long name options. 2018-09-19 Carlos Alberto Enciso * command_options.c: Move the code associated with each option, to an individual function. Preliminary work for the implementation of long name options. * glflags.h, glflags.c: New field to record the full program name. It is used by the '-V' option. 2018-09-21 David Anderson * Makefile.am: Ensured cmake files get into distributions. and the CODINGSTYLE text too. 2018-09-12 David Anderson * esb.c: Corrected the use of HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson & Carlos Alberto Enciso * dwconf.c: Fixed typo in a comment. * dwarf_tsearchbal.c: int->size_t three places. A couple too-long lines indented. Matches tsearch directory version now. * esb.c: The test for _WIN32 in looking at printf formats also allows config.h define HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson & Carlos Alberto Enciso * dwarfdump.c: Simplify the WIN32 code redirecting stderr to stdout as earlier workarounds no longer needed. Printing of parts of an Elf32 header had the wrong printf format-- fixed. * print_die.c: An implicit fallthrough to case DW_AT_LOCATION about line 2943 generates a warning with --enable-wall so added a comment to make it clear to readers this is intended. 2018-09-02 David Anderson * Makefile.am: Changed the way to build tag_tree and tag_attr executables to the automake way, eliminating make warnings when building. * Makefile.in: regenerated. 2018-08-23 David Anderson * CMakeLists.txt: Adjusted to fit new/changed file names. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall * print_die.c,print_ranges.c,print_strings.c: Removed unused variables. * print_dnames.c: Removed unused variables and fixed the section-name print (.debug_str-> .debug_names). 2018-08-14 David Anderson * Makefile.am: CPPFLAGS_FOR_BUILD a few places it was accidentally omitted. 2018-08-09 David Anderson * Makefile.am: Added AM_TESTS_ENVIRONMENT enabling make check from any build directory. Also,add getopttest.c and testesb.c to the files in a release so make check can work * runtests.sh: Handle the environment variable AM_TESTS_ENVIRONMENT sets: DWTOPSRCDIR 2018-08-08 David Anderson * Makefile.am: corrected dwarfdump_DATA reference to be dwarfdumpdev_DATA 2018-08-07 David Anderson * dwconf.c: Removed trailing whitespace. * globals.h: Added DWARF_SECNAME_BUFFER_SIZE define (space for a small string) so if it need change there is just one place to change it. Used in many files with esb_constructor_fixed().. * print_abbrevs.c,print_die.c,print_locs.c,print_strings.c: Refactored the section name printing into a function and call after calling libdwarf so the interesting section compression info is available to print. * print_aranges.c,print_pubnames.c, print_ranges.c, print_static_funcs.c,print_static_vars.c,print_weaknames.c: Moved a libdwarf call above the section name print so the interesting section compression info is available to print. * print_dnames.c,print_frames.c: Removed trailing whitespace, use DWARF_SECNAME_BUFFER_SIZE. * print_gdbindex.c,print_lines.c,print_macro.c, print_macros.c,print_str_offsets.c: Use DWARF_SECNAME_BUFFER_SIZE . * true_section_name.c: Now prints compression values. 2018-08-06 David Anderson * globals.h: Added DWARF_SECNAME_BUFFER_SIZE for the esb preallocation of section names. * print_abbrevs.c,print_aranges.c,print_debugfission.c, print_die.c,print_dnames.c,print_frames.c, print_gdbindex.c,print_lines.c,print_locs.c,print_macro.c, print_macros.c,print_pubnames.c,print_ranges.c, print_static_funcs.c,print_static_vars.c,print_str_offsets.c, print_strings.c,print_types.c,print_weaknames.c: Now uses DWARF_SECNAME_BUFFER_SIZE instead of plain 40. * print_die.c: In print_ranges_list_to_extra() we do not want the section name to have the compressed-notes appear. * print_lines.c: In print_line_numbers_this_cu() we do not want the section name to have the compressed-notes appear. * print_ranges.c: In check_ranges_list() we do not want the section name to have the compressed-notes appear. * true_section_name.c: Added a pointer argument to get_true_section_name() so it returns three distinct compression flags. one for .zdebug*, one for SHF_COMPRESSED, and one for a ZLIB initial byte group in the section. 2018-08-05 David Anderson * Makefile.am: Fixed dwarfdump_CFLAGS to set CONFPREFIX * command_options.c Fixed config_file_defaults[] to honor CONFPREFIX sensibly. * globals.h: Declares get_true_section_name(), a new function/refactoring so section names print more usefully. * true_section_name.c: New. Implements get_true_section_name(). * print_abbrevs.c, print_aranges.c, print_debugfission.c, print_die.c, print_dnames.c, print_frames.c, print_gdbindex.c, print_lines.c, print_locs.c, print_macro.c, print_macros.c, print_pubnames.c, print_ranges.c, print_static_funcs.c, print_static_vars.c, print_str_offsets.c, print_strings.c, print_types.c, print_weaknames.c. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. * Makefile.in: Regenerated (usually won't mention this). 2018-07-31 David Anderson * command_options.c: New option --print-debug-names. * print_dnames.c: Giving print_debug_names() some content. 2018-07-30 David Anderson * command_options.c: For abbreviation checking also try running print_abbrevs() with its checks. * print_abbrevs.c: If checking turn off normal printing, just print checking issues. 2018-07-30 David Anderson * tag_attr.list,tag_attr_ext.list,tag_common.h,tag_tree.list, tag_tree_ext.list: Some important relationships needed to be added to avoid -ka warnings about normal DWARF. And the table sizes are just a tiny bit bigger. 2018-07-13 David Anderson * Makefile.am: Add dwarfdump.1 to output. Move COPYRIGHT and a few files out of the installed set, leaving just dwarfdump.1, and libdwarf*pdf in /usr/local/share. * command_options.c: Removed duplicate extern declaration of dwoptind. 2018-07-16 David Anderson * dwarf_tsearch.h: Corrected web-reference links in the comments. * uritableblebuild.c: Changed some commentary to have shorter line lengths. Added comment explaining how the source was used in creating uri.c . * common.c: Refines the ifdef HAVE_STDAFX_H. * dwarf_tsearch.h: Remove obsolete link in comment and substitute a valid link. * dwarf_tsearchbal.c: Remove include of dwarf_incl.h and use config.h to set UNUSEDARG as appropriate. * dwconf.c,globals.h: Refines the ifdef HAVE_STDAFX_H. * uritablebuild.c: Reformat initial comments to fit on shorter lines. 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-21 David Anderson * esb.c: For _WIN32 a closing } was missing int two places. Fixed. 2018-06-19 David Anderson * common.c: Added missing ; for Windows code * dwconf.c: ifdef _WIN32, not a HAVE* name. Spell include windows.h not Windows.h for maximum compatibility. 2018-06-13 David Anderson * Remove mention of HAVE_NONSTANDARD_PRINTF. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * dwarfdump.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-10 David Anderson * checkutil.c: Fixed indentation mistake. * common.c: Removed trailing blank. 2018-06-10 David Anderson * checkutil.c: snprintf-> esb * common.c: snprint -> printf * dwarf_tsearchbal.c: snprintf -> sprintf, it is safe. * naming.c: snprintf-> esb. * print_die.c: Trimmed the size of a buffer in a safe sprintf use. * esb.c: Modified to remove an implementation-defined conversion issue. 2018-06-10 David Anderson * esb.c: Added checks so passing %s to _d or _u gets a useful output (an ESBERR string). * print_abbrevs.c,print_die.c,print_lines.c: Converted all sprintf to the new esb_append_printf_s,i,u. 2018-06-09 David Anderson * esb.c: Fixed an issue printing the most-negative integer. * print_die.c: Now all the relevant places avoid s[n]printf. 2018-06-09 David Anderson * esb.c, testesb.c: These now support and test %+d. * print_die.c: Used esb_constructor_fixed() and esb_append_printf_s,_i,_u(), replacing many s[n]printf. 2018-06-08 David Anderson * Makefile.in: Altered the esb testing lines. * testesb.c: Now this is the esb test code. * esb.c: Removed test code, moved to testesb.c. Added esb_append_printf_s(), esb_append_printf_i() and esb_append_printf_u() to get faster formatting without any varargs. 2018-06-07 David Anderson * print_frames.c: Vincent T. noticed unnecessary and/or incorrect casts, here fixed. Also fixed some too-long lines -- changed the existing line break to a better place. 2018-06-05 David Anderson * dwarfdump.c: Remove erroneous _MSC_VER per Carlos Alberto Enciso. Change WIN32 to _WIN32. 2018-05-26 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Remove DW_VERSION_DATE_STR and #include ../libdwarf/libdwarf_version.h to provide it. 2018-05-26 David Anderson * dwarfdump.c,tag_attr.c,tag_tree.c, common.c: Update version string 2018-05-23 David Anderson * esb.c, esb.h: Added esb_constructor_fixed() and new fields in esb_s to support use of a static buffer so normally no malloc needed when using the esb. * print_frames.c: Changed, where appropriate, to use esb_constructor_fixed. * dwarfdump/sanitized.c: The static initializer of all zero needed update for the new esb_s declaration. 2018-05-22 David Anderson * glflags.h, glflags.c: set_checks_off(void) needed the (void) as argument to be a C90 prototype. 2018-05-22 David Anderson * esb.c: Changed INITIAL_ALLOC to 100 as experiments show that a length in a range near 100 gives the best runtimes, by 10-20% user time. 2018-05-22 David Anderson * glflags.c: Removed the c99 'for (int i=0;' and declare the 'i' separately. 2018-05-20 David Anderson * dwarfdump.c: Change strcpy to safe_strcpy. Comment a safe sprintf call. * glflags.c: Change strcpy to safe_strcpy and fix indents. * dwconf.c: Change strcpy to safe_strcpy. * print_frames.c: Change snprintf to esb_append. Change the name of a local pointer to make it clearer it is not the same as other similar local variables. Use esb instead of char *, Change strcpy to safe_strcpy (and eliminate strcat). * print_gdbindex.c: Reinserted return statement that was accidentally dropped. * print_lines.c,print_macros.c: Remove trailing whitespace. * print_ranges.c: Remove trailing whitespace. * tag_attr.c: Remove unused 'len' local variable, 3 places. 2018-05-19 David Anderson * print_die.c,print_lines.c,print_macros.c,print_gdbindex.c, print_pubnames.c,print_ranges.c: Replace snprintf with esb_append_printf. * sanitized.c: Deleted a function call and snprintf with simple esb_append_printf. 2018-05-17 David Anderson * Makefile.in: Adding esb.c to build time of tag_tree_build and tag_attr_build. See besb.o * config.h.in: #undef for HAVE_VSNPRINTF and HAVE_SNPRINTF * configure: regenerated * configure.ac: Added AC_CHECK_FUNCS(snprintf), AC_CHECK_FUNCS(vsnprintf) * esb.c: Removed static buffers. No longer needed. Allocated extra byte in esb_force_allocation() and in calls to esb_allocate_more. Checks HAVE_VSNPRINTF. Added extra checks of esb_append_printf(). Moved one static function up in the source to eliminate an explicit prototype. * esb.h: Added comments documenting esb_s field use. * print_die.c,print_reloc.c,tag_attr.c, tag_tree.c,uri.c: Removed snprintf,sprintf. Using esb_append_printf. * makename.c: Removed noise from selftest, just print pass/fail. 2018-05-16 David Anderson * dwarfdump.c,esb.c,esb.h,globals.h: Removed of C99 vsnprintf and completely removed esb_printf_append_ap() from esb. 2018-05-15 David Anderson * tmp-tt-table.c,tmp-ta-table.c,tmp-ta-ext-table.c, tmp-tt-ext-table.c: All endings changed from .c to .h as these are all used via #include. * Makefile.in: Reflect the .c->.h change for these files. * checkutil.c,dwarf_tsearch.h,dwarf_tsearchbal.c, glflags.c,naming.c,naming.h,print_debugfission.c, print_die.c,print_frames.c,print_gdbindex.c,print_macros.c, print_pubnames.c,print_reloc.h,print_sections.c, print_static_vars.c,uri.c,uritablebuild.c: Removed trailing blank lines. 2018-05-15 David Anderson * command_options.c: Removed an extra break on option -ER that was an accident. It's been broken for quite a long time. section_map[DW_HDR_DEBUG_RNGLISTS]=TRUE, applicable to DWARF5, was getting ignored due to the mistake. This has to do with printing section header information. 2018-05-14 David Anderson * command_options.c,compiler_info.c,print_frames.c: Fix indents, remove trailing whitespace. 2018-05-14 David Anderson * dwarfdump.c,tag_attr.c,tag_tree.c, common.c: Update version string 2018-05-14 David Anderson * print_frames.c: Validate augmentation bytes from eh_frame to catch bogus augmentation length. 2018-05-14 David Anderson * dwarfdump.c: gcc caught a memset given a pointer as the size. Fixed. * naming.c: Needed #ifndef TRIVIAL_NAMING around skipunder() to compile without warnings. * section_bitmaps.c, section_bitmaps.h: Needed (void) as function argument list, for example set_all_sections_on(void) . 2018-05-14 Carlos Alberto Enciso * Rename producer_info.[ch] to compiler_info.[ch]. 2018-05-11 Carlos Alberto Enciso * New files: command_options.c,command_options.h Command line arguments processing; the original code moved from dwarfdump.c. * New files: producer_info.c,producer_info.h Record statistics about the producers (compilers). The original code moved from dwarfdump.c. * glflags.c,glflags.h,globals.h: Moved the remaining individual global flags and what they control into glflags.h. * section_bitmaps.c,section_bitmaps.h: process the header and relocation maps. Original code moved from dwarfdump.c * dwarfdump.c: Moved the code for command line arguments processing to command_options.c and producer_info.c. * print_reloc.c,sanitized.h,defined_types.h,dwconf.c,print_aranges.c Minor changes due to refactoring of the command line and producer refactoring. 2018-05-09 David Anderson * common.c,dwarfdump.c,glflags.c,glflags.h,print_aranges.c, print_die.c: Fixed indents to match dicheck requirements and removed some trailing whitespace. 2018-05-01 Carlos Alberto Enciso * common.c,dwarfdump.c,dwconf.c,glflags.c,glflags.h,globals.h, naming.c,print_abbrevs.c,print_aranges.c,print_die.c, print_dnames.c,print_frames.c,print_gdbindex.c,print_lines.c, print_locs.c,print_macro.c,print_macros.c,print_pubnames.c, print_ranges.c,print_static_funcs.c,print_static_vars.c, print_strings.c,print_weaknames.c,tag_attr.c,tag_tree.c: Moved the remaining individual global flags and what they control into glflags.h, making it easier to understand what one is looking at when reading the code. 2018-04-22 David Anderson * print_str_offsets.c: Created consistent terminology for the parts of a table and reflecting that in the table output. The DWARF5 standard uses more than one set of terms for the section contents. * dwarfdump.c,tag_attr.c,tag_tree.c: Update version string * common.c: Update version string. Now that usage text in full is only on request it now becomes stdout instead of stderr. 2018-04-19 David Anderson * Makefile.in: Added additional lines to test native getopt_long to verify dwgetopt_long works consistently with GNU getopt_long (for the features tested, anyway). * dwgetopt.c: Better checking for dwgetopt_long correctness. * getopttest.c: Added tests and revised the checking to avoid nasty corner cases. 2018-04-17 David Anderson * dwarfdump.c, dwarfdump.1: The -h option has not been supported for years (it printed an IRIX table of no interest now) so now -h means print the help message showing the options available. * dwgetopt.c: Now prints the name of any incorrect long-option it sees and prints if user-specified =arg on a long option violates requirements . For either returns -1. Should have done that all along. * getopttest.c: Added tests and revised the checking functions to show all the relevant data if a test fails. Added line number of the original test to the output so it's easier to find the actual test. 2018-04-16 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version string 2018-04-14 David Anderson * dwarfdump.1: Add --print-str-offsets. * dwarfdump.c: Add --print-str-offsets to the usage text. 2018-04-13 David Anderson * CMakeLists.txt: Added new source files to cmake info. 2018-04-13 David Anderson * common.c,tag_attr.c,tag_tree.c: Updated version string. * configure.ac: Added a comment about HAVE_LOCATION_OF_LIBELFHEADER * dwarfdump.c: Added support for option --print_str_offsets to print .debug_str_offsets. Updated version string. * glflags.h: Added new flag: boolean gf_print_str_offsets. * globals.h: Added print function print_str_offsets_section() to interfaces. * print_str_offsets.c: New code to print the .debug_str_offsets section independent of anything else. * Makefile.in: Added print_str_offsets.o to targets. 2018-04-06 David Anderson * configure.ac: Previous recent change introduced a mistake. Now we set HAVE_ELF64_R_INFO as intended all along. * configure: Regenerated 2018-04-02 David Anderson * CMakeLists.txt: Added defined_types.h to the set_source_group HEADERS list, but cmake is not currently working with libdwarf or dwarfdump. * configure.ac: Removed AC_CHECK_LIB and replaced with the newer AC_SEARCH_LIBS. Removed two cases using HAVE_LOCATION_OF_LIBELF_HEADER that never worked, it seems. * configure: Regenerated 2018-03-29 David Anderson * configure.ac: Corrected AC_CHECK_HEADERS use. Removed AC_TRY_COMPILE in favor of AC_COMPILE_IFELSE. Revamped checks for libelf and zlib. * configure: regenerated * config.h.in: regenerated 2018-03-28 David Anderson * configure.in renamed configure.ac 2018-03-27 David Anderson * configure.in: Cross compiling tested, working. * configure: regenerated. 2018-03-25 David Anderson * configure.in: Support for cross compiling * configure: regenerated. * Makefile.in: Support for cross compiling 2018-03-25 David Anderson * defined_types.h,dwarfdump/dwarfdump.c,esb.c,esb.h, globals.h,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_macro.c,print_macros.c, print_ranges.c, sanitized.c,sanitized.h,uri.h: Updated copyright year on the merged changes. * getopttest.c: Fixed compiler warnings (this is just for selftest, not usually compiled). 2018-03-25 Carlos Alberto Enciso: * many: Merged header simplifications into master. 2018-03-24 David Anderson * print_lines.c: Now uses dwarf_srclines_files_indexes() to simplify printing of DWARF2,3,4 and 5 line headers in a simple uniform way. 2018-03-22 David Anderson * print_lines.c: Now works with DWARF5 line table, showing correct file index for all versions. 2018-03-21 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Updated version string. 2018-03-21 David Anderson * print_die.c: Add support for DWARF5 FORMs. * print_lines.c: Fix a too-long line. 2018-01-29 David Anderson * print_frames.c: When printing detailed frame data ensure we check for corrupt data. 2018-01-29 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version string libdwarf-20210528/dwarfdump/dwarfdump.conf0000664000175000017500000003642013756630357015351 00000000000000# MIPS/IRIX ISA/ABI # Used to configure dwarfdump printing of .debug_frame and # .eh_frame. # To always format DWARF expressions blocks as all operations on # one line (a limited version of -d (--format-dense)) # without needing to use the dwarfdump option # --format-expr-ops-joined explicitly, # remove the # from the following line. #option: --format-expr-ops-joined # Any number of abi's can be described. Only one can be selected # in a given dwarfdump run (see dwarfdump options) # Available commands are # beginabi: # reg: # frame_interface: # cfa_reg: # initial_reg_value: # same_val_reg: 1035 # undefined_val_reg: 1034 # reg_table_size: # address_size: <4 or 8, Rarely needed, see example below. > # includeabi: # endabi: # # Symbolic names do not work here, use literal numbers # where applicable (in C standard decimal, octal (leading 0) or # hexadecimal ). # # Whitespace is required to separate command: from operands and # operands from each other on a line. # # There is no ordering required within a beginabi/endabi pair. # As many ABIs as required may be listed. # dwarfdump will choose exactly one abi to dump frame information. # # MIPS abi,the old IRIX form, not to be used on modern objects. # Begin with abi name (use here and on dwarfdump command line). beginabi: mips-irix # Instructs dwarfdump to default to the older frame interface. # Use value 3 to use the newer interface. # The '2' interface is supported but deprecated (deprecated # because it cannot work with all popular ABIs: mixing # the cfa-rule into the table column set was not a good idea # but it is part of the MIPS/IRIX standard usage). frame_interface: 2 # If (and only if) using frame_interface: 2 tell dwarfdump # what table colum that DW_FRAME_CFA_COL is. # If using frame_interface: 3 cfa_reg: should be # DW_FRAME_CFA_COL3 (1436) cfa_reg: 0 # For MIPS, the same as DW_FRAME_SAME_VAL (1035). # For other ISA/ABIs 1034 (DW_FRAME_UNDEFINED_VAL) might be better. # Depends on the ABI convention, if set wrong way too many # regs will be listed in the frame output. # This instructs dwarfdump to set libdwarf to this value, # overriding the libdwarf default. # If initial_reg_value not set the libdwarf default is used # (see libdwarf.h DW_FRAME_REG_INITIAL_VALUE). initial_reg_value: 1035 # DW_FRAME_SAME_VAL same_val_reg: 1035 undefined_val_reg: 1034 # Built in to frame_interface: 2 as 66. reg_table_size: 66 # Only name registers for wich a r4 (for example) is not what you # want to see # No particular order of the reg: lines required. reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface reg: r1/at 1 reg: r2/v0 2 reg: r3/v1 3 reg: r4/a0 4 reg: r5/a1 5 reg: r6/a2 6 reg: r7/a3 7 reg: r8/t0 8 reg: r9/t1 9 reg: r10/t2 10 reg: r11/t3 11 reg: r12/t4 12 reg: r13/t5 13 reg: r14/t6 14 reg: r15/t7 15 reg: r16/s0 16 reg: r17/s1 17 reg: r18/s2 18 reg: r19/s3 19 reg: r20/s4 20 reg: r21/s5 21 reg: r22/s6 22 reg: r23/s7 23 reg: r24/t8 24 reg: r25/t9 25 reg: r26/k0 26 reg: r27/k1 27 reg: r28/gp 28 reg: r29/sp 29 reg: r30/s8 30 reg: r31 31 reg: $f0 32 reg: $f1 33 reg: $f2 34 reg: $f3 35 reg: $f4 36 reg: $f5 37 reg: $f6 38 reg: $f7 39 reg: $f8 40 reg: $f9 41 reg: $f10 42 reg: $f11 43 reg: $f12 44 reg: $f13 45 reg: $f14 46 reg: $f15 47 reg: $f16 48 reg: $f17 49 reg: $f18 50 reg: $f19 51 reg: $f20 52 reg: $f21 53 reg: $f22 54 reg: $f23 55 reg: $f24 56 reg: $f25 57 reg: $f26 58 reg: $f27 59 reg: $f28 60 reg: $f29 61 reg: $f30 62 reg: $f31 63 reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-irix # Make 'mips' abi be a modern MIPS, not an old IRIX version. beginabi: mips includeabi: mips-simple3 endabi: mips # MIPS/IRIX ISA/ABI for testing libdwarf. beginabi: mips-irix2 frame_interface: 2 reg_table_size: 66 cfa_reg: 0 same_val_reg: 1035 undefined_val_reg: 1034 initial_reg_value: 1035 reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-irix2 # MIPS/IRIX ISA/ABI for testing the new frame interface # with libdwarf. beginabi: mips-simple3 frame_interface: 3 # When using frame_interface: 3 the size of the register table # is not fixed. It can be as large as needed. reg_table_size: 66 cfa_reg: 1436 # DW_FRAME_CFA_COL3 initial_reg_value: 1035 same_val_reg: 1035 undefined_val_reg: 1034 # No cfa as a 'normal' register. # Rule 0 is just register 0, which is not used # in frame descriptions. # (so cfa does not have a number here, and dwarfdump gives # it the name 'cfa' automatically). reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-simple3 beginabi: ia64 frame_interface: 3 initial_reg_value: 1034 # DW_FRAME_UNDEFINED_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 695 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... # Register indexes r32-r127 not used. reg: f0 128 # ... reg: f127 255 reg: b0 321 reg: b1 322 reg: b2 323 reg: b3 324 reg: b4 325 reg: b5 326 reg: b6 327 reg: b7 328 reg: vfp 329 reg: vrap 330 reg: pr 331 reg: ip 332 reg: psr 333 reg: cfm 334 reg: k0 335 reg: k1 336 reg: k2 337 reg: k3 338 reg: k4 339 reg: k5 340 reg: k6 341 reg: k7 342 reg: rsc 350 reg: bsp 351 reg: bspstore 352 reg: rnat 353 reg: fcr 355 reg: eflag 358 reg: csd 359 reg: ssd 360 reg: cflg 361 reg: fsr 362 reg: fir 363 reg: fdr 364 reg: pfs 398 reg: lc 399 reg: ec 400 endabi: ia64 beginabi: x86 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... reg: eax 0 reg: ecx 1 reg: edx 2 reg: ebx 3 reg: esp 4 reg: ebp 5 reg: esi 6 reg: edi 7 reg: eip 8 reg: eflags 9 reg: trapno 10 reg: st0 11 reg: st1 12 reg: st2 13 reg: st3 14 reg: st4 15 reg: st5 16 reg: st6 17 reg: st7 18 # 19 is ? 20 is ? reg: xmm0 21 reg: xmm1 22 reg: xmm2 23 reg: xmm3 24 reg: xmm4 25 reg: xmm5 26 reg: xmm6 27 reg: xmm7 28 reg: mm0 29 reg: mm1 30 reg: mm2 31 reg: mm3 32 reg: mm4 33 reg: mm5 34 reg: mm6 35 reg: mm7 36 reg: fcw 37 reg: fsw 38 reg: mxcsr 39 reg: es 40 reg: cs 41 reg: ss 42 reg: ds 43 reg: fs 44 reg: gs 45 # 46 47 are ? reg: tr 48 reg: ldtr 49 endabi: x86 beginabi: x86_64 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... reg: rax 0 reg: rdx 1 reg: rcx 2 reg: rbx 3 reg: rsi 4 reg: rdi 5 reg: rbp 6 reg: rsp 7 reg: r8 8 reg: r9 9 reg: r10 10 reg: r11 11 reg: r12 12 reg: r13 13 reg: r14 14 reg: r15 15 reg: rip 16 reg: xmm0 17 reg: xmm1 18 reg: xmm2 19 reg: xmm3 20 reg: xmm4 21 reg: xmm5 22 reg: xmm6 23 reg: xmm7 24 reg: xmm8 25 reg: xmm9 26 reg: xmm10 27 reg: xmm11 28 reg: xmm12 29 reg: xmm13 30 reg: xmm14 31 reg: xmm15 32 reg: st0 33 reg: st1 34 reg: st2 35 reg: st3 36 reg: st4 37 reg: st5 38 reg: st6 39 reg: st7 40 reg: mm0 41 reg: mm1 42 reg: mm2 43 reg: mm3 44 reg: mm4 45 reg: mm5 46 reg: mm6 47 reg: mm7 48 reg: rflags 49 reg: es 50 reg: cs 51 reg: ss 52 reg: ds 53 reg: fs 54 reg: gs 55 # 56, 57 are ? reg: fs.base 58 reg: gs.base 59 # 60 61 are ? reg: tr 62 reg: ldtr 63 endabi: x86_64 beginabi: m68k frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 reg: d0 0 reg: d1 1 reg: d2 2 reg: d3 3 reg: d4 4 reg: d5 5 reg: d6 6 reg: d7 7 reg: a0 8 reg: a1 9 reg: a2 10 reg: a3 11 reg: a4 12 reg: a5 13 reg: a6 14 reg: sp 15 reg: fp0 16 reg: fp1 17 reg: fp2 18 reg: fp3 19 reg: fp4 20 reg: fp5 21 reg: fp6 22 reg: pc 23 endabi: m68k # Demonstrates use of address_size and includeabi keywords. # address_size is useful when an Elf64 object has DWARF2 # 32bit (4 byte) address-size frame data (which has no address_size field) # and no .debug_info section to provide the 32bit address size. beginabi: ppc32bitaddress address_size: 4 includeabi: ppc endabi: ppc32bitaddress beginabi: ppc # This abi defined Oct 2008 based on: # http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html frame_interface: 3 # abi dwarf table uses up thru 1155. # As of Oct 2008, the only ABI requiring a higher # DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3. initial_reg_value: 1235 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1235 undefined_val_reg: 1234 reg_table_size: 1200 reg: r0 0 reg: f0 32 reg: f1 33 reg: f2 34 reg: f3 35 reg: f4 36 reg: f5 37 reg: f6 38 reg: f7 39 reg: f8 40 reg: f9 41 reg: f10 42 reg: f11 43 reg: f12 44 reg: f13 45 reg: f14 46 reg: f16 47 reg: f17 48 reg: f18 49 reg: f19 50 reg: f20 51 reg: f21 52 reg: f22 53 reg: f23 54 reg: f24 55 reg: f25 56 reg: f26 57 reg: f27 58 reg: f28 59 reg: f29 60 reg: f30 62 reg: f31 63 reg: cr 64 reg: fpcsr 65 # spr0 is also called MQ reg: spr0 100 # spr1 is also called XER reg: spr1 101 # spr4 also called rtcu reg: spr4 104 # spr5 also called rtcl reg: spr5 105 #spr8 also called LR reg: spr8 108 # spr9 also called ctr reg: spr9 109 reg: msr 66 reg: sr0 70 reg: sr1 71 reg: sr2 72 reg: sr3 73 reg: sr4 74 reg: sr5 75 reg: sr6 76 reg: sr7 77 reg: sr8 78 reg: sr9 79 #dsisr also called spr18 reg: spr18 118 # dar also called spr19 reg: spr19 119 #dec also called spr22 reg: spr22 122 #sdr1 also called spr25 reg: spr25 125 #srr0 also called spr26 reg: spr26 126 #srr1 also called spr27 reg: spr27 127 #vrsave also called spr256 reg: spr256 356 #sprg0 also called spr272 reg: spr272 372 #sprg1 also called spr273 reg: spr273 373 #sprg2 also called spr274 reg: spr274 374 #sprg3 also called spr275 reg: spr275 375 #asr also called spr280 reg: spr280 380 #ear also called spr282 reg: spr282 382 #tb also called spr284 reg: spr284 384 #tbu also called spr285 reg: spr285 385 #pvr also called spr287 reg: spr287 387 #ibat0u also called spr528 reg: spr528 628 #ibat0l also called spr529 reg: spr529 629 #ibat1u also called spr530 reg: spr530 630 #ibat1l also called spr531 reg: spr531 631 #ibat2u also called spr532 reg: spr532 632 #ibat2l also called spr533 reg: spr533 633 #ibat3u also called spr534 reg: spr534 634 #ibat3l also called spr535 reg: spr535 635 #dbat0u also called spr536 reg: spr536 636 #dbat0l also called spr537 reg: spr537 637 #dbat1u also called spr538 reg: spr538 638 #dbat1l also called spr539 reg: spr539 639 #dbat2u also called spr540 reg: spr540 640 #dbat2l also called spr541 reg: spr541 641 #dbat3u also called spr542 reg: spr542 642 #dbat3l also called spr543 reg: spr543 643 #hid0 also called spr1008 reg: spr1008 1108 #hid1 also called spr1009 reg: spr1009 1109 #hid2 also called iabr or spr1010 reg: spr1010 1110 #hid5 also called dabr or spr1013 reg: spr1013 1113 #hid15 also called pir or spr1023 reg: spr1023 1123 # vector registers 0-31 reg: vr0 1124 reg: vr1 1125 reg: vr2 1126 reg: vr3 1127 reg: vr4 1128 reg: vr5 1129 reg: vr6 1130 reg: vr7 1131 reg: vr8 1132 reg: vr9 1133 reg: vr10 1134 reg: vr11 1135 reg: vr12 1136 reg: vr13 1137 reg: vr14 1138 reg: vr15 1130 reg: vr16 1140 reg: vr17 1141 reg: vr18 1142 reg: vr19 1143 reg: vr20 1144 reg: vr21 1145 reg: vr22 1146 reg: vr23 1147 reg: vr24 1148 reg: vr25 1149 reg: vr26 1150 reg: vr27 1151 reg: vr28 1152 reg: vr29 1153 reg: vr30 1154 reg: vr31 1155 endabi: ppc # 'Generic 1000 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 1000 registers. The register names # show as a number, like 'r991'. beginabi: generic frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 1000 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic # 'Generic 500 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 500 registers. The register names # show as a number, like 'r91'. beginabi: generic500 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 500 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic500 # 'Generic 100 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 100 registers. The register names # show as a number, like 'r91'. beginabi: generic100 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 100 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic100 beginabi: arm frame_interface: 3 # When using frame_interface: 3 the size of the register # table is not fixed. It can be as large as needed. reg_table_size: 288 cfa_reg: 1436 # DW_FRAME_CFA_COL3 initial_reg_value: 1034 same_val_reg: 1035 undefined_val_reg: 1034 # If the vendor co-processor registers are allowed # or other numbers above 287 used then # the reg_table_size must be increased and (possibly) # the cfa, same_value, undefined_value reg values changed # here. # r0-r15 are 0 through 15. # Numbers 16 through 63 had meaning # in some ARM DWARF register mappings. reg: s0 64 reg: s1 65 reg: s2 66 reg: s3 67 reg: s4 68 reg: s5 69 reg: s6 70 reg: s7 71 reg: s8 72 reg: s9 73 reg: s10 74 reg: s11 75 reg: s12 76 reg: s13 77 reg: s14 78 reg: s15 79 reg: s16 80 reg: s17 81 reg: s18 82 reg: s19 83 reg: s20 84 reg: s21 85 reg: s22 86 reg: s23 87 reg: s24 88 reg: s25 89 reg: s26 90 reg: s27 91 reg: s28 92 reg: s29 93 reg: s30 94 reg: s31 95 reg: f0 96 reg: f1 97 reg: f2 98 reg: f3 99 reg: f4 100 reg: f5 101 reg: f6 102 reg: f7 103 reg: wcgr0 104 reg: wcgr0 105 reg: wcgr0 106 reg: wcgr0 107 reg: wcgr0 108 reg: wcgr0 109 reg: wcgr0 110 reg: wcgr0 111 reg: wr0 112 reg: wr1 113 reg: wr2 114 reg: wr3 115 reg: wr4 116 reg: wr5 117 reg: wr6 118 reg: wr7 119 reg: wr8 120 reg: wr9 121 reg: wr10 122 reg: wr11 123 reg: wr12 124 reg: wr13 125 reg: wr14 126 reg: wr15 127 reg: spsr 128 reg: spsr_fiq 129 reg: spsr_irq 130 reg: spsr_abt 131 reg: spsr_und 132 reg: spsr_svc 133 reg: r8_usr 144 reg: r9_usr 145 reg: r10_usr 146 reg: r11_usr 147 reg: r12_usr 148 reg: r13_usr 149 reg: r14_usr 150 reg: r8_fiq 151 reg: r9_fiq 152 reg: r10_fiq 153 reg: r11_fiq 154 reg: r12_fiq 155 reg: r13_fiq 156 reg: r14_fiq 157 reg: r13_riq 158 reg: r14_riq 159 reg: r14_abt 160 reg: r13_abt 161 reg: r14_und 162 reg: r13_und 163 reg: r14_svc 164 reg: r13_svc 165 reg: wc0 192 reg: wc1 193 reg: wc2 192 reg: wc3 192 reg: wc4 192 reg: wc5 197 reg: wc6 198 reg: wc7 199 reg: d0 256 reg: d1 257 reg: d2 258 reg: d3 259 reg: d4 260 reg: d5 261 reg: d6 262 reg: d7 263 reg: d8 264 reg: d9 265 reg: d10 266 reg: d11 267 reg: d12 268 reg: d13 269 reg: d14 270 reg: d15 271 reg: d16 272 reg: d17 273 reg: d18 274 reg: d19 275 reg: d20 266 reg: d21 277 reg: d22 278 reg: d23 279 reg: d24 280 reg: d25 281 reg: d26 282 reg: d27 283 reg: d28 284 reg: d29 285 reg: d30 286 reg: d31 287 # End of abi definition. endabi: arm libdwarf-20210528/dwarfdump/README.testcases0000664000175000017500000000240014046761606015350 00000000000000The following binary test cases are included in the dwarfdump distribution to provide an unchanging means of verifying that dwarfdump basically works. November 5, 2019. Each .base is the inital 500 lines produced by dwarfdump as a baseline to check against the latest compiled dwarfdump output. testobjLE32PE.test.c was compiled to an executable on a Windows 8.1 system with MinGW using a gcc compiler (called just test.c at the time of the compilation). testobjLE32PE.test.c testobjLE32PE.base testobjLE32PE.exe testuriLE64ELf is a compilation of dwarfdump/uri.c and is a plain .o, a relocatable (renamed .obj to avoid a reader confusing this with build-time .o objects). testuriLE64ELf.base testuriLE64ELf.obj test-mach-o-32 is a little-endian compilation to an executable of dwarfexample/simplereader.c on a 32bit Apple system using Apple compilers. The DWARF is in the .dSYM as is normal for Apple and the executable is not present here: There is no executable code here. Notice the __TEXT and __DATA and __PAGEZERO sections are empty (zero length). test-mach-o-32.base test-mach-o-32.dSYM The readelfobj project on sourceforge.net can build executables for all three object formats: readelfobj readobjpe readobjmacho which will show the object file headers. libdwarf-20210528/dwarfdump/tag_common.c0000664000175000017500000001404414012575576014773 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include #include #include /* For va_start va_arg va_list */ #include /* For exit() declaration etc. */ #include /* For errno declaration. */ #include /* For isspace() declaration */ #include "globals.h" #include "naming.h" #include "tag_common.h" static int linecount = 0; static char line_in[MAX_LINE_SIZE]; void bad_line_input(char *format,...) { va_list ap; va_start(ap,format); fprintf(stderr, "tag_(tree,attr,form) table build failed, line %d: \"%s\". ", linecount, line_in); vfprintf(stderr,format, ap); /* "The object ap may be passed as an argument to another function; if that function invokes the va_arg() macro with parameter ap, the value of ap in the calling function is unspecified and shall be passed to the va_end() macro prior to any further reference to ap." Single Unix Specification. */ va_end(ap); fprintf(stderr,"\n"); exit(FAILED); } void trim_newline(char *line, int max) { char *end = line + max - 1; for (; *line && (line < end); ++line) { if (*line == '\n') { /* Found newline, drop it */ *line = 0; return; } } return; } /* Detect empty lines (and other lines we do not want to read) */ static Dwarf_Bool is_skippable_line(char *pLine) { Dwarf_Bool empty = TRUE; if (pLine[0] == '#') { /* Preprocessor lines are of no interest. */ return TRUE; } for (; *pLine && empty; ++pLine) { empty = isspace(*pLine); } return empty; } /* Reads a value from the text table. Exits with non-zero status if the table is erroneous in some way. */ /* This array must match exactly the order of the enum entries in Dwarf_Form_Class in libdwarf.h.in. */ static char *enumvals[] = { "DW_FORM_CLASS_UNKNOWN", "DW_FORM_CLASS_ADDRESS", "DW_FORM_CLASS_BLOCK", "DW_FORM_CLASS_CONSTANT", "DW_FORM_CLASS_EXPRLOC", "DW_FORM_CLASS_FLAG", "DW_FORM_CLASS_LINEPTR", "DW_FORM_CLASS_LOCLISTPTR", /* DWARF2,3,4 only */ "DW_FORM_CLASS_MACPTR", /* DWARF2,3,4 only */ "DW_FORM_CLASS_RANGELISTPTR", /* DWARF2,3,4 only */ "DW_FORM_CLASS_REFERENCE", "DW_FORM_CLASS_STRING", "DW_FORM_CLASS_FRAMEPTR", /* MIPS/IRIX DWARF2 only */ "DW_FORM_CLASS_MACROPTR", /* DWARF5 */ "DW_FORM_CLASS_ADDRPTR", /* DWARF5 */ "DW_FORM_CLASS_LOCLIST", /* DWARF5 */ "DW_FORM_CLASS_LOCLISTSPTR", /* DWARF5 */ "DW_FORM_CLASS_RNGLIST", /* DWARF5 */ "DW_FORM_CLASS_RNGLISTSPTR", /* DWARF5 */ "DW_FORM_CLASS_STROFFSETSPTR", /* DWARF5 */ 0 }; static int lookup_enum_val( char * lin) { const char *s = enumvals[0]; char *lp = lin; int inputlen = 0; int enumindex = -1; int i = 0; for (i = 0;*lp; ++lp,++i) { if (*lp == ' ' || *lp == '\n') { break; } ++inputlen; } if (inputlen < 14) { bad_line_input("bad DW_FORM_CLASS_ input!"); } if (strncmp(lin,"DW_FORM_CLASS_",14)) { bad_line_input("bad DW_FORM_CLASS_ input.."); } for (i = 0 ; s ; ++i, s = enumvals[i]) { int len = inputlen; int arslen = strlen(s); if (arslen > len) { len = arslen; } if (!strncmp(s,lin,len)) { enumindex = i; return enumindex; break; } } if (enumindex < 1) { bad_line_input("DW_FORM_CLASS not matched"); } return -1; } int read_value(unsigned int *outval,FILE*file) { char *res = 0; unsigned long lval; char *strout = 0; Dwarf_Bool bBlankLine = TRUE; ++linecount; *outval = 0; while (bBlankLine) { res = fgets(line_in, sizeof(line_in), file); if (res == 0) { if (ferror(file)) { fprintf(stderr, "attr_form: Error reading table, %d lines read\n", linecount); exit(FAILED); } if (feof(file)) { return IS_EOF; } /* Impossible */ fprintf(stderr, "attr_form: " "Impossible error reading table, " "%d lines read\n", linecount); exit(FAILED); } bBlankLine = is_skippable_line(line_in); } trim_newline(line_in, sizeof(line_in)); errno = 0; lval = strtoul(line_in, &strout, 0); if (strout == line_in) { int enumindex = -1; /* We have outlen, so look up an enum value */ enumindex = lookup_enum_val(line_in); if (enumindex < 1) { bad_line_input("Cannot find enum value"); } *outval = enumindex; return NOT_EOF; } if (errno != 0) { int myerr = errno; fprintf(stderr, "attr_form errno %d\n", myerr); bad_line_input("invalid number on line"); } *outval = (int) lval; return NOT_EOF; } libdwarf-20210528/dwarfdump/print_llex_codes.c0000664000175000017500000001670313764006205016200 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "helpertree.h" #include "tag_common.h" /* Prints locentry descriptsions for DW_LKIND_GNU_exp_list */ int print_llex_linecodes( Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char * attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * esbp, Dwarf_Bool * bError) { if (debug_addr_unavailable) { *bError = TRUE; } switch(lle_value) { case DW_LLEX_base_address_selection_entry: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "", rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "< new base address 0x%" DW_PR_XZEROS DW_PR_DUx ">", hipc); } break; case DW_LLEX_end_of_list_entry: /* Nothing to do. */ esb_append(esbp,""); break; case DW_LLEX_start_length_entry: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawlopc); esb_append_printf_u(esbp, "< length : 0x%" DW_PR_XZEROS DW_PR_DUx ">",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "< start-addr 0x%" DW_PR_XZEROS DW_PR_DUx , lopc); esb_append_printf_u(esbp, " endaddr 0x%" DW_PR_XZEROS DW_PR_DUx ">",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check( tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLEX_offset_pair_entry: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "< offset pair low-off : 0x%" DW_PR_XZEROS DW_PR_DUx,rawlopc); esb_append_printf_u(esbp, " high-off 0x%" DW_PR_XZEROS DW_PR_DUx ">",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "< loaddr 0x%" DW_PR_XZEROS DW_PR_DUx,lopc); esb_append_printf_u(esbp, " hiaddr 0x%" DW_PR_XZEROS DW_PR_DUx ">",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check( tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLEX_start_end_entry: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",hipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "< lowaddr : 0x%" DW_PR_XZEROS DW_PR_DUx,lopc); esb_append_printf_u(esbp, " highaddr 0x%" DW_PR_XZEROS DW_PR_DUx ">",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check( tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; default: { struct esb_s unexp; esb_constructor(&unexp); esb_append_printf_u(&unexp, "ERROR: Unexpected LLEX code 0x%x", lle_value); print_error_and_continue(dbg, esb_get_string(&unexp), DW_DLV_OK, 0); esb_destructor(&unexp); *bError = TRUE; } break; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/runtests.sh0000775000175000017500000001554414050030767014726 00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run in the dwarfdump directory # Run only after config.h created in a configure # in the source directory # Assumes env vars DWTOPSRCDIR set to the path to source. # Assumes CFLAGS warning stuff set in env var DWCOMPILERFLAGS # Assumes we run the script in the dwarfdump directory. top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/dwarfdump if [ x"$DWCOMPILERFLAGS" = 'x' ] then CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra" echo "CFLAGS basic default default $CFLAGS" else CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf $DWCOMPILERFLAGS" echo "CFLAGS via configure $CFLAGS" fi goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status for the test $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } which cc if [ $? -eq 0 ] then CC=cc else which gcc if [ $? -eq 0 ] then CC=gcc else # we will fail CC=cc fi fi #echo "cflags before runtests.sh sets it $CFLAGS" #CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" echo "dwgetopt test" $CC $CFLAGS -o getopttest $srcdir/getopttest.c $srcdir/dwgetopt.c chkres $? "compiling getopttest test" ./getopttest chkres $? "running getopttest" # we will want to know if windows if [ -f getopttest.exe ] then win=y else win=n fi rm -f getopttest getopttest.exe # The following tests are not really relevant: # we do not use system getopt in libdwarf etc. #echo "Now use system getopt to validate our tests" #$CC $CFLAGS -DGETOPT_FROM_SYSTEM -o getopttestnat $srcdir/getopttest.c $srcdir/dwgetopt.c #chkres $? "compiling getopttestnat " #./getopttestnat -c 1 #chkres $? "running getopttestnat -c 1 " #./getopttestnat -c 2 #chkres $? "running getopttestnat -c 2 " #./getopttestnat -c 3 #chkres $? "running getopttestnat -c 3 " #./getopttestnat -c 5 #chkres $? "running getopttestnat -c 5 " #./getopttestnat -c 6 #chkres $? "running getopttestnat -c 6 " #./getopttestnat -c 7 #chkres $? "running getopttestnat -c 7 " #./getopttestnat -c 8 #chkres $? "running getopttestnat -c 8 " #./getopttestnat -c 9 #chkres $? "running getopttestnat -c 9 " #./getopttestnat -c 10 #chkres $? "running getopttestnat -c 10 " #rm ./getopttestnat echo "start selfmakename" $CC $CFLAGS -c $srcdir/esb.c $srcdir/dwarf_tsearchbal.c chkres $? "compiling makename test" $CC -g $CFLAGS $srcdir/makename.c $srcdir/makename_test.c dwarf_tsearchbal.o esb.o -o selfmakename chkres $? "compiling selfmakename test" ./selfmakename chkres $? "running selfmakename " rm -f selfmakename selfmakename.exe echo "start selfhelpertree" $CC $CFLAGS -g $srcdir/helpertree_test.c $srcdir/helpertree.c dwarf_tsearchbal.o -o selfhelpertree chkres $? "compiling helpertree.c selfhelpertree" ./selfhelpertree chkres $? "running selfhelpertree " rm -f selfhelpertree selfhelpertree.exe echo "start selfmc macrocheck.c tests" $CC -DSELFTEST $CFLAGS -g $srcdir/macrocheck.c $srcdir/esb.c dwarf_tsearchbal.o -o selfmc chkres $? "compiling macrocheck.c selfmc" ./selfmc chkres $? "running selfmc " rm -f ./selfmc selfmc.exe echo "start selfesb" $CC $CFLAGS $srcdir/testesb.c $srcdir/esb.c -o selfesb chkres $? "compiling selfesb.c selfesb" ./selfesb chkres $? "running selfesb " rm -f ./selfesb selfesb.exe echo "start selfsetion_bitmaps" $CC $CFLAGS -g $srcdir/section_bitmaps_test.c $srcdir/section_bitmaps.c -o selfsection_bitmaps chkres $? "compiling bitmaps.c section_bitmaps" ./selfsection_bitmaps chkres $? "running selfsection_bitmaps " rm -f ./selfsection_bitmaps selfsection_bitmaps.exe echo "start selfprint_reloc" $CC $CFLAGS -DSELFTEST=1 -DTESTING=1 $srcdir/print_reloc_test.c esb.o -o selfprint_reloc chkres $? "compiling print_reloc.c selfprint_reloc" ./selfprint_reloc chkres $? "running selfprint_reloc " rm -f ./selfprint_reloc selfprint_reloc.exe # Remove the leading two lines for windows # as windows dwarfdump emits two leading lines # as compared to non-windows dwarfdump droptwoifwin() { i=$1 l=`wc -l < $i` if [ $l -gt 2 ] then l=`expr $l - 2` tail -$l <$i >junk.tmp cp junk.tmp $i rm -f junk.tmp fi } fixlasttime() { i=$1 sed 's/last time 0x.*/last time 0x0/' <$i >junk.tmp cp junk.tmp $i rm -f junk.tmp } # The following stop after 400 lines to limit the size # of the data here. # It is a sanity check, not a full check. f=$srcdir/testobjLE32PE.exe b=$srcdir/testobjLE32PE.base t=junk.testobjLE32PE.base echo "start dwarfdump sanity check on pe $f" # Windows dwarfdump emits a couple prefix lines #we do not want. # So let dwarfdump emit more then trim. # In addition the zero date for file time in line tables # prints differently for different time zones. # Delete what follows 'last time 0x0' if [ x$win = "xy" ] then textlim=702 else textlim=700 fi echo "./dwarfdump -a -vvv $f | head -n $textlim > $t " ./dwarfdump -a -vvv $f | head -n $textlim > $t chkres $? "Running dwarfdump $f output to $t base $b" if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t echo did drop two wc $t fi fixlasttime $t which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diffjunk.testsmallpe.diff r=$? chkres $r "FAIL diff of $b $t" if [ $r -ne 0 ] then echo "to update , mv $top_blddir/dwarfdump/$t $b" fi rm -f $t rm -f $t.diffjunk.testsmallpe.diff f=$srcdir/testuriLE64ELf.obj b=$srcdir/testuriLE64ELf.base t=junk.testuriLE64ELf.base echo "start dwarfdump sanity check on $f" ./dwarfdump -vvv -a $f | head -n $textlim > $t chkres $? "running ./dwarfdump $f otuput to $t base $b " if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t fi echo "if update required, mv $top_blddir/dwarfdump/$t $b" fixlasttime $t which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diff r=$? chkres $r "FAIL diff of $b $t" if [ $r -ne 0 ] then echo "to update , mv $top_blddir/dwarfdump/$t $b" fi rm -f $t rm -f $t.diff f=$srcdir/test-mach-o-32.dSYM b=$srcdir/test-mach-o-32.base t=junk.test-mach-o-32.base echo "start dwarfdump sanity check on $f" ./dwarfdump $f | head -n $textlim > $t chkres $? "FAIL dwarfdump/runtests.sh ./dwarfdump $f to $t base $b " if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t fi chkres $? "Running dwarfdump on $f" echo "if update required, mv $top_blddir/dwarfdump/$t $b" fixlasttime $t which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diff r=$? chkres $r "FAIL dwarfdump/runtests.sh diff of $b $t" if [ $r -ne 0 ] then echo "to update , mv $top_blddir/dwarfdump/$t $b" fi if [ $failcount -ne 0 ] then echo "FAIL $failcount dwarfdump/runtests.sh" exit 1 fi rm -f $t rm -f $t.diff exit 0 libdwarf-20210528/dwarfdump/print_reloc_decls.h0000664000175000017500000001572613762721764016362 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #ifndef SELFTEST #include "print_reloc.h" #endif /* SELFTEST */ #include "section_bitmaps.h" #include "esb.h" #include "sanitized.h" #ifndef HAVE_ELF64_GETEHDR #define Elf64_Addr long #define Elf64_Word unsigned long #define Elf64_Xword unsigned long #define Elf64_Sym long #endif struct sect_data_s { Dwarf_Small *buf; Dwarf_Unsigned size; Dwarf_Bool display; /* Display reloc if TRUE */ const char *name; /* Section name */ Elf64_Xword type; /* To cover 32 and 64 records types */ }; #ifndef SELFTEST static struct sect_data_s sect_data[DW_SECTION_REL_ARRAY_SIZE]; #endif /* SELFTEST */ typedef size_t indx_type; typedef struct { indx_type indx; char *name; Elf32_Addr value; Elf32_Word size; int type; int bind; unsigned char other; Elf32_Half shndx; } SYM; typedef struct { indx_type indx; char *name; Elf64_Addr value; Elf64_Xword size; int type; int bind; unsigned char other; unsigned short shndx; } SYM64; #ifndef SELFTEST static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link); static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link); static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size); static int print_relocinfo_64(Elf * elf); static int print_relocinfo_32(Elf * elf); static SYM *sym_data; static SYM64 *sym_data_64; static unsigned long sym_data_entry_count; static unsigned long sym_data_64_entry_count; /* Include Section type, to be able to deal with all the Elf32_Rel, Elf32_Rela, Elf64_Rel, Elf64_Rela relocation types */ #define SECT_DATA_SET(x,t,n,sout,r2) { \ data = elf_getdata(scn, 0); \ if (!data || !data->d_size) { \ const char * version = "null"; \ if (data) { \ version = "d_size of 0"; \ } \ glflags.gf_count_major_errors++; \ printf("ERROR: elf_getdata fails:" \ "elf_getdata returns %s\n", \ version); \ return DW_DLV_NO_ENTRY; \ } \ sout[(r2)] = sect_data[(x)]; \ sout[(r2)].buf = data->d_buf; \ sout[(r2)].size = data->d_size; \ sout[(r2)].type = (t); \ sout[(r2)].name = (n); \ } /* Record the relocation table name information */ static const char **reloc_type_names = NULL; static int number_of_reloc_type_names = 0; #endif /* SELFTEST */ typedef struct { indx_type index; char *name_rel; /* .rel.debug_* names */ char *name_rela; /* .rela.debug_* names */ } REL_INFO; /* If the incoming scn_name is known, record the name in our reloc section names table. For a given (debug) section there can be a .rel or a .rela, not both. The name-to-index in this table is fixed, invariant. */ static REL_INFO rel_info[DW_SECTION_REL_ARRAY_SIZE] = { {0,0,0}, {/*1*/ DW_SECTION_REL_DEBUG_INFO, DW_SECTNAME_REL_DEBUG_INFO, DW_SECTNAME_RELA_DEBUG_INFO}, {/*2*/ DW_SECTION_REL_DEBUG_LINE, DW_SECTNAME_REL_DEBUG_LINE, DW_SECTNAME_RELA_DEBUG_LINE}, {/*3*/ DW_SECTION_REL_DEBUG_PUBNAMES, DW_SECTNAME_REL_DEBUG_PUBNAMES, DW_SECTNAME_RELA_DEBUG_PUBNAMES}, {/*4*/ DW_SECTION_REL_DEBUG_ABBREV, DW_SECTNAME_REL_DEBUG_ABBREV, DW_SECTNAME_RELA_DEBUG_ABBREV}, {/*5*/ DW_SECTION_REL_DEBUG_ARANGES, DW_SECTNAME_REL_DEBUG_ARANGES, DW_SECTNAME_RELA_DEBUG_ARANGES}, {/*6*/ DW_SECTION_REL_DEBUG_FRAME, DW_SECTNAME_REL_DEBUG_FRAME, DW_SECTNAME_RELA_DEBUG_FRAME}, {/*7*/ DW_SECTION_REL_DEBUG_LOC, DW_SECTNAME_REL_DEBUG_LOC, DW_SECTNAME_RELA_DEBUG_LOC}, {/*8*/ DW_SECTION_REL_DEBUG_LOCLISTS, DW_SECTNAME_REL_DEBUG_LOCLISTS, DW_SECTNAME_RELA_DEBUG_LOCLISTS}, {/*9*/ DW_SECTION_REL_DEBUG_RANGES, DW_SECTNAME_REL_DEBUG_RANGES, DW_SECTNAME_RELA_DEBUG_RANGES}, {/*10*/ DW_SECTION_REL_DEBUG_RNGLISTS, DW_SECTNAME_REL_DEBUG_RNGLISTS, DW_SECTNAME_RELA_DEBUG_RNGLISTS}, {/*11*/ DW_SECTION_REL_DEBUG_TYPES, DW_SECTNAME_REL_DEBUG_TYPES, DW_SECTNAME_RELA_DEBUG_TYPES}, {/*12*/ DW_SECTION_REL_DEBUG_STR_OFFSETS, DW_SECTNAME_REL_DEBUG_STR_OFFSETS, DW_SECTNAME_RELA_DEBUG_STR_OFFSETS}, {/*13*/ DW_SECTION_REL_DEBUG_PUBTYPES, DW_SECTNAME_REL_DEBUG_PUBTYPES, DW_SECTNAME_RELA_DEBUG_PUBTYPES}, {/*14*/ DW_SECTION_REL_GDB_INDEX, DW_SECTNAME_REL_GDB_INDEX, DW_SECTNAME_RELA_GDB_INDEX}, {/*15*/ DW_SECTION_REL_EH_FRAME, DW_SECTNAME_REL_EH_FRAME, DW_SECTNAME_RELA_EH_FRAME}, {/*16*/ DW_SECTION_REL_DEBUG_SUP, DW_SECTNAME_REL_DEBUG_SUP, DW_SECTNAME_RELA_DEBUG_SUP}, {/*17*/ DW_SECTION_REL_DEBUG_MACINFO, DW_SECTNAME_REL_DEBUG_MACINFO, DW_SECTNAME_RELA_DEBUG_MACINFO}, {/*18*/ DW_SECTION_REL_DEBUG_MACRO, DW_SECTNAME_REL_DEBUG_MACRO, DW_SECTNAME_RELA_DEBUG_MACRO}, {/*19*/ DW_SECTION_REL_DEBUG_NAMES, DW_SECTNAME_REL_DEBUG_NAMES, DW_SECTNAME_RELA_DEBUG_NAMES}, }; #endif /* DWARF_WITH_LIBELF */ libdwarf-20210528/dwarfdump/addrmap.h0000644000175000017500000000273113762722254014261 00000000000000/* Copyright 2010 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef ADDRMAP_H #define ADDRMAP_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct Addr_Map_Entry { Dwarf_Unsigned mp_key; char * mp_name; }; struct Addr_Map_Entry * addr_map_insert(Dwarf_Unsigned addr, char *name, void **map); struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr, void **map); void addr_map_destroy(void *map); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ADDRMAP_H */ libdwarf-20210528/dwarfdump/helpertree.h0000644000175000017500000000471713762722137015016 00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef HELPERTREE_H #define HELPERTREE_H /* This is a tsearch tree interface we may use in various ways where each different sort of use is a different Helpertree_Base_s instance. */ /* We create Helpertree_Base_s so we can use type-checked calls, not showing the tsearch void* outside of helpertree.c. */ struct Helpertree_Base_s { void * hb_base; }; /* For .debug_info */ extern struct Helpertree_Base_s helpertree_offsets_base_info; /* For .debug_types. */ extern struct Helpertree_Base_s helpertree_offsets_base_types; struct Helpertree_Map_Entry_s { /* Key is offset. It will be a section-global offset so applicable across an entire executable/object section. */ Dwarf_Unsigned hm_key; /* val is something defined differently in different uses. for integer type it is 0 means unknown -1 known signed 1 known unsigned. */ int hm_val; /* Add fields here as needed. */ }; /* Add entry or set to known-signed or known-unsigned. */ struct Helpertree_Map_Entry_s * helpertree_add_entry( Dwarf_Unsigned offset, int val, struct Helpertree_Base_s *helper); /* Look for entry. Use hm_val (if non-null return) to determine signedness. */ struct Helpertree_Map_Entry_s * helpertree_find(Dwarf_Unsigned offset, struct Helpertree_Base_s *helper); void helpertree_clear_statistics(struct Helpertree_Base_s *helper); #endif /* HELPERTREE_H */ libdwarf-20210528/dwarfdump/print_section_groups.c0000664000175000017500000002217613767716277017147 00000000000000/* Copyright (C) 2017-2017 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "sanitized.h" #include "naming.h" /* Two purposes here related to COMDAT: A) get and print the data on sections and groups. B) reset certain global 'print' flags so printing a COMDAT section does not print the major sections that are from group 1 (DW_GROUPDATA_BASE) The functions are called from dwarfdump.c and only once. So static vars are safe. */ static Dwarf_Unsigned group_map_entry_count = 0; static Dwarf_Unsigned selected_group = 0; static Dwarf_Unsigned *sec_nums = 0; static Dwarf_Unsigned *group_nums = 0; static const char ** sec_names = 0; static Dwarf_Unsigned group_count; static Dwarf_Unsigned section_count; static void freeall_groups_tables(void) { free(sec_nums); sec_nums = 0; free(group_nums); group_nums = 0; /* Cast prevents an ugly warning about the const being stripped off. */ free((void*)sec_names); sec_names = 0; group_map_entry_count = 0; selected_group = 0; group_count = 0; section_count = 0; } #define TRUE 1 #define FALSE 0 #if 0 static struct glfsetting_s { const char *secname; Dwarf_Bool *flag; Dwarf_Bool origset; Dwarf_Bool origflag; } glftab[] = { {".debug_abbrev", &glflags.gf_abbrev_flag,FALSE,FALSE}, {".debug_aranges", &glflags.gf_aranges_flag,FALSE,FALSE}, {".debug_debug_macinfo",&glflags.gf_macinfo_flag,FALSE,FALSE}, {".debug_debug_macro", &glflags.gf_macro_flag,FALSE,FALSE}, {".debug_debug_names", &glflags.gf_debug_names_flag,FALSE,FALSE}, {".debug_eh_frame", &glflags.gf_eh_frame_flag,FALSE,FALSE}, {".debug_frame", &glflags.gf_frame_flag,FALSE,FALSE}, {".gdb_index", &glflags.gf_gdbindex_flag,FALSE,FALSE}, {".debug_info", &glflags.gf_info_flag,FALSE,FALSE}, {".debug_line", &glflags.gf_line_flag,FALSE,FALSE}, {".debug_loc", &glflags.gf_loc_flag,FALSE,FALSE}, /*{".debug_loclists", &glflags.gf_loclists_flag,FALSE,FALSE}, */ {".debug_pubnames", &glflags.gf_pubnames_flag,FALSE,FALSE}, /* SGI only */ {".debug_pubtypes", &glflags.gf_pubtypes_flag,FALSE,FALSE}, {".debug_ranges", &glflags.gf_ranges_flag,FALSE,FALSE}, /*{".debug_rnglists", &glflags.gf_rnglists_flag,FALSE,FALSE}, */ /* SGI only */ {".debug_static_func", &glflags.gf_static_func_flag,FALSE,FALSE}, /* SGI only */ {".debug_static_var", &glflags.gf_static_var_flag,FALSE,FALSE}, {".debug_str", &glflags.gf_string_flag,FALSE,FALSE}, {".debug_types", &glflags.gf_types_flag,FALSE,FALSE}, /* SGI only */ {".debug_weaknames", &glflags.gf_weakname_flag,FALSE,FALSE}, {0,0,0,0} }; #endif /* 0 */ /* If a section is not in group N but is in group 1 then turn off its flag. Since sections are never in both (various DW_DLE*DUPLICATE errors if libdwarf tries to set in both), just look in group one. See groups_restore_subsidiary_flags() just below. FIXME: It would be good if, for a wholly missing section related to a flag, that the flag got turned off. */ #if 0 static void turn_off_subsidiary_flags(UNUSEDARG Dwarf_Debug dbg) { Dwarf_Unsigned i = 0; for ( ; i < group_map_entry_count; ++i) { if (group_nums[i] == 1) { unsigned k = 0; const char* oursec = sec_names[i]; for ( ; glftab[k].secname; ++k ) { if (!strcmp(oursec,glftab[k].secname)) { if (!glftab[k].origset) { glftab[k].origset = TRUE; glftab[k].origflag = *(glftab[k].flag); } *(glftab[k].flag) = FALSE; } } } } } #endif /* Restoring original condition in the glftab array and in the global flags it points to. So that when processing an archive one can restore the user-chosen flags and print subsequent object groups correctly. New October 16, 2017. */ void groups_restore_subsidiary_flags(void) { #if 0 unsigned k = 0; #endif /* Duplicative but harmless free. */ freeall_groups_tables(); #if 0 for ( ; glftab[k].secname; ++k ) { if (glftab[k].origset) { *(glftab[k].flag) = glftab[k].origflag; glftab[k].origset = FALSE; glftab[k].origflag = FALSE; } } #endif } /* NEW May 2017. Has a side effect of using the local table set up by print_section_groups_data() and then frees the table data. For multi-object archive reading: main() calls groups_restore_subsidiary_flags() at the end of each object file to restore the original flags that turn_off_subsidiary_flags() changed. */ void update_section_flags_per_groups( UNUSEDARG Dwarf_Debug dbg) { if (!sec_names) { /* The tables are absent. Internal logic error here somewhere. */ freeall_groups_tables(); return; } if (selected_group == DW_GROUPNUMBER_BASE) { freeall_groups_tables(); return; } if (selected_group == DW_GROUPNUMBER_DWO) { freeall_groups_tables(); return; } #if 0 turn_off_subsidiary_flags(dbg); #endif freeall_groups_tables(); } /* NEW May 2017. Reports on section groupings like DWO(split dwarf) and COMDAT groups. As a side effect creates local table of section and group data */ int print_section_groups_data(Dwarf_Debug dbg,Dwarf_Error *error) { int res = 0; Dwarf_Unsigned i = 0; res = dwarf_sec_group_sizes(dbg,§ion_count, &group_count,&selected_group, &group_map_entry_count, error); if (res != DW_DLV_OK) { simple_err_return_msg_either_action(res, "ERROR: dwarf_sec_group_sizes failed"); return res; } if (group_count == 1 && selected_group ==1 ) { /* This is the traditional DWARF with no split-dwarf and no COMDAT data. We don't want to print anything as we do not want to see differences from existing output in this case. Simplifies regression testing for now. */ return DW_DLV_OK; } printf("Section Groups data\n"); printf(" Number of Elf-like sections: %4" DW_PR_DUu "\n", section_count); printf(" Number of groups : %4" DW_PR_DUu "\n", group_count); printf(" Group to print : %4" DW_PR_DUu "\n", selected_group); printf(" Count of map entries : %4" DW_PR_DUu "\n", group_map_entry_count); sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if (!sec_nums) { glflags.gf_count_major_errors++; printf("ERROR: Unable to allocate %4" DW_PR_DUu " map section values, cannot print group map\n", group_map_entry_count); return DW_DLV_OK; } group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if (!group_nums) { free(group_nums); glflags.gf_count_major_errors++; printf("ERROR: Unable to allocate %4" DW_PR_DUu " map group values, cannot print group map\n", group_map_entry_count); return DW_DLV_OK; } sec_names = calloc(group_map_entry_count,sizeof(char*)); if (!sec_names) { free(group_nums); free(sec_nums); glflags.gf_count_major_errors++; printf("ERROR: Unable to allocate %4" DW_PR_DUu " section name pointers, cannot print group map\n", group_map_entry_count); return DW_DLV_OK; } res = dwarf_sec_group_map(dbg,group_map_entry_count, group_nums,sec_nums,sec_names,error); if (res != DW_DLV_OK) { simple_err_return_msg_either_action(res, "ERROR: dwarf_sec_group_map failed"); return res; } for ( i = 0; i < group_map_entry_count; ++i) { if (i == 0) { printf(" [index] group section\n"); } printf(" [%5" DW_PR_DUu "] " "%4" DW_PR_DUu " %4" DW_PR_DUu " %s\n",i, group_nums[i],sec_nums[i],sanitized(sec_names[i])); } /* Do not free our allocations. Will do later using freeall_groups_tables() */ return DW_DLV_OK; } libdwarf-20210528/dwarfdump/print_die.c0000664000175000017500000107220614051761201014613 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2021 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "print_frames.h" /* for print_location_operations() . */ #include "macrocheck.h" #include "helpertree.h" #include "opscounttab.h" #include "tag_common.h" #include "attr_form.h" /* OpBranchHead_s gives us nice type-checking in calls. */ struct OpBranchEntry_s { Dwarf_Unsigned offset; Dwarf_Unsigned target_offset; Dwarf_Small op; }; struct OpBranchHead_s { Dwarf_Half opcount; struct OpBranchEntry_s * ops_array; }; /* Defaults to all 0, never changes */ static const LoHiPc lohipc_zero; /* Traverse a DIE and attributes to check self references */ static int traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool Dwarf_Bool, char **srcfiles, Dwarf_Signed srcfiles_cnt, int die_indent_level, Dwarf_Error*err); static int traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, Dwarf_Half attr, Dwarf_Attribute attr_in, Dwarf_Bool print_else_name_match, char **srcfiles, Dwarf_Signed srcfiles_cnt, int die_indent_level, Dwarf_Error * err); static int print_die_and_children_internal(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed srcfiles_cnt, Dwarf_Error *); static int print_one_die_section(Dwarf_Debug dbg, Dwarf_Bool is_info, Dwarf_Error *pod_err); static int handle_rnglists(Dwarf_Die die, Dwarf_Attribute attrib, Dwarf_Half theform, Dwarf_Unsigned value, Dwarf_Unsigned *rle_offset_out, struct esb_s * esbp, int show_form, int local_verbose, Dwarf_Error *err); static int _dwarf_print_one_expr_op(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Small lkind, int die_indent_level, Dwarf_Loc* expr, Dwarf_Locdesc_c exprc, int index, Dwarf_Bool has_skip_or_branch, struct OpBranchHead_s *oparray, Dwarf_Bool report_raw, /* non-zero reports cooked values */ Dwarf_Addr baseaddr, struct esb_s *string_out, Dwarf_Error *err); static int get_form_values(Dwarf_Debug dbg,Dwarf_Attribute attrib, Dwarf_Half * theform, Dwarf_Half * directform,Dwarf_Error *err); static void show_form_itself(int show_form,int verbose, int theform, int directform, struct esb_s * str_out); static int print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Half attr, Dwarf_Attribute actual_addr, Dwarf_Bool print_else_name_match, int die_indent_level, char **srcfiles, Dwarf_Signed srcfcnt, LoHiPc *lohipc, Dwarf_Bool *attr_matched, Dwarf_Error *err); static int print_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Bool checking, int die_indent_level, int no_ending_newline, struct esb_s *details,Dwarf_Error *); static int formxdata_print_value(Dwarf_Debug dbg, Dwarf_Die die,Dwarf_Attribute attrib, Dwarf_Half theform, struct esb_s *esbp, Dwarf_Error * err, Dwarf_Bool hex_format); static void bracket_hex(const char *s1, Dwarf_Unsigned v, const char *s2, struct esb_s * esbp); static void formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp, Dwarf_Bool hex_format); static void formx_data16(Dwarf_Form_Data16 * u, struct esb_s *esbp, Dwarf_Bool hex_format); static void formx_signed(Dwarf_Signed s, struct esb_s *esbp); static int pd_dwarf_names_print_on_error = 1; static int die_stack_indent_level = 0; static Dwarf_Bool local_symbols_already_began = FALSE; /* See tag_specific_globals_setup() and glflags.need_PU_valid_code as those oversee resetting of this. It is set when a compilation-unit DIE or a subprogram DIE is seen and that DIE setting is kept till the next such is seen. glflags.in_valid_code; Used to be a static variable. */ static const Dwarf_Sig8 zerosig; #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ /* 20 characters */ static char * indentspace = " " " "; static int indentspacelen = 20; static void appendn( struct esb_s *m, int len) { int remaining = len; while (remaining > indentspacelen) { esb_append(m,indentspace); remaining -= indentspacelen; } esb_appendn(m,indentspace,remaining); } static void append_indent_prefix(struct esb_s *m, int prespaces, int indent, int postspaces) { if (indent < glflags.gf_max_space_indent) { appendn(m,2*indent + prespaces+postspaces); return; } appendn(m,prespaces); esb_append_printf_i(m,"...%d...",indent); appendn(m,postspaces); } static int standard_indent(void) { /* Attribute indent. The global offset printed length is actually 32. With GOFF the length is actually 16. Usually. */ int nColumn = glflags.gf_show_global_offsets ? 34 : 18; if (!glflags.gf_display_offsets) { nColumn = 2; } return nColumn; } static void print_indent_prefix(int prespaces,int indent,int postspaces) { if (indent < glflags.gf_max_space_indent) { int len = prespaces+postspaces+ 2*indent; printf("%*s",len," "); return; } if (prespaces) { printf("%*s",prespaces," "); } printf("...%d...",indent); if (postspaces) { printf("%*s",postspaces," "); } } struct die_stack_data_s { Dwarf_Die die_; /* sibling_die_globaloffset_ is set while processing the DIE. We do not know the sibling global offset when we create the stack entry. If the sibling attribute absent we never know. */ Dwarf_Off sibling_die_globaloffset_; /* We may need is_info here too. */ Dwarf_Off cu_die_offset_; /* global offset. */ Dwarf_Bool already_printed_; }; static struct die_stack_data_s empty_stack_entry; #define DIE_STACK_SIZE 800 static struct die_stack_data_s die_stack[DIE_STACK_SIZE]; #define SET_DIE_STACK_ENTRY(i,x,o) { die_stack[i].die_ = x; \ die_stack[i].cu_die_offset_ = o; \ die_stack[i].sibling_die_globaloffset_ = 0; \ die_stack[i].already_printed_ = FALSE; } #define EMPTY_DIE_STACK_ENTRY(i) { die_stack[i] = empty_stack_entry; } #define SET_DIE_STACK_SIBLING(x) { \ die_stack[die_stack_indent_level].sibling_die_globaloffset_ = x; } static void report_die_stack_error(Dwarf_Debug dbg, Dwarf_Error *err) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "ERROR: compiled in DIE_STACK_SIZE " "(the depth of the DIE tree in this CU)" " of %d exceeded!" " Likely a circular DIE reference." ,DIE_STACK_SIZE); dwarf_error_creation(dbg,err, esb_get_string(&m)); print_error_and_continue(dbg, esb_get_string(&m), DW_DLV_OK,*err); esb_destructor(&m); } /* Just access the die and print selected fields into the string. In case of error print an error message and return DW_DLV_NO_ENTRY. Initially we just verify the offset is ok. */ #define NO_SPECIFIC_TAG 0 /* The following two must differ, but value unimportant. We choose each to be a small prime number. */ #define NON_ZERO_OFFSET_REQUIRED 3 #define ZERO_OFFSET_GENERIC_TYPE 19 #define WITHIN_CU TRUE static void check_die_expr_op_basic_data(Dwarf_Debug dbg,Dwarf_Die die, const char * op_name, int indentprespaces, int die_indent_level, int indentpostspaces, int required_tag, int required_offset, int within_cu, Dwarf_Unsigned offset, struct esb_s *string_out) { Dwarf_Error err = 0; Dwarf_Off globaloff = 0; Dwarf_Bool is_info =0; Dwarf_Die other_die = 0; int res = 0; Dwarf_Half tag = 0; const char * required_tag_name = 0; const char * actual_tag_name = 0; if (! glflags.gf_do_print_dwarf) { /* We are checking so any errors detected will not print, so do not check. Even though this all seems self-contradictory! */ return; } if (within_cu && !offset && required_offset == ZERO_OFFSET_GENERIC_TYPE ) { /* Means the offset zero represents generic type, not a DIE DW_OP_convert DW_OP_reinterpret */ return; } if (!die) { esb_append(string_out," "); return; } is_info = dwarf_get_die_infotypes_flag(die); if (within_cu) { /* Our target DIE is in same CU as die argument */ /* DW_OP_const_type */ Dwarf_Unsigned length = 0; res = dwarf_die_CU_offset_range(die,&globaloff, &length,&err); if (res != DW_DLV_OK) { esb_append_printf_s(string_out, " ERROR: %s Cannot access CU DIE global offset ", (char *)op_name); if (res == DW_DLV_ERROR) { esb_append(string_out, dwarf_errmsg(err)); dwarf_dealloc_error(dbg,err); err = 0; } else { esb_append(string_out, "DW_DLV_NO_ENTRY "); } glflags.gf_count_major_errors++; return; } /* Offset passed in is off of CU header, not CU DIE. */ globaloff += offset; } else { /* DW_OP_implicit_ptr */ globaloff = offset; } if ((required_offset == NON_ZERO_OFFSET_REQUIRED) && !globaloff) { esb_append_printf_s(string_out, "ERROR: %s DIE global offset 0, but 0 not allowed ", op_name); glflags.gf_count_major_errors++; return; } if (!globaloff) { return; } res = dwarf_offdie_b(dbg,globaloff,is_info, &other_die,&err); if (res != DW_DLV_OK) { esb_append_printf_s(string_out, "ERROR: %s Cannot access DIE via global offset ", op_name); esb_append_printf_u(string_out, "0x%x ",globaloff); if (res == DW_DLV_ERROR) { esb_append(string_out, dwarf_errmsg(err)); esb_append(string_out, " "); dwarf_dealloc_error(dbg,err); err = 0; } else { esb_append(string_out, "DW_DLV_NO_ENTRY "); } if (!within_cu) { esb_append(string_out,"DW_OP_implicit_ptr offset " "might apply to another object file "); } glflags.gf_count_major_errors++; return; } res = dwarf_tag(other_die,&tag,&err); if (res != DW_DLV_OK) { esb_append_printf_s(string_out, "ERROR: %s Cannot access DIE tag ", op_name); esb_append_printf_u(string_out, "0x%x ",globaloff); if (res == DW_DLV_ERROR) { esb_append(string_out, dwarf_errmsg(err)); esb_append(string_out, " "); dwarf_dealloc_error(dbg,err); err = 0; } else { esb_append(string_out, "DW_DLV_NO_ENTRY "); } glflags.gf_count_major_errors++; dwarf_dealloc_die(other_die); return; } if (required_tag) { required_tag_name = get_TAG_name(required_tag,FALSE); } actual_tag_name = get_TAG_name(tag,FALSE); if (required_tag && tag != required_tag) { esb_append_printf_s(string_out, "ERROR: %s incorrect target die tag ", op_name); esb_append_printf_s(string_out, " Tag required: %s",required_tag_name); esb_append_printf_s(string_out, " Tag found: %s",actual_tag_name); glflags.gf_count_major_errors++; } if (!glflags.dense && !glflags.gf_expr_ops_joined) { char *diename = 0; /* <0x000854ff GOFF=0x00546047> */ esb_append(string_out,"\n"); append_indent_prefix(string_out,indentprespaces, die_indent_level,indentpostspaces+2); esb_append(string_out," Target Die: "); if (within_cu) { esb_append_printf_u(string_out, "<0x%" DW_PR_XZEROS DW_PR_DUx ,offset); if (glflags.gf_show_global_offsets) { esb_append_printf_u(string_out, " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx, globaloff); } esb_append(string_out,"> "); } else { esb_append_printf_u(string_out, " ",globaloff); } esb_append(string_out,actual_tag_name); res = dwarf_diename(other_die,&diename,&err); if ( res == DW_DLV_OK) { esb_append_printf_s(string_out, " name: %s",diename); } else if (res == DW_DLV_ERROR) { esb_append_printf_s(string_out, "ERROR: gets error reading " "DW_AT_diename: %s ", dwarf_errmsg(err)); dwarf_dealloc_error(dbg,err); err = 0; } /* Else no entry */ } dwarf_dealloc_die(other_die); } /* The first non-zero sibling offset we can find is what we want to return. The lowest sibling offset in the stack. Or 0 if we have none known. */ static Dwarf_Off get_die_stack_sibling() { int i = die_stack_indent_level; for ( ; i >=0 ; --i) { Dwarf_Off v = die_stack[i].sibling_die_globaloffset_; if (v) { return v; } } return 0; } static void possibly_increase_esb_alloc(struct esb_s *esbp, Dwarf_Unsigned count, Dwarf_Unsigned entrysize) { /* for bytes of text needed per element */ Dwarf_Unsigned targetsize = count*entrysize; Dwarf_Unsigned used = esb_string_len(esbp); Dwarf_Unsigned cursize = esb_get_allocated_size(esbp); if ((targetsize+used) > cursize) { esb_force_allocation(esbp,targetsize+used); } } static void dealloc_all_srcfiles(Dwarf_Debug dbg, char **srcfiles, Dwarf_Signed srcfiles_cnt) { Dwarf_Signed i = 0; if (!srcfiles) { return; } for ( ; i < srcfiles_cnt; ++i) { dwarf_dealloc(dbg,srcfiles[i],DW_DLA_STRING); } dwarf_dealloc(dbg,srcfiles, DW_DLA_LIST); } /* Higher stack level numbers must have a smaller sibling offset than lower or else the sibling offsets are wrong. Stack entries with sibling_die_globaloffset_ 0 must be ignored in this, it just means there was no sibling attribute at that level. */ static void validate_die_stack_siblings(Dwarf_Debug dbg) { int i = die_stack_indent_level; Dwarf_Off innersiboffset = 0; for ( ; i >=0 ; --i) { Dwarf_Off v = die_stack[i].sibling_die_globaloffset_; if (v) { innersiboffset = v; break; } } if (!innersiboffset) { /* no sibling values to check. */ return; } for (--i ; i >= 0 ; --i) { /* outersiboffset is an outer sibling offset. */ Dwarf_Off outersiboffset = die_stack[i].sibling_die_globaloffset_; if (outersiboffset ) { if (outersiboffset < innersiboffset) { char small_buf[ESB_FIXED_ALLOC_SIZE]; Dwarf_Error ouerr = 0; /* safe: all values known length. */ struct esb_s pm; esb_constructor_fixed(&pm,small_buf, sizeof(small_buf)); esb_append_printf_u(&pm, "ERROR: Die stack sibling error, " "outer global offset " "0x%" DW_PR_XZEROS DW_PR_DUx,outersiboffset); esb_append_printf_u(&pm, " less than inner global offset " "0x%" DW_PR_XZEROS DW_PR_DUx ", the DIE tree is erroneous.", innersiboffset); esb_append_printf_i(&pm, "Die indent level; %d",i); print_error_and_continue(dbg, esb_get_string(&pm), DW_DLV_OK,ouerr); esb_destructor(&pm); return; } /* We only need check one level with an offset at each entry. */ break; } } return; } static void append_local_prefix(struct esb_s *esbp) { esb_append(esbp,"\n "); } static int print_as_info_or_by_cuname() { return (glflags.gf_info_flag || glflags.gf_types_flag || glflags.gf_cu_name_flag); } #if 0 /* Only used for debugging. */ static void dump_die_offsets(Dwarf_Debug dbg, Dwarf_Die die, const char *msg) { Dwarf_Error dderr = 0; Dwarf_Off goff = 0; Dwarf_Off loff = 0; Dwarf_Half tag = 0; int res = 0; res = dwarf_die_offsets(die,&goff, &loff,&dderr); DROP_ERROR_INSTANCE(dbg,res,dderr); res = dwarf_tag(die, &tag, &dderr); DROP_ERROR_INSTANCE(dbg,res,dderr); printf("debugonly: Die tag 0x%x GOFF 0x%llx Loff 0x%llx %s\n", tag,goff,loff,msg); } #endif /* These for sure are not to debug_info or debug_types. */ static Dwarf_Bool form_refers_local_info(Dwarf_Half form) { switch(form) { case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: case DW_FORM_line_strp: /* These do not refer to the current section and cannot be checked as if they did. */ return FALSE; } return TRUE; } /* process each compilation unit in .debug_info */ int print_infos(Dwarf_Debug dbg,Dwarf_Bool is_info, Dwarf_Error *pi_err) { int nres = 0; nres = print_one_die_section(dbg,is_info,pi_err); return nres; } static void print_debug_fission_header(struct Dwarf_Debug_Fission_Per_CU_s *fsd) { const char * fissionsec = ".debug_cu_index"; unsigned i = 0; struct esb_s hash_str; if (!fsd || !fsd->pcu_type) { /* No fission data. */ return; } esb_constructor(&hash_str); printf("\n"); if (!strcmp(fsd->pcu_type,"tu")) { fissionsec = ".debug_tu_index"; } printf(" %-19s = %s\n","Fission section",fissionsec); printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx "\n", "Fission index ", fsd->pcu_index); format_sig8_string(&fsd->pcu_hash,&hash_str); printf(" %-19s = %s\n","Fission hash",esb_get_string(&hash_str)); /* 0 is always unused. Skip it. */ esb_destructor(&hash_str); printf(" %-19s = %s\n","Fission entries", "offset size DW_SECTn"); for ( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int res = 0; if (size == 0) { continue; } res = dwarf_get_SECT_name(i,&nstring); if (res != DW_DLV_OK) { nstring = "Unknown SECT"; } off = fsd->pcu_offset[i]; printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %2d\n", nstring, off,size,i); } } static void print_cu_hdr_cudie(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Die cudie, Dwarf_Unsigned overall_offset, Dwarf_Unsigned offset ) { struct Dwarf_Debug_Fission_Per_CU_s fission_data; if (glflags.dense) { printf("\n"); return; } memset(&fission_data,0,sizeof(fission_data)); printf("\nCOMPILE_UNIT
", (Dwarf_Unsigned)(overall_offset - offset)); printf(":\n"); } static void print_cu_hdr_std(Dwarf_Unsigned cu_header_length, Dwarf_Unsigned abbrev_offset, Dwarf_Half version_stamp, Dwarf_Half address_size, /* offset_size is often called length_size in libdwarf. */ Dwarf_Half offset_size, int debug_fission_res, Dwarf_Half cu_type, struct Dwarf_Debug_Fission_Per_CU_s * fsd) { int res = 0; const char *utname = 0; res = dwarf_get_UT_name(cu_type,&utname); if (res != DW_DLV_OK) { glflags.gf_count_major_errors++; utname = "ERROR"; } if (glflags.dense) { printf("<%s>", "cu_header"); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "cu_header_length", cu_header_length); printf(" %s<0x%04x>", "version_stamp", version_stamp); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "abbrev_offset", abbrev_offset); printf(" %s<0x%02x>", "address_size", address_size); printf(" %s<0x%02x>", "offset_size", offset_size); printf(" %s<0x%02x %s>", "cu_type", cu_type,utname); if (debug_fission_res == DW_DLV_OK) { struct esb_s hash_str; unsigned i = 0; esb_constructor(&hash_str); format_sig8_string(&fsd->pcu_hash,&hash_str); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "fissionindex", fsd->pcu_index); printf(" %s<%s>", "fissionhash", esb_get_string(&hash_str)); esb_destructor(&hash_str); for ( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int fires = 0; if (size == 0) { continue; } fires = dwarf_get_SECT_name(i,&nstring); if (fires != DW_DLV_OK) { nstring = "UnknownDW_SECT"; } off = fsd->pcu_offset[i]; printf(" %s< 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ">", nstring, off,size); } } } else { printf("\nCU_HEADER:\n"); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "cu_header_length", cu_header_length, cu_header_length); printf(" %-16s = 0x%04x %u\n", "version_stamp", version_stamp,version_stamp); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "abbrev_offset", abbrev_offset, abbrev_offset); printf(" %-16s = 0x%02x %u\n", "address_size", address_size,address_size); printf(" %-16s = 0x%02x %u\n", "offset_size", offset_size,offset_size); printf(" %-16s = 0x%02x %s\n", "cu_type", cu_type,utname); if (debug_fission_res == DW_DLV_OK) { print_debug_fission_header(fsd); } } } static void print_cu_hdr_signature(Dwarf_Sig8 *signature, Dwarf_Unsigned typeoffset) { if (glflags.dense) { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(signature,&sig8str); printf(" %s<%s>", "signature",esb_get_string(&sig8str)); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "typeoffset", typeoffset); esb_destructor(&sig8str); } else { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(signature,&sig8str); printf(" %-16s = %s\n", "signature", esb_get_string(&sig8str)); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "typeoffset", typeoffset,typeoffset); esb_destructor(&sig8str); } } static int get_macinfo_offset(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Unsigned *offset, Dwarf_Error *macerr) { Dwarf_Attribute attrib= 0; int vres = 0; int ares = 0; ares = dwarf_attr(cu_die, DW_AT_macro_info, &attrib, macerr); if (ares == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: getting dwarf_attr for DW_AT_macro_info" " failed", ares,*macerr); return ares; } else if (ares == DW_DLV_NO_ENTRY) { return ares; } vres = dwarf_global_formref(attrib,offset,macerr); if (vres == DW_DLV_ERROR) { dwarf_dealloc_attribute(attrib); print_error_and_continue(dbg, "ERROR: dwarf_global_formref on DW_AT_macro_info failed", vres, *macerr); return vres; } else if (vres == DW_DLV_OK) { dwarf_dealloc_attribute(attrib); } return vres; } static void print_die_secname(Dwarf_Debug dbg,int is_info) { if (print_as_info_or_by_cuname() && glflags.gf_do_print_dwarf) { const char * section_name = 0; struct esb_s truename; char buf[ESB_FIXED_ALLOC_SIZE]; if (is_info) { section_name = ".debug_info"; } else { section_name = ".debug_types"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } } static Dwarf_Bool empty_signature(const Dwarf_Sig8 *sigp) { if (memcmp(sigp,&zerosig,sizeof(zerosig))) { return FALSE ; /* empty */ } return TRUE; } static int print_macinfo_for_cu( Dwarf_Debug dbg, Dwarf_Die cu_die2, Dwarf_Error *err) { int mres = 0; Dwarf_Unsigned offset = 0; mres = get_macinfo_offset(dbg,cu_die2,&offset,err); if (mres == DW_DLV_NO_ENTRY) { /* By far the most likely result. */ return mres; }else if (mres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: get_macinfo_offset for " "DWARF 2,3,or 4 failed " "on a CU die", mres,*err); return mres; } else { mres = print_macinfo_by_offset(dbg, cu_die2, offset,err); if (mres==DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: printing macros for " " a CU at macinfo offset 0x%x " " failed ",offset); print_error_and_continue(dbg, esb_get_string(&m), mres,*err); esb_destructor(&m); } } return DW_DLV_OK; } /* Called with a CU_Die as in_die_in. */ static int print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed srcfiles_cnt, Dwarf_Error *err) { int res = 0; local_symbols_already_began = FALSE; res =print_die_and_children_internal(dbg, in_die_in, dieprint_cu_goffset, is_info,srcfiles,srcfiles_cnt,err); return res; } static int print_cu_hdr_abbrev_data(Dwarf_Debug dbg, Dwarf_Off aboffset, Dwarf_Error *error) { Dwarf_Unsigned initial_abbnum = 1; Dwarf_Unsigned final_abbnum = 0; Dwarf_Unsigned length = 0; int ores = 0; if (glflags.gf_do_print_dwarf) { printf("\nAbbreviation table this CU, offset " "0x%" DW_PR_XZEROS DW_PR_DUx ":\n", aboffset); } ores = print_all_abbrevs_for_cu(dbg, aboffset, initial_abbnum, &length,&final_abbnum,error); return ores; } /* */ static int print_one_die_section(Dwarf_Debug dbg,Dwarf_Bool is_info, Dwarf_Error *pod_err) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Half extension_size = 0; Dwarf_Half length_size = 0; Dwarf_Unsigned typeoffset = 0; Dwarf_Unsigned next_cu_offset = 0; unsigned loop_count = 0; int nres = DW_DLV_OK; int cu_count = 0; char * cu_short_name = NULL; char * cu_long_name = NULL; int res = 0; Dwarf_Off dieprint_cu_goffset = 0; glflags.current_section_id = is_info?DEBUG_INFO: DEBUG_TYPES; { const char * test_section_name = 0; res = dwarf_get_die_section_name(dbg,is_info, &test_section_name,pod_err); if (res == DW_DLV_NO_ENTRY) { if (!is_info) { /* No .debug_types. Do not print .debug_types name */ return DW_DLV_NO_ENTRY; } } } /* Loop until it fails. */ for (;;++loop_count) { int sres = DW_DLV_OK; Dwarf_Die cu_die = 0; Dwarf_Die cu_die2 = 0; struct Dwarf_Debug_Fission_Per_CU_s fission_data; int fission_data_result = 0; Dwarf_Half cu_type = 0; Dwarf_Sig8 signature; int offres = 0; signature = zerosig; /* glflags.DIE_overall_offset: in case dwarf_next_cu_header_d fails due to corrupt dwarf. */ glflags.DIE_overall_offset = dieprint_cu_goffset; memset(&fission_data,0,sizeof(fission_data)); nres = dwarf_next_cu_header_d(dbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &length_size,&extension_size, &signature, &typeoffset, &next_cu_offset, &cu_type, pod_err); if (!loop_count) { /* So compress flags show, we waited till section loaded to do this. */ print_die_secname(dbg,is_info); } if (nres == DW_DLV_NO_ENTRY) { return nres; } if (nres == DW_DLV_ERROR) { /* With corrupt DWARF due to a bad CU die we won't know much. */ print_error_and_continue(dbg, "ERROR: Failure reading CU header" " or DIE, corrupt DWARF", nres, *pod_err); return nres; } if (cu_count >= glflags.break_after_n_units) { const char *m = "CUs"; if (cu_count == 1) { m="CU"; } printf("Break at %d %s\n",cu_count,m); break; } /* Regardless of any options used, get basic information about the current CU: producer, name */ sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die, pod_err); if (sres != DW_DLV_OK) { /* There is no CU die, which should be impossible. */ if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_siblingof_b failed, no CU die", sres, *pod_err); return sres; } print_error_and_continue(dbg, "ERROR: dwarf_siblingof_b got NO_ENTRY, no CU die", sres, *pod_err); return sres; } /* Get the CU offset (when we can) for easy error reporting. Ignore errors. */ offres = dwarf_die_offsets(cu_die, &glflags.DIE_overall_offset, &glflags.DIE_offset,pod_err); DROP_ERROR_INSTANCE(dbg,offres,*pod_err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; dieprint_cu_goffset = glflags.DIE_overall_offset; if (glflags.gf_cu_name_flag) { Dwarf_Bool should_skip = FALSE; /* always sets should_skip, even if error */ should_skip_this_cu(dbg, &should_skip,cu_die); if (should_skip) { dwarf_dealloc_die(cu_die); cu_die = 0; ++cu_count; continue; } } { /* Get producer name for this CU and update compiler list */ int cures = 0; struct esb_s producername; esb_constructor(&producername); /* Fills in some producername no matter what status returned. */ cures = get_producer_name(dbg,cu_die, dieprint_cu_goffset,&producername,pod_err); if (cures == DW_DLV_OK) { update_compiler_target(esb_get_string(&producername)); } else { DROP_ERROR_INSTANCE(dbg,cures,*pod_err); } esb_destructor(&producername); } /* Once the compiler table has been updated, see if we need to generate the list of CU compiled by all the producers contained in the elf file */ if (glflags.gf_producer_children_flag) { int chres = 0; chres = get_cu_name(dbg,cu_die, dieprint_cu_goffset, &cu_short_name,&cu_long_name, pod_err); if (chres == DW_DLV_ERROR ) { return chres; } if (chres == DW_DLV_OK) { /* Add CU name to current compiler entry */ add_cu_name_compiler_target(cu_long_name); } } /* If the current compiler is not requested by the user, then move to the next CU */ if (!checking_this_compiler()) { dwarf_dealloc_die(cu_die); ++cu_count; cu_die = 0; continue; } fission_data_result = dwarf_get_debugfission_for_die( cu_die, &fission_data,pod_err); if (fission_data_result == DW_DLV_ERROR) { dwarf_dealloc_die(cu_die); cu_die = 0; print_error_and_continue(dbg, "ERROR: Failure looking for Debug Fission data", fission_data_result, *pod_err); return fission_data_result; } if (fission_data_result == DW_DLV_OK) { /* In a .dwp file some checks get all sorts of spurious errors. */ glflags.gf_suppress_checking_on_dwp = TRUE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_fdes = FALSE; } /* We have not seen the compile unit yet, reset these error-reporting globals. */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; glflags.need_CU_base_address = TRUE; glflags.need_CU_high_address = TRUE; /* Some prerelease gcc versions used ranges but seemingly assumed the lack of a base address in the CU was defined to be a zero base. Assuming a base address (and low and high) is sensible. */ glflags.CU_base_address = 0; glflags.CU_high_address = 0; glflags.CU_low_address = 0; /* Release the 'cu_die' created by the call to 'dwarf_next_cu_header_d' at the top of the main loop. */ dwarf_dealloc_die(cu_die); cu_die = 0; /* For debugging, stale die should be NULL. */ if ((glflags.gf_info_flag || glflags.gf_types_flag) && glflags.gf_do_print_dwarf) { if (glflags.verbose) { print_cu_hdr_std(cu_header_length,abbrev_offset, version_stamp,address_size,length_size, fission_data_result,cu_type,&fission_data); if (!empty_signature(&signature)) { print_cu_hdr_signature(&signature,typeoffset); } if (glflags.dense) { printf("\n"); } } else { if (!empty_signature(&signature)) { if (glflags.dense) { printf("<%s>", "cu_header"); } else { printf("\nCU_HEADER:\n"); } print_cu_hdr_signature(&signature,typeoffset); if (glflags.dense) { printf("\n"); } } } } if (glflags.gf_check_abbreviations || (glflags.verbose > 3 && (glflags.gf_info_flag || glflags.gf_types_flag) && glflags.gf_do_print_dwarf)) { int hares = 0; hares = print_cu_hdr_abbrev_data(dbg, abbrev_offset, pod_err); if (hares == DW_DLV_ERROR) { /* Will be reported later, no doubt. */ DROP_ERROR_INSTANCE(dbg,hares,*pod_err); *pod_err = 0; } } /* Get abbreviation info for this CU */ get_abbrev_array_info(dbg,abbrev_offset); /* Process a single compilation unit in .debug_info or .debug_types. */ cu_die2 = 0; sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die2, pod_err); if (sres == DW_DLV_OK) { int pres = 0; Dwarf_Signed srcfiles_cnt = 0; char **srcfiles = 0; int srcf = 0; Dwarf_Error srcerr = 0; srcf = dwarf_srcfiles(cu_die2, &srcfiles, &srcfiles_cnt, &srcerr); if (srcf == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_srcfiles problem ", srcf,srcerr); DROP_ERROR_INSTANCE(dbg,srcf,srcerr); srcfiles = 0; srcfiles_cnt = 0; } else if (srcf == DW_DLV_NO_ENTRY) { /* DW_DLV_NO_ENTRY generally means there there is no DW_AT_stmt_list attribute. and we do not want to print anything about statements in that case */ } if (print_as_info_or_by_cuname() || glflags.gf_search_is_on) { /* Do regardless if dwarf_srcfiles was successful to print die and children as best we can even with errors . */ int podres2 = 0; Dwarf_Error lperr = 0; /* Get the CU offset for easy error reporting */ podres2 = dwarf_die_offsets(cu_die2, &glflags.DIE_overall_offset, &glflags.DIE_offset,&lperr); DROP_ERROR_INSTANCE(dbg,podres2,lperr); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; dieprint_cu_goffset = glflags.DIE_overall_offset; pres = print_die_and_children(dbg, cu_die2, dieprint_cu_goffset,is_info, srcfiles, srcfiles_cnt,pod_err); if (pres == DW_DLV_ERROR) { if (srcfiles) { dealloc_all_srcfiles(dbg,srcfiles, srcfiles_cnt); srcfiles = 0; srcfiles_cnt = 0; } dwarf_dealloc_die(cu_die2); return pres; } } /* Dump Ranges Information */ if (dump_ranges_info) { PrintBucketGroup(glflags.pRangesInfo,TRUE); } /* Check the range array if in checl mode */ if ( glflags.gf_check_ranges) { int rares = 0; Dwarf_Error raerr = 0; rares = check_range_array_info(dbg,&raerr); if (rares == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: range array checks for " "the current CU failed. ", rares,raerr); DROP_ERROR_INSTANCE(dbg,rares,raerr); } } /* Traverse the line section if in check mode or if line-printing requested */ if (glflags.gf_line_flag || glflags.gf_check_decl_file) { int plnres = 0; int oldsection = glflags.current_section_id; plnres = print_line_numbers_this_cu(dbg, cu_die2, srcfiles,srcfiles_cnt,pod_err); if (plnres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: Printing line numbers for " "the current CU failed. ", plnres,*pod_err); /* Suppress the error so we print whatever we can */ DROP_ERROR_INSTANCE(dbg,plnres,*pod_err); } glflags.current_section_id = oldsection; } if (glflags.gf_macro_flag || glflags.gf_check_macros) { int mres = 0; Dwarf_Bool in_import_list = FALSE; Dwarf_Unsigned import_offset = 0; int oldsection = glflags.current_section_id; /* DWARF5 .debug_macro (version 5 in the macro header) or GNU extension of DWARF4 .debug_macro, with version 4 in the macro header. */ macro_import_stack_cleanout(); mres = print_macros_5style_this_cu(dbg, cu_die2, srcfiles,srcfiles_cnt, glflags.gf_do_print_dwarf, TRUE /* descend_into_imports */, in_import_list, import_offset,pod_err); if (mres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: Printing DWARF5 macros " "for the current CU failed. ", mres,*pod_err); /* Suppress the error so we print whatever we can */ DROP_ERROR_INSTANCE(dbg,mres,*pod_err); } macro_import_stack_cleanout(); in_import_list = TRUE; /* The above would have checked all reachable macro units, so no need to check here. */ if (!glflags.gf_do_check_dwarf && mres == DW_DLV_OK) { for (;;) { /* Never returns DW_DLV_ERROR */ mres = get_next_unprinted_macro_offset( ¯o_check_tree, &import_offset); if (mres != DW_DLV_OK) { break; } macro_import_stack_cleanout(); mres = print_macros_5style_this_cu(dbg, cu_die2, srcfiles,srcfiles_cnt, glflags.gf_do_print_dwarf, FALSE /* no descend_into_imports */, in_import_list, import_offset, pod_err); if (mres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "ERROR: Printing DWARF5 macros " " at offset 0x%x " "for the current macro import" " in the macros failed. ", import_offset); print_error_and_continue(dbg, esb_get_string(&m), mres,*pod_err); DROP_ERROR_INSTANCE(dbg,mres, *pod_err); esb_destructor(&m); break; } macro_import_stack_cleanout(); } } glflags.current_section_id = oldsection; } if ( glflags.gf_macinfo_flag || glflags.gf_check_macros) { int mres = 0; /* Macros have no version number before DWARF 5. */ mres = print_macinfo_for_cu(dbg,cu_die2, pod_err); if (mres == DW_DLV_ERROR) { if (cu_die2) { dwarf_dealloc_die(cu_die2); } if (srcfiles) { dealloc_all_srcfiles(dbg,srcfiles, srcfiles_cnt); srcfiles = 0; srcfiles_cnt = 0; } return mres; } } if (cu_die2) { dwarf_dealloc_die(cu_die2); } cu_die2 = 0; if (srcfiles) { dealloc_all_srcfiles(dbg,srcfiles,srcfiles_cnt); srcfiles = 0; srcfiles_cnt = 0; } } else if (sres == DW_DLV_NO_ENTRY) { /* Do nothing I guess. */ } else { print_error_and_continue(dbg, "ERROR: getting a compilation-unit " "CU die failed ", sres,*pod_err); DROP_ERROR_INSTANCE(dbg,sres,*pod_err); } cu_die2 = 0; ++cu_count; } /* End loop on loop_count */ return nres; } static int print_a_die_stack(Dwarf_Debug dbg, char **srcfiles, Dwarf_Signed srcfiles_cnt, int lev, Dwarf_Error *err) { /* Print_information TRUE means attribute_matched will NOT be set by attribute name match. Just print the die at the top of stack.*/ Dwarf_Bool print_else_name_match = TRUE; Dwarf_Bool ignore_die_stack = FALSE; Dwarf_Bool attribute_matched = FALSE; int res = 0; res = print_one_die(dbg, die_stack[lev].die_, die_stack[lev].cu_die_offset_, print_else_name_match,lev,srcfiles,srcfiles_cnt, &attribute_matched, ignore_die_stack, err); return res; } static int print_die_stack(Dwarf_Debug dbg, char **srcfiles, Dwarf_Signed srcfiles_cnt, Dwarf_Error*err) { int lev = 0; /* Print_information TRUE means attribute_matched will NOT be set by attribute name match. Just print the dies in the stack.*/ Dwarf_Bool print_else_name_match = TRUE; Dwarf_Bool ignore_die_stack = FALSE; Dwarf_Bool attribute_matched = FALSE; for (lev = 0; lev <= die_stack_indent_level; ++lev) { int res = 0; res = print_one_die(dbg,die_stack[lev].die_, die_stack[lev].cu_die_offset_, print_else_name_match, lev,srcfiles,srcfiles_cnt, &attribute_matched, ignore_die_stack,err); if (res == DW_DLV_ERROR) { return res; } } return DW_DLV_OK; } /* recursively follow the die tree */ static int print_die_and_children_internal(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt, Dwarf_Error *err) { Dwarf_Die child = 0; Dwarf_Die sibling = 0; int cdres = 0; Dwarf_Die in_die = in_die_in; for (;;) { int offres = 0; /* Get the CU offset for easy error reporting */ offres = dwarf_die_offsets(in_die, &glflags.DIE_overall_offset, &glflags.DIE_offset,err); DROP_ERROR_INSTANCE(dbg,offres,*err); SET_DIE_STACK_ENTRY(die_stack_indent_level,in_die, dieprint_cu_goffset); if ( glflags.gf_check_tag_tree || glflags.gf_print_usage_tag_attr) { DWARF_CHECK_COUNT(tag_tree_result,1); if (die_stack_indent_level == 0) { Dwarf_Half tag = 0; int dtres = 0; dtres = dwarf_tag(in_die, &tag, err); if (dtres != DW_DLV_OK) { DROP_ERROR_INSTANCE(dbg,dtres,*err); DWARF_CHECK_ERROR(tag_tree_result, "Tag-tree root tag unavailable: " "is not DW_TAG_compile_unit"); } else if (tag == DW_TAG_skeleton_unit) { /* OK */ } else if (tag == DW_TAG_compile_unit) { /* OK */ } else if (tag == DW_TAG_partial_unit) { /* OK */ } else if (tag == DW_TAG_type_unit) { /* OK */ } else { DWARF_CHECK_ERROR(tag_tree_result, "tag-tree root is not " "DW_TAG_compile_unit " "or DW_TAG_partial_unit or " "DW_TAG_type_unit"); } } else { Dwarf_Half tag_parent = 0; Dwarf_Half tag_child = 0; int pres = 0; int cres = 0; const char *ctagname = ""; const char *ptagname = ""; pres = dwarf_tag(die_stack[ die_stack_indent_level - 1].die_, &tag_parent, err); if (pres != DW_DLV_OK) { if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return cres; } cres = dwarf_tag(in_die, &tag_child, err); if (cres != DW_DLV_OK) { return cres; } /* Check for specific compiler */ if (checking_this_compiler()) { /* Process specific TAGs. */ tag_specific_globals_setup(dbg,tag_child, die_stack_indent_level); if (cres != DW_DLV_OK || pres != DW_DLV_OK) { if (cres == DW_DLV_OK) { ctagname = get_TAG_name(tag_child, pd_dwarf_names_print_on_error); } if (pres == DW_DLV_OK) { ptagname = get_TAG_name(tag_parent, pd_dwarf_names_print_on_error); } DWARF_CHECK_ERROR3(tag_tree_result, ptagname, ctagname, "Tag-tree relation is " "not standard.."); } else if (legal_tag_tree_combination( tag_parent, tag_child)) { /* OK */ } else { /* Report errors only if tag-tree check is on */ if (glflags.gf_check_tag_tree) { DWARF_CHECK_ERROR3(tag_tree_result, get_TAG_name(tag_parent, pd_dwarf_names_print_on_error), get_TAG_name(tag_child, pd_dwarf_names_print_on_error), "tag-tree relation is " "not standard."); } } } } } if (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode) { glflags.gf_record_dwarf_error = FALSE; } /* Here do pre-descent processing of the die. */ { Dwarf_Bool an_attribute_match_local = FALSE; Dwarf_Bool ignore_die_stack = FALSE; int pdres = 0; pdres = print_one_die(dbg, in_die, dieprint_cu_goffset, print_as_info_or_by_cuname(), die_stack_indent_level, srcfiles, cnt, &an_attribute_match_local, ignore_die_stack, err); if (pdres != DW_DLV_OK) { if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return pdres; } validate_die_stack_siblings(dbg); if (!print_as_info_or_by_cuname() && an_attribute_match_local) { if (glflags.gf_display_parent_tree) { pdres = print_die_stack(dbg,srcfiles,cnt, err); if (pdres == DW_DLV_ERROR) { if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return pdres; } } else { if (glflags.gf_display_children_tree) { pdres = print_a_die_stack( dbg,srcfiles,cnt, die_stack_indent_level,err); if (pdres == DW_DLV_ERROR) { if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return pdres; } } } if (glflags.gf_display_children_tree) { glflags.gf_stop_indent_level = die_stack_indent_level; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } } } cdres = dwarf_child(in_die, &child, err); if (cdres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Call to dwarf_child failed printing die tree", cdres,*err); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return cdres; } /* Check for specific compiler */ if (glflags.gf_check_abbreviations && checking_this_compiler()) { Dwarf_Half ab_has_child; Dwarf_Bool bError = FALSE; Dwarf_Half tag = 0; int abtres = 0; /* This does not return a Dwarf_Error value! */ abtres = dwarf_die_abbrev_children_flag(in_die, &ab_has_child); if (abtres == DW_DLV_OK) { Dwarf_Error tagerr = 0; int tagres = 0; DWARF_CHECK_COUNT(abbreviations_result,1); tagres = dwarf_tag(in_die, &tag, &tagerr); if (tagres == DW_DLV_OK) { switch (tag) { case DW_TAG_array_type: case DW_TAG_class_type: case DW_TAG_compile_unit: case DW_TAG_type_unit: case DW_TAG_partial_unit: case DW_TAG_enumeration_type: case DW_TAG_lexical_block: case DW_TAG_namespace: case DW_TAG_structure_type: case DW_TAG_subprogram: case DW_TAG_subroutine_type: case DW_TAG_union_type: case DW_TAG_entry_point: case DW_TAG_inlined_subroutine: break; default: bError = (cdres == DW_DLV_OK && !ab_has_child) || (cdres == DW_DLV_NO_ENTRY && ab_has_child); if (bError) { DWARF_CHECK_ERROR( abbreviations_result, "check 'dw_children'" " flag combination."); } break; } } else if (tagres == DW_DLV_ERROR) { dwarf_dealloc_die(child); print_error_and_continue(dbg, "Unable to read die tag!", tagres,tagerr); /* tagerr is unrelated to *error but leaving *error NULL should be ok. */ return tagres; } } else if (abtres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: Unable to read die children " "flag.\n"); /* return is unrelated to *error but leaving *error NULL should be ok. */ return abtres; } } /* child first: we are doing depth-first walk */ if (cdres == DW_DLV_OK) { /* If the global offset of the (first) child is <= the parent DW_AT_sibling global-offset-value then the compiler has made a mistake, and the DIE tree is corrupt. */ int pdacres = 0; Dwarf_Off child_overall_offset = 0; int cores = dwarf_dieoffset(child, &child_overall_offset, err); if (cores == DW_DLV_OK) { Dwarf_Off parent_sib_val = get_die_stack_sibling(); if (parent_sib_val && (parent_sib_val <= child_overall_offset )) { char small_buf[ESB_FIXED_ALLOC_SIZE]; struct esb_s pm; esb_constructor_fixed(&pm,small_buf, sizeof(small_buf)); esb_append_printf_u(&pm, "ERROR: A parent DW_AT_sibling of " "0x%" DW_PR_XZEROS DW_PR_DUx, parent_sib_val); esb_append_printf_s(&pm, " points %s the first child ", (parent_sib_val == child_overall_offset)? "at":"before"); esb_append_printf_u(&pm, "0x%" DW_PR_XZEROS DW_PR_DUx " so the die tree is corrupt " "(showing section, not CU, offsets). ", child_overall_offset); dwarf_error_creation(dbg,err, esb_get_string(&pm)); print_error_and_continue(dbg, esb_get_string(&pm), DW_DLV_ERROR,*err); /* Original test did a print_error() here, which did exit(). We would like to return ERROR all the way back, but have no way at present to generate a Dwarf_Error record. Because these sorts of errors are not really recoverable. */ esb_destructor(&pm); dwarf_dealloc_die(child); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return DW_DLV_ERROR; } } else if (cores == DW_DLV_ERROR) { print_error_and_continue(dbg, "Finding a DIE offset (dwarf_dieoffset())" "failed.",cores,*err); dwarf_dealloc_die(child); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return cores; } if ((1+die_stack_indent_level) >= DIE_STACK_SIZE ) { report_die_stack_error(dbg,err); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } dwarf_dealloc_die(child); return DW_DLV_ERROR; } die_stack_indent_level++; SET_DIE_STACK_ENTRY(die_stack_indent_level,0, dieprint_cu_goffset); pdacres = print_die_and_children_internal(dbg, child, dieprint_cu_goffset, is_info, srcfiles, cnt,err); EMPTY_DIE_STACK_ENTRY(die_stack_indent_level); dwarf_dealloc_die(child); die_stack_indent_level--; if (pdacres == DW_DLV_ERROR) { if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return pdacres; } child = 0; } else if (cdres == DW_DLV_ERROR) { dwarf_dealloc_die(child); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return cdres; } /* Stop the display of all children */ if (glflags.gf_display_children_tree && (glflags.gf_info_flag || glflags.gf_types_flag) && glflags.gf_stop_indent_level == die_stack_indent_level) { glflags.gf_info_flag = FALSE; glflags.gf_types_flag = FALSE; } sibling = 0; dwarf_dealloc_die(child); child = 0; cdres = dwarf_siblingof_b(dbg, in_die,is_info, &sibling, err); if (cdres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_siblingof fails" " tracing siblings of a DIE.", cdres, *err); if (in_die != in_die_in) { dwarf_dealloc_die(in_die); } return cdres; } /* print_die_and_children(dbg,sibling,srcfiles,cnt); We loop around to actually print this, rather than recursing. Recursing is horribly wasteful of stack space. */ /* If we have a sibling, verify that its offset is next to the last processed DIE; An incorrect sibling chain is a nasty bug. */ if (cdres == DW_DLV_OK && sibling && glflags.gf_check_di_gaps && checking_this_compiler()) { Dwarf_Off glb_off; DWARF_CHECK_COUNT(di_gaps_result,1); if (dwarf_validate_die_sibling(sibling,&glb_off) == DW_DLV_ERROR) { Dwarf_Off sib_off; struct esb_s msg; esb_constructor(&msg); dwarf_dieoffset(sibling,&sib_off,err); esb_append_printf_u(&msg, "GSIB = 0x%" DW_PR_XZEROS DW_PR_DUx, sib_off); esb_append_printf_u(&msg, " GOFF = 0x%" DW_PR_XZEROS DW_PR_DUx, glb_off); esb_append_printf_u(&msg, " Gap = %" DW_PR_DUu " bytes", sib_off-glb_off); DWARF_CHECK_ERROR2(di_gaps_result, "Incorrect sibling chain", esb_get_string(&msg)); esb_destructor(&msg); } } /* Here do any post-descent (ie post-dwarf_child) processing of the in_die. */ EMPTY_DIE_STACK_ENTRY(die_stack_indent_level); if (in_die != in_die_in) { /* Dealloc our in_die, but not the argument die, it belongs to our caller. Whether the siblingof call worked or not. */ dwarf_dealloc_die(in_die); in_die = 0; } if (cdres == DW_DLV_OK) { /* Set to process the sibling, loop again. */ in_die = sibling; sibling = 0; } else { /* ASSERT: cdres is DW_DLV_NO_ENTRY */ sibling = 0; in_die = 0; /* We are done, no more siblings at this level. */ break; } } /* end for loop on siblings */ return DW_DLV_OK; } static void dealloc_local_atlist(Dwarf_Debug dbg, Dwarf_Attribute *atlist, Dwarf_Signed atcnt) { Dwarf_Signed i = 0; for (i = 0; i < atcnt; i++) { dwarf_dealloc_attribute(atlist[i]); atlist[i] = 0; } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } /* Print one die on error and verbose or non check mode */ #define PRINTING_DIES (glflags.gf_do_print_dwarf || \ (glflags.gf_record_dwarf_error && \ glflags.gf_check_verbose_mode)) static void print_srcfiles( char **srcfiles,Dwarf_Signed srcfcnt) { Dwarf_Signed i = 0; const char * cntstr = " [%" DW_PR_DSd "]"; printf(" dwarf_srcfiles() returned strings. Count = %" DW_PR_DSd ".\n",srcfcnt); if (srcfcnt < 0) { glflags.gf_count_major_errors++; printf("ERROR: dwarf_srcfiles count less than zero " "which should be impossible. Ignoring srcfiles."); return; } if (srcfcnt > 9) { if (srcfcnt > 99) { cntstr = " [%3" DW_PR_DSd "]"; } else { cntstr = " [%2" DW_PR_DSd "]"; } } for ( ; i < srcfcnt; ++i) { printf(cntstr,i); printf(" %s\n",sanitized(srcfiles[i])); } } /* If print_else_name_match is FALSE, check for attribute matches with -S inr print_attribute, and if found, print the information anyway. if print_else_name_match is true, do not check for attribute name matches. Just print. Sets *an_attr_matched TRUE if there is attribute name or value that matches a -S option (the long form option starts with --search) Returns DW_DLV_OK DW_DLV_ERROR or DW_DLV_NO_ENTRY */ int print_one_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool print_else_name_match, int die_indent_level, char **srcfiles, Dwarf_Signed srcfcnt, Dwarf_Bool *an_attr_matched_io, Dwarf_Bool ignore_die_stack, Dwarf_Error *err) { Dwarf_Signed i = 0; Dwarf_Signed j = 0; Dwarf_Off offset = 0; Dwarf_Off overall_offset = 0; const char * tagname = 0; Dwarf_Half tag = 0; Dwarf_Signed atcnt = 0; Dwarf_Attribute *atlist = 0; int tres = 0; int ores = 0; Dwarf_Bool attribute_matchedpod = FALSE; int atres = 0; int abbrev_code = dwarf_die_abbrev_code(die); LoHiPc lohipc; int indentprespaces = 0; lohipc = lohipc_zero; /* Print using indentation see standard_indent() above. < 1><0x000854ff GOFF=0x00546047> DW_TAG_pointer_type -> 34 < 1><0x000854ff> DW_TAG_pointer_type -> 18 DW_TAG_pointer_type -> 2 */ if (glflags.gf_check_abbreviations && checking_this_compiler()) { validate_abbrev_code(dbg,abbrev_code); } if (!ignore_die_stack && die_stack[die_indent_level].already_printed_) { /* FALSE seems safe . */ *an_attr_matched_io = FALSE; return DW_DLV_OK; } indentprespaces = standard_indent(); tres = dwarf_tag(die, &tag, err); if (tres != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: accessing tag of die!", tres, *err); return tres; } tagname = get_TAG_name(tag,pd_dwarf_names_print_on_error); #ifdef HAVE_USAGE_TAG_ATTR if ( glflags.gf_print_usage_tag_attr) { record_tag_usage(tag); } #endif /* HAVE_USAGE_TAG_ATTR */ tag_specific_globals_setup(dbg,tag,die_indent_level); ores = dwarf_dieoffset(die, &overall_offset, err); if (ores != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: failed dwarf_dieoffset call", ores, *err); return ores; } ores = dwarf_die_CU_offset(die, &offset, err); if (ores != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: dwarf_die_CU_offset failed", ores, *err); return ores; } if (dump_visited_info && glflags.gf_check_self_references) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); print_indent_prefix(0,die_indent_level,2); printf("%s\n",tagname); } /* Print the die */ if (PRINTING_DIES && print_else_name_match) { if (!ignore_die_stack) { die_stack[die_indent_level].already_printed_ = TRUE; } if (die_indent_level == 0) { print_cu_hdr_cudie(dbg,die, overall_offset, offset); } else if (local_symbols_already_began == FALSE && die_indent_level == 1 && !glflags.dense) { printf("\nLOCAL_SYMBOLS:\n"); local_symbols_already_began = TRUE; } /* Print just the Tags and Attributes */ if (!glflags.gf_display_offsets) { /* Print using indentation */ print_indent_prefix(0,die_indent_level,2); printf("%s\n",tagname); } else { if (glflags.dense) { if (glflags.gf_show_global_offsets) { if (die_indent_level == 0) { printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx " GOFF=0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned) (overall_offset - offset), (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } else { printf("<%d><0x%" DW_PR_DUx " GOFF=0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } } else { if (die_indent_level == 0) { printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned) (overall_offset - offset), (Dwarf_Unsigned)offset); } else { printf("<%d><0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset); } } printf("<%s>",tagname); if (glflags.verbose) { Dwarf_Off agoff = 0; Dwarf_Unsigned acount = 0; printf(" "); } } else { if (glflags.gf_show_global_offsets) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } else { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset); } /* Print using indentation */ print_indent_prefix(0,die_indent_level, 2); printf("%s",tagname); if (glflags.verbose) { Dwarf_Off agoff = 0; Dwarf_Unsigned acount = 0; printf(" "); } fputs("\n",stdout); } } } if ((glflags.verbose > 2) && (die_indent_level == 0) && srcfcnt && PRINTING_DIES) { print_srcfiles(srcfiles,srcfcnt); } atres = dwarf_attrlist(die, &atlist, &atcnt, err); if (atres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: A call to dwarf_attrlist failed. " " Impossible error.", atres,*err); return atres; } else if (atres == DW_DLV_NO_ENTRY) { /* indicates there are no attrs. It is not an error. */ atcnt = 0; } /* Get the offset for easy error reporting: This is not the CU die. */ atres = dwarf_die_offsets(die,&glflags.DIE_overall_offset, &glflags.DIE_offset,err); if (atres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: A call to dwarf_die_offsets failed in " "printing an attribute. " , atres,*err); dealloc_local_atlist(dbg,atlist,atcnt); return atres; } for (i = 0; i < atcnt; i++) { Dwarf_Half attr; int ares; ares = dwarf_whatattr(atlist[i], &attr, err); if (ares == DW_DLV_OK) { /* Check duplicated attributes; use brute force as the number of attributes is quite small; the problem was detected with the LLVM toolchain, generating more than 12 repeated attributes */ if (glflags.gf_check_duplicated_attributes) { Dwarf_Half attr_next; DWARF_CHECK_COUNT(duplicated_attributes_result,1); for (j = i + 1; j < atcnt; ++j) { ares = dwarf_whatattr(atlist[j], &attr_next,err); if (ares == DW_DLV_OK) { if (attr == attr_next) { DWARF_CHECK_ERROR2( duplicated_attributes_result, "Duplicated attribute ", get_AT_name(attr, pd_dwarf_names_print_on_error)); } } else { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "ERROR: dwarf_whatattr entry missing " " when checking for duplicated " "attributes" " reading attribute ",j); print_error_and_continue(dbg, esb_get_string(&m), ares, *err); esb_destructor(&m); dealloc_local_atlist(dbg,atlist,atcnt); return ares; } } } /* Print using indentation */ if (!glflags.dense && PRINTING_DIES && print_else_name_match) { print_indent_prefix(indentprespaces, die_indent_level,2); } { Dwarf_Bool attr_match_localb = FALSE; int aresb = 0; aresb = print_attribute(dbg, die, dieprint_cu_goffset, attr, atlist[i], print_else_name_match, die_indent_level, srcfiles, srcfcnt, &lohipc, &attr_match_localb,err); if (aresb == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "ERROR: Failed printing attribute %d", i); esb_append_printf_i(&m, " of %d attributes.",atcnt); print_error_and_continue(dbg, esb_get_string(&m), aresb,*err); esb_destructor(&m); DROP_ERROR_INSTANCE(dbg,aresb,*err) } if (print_else_name_match == FALSE && attr_match_localb) { attribute_matchedpod = TRUE; } } if (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode) { glflags.gf_record_dwarf_error = FALSE; } } else { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "ERROR: Failed getting attribute %d", i); esb_append_printf_i(&m, " of %d attributes.", atcnt); print_error_and_continue(dbg, esb_get_string(&m),ares,*err); esb_destructor(&m); dealloc_local_atlist(dbg,atlist,atcnt); return ares; } } /* atres might have been DW_DLV_NO_ENTRY, atlist NULL */ if (atlist) { dealloc_local_atlist(dbg,atlist,atcnt); } if (PRINTING_DIES && glflags.dense && print_else_name_match) { printf("\n"); } *an_attr_matched_io = attribute_matchedpod; return DW_DLV_OK; } /* Encodings have undefined signedness. Accept either signedness. The values are integer-like (they are defined in the DWARF specification), so the form the compiler uses (as long as it is a constant value) is a non-issue. The numbers need not be small (in spite of the function name), but the result should be an integer. If string_out is non-NULL, construct a string output, either an error message or the name of the encoding. The function pointer passed in is to code generated by a script at dwarfdump build time. The code for the val_as_string function is generated from dwarf.h. See /dwarf_names.c The known_signed bool is set TRUE(nonzero) or FALSE (zero) and *both* uval_out and sval_out are set to the value, though of course uval_out cannot represent a signed value properly and sval_out cannot represent all unsigned values properly. If string_out is non-NULL then attr_name and val_as_string must also be non-NULL. */ int dd_get_integer_and_name(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Unsigned * uval_out, const char *attr_name, struct esb_s* string_out, encoding_type_func val_as_string, Dwarf_Error * err, int show_form) { Dwarf_Unsigned uval = 0; int vres = dwarf_formudata(attrib, &uval, err); /* if it is not formudata, lets check further */ DROP_ERROR_INSTANCE(dbg,vres,*err); if (vres != DW_DLV_OK) { Dwarf_Signed sval = 0; int ires = 0; ires = dwarf_formsdata(attrib, &sval, err); /* It is not formudata, lets check further */ DROP_ERROR_INSTANCE(dbg,ires,*err); if (ires != DW_DLV_OK) { int jres = 0; jres = dwarf_global_formref(attrib,&uval,err); if (jres != DW_DLV_OK) { if (string_out) { glflags.gf_count_major_errors++; esb_append_printf_s(string_out, "ERROR: %s has a bad form" " for reading a value.", attr_name); } return jres; } *uval_out = uval; } else { uval = (Dwarf_Unsigned) sval; *uval_out = uval; } } else { *uval_out = uval; } if (string_out) { Dwarf_Half theform = 0; Dwarf_Half directform = 0; char fsbuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s fstring; int fres = 0; esb_constructor_fixed(&fstring,fsbuf,sizeof(fsbuf)); fres = get_form_values(dbg,attrib,&theform, &directform,err); if (fres == DW_DLV_ERROR) { return fres; } esb_append(&fstring, val_as_string((Dwarf_Half) uval, pd_dwarf_names_print_on_error)); show_form_itself(show_form,glflags.verbose,theform, directform,&fstring); esb_append(string_out,esb_get_string(&fstring)); esb_destructor(&fstring); } return DW_DLV_OK; } /* Called for DW_AT_SUN_func_offsets We need a 32-bit signed number here. But we're getting rid of the __[u]int[n]_t dependence so lets use plain characters. This is rarely, if ever, used so lets report errors but not stop the processing. */ static void get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib, struct esb_s*esbp) { int fres = 0; Dwarf_Block *tempb = 0; Dwarf_Unsigned array_len = 0; Dwarf_Signed *array = 0; Dwarf_Unsigned next = 0; Dwarf_Error fblkerr = 0; /* first get compressed block data */ fres = dwarf_formblock (attrib,&tempb, &fblkerr); if (fres != DW_DLV_OK) { print_error_and_continue(dbg, "DW_FORM_blockn cannot get block\n", fres,fblkerr); DROP_ERROR_INSTANCE(dbg,fres,fblkerr); return; } fres = dwarf_uncompress_integer_block_a(dbg, tempb->bl_len, (void *)tempb->bl_data, &array_len,&array,&fblkerr); /* uncompress block into 32bit signed int array. It's really a block of sleb numbers so the compression is minor unless the values are close to zero. */ if (fres != DW_DLV_OK) { dwarf_dealloc(dbg,tempb,DW_DLA_BLOCK); print_error_and_continue(dbg, "DW_AT_SUN_func_offsets cannot uncompress data\n", 0,fblkerr); DROP_ERROR_INSTANCE(dbg,fres,fblkerr); return; } if (array_len == 0) { print_error_and_continue(dbg, "DW_AT_SUN_func_offsets has no data (array" " length is zero), something badly" " wrong", DW_DLV_OK,fblkerr); return; } /* fill in string buffer */ next = 0; while (next < array_len) { unsigned i = 0; /* Print a full line */ esb_append(esbp,"\n "); for (i = 0 ; i < 2 && next < array_len; ++i,++next) { Dwarf_Signed vs = array[next]; Dwarf_Unsigned vu = (Dwarf_Unsigned)vs; if (i== 1) { esb_append(esbp," "); } esb_append_printf_i(esbp,"%6" DW_PR_DSd " ",vs); esb_append_printf_u(esbp, "(0x%" DW_PR_XZEROS DW_PR_DUx ")",vu); } } dwarf_dealloc(dbg,tempb,DW_DLA_BLOCK); /* free array buffer */ dwarf_dealloc_uncompressed_block(dbg, array); } static const char * get_rangelist_type_descr(Dwarf_Ranges *r) { switch (r->dwr_type) { case DW_RANGES_ENTRY: return "range entry"; case DW_RANGES_ADDRESS_SELECTION: return "addr selection"; case DW_RANGES_END: return "range end"; } /* Impossible. */ return "Unknown"; } /* The string produced here will need to be passed through sanitized() before actually printing. Always returns DW_DLV_OK. */ int print_ranges_list_to_extra(Dwarf_Debug dbg, Dwarf_Unsigned originaloff, Dwarf_Unsigned finaloff, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount, struct esb_s *stringbuf) { const char * sec_name = 0; Dwarf_Signed i = 0; struct esb_s truename; char buf[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); /* We don't want to set the compress data into the secname here. */ get_true_section_name(dbg,".debug_ranges", &truename,FALSE); sec_name = esb_get_string(&truename); if (glflags.dense) { esb_append_printf_i(stringbuf,"< ranges: %" DW_PR_DSd,rangecount); esb_append_printf_s(stringbuf," ranges at %s" , sanitized(sec_name)); if (originaloff == finaloff) { esb_append_printf_u(stringbuf," offset %" DW_PR_DUu , finaloff); } else { esb_append_printf_u(stringbuf, " offset with non-zero ranges base %" DW_PR_DUu , finaloff); } esb_append_printf_u(stringbuf," (0x%" DW_PR_XZEROS DW_PR_DUx, finaloff); esb_append_printf_u(stringbuf,") " "(%" DW_PR_DUu " bytes)>", bytecount); } else { esb_append_printf_i(stringbuf," ranges: %" DW_PR_DSd, rangecount); esb_append_printf_s(stringbuf," at %s" , sanitized(sec_name)); if (originaloff == finaloff) { esb_append_printf_u(stringbuf," offset %" DW_PR_DUu , finaloff); } else { esb_append_printf_u(stringbuf, " offset with non-zero ranges base %" DW_PR_DUu , finaloff); } esb_append_printf_u(stringbuf," (0x%" DW_PR_XZEROS DW_PR_DUx, finaloff); esb_append_printf_u(stringbuf,") " "(%" DW_PR_DUu " bytes)\n", bytecount); } for (i = 0; i < rangecount; ++i) { Dwarf_Ranges * r = rangeset +i; const char *type = get_rangelist_type_descr(r); if (glflags.dense) { esb_append_printf_i(stringbuf,"<[%2" DW_PR_DSd,i); esb_append_printf_s(stringbuf,"] %s",type); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx,r->dwr_addr1); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx ">",r->dwr_addr2); } else { esb_append_printf_i(stringbuf," [%2" DW_PR_DSd,i); esb_append_printf_s(stringbuf,"] %-14s",type); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx, r->dwr_addr1); esb_append_printf_u(stringbuf, " 0x%" DW_PR_XZEROS DW_PR_DUx "\n",r->dwr_addr2); } } esb_destructor(&truename); return DW_DLV_OK; } static void do_dump_visited_info(int level, Dwarf_Off loff,Dwarf_Off goff, Dwarf_Off cu_die_goff, const char *atname, const char *valname) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx " CU-GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ", level, loff, goff,cu_die_goff); print_indent_prefix(0,level,2); printf("%s -> %s\n",atname,valname); } /* Always returns DW_DLV_OK. Expected attr is DW_AT_decl_file or DW_AT_call_file */ static int turn_file_num_to_string(UNUSEDARG Dwarf_Debug dbg, Dwarf_Die die, UNUSEDARG Dwarf_Attribute attrib, Dwarf_Half theform, Dwarf_Half dwversion, Dwarf_Unsigned filenum,/* decl_file number */ char **srcfiles, Dwarf_Signed srcfiles_cnt, struct esb_s * esbp, Dwarf_Error *err) { Dwarf_Half offset_size=0; int vres = 0; char declmsgbuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s declmsg; char *fname = 0; Dwarf_Half attrnum = 0; vres = dwarf_whatattr(attrib,&attrnum,err); if (vres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append(&m, "ERROR: Cannot get DIE context " "attribute number for attr "); esb_append_printf_s(&m, "form %s ", get_FORM_name(theform, FALSE)); print_error_and_continue(dbg, esb_get_string(&m),vres,*err); esb_destructor(&m); if (vres == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,vres,*err); } return DW_DLV_OK; } vres = dwarf_get_version_of_die(die, &dwversion,&offset_size); if (vres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_s(&m, "ERROR: Cannot get DIE context " "version number for attr %s ", get_AT_name(attrnum, FALSE)); esb_append_printf_s(&m, "form %s ", get_FORM_name(theform, FALSE)); print_error_and_continue(dbg, esb_get_string(&m),vres,*err); esb_destructor(&m); if (vres == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,vres,*err); } return DW_DLV_OK; } esb_constructor_fixed(&declmsg,declmsgbuf, sizeof(declmsgbuf)); if (!srcfiles) { if (glflags.verbose > 2) { esb_append_printf_s(&declmsg, " <%s file index ", get_AT_name(attrnum,FALSE)); esb_append_printf_u(&declmsg, "%" DW_PR_DUu,filenum); esb_append(&declmsg," No file list for CU>"); esb_append(esbp, " "); esb_append(esbp, esb_get_string(&declmsg)); } esb_destructor(&declmsg); return DW_DLV_OK; } else { Dwarf_Unsigned localud = filenum; Dwarf_Bool done = FALSE; if (dwversion == DWVERSION5) { if ( localud < (Dwarf_Unsigned)srcfiles_cnt) { fname = srcfiles[localud]; esb_append(&declmsg,fname); done = TRUE; } } else { if (!localud) { /* Just print the number, there is no name. */ done=TRUE; } else if (localud && localud <= (Dwarf_Unsigned)srcfiles_cnt) { fname = srcfiles[localud - 1]; esb_append(&declmsg,fname); done = TRUE; } } if (!done) { esb_append_printf_s(&declmsg, " <%s file index ", get_AT_name(attrnum,FALSE)); esb_append_printf_u(&declmsg, "%" DW_PR_DUu,filenum); esb_append(&declmsg," out of range>"); } } if (fname) { esb_append(esbp, " "); esb_append(esbp, esb_get_string(&declmsg)); } esb_destructor(&declmsg); return DW_DLV_OK; } static void append_useful_die_name(UNUSEDARG Dwarf_Debug dbg, Dwarf_Die die, char **srcfiles, Dwarf_Signed srcfiles_cnt, struct esb_s *outstr, Dwarf_Error *err) { int res = 0; Dwarf_Attribute nattr = 0; Dwarf_Half nattr_form = 0; Dwarf_Attribute lattr = 0; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned linenum = 0; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; res = dwarf_get_version_of_die(die,&version,&offset_size); if (res != DW_DLV_OK) { /* FAIL. */ return; } res = dwarf_attr(die,DW_AT_decl_file, &nattr,err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } return; } res =dwarf_whatform(nattr,&nattr_form,err); if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } dwarf_dealloc_attribute(nattr); return; } res = dwarf_attr(die,DW_AT_decl_line,&lattr,err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } linenum = 0; } else { res = dwarf_formudata(lattr,&linenum,err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } linenum = 0; } } dwarf_dealloc_attribute(lattr); lattr = 0; turn_file_num_to_string(dbg,die, nattr, nattr_form, version,filenum, srcfiles,srcfiles_cnt, outstr, err); if (linenum) { esb_append_printf_u(outstr, " line: %u",linenum); } dwarf_dealloc_attribute(nattr); return; } /* So far, designed for DW_AT_type with a Dwarf_Sig8 reference. Does not yet look at tied object even if one is present. Does not currently attempt to use any signature resolution fast-access DWARF sections. */ static int print_sig8_target(Dwarf_Debug dbg, Dwarf_Attribute attrib, int die_indent_level, char **srcfiles, Dwarf_Signed srcfiles_cnt, struct esb_s * valname, Dwarf_Error *err) { Dwarf_Sig8 signature; Dwarf_Die targdie = 0; Dwarf_Bool targ_is_info = FALSE; Dwarf_Half targtag = 0; Dwarf_Unsigned targ_goff = 0; const char * targtagname = 0; char * targdiename = 0; int res = 0; res = dwarf_formsig8(attrib,&signature,err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_formsig8 fails in " "attribute traversal", res, *err); return res; } if (res == DW_DLV_NO_ENTRY) { return res; } res = dwarf_find_die_given_sig8(dbg, &signature, &targdie, &targ_is_info,err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_find_die_given_sig8 fails " "following a signature in " "attribute traversal", res, *err); return res; } if (res == DW_DLV_NO_ENTRY) { /* We did not find the target */ return res; } res = dwarf_dieoffset(targdie, &targ_goff, err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_dieoffset fails following a signature in " "attribute traversal", res, *err); dwarf_dealloc_die(targdie); return res; } if (res == DW_DLV_OK) { if (!glflags.dense) { esb_append(valname,"\n"); append_indent_prefix(valname,standard_indent(), die_indent_level,0); } esb_append_printf_u(valname, " \n"); } /* If we get here we extablished the target. */ dwarf_dealloc_die(targdie); return DW_DLV_OK; } /* DW_FORM_data16 should not apply here. */ static Dwarf_Bool is_simple_location_expr(int form) { if (form == DW_FORM_block1 || form == DW_FORM_block2 || form == DW_FORM_block4 || form == DW_FORM_block || form == DW_FORM_exprloc) { return TRUE; } return FALSE; } static Dwarf_Bool is_location_form(int form) { if (form == DW_FORM_data4 || form == DW_FORM_data8 || form == DW_FORM_sec_offset || form == DW_FORM_loclistx || form == DW_FORM_rnglistx ) { return TRUE; } return FALSE; } static void show_attr_form_error(Dwarf_Debug dbg,unsigned attr, unsigned form, struct esb_s *out) { const char *n = 0; int res = 0; Dwarf_Error formerr = 0; esb_append(out,"ERROR: Attribute "); esb_append_printf_u(out,"%u",attr); esb_append(out," ("); res = dwarf_get_AT_name(attr,&n); if (res != DW_DLV_OK) { n = "UknownAttribute"; } esb_append(out,n); esb_append(out,") "); esb_append(out," has form "); esb_append_printf_u(out,"%u",form); esb_append(out," ("); esb_append(out,get_FORM_name(form,FALSE)); esb_append(out,"), a form which is not appropriate"); print_error_and_continue(dbg, esb_get_string(out), DW_DLV_OK,formerr); } /* Traverse an attribute and following any reference in order to detect self references to DIES (loop). We do not use print_else_name_match here. Just looking for self references to report on. */ static int traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, Dwarf_Half attr, Dwarf_Attribute attr_in, UNUSEDARG Dwarf_Bool print_else_name_match, char **srcfiles, Dwarf_Signed srcfcnt, int die_indent_level, Dwarf_Error *err) { Dwarf_Attribute attrib = 0; const char * atname = 0; int tres = 0; Dwarf_Half tag = 0; struct esb_s valname; esb_constructor(&valname); is_info = dwarf_get_die_infotypes_flag(die); atname = get_AT_name(attr,pd_dwarf_names_print_on_error); /* The following gets the real attribute, even in the face of an incorrect doubling, or worse, of attributes. */ attrib = attr_in; /* Do not get attr via dwarf_attr: if there are (erroneously) multiple of an attr in a DIE, dwarf_attr will not get the second, erroneous one and dwarfdump will print the first one multiple times. Oops. */ tres = dwarf_tag(die, &tag, err); if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DIE tag in traverse_attribute!", tres,*err); esb_destructor(&valname); return tres; } else if (tres == DW_DLV_NO_ENTRY) { tag = 0; } else { /* ok */ } switch (attr) { case DW_AT_specification: case DW_AT_abstract_origin: case DW_AT_type: { int res = 0; Dwarf_Off die_goff = 0; Dwarf_Off ref_goff = 0; Dwarf_Die ref_die = 0; struct esb_s specificationstr; Dwarf_Half theform = 0; Dwarf_Half directform = 0; char buf[ESB_FIXED_ALLOC_SIZE]; res = get_form_values(dbg,attrib,&theform, &directform,err); if (res != DW_DLV_OK) { esb_destructor(&valname); return res; } if (!form_refers_local_info(theform)) { break; } esb_constructor_fixed(&specificationstr,buf,sizeof(buf)); ++die_indent_level; if (die_indent_level >= DIE_STACK_SIZE ) { esb_destructor(&valname); report_die_stack_error(dbg,err); return DW_DLV_ERROR; } res = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, srcfcnt, &specificationstr,glflags.show_form_used, glflags.verbose, err); if (res != DW_DLV_OK) { esb_destructor(&valname); return res; } esb_append(&valname, esb_get_string(&specificationstr)); esb_destructor(&specificationstr); /* Get the global offset for reference */ if (theform == DW_FORM_ref_sig8) { res = print_sig8_target(dbg,attrib, die_indent_level, srcfiles,srcfcnt, &valname,err); if (res == DW_DLV_ERROR) { esb_destructor(&valname); return res; } break; } res = dwarf_global_formref(attrib, &ref_goff, err); if (res == DW_DLV_ERROR) { int dwerrno = dwarf_errno(*err); if (dwerrno == DW_DLE_REF_SIG8_NOT_HANDLED ) { /* No need to stop, ref_sig8 refers out of the current section. */ DROP_ERROR_INSTANCE(dbg,res,*err); break; } else { print_error_and_continue(dbg, "dwarf_global_formref fails in " "attribute traversal", res, *err); esb_destructor(&valname); return res; } } else if (res == DW_DLV_NO_ENTRY) { return res; } /* Gives die offset in section. */ res = dwarf_dieoffset(die, &die_goff, err); if (res == DW_DLV_ERROR) { int dwerrno = dwarf_errno(*err); if (dwerrno == DW_DLE_REF_SIG8_NOT_HANDLED ) { /* No need to stop, ref_sig8 refers out of the current section. */ DROP_ERROR_INSTANCE(dbg,res,*err); break; } else { print_error_and_continue(dbg, "dwarf_dieoffset fails in " " attribute traversal", res, *err); esb_destructor(&valname); return res; } } /* Follow reference chain, looking for self references */ res = dwarf_offdie_b(dbg,ref_goff,is_info,&ref_die,err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_dieoff_b fails in " " attribute traversal", res, *err); esb_destructor(&valname); return res; } if (res == DW_DLV_OK) { Dwarf_Off target_die_cu_goff = 0; if (dump_visited_info) { Dwarf_Off die_loff = 0; res = dwarf_die_CU_offset(die, &die_loff, err); if (res != DW_DLV_OK) { esb_destructor(&valname); return res; } do_dump_visited_info(die_indent_level, die_loff,die_goff, dieprint_cu_goffset, atname,esb_get_string(&valname)); } ++die_indent_level; if (die_indent_level >= DIE_STACK_SIZE ) { report_die_stack_error(dbg,err); esb_destructor(&valname); return DW_DLV_ERROR; } res =dwarf_CU_dieoffset_given_die(ref_die, &target_die_cu_goff, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_dieoffset() accessing cu_goff " "die fails in traversal", res,*err); esb_destructor(&valname); return res; } res = traverse_one_die(dbg,attrib,ref_die, target_die_cu_goff, is_info, srcfiles,srcfcnt,die_indent_level, err); DeleteKeyInBucketGroup(glflags.pVisitedInfo,ref_goff); dwarf_dealloc_die(ref_die); if (res == DW_DLV_ERROR) { esb_destructor(&valname); return res; } --die_indent_level; ref_die = 0; } } break; } /* End switch. */ esb_destructor(&valname); return DW_DLV_OK; } /* Traverse one DIE in order to detect self references to DIES. This fails to deal with changing CUs via global references so srcfiles and cnt have possibly inappropriate values. FIXME. */ static int traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt, int die_indent_level, Dwarf_Error *err) { Dwarf_Half tag = 0; Dwarf_Off overall_offset = 0; Dwarf_Signed atcnt = 0; int res = 0; Dwarf_Bool print_else_name_match = FALSE; res = dwarf_tag(die, &tag, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "Problem accessing tag of die!" " from traverse_one_die", res, *err); return res; } res = dwarf_dieoffset(die, &overall_offset, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_dieoffset fails in traversing die", res, *err); return res; } if (dump_visited_info) { Dwarf_Off offset = 0; const char * tagname = 0; res = dwarf_die_CU_offset(die, &offset, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_die_CU_offset fails in traversing die", res, *err); return res; } tagname = get_TAG_name(tag,pd_dwarf_names_print_on_error); do_dump_visited_info(die_indent_level,offset, overall_offset, dieprint_cu_goffset, tagname,""); } DWARF_CHECK_COUNT(self_references_result,1); if (FindKeyInBucketGroup(glflags.pVisitedInfo, overall_offset)) { char * localvaln = NULL; Dwarf_Half attr = 0; struct esb_s bucketgroupstr; const char *atname = NULL; esb_constructor(&bucketgroupstr); res = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, cnt, &bucketgroupstr, glflags.show_form_used, glflags.verbose,err); if (res != DW_DLV_OK) { return res; } localvaln = esb_get_string(&bucketgroupstr); res = dwarf_whatattr(attrib, &attr, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: dwarf_whatattr fails in traverse die", res,*err); return res; } atname = get_AT_name(attr,pd_dwarf_names_print_on_error); /* We have a self reference */ DWARF_CHECK_ERROR3(self_references_result, "Invalid self reference to DIE: ",atname,localvaln); esb_destructor(&bucketgroupstr); } else { Dwarf_Signed i = 0; Dwarf_Attribute *atlist = 0; /* Add current DIE */ AddEntryIntoBucketGroup(glflags.pVisitedInfo, overall_offset, 0,0,0,NULL,FALSE); res = dwarf_attrlist(die, &atlist, &atcnt, err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_attrlist fails in traverse die", res, *err); } else if (res == DW_DLV_NO_ENTRY) { /* indicates there are no attrs. It is not an error. */ atcnt = 0; } for (i = 0; i < atcnt; i++) { Dwarf_Half attr; int ares; ares = dwarf_whatattr(atlist[i], &attr, err); if (ares == DW_DLV_OK) { ares = traverse_attribute(dbg, die, dieprint_cu_goffset, is_info, attr, atlist[i], print_else_name_match, srcfiles, cnt, die_indent_level,err); if (ares == DW_DLV_ERROR) { dealloc_local_atlist(dbg,atlist,atcnt); return ares; } } else { print_error_and_continue(dbg, "dwarf_whatattr entry missing in " " traverse die", ares, *err); return ares; } } dealloc_local_atlist(dbg,atlist,atcnt); /* Delete current DIE */ DeleteKeyInBucketGroup(glflags.pVisitedInfo, overall_offset); } return DW_DLV_OK; } /* Extracted this from print_attribute() to get tolerable indents. In other words to make it readable. It uses global data fields excessively, but so does print_attribute(). The majority of the code here is checking for compiler errors. Support for .debug_rnglists here is new May 2020. */ static int print_range_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute attr_in, Dwarf_Half theform, int pra_dwarf_names_print_on_error, Dwarf_Bool print_else_name_match, int *append_extra_string, struct esb_s *esb_extrap, Dwarf_Error *raerr) { Dwarf_Unsigned original_off = 0; int fres = 0; Dwarf_Half cu_version = 2; Dwarf_Half cu_offset_size = 4; fres = dwarf_get_version_of_die(die,&cu_version, &cu_offset_size); if (fres != DW_DLV_OK) { simple_err_return_msg_either_action(fres, "\nERROR: Unable to get version of a DIE " "to print a range attribute so something " " is badly wrong. Assuming DWARF2, offset size 4" " and continuing!"); } if (theform == DW_FORM_rnglistx) { fres = dwarf_formudata(attr_in, &original_off, raerr); if (fres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: In printing a range " "DW_FORM_rnglistx attribute " "dwarf_formudata failed ",fres,*raerr); return fres; } } else { fres = dwarf_global_formref(attr_in, &original_off, raerr); if (fres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: In printing a range attribute " "dwarf_global_formref failed ",fres,*raerr); return fres; } } if (fres == DW_DLV_OK && cu_version < DWVERSION5) { Dwarf_Ranges *rangeset = 0; Dwarf_Signed rangecount = 0; Dwarf_Unsigned bytecount = 0; Dwarf_Unsigned realoffset = 0; /* If this is a dwp the ranges will be missing or reported from a tied file. For now we add the ranges to dbg, not tiedbg as we do not mention tieddbg here. May need a new interface. FIXME? In the dwp case where the actual section is in tied (ie, a.out) the DW_AT_GNU_ranges_base is used, not the original_off. We really want to print the actual offset, in that case, not original_off. realoffset is that final actual section offset. */ int rres = dwarf_get_ranges_b(dbg,original_off, die, &realoffset, &rangeset, &rangecount,&bytecount,raerr); if (rres == DW_DLV_OK) { /* Ignore ranges inside a stripped function */ if (!glflags.gf_suppress_checking_on_dwp && glflags.gf_check_ranges && glflags.in_valid_code && checking_this_compiler()) { /* Record the offset, as the ranges check will be done at the end of the compilation unit; this approach solves the issue of DWARF4 generating values for the high pc as offsets relative to the low pc and the compilation unit having DW_AT_ranges attribute. */ int dores = 0; Dwarf_Off die_glb_offset = 0; Dwarf_Off die_off = 0; dores = dwarf_die_offsets(die,&die_glb_offset, &die_off,raerr); if (dores == DW_DLV_ERROR) { return dores; } if (dores == DW_DLV_OK) { record_range_array_info_entry(die_glb_offset, realoffset); } } if (print_else_name_match) { *append_extra_string = 1; print_ranges_list_to_extra(dbg, original_off, realoffset, rangeset,rangecount,bytecount, esb_extrap); } dwarf_ranges_dealloc(dbg,rangeset,rangecount); } else if (rres == DW_DLV_ERROR) { if ( glflags.gf_suppress_checking_on_dwp) { /* Ignore checks */ } else if ( glflags.gf_do_print_dwarf) { printf("\ndwarf_get_ranges_a() " "cannot find DW_AT_ranges at offset 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx ").", original_off, original_off); } else { DWARF_CHECK_COUNT(ranges_result,1); DWARF_CHECK_ERROR2(ranges_result, get_AT_name(attr, pra_dwarf_names_print_on_error), " cannot find DW_AT_ranges at offset"); } return rres; } else { /* NO ENTRY */ if ( glflags.gf_suppress_checking_on_dwp) { /* Ignore checks */ } else if ( glflags.gf_do_print_dwarf) { printf("\ndwarf_get_ranges_a() " "finds no DW_AT_ranges at offset 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ").", original_off, original_off); } else { DWARF_CHECK_COUNT(ranges_result,1); DWARF_CHECK_ERROR2(ranges_result, get_AT_name(attr, pra_dwarf_names_print_on_error), " fails to find DW_AT_ranges at offset"); } } return DW_DLV_OK; } else if (fres == DW_DLV_OK && cu_version >= DWVERSION5) { /* Here we have to access the .debug_rnglists section data with a new layout for DW5. Here we do not need to actually use rleoffset since it is identical to original_off. */ int res = 0; Dwarf_Unsigned rleoffset = 0; res = handle_rnglists(die, attr_in, theform, original_off, &rleoffset, esb_extrap, glflags.show_form_used, glflags.verbose, raerr); if (print_else_name_match) { *append_extra_string = 1; } return res; } /* DW_DLV_NO_ENTRY or DW_DLV_ERROR */ if (glflags.gf_do_print_dwarf) { struct esb_s local; char tmp[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&local,tmp,sizeof(tmp)); esb_append(&local, " fails to find DW_AT_ranges offset"); esb_append_printf_u(&local," attr 0x%x",attr); esb_append_printf_u(&local," form 0x%x",theform); printf(" %s ",esb_get_string(&local)); esb_destructor(&local); } else { DWARF_CHECK_COUNT(ranges_result,1); DWARF_CHECK_ERROR2(ranges_result, get_AT_name(attr, pra_dwarf_names_print_on_error), " fails to find DW_AT_ranges offset"); } return fres; } /* A DW_AT_name in a CU DIE will likely have dots and be entirely sensible. So lets not call things a possible error when they are not. Some assemblers allow '.' in an identifier too. This is a heuristic, not all that reliable. It is only used for a specific DWARF_CHECK_ERROR, and the 'altabi.' is from a specific (unnamed here) compiler. Return 0 (FALSE) if it is a vaguely standard identifier. Else return 1 (TRUE), meaning 'it might be a file name or have '.' in it quite sensibly.' If we don't do the TAG check we might report "t.c" as a questionable DW_AT_name. Which would be silly. */ static Dwarf_Bool dot_ok_in_identifier(int tag, const char *val) { if (strncmp(val,"altabi.",7)) { /* Ignore the names of the form 'altabi.name', which apply to one specific compiler. */ return TRUE; } if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_imported_unit || tag == DW_TAG_skeleton_unit || tag == DW_TAG_type_unit) { return TRUE; } return FALSE; } static void trim_quotes(const char *val,struct esb_s *es) { if (val[0] == '"') { size_t l = strlen(val); if (l > 2 && val[l-1] == '"') { esb_appendn(es,val+1,l-2); return; } } esb_append(es,val); } static Dwarf_Bool have_a_search_match(const char *valname,const char *atname) { /* valname may have had quotes inserted, but search_match_text will not. So we need to use a new copy, not valname here. */ char matchbuf[100]; /* not ESB_FIXED_ALLOC_SIZE ? */ struct esb_s esb_match; char *s2; esb_constructor_fixed(&esb_match,matchbuf,sizeof(matchbuf)); trim_quotes(valname,&esb_match); s2 = esb_get_string(&esb_match); if (glflags.search_match_text ) { if (!strcmp(s2,glflags.search_match_text) || !strcmp(atname,glflags.search_match_text)) { esb_destructor(&esb_match); return TRUE; } } if (glflags.search_any_text) { if (is_strstrnocase(s2,glflags.search_any_text) || is_strstrnocase(atname,glflags.search_any_text)) { esb_destructor(&esb_match); return TRUE; } } #ifdef HAVE_REGEX if (glflags.search_regex_text) { if (!regexec(glflags.search_re,s2,0,NULL,0) || !regexec(glflags.search_re,atname,0,NULL,0)) { esb_destructor(&esb_match); return TRUE; } } #endif esb_destructor(&esb_match); return FALSE; } /* Use our local die_stack to try to determine signedness of the DW_AT_discr_list LEB numbers. Returns -1 if we know it is signed. Returns 1 if we know it is unsigned. Returns 0 if we really do not know. */ static int determine_discr_signedness(Dwarf_Debug dbg) { Dwarf_Die parent = 0; Dwarf_Half tag = 0; int tres = 0; Dwarf_Error descrerr = 0; if (die_stack_indent_level < 1) { /* We have no idea. */ return 0; } parent = die_stack[die_stack_indent_level -1].die_; if (!parent) { /* We have no idea. */ return 0; } tres = dwarf_tag(parent, &tag, &descrerr); if (tres != DW_DLV_OK) { DROP_ERROR_INSTANCE(dbg,tres,descrerr); return 0; } if (tag != DW_TAG_variant_part) { return 0; } /* Expect DW_AT_discr or DW_AT_type here, and if DW_AT_discr, that might have the DW_AT_type. */ /* FIXME: For now lets just punt, say unsigned. */ return 1; } static void checksignv( struct esb_s *strout, const char *title, Dwarf_Signed sv, Dwarf_Unsigned uv) { /* The test and output are not entirely meaningful, but it can be useful for readers of dwarfdump output. */ if (uv == (Dwarf_Unsigned)sv) { /* Nothing to do here. */ return; } esb_append(strout," <"); esb_append(strout,title); esb_append(strout," "); esb_append_printf_i(strout,"%" DW_PR_DSd ":",sv); esb_append_printf_u(strout,"%" DW_PR_DUu ">",uv); } static int append_discr_array_vals(Dwarf_Debug dbg, Dwarf_Dsc_Head h, Dwarf_Unsigned arraycount, int isunsigned, struct esb_s *strout, Dwarf_Error*paerr) { Dwarf_Unsigned u = 0; if (isunsigned == 0) { esb_append(strout, ""); } esb_append_printf_u(strout, "\n discr list array len: " "%" DW_PR_DUu "\n",arraycount); for (u = 0; u < arraycount; u++) { int u2res = 0; Dwarf_Half dtype = 0; Dwarf_Signed slow = 0; Dwarf_Signed shigh = 0; Dwarf_Unsigned ulow = 0; Dwarf_Unsigned uhigh = 0; const char *dsc_name = ""; u2res = dwarf_discr_entry_u(h,u, &dtype,&ulow,&uhigh,paerr); if (u2res == DW_DLV_ERROR) { print_error_and_continue(dbg, "DW_AT_discr_list entry access fail\n", u2res, *paerr); return u2res; } u2res = dwarf_discr_entry_s(h,u, &dtype,&slow,&shigh,paerr); if (u2res == DW_DLV_ERROR) { print_error_and_continue(dbg, "DW_AT_discr_list entry access fail\n", u2res, *paerr); } if (u2res == DW_DLV_NO_ENTRY) { glflags.gf_count_major_errors++; esb_append_printf_u(strout, "\n " "ERROR: discr index missing! %" DW_PR_DUu,u); break; } esb_append_printf_u(strout, " " "%" DW_PR_DUu ": ",u); dsc_name = get_DSC_name(dtype, pd_dwarf_names_print_on_error); esb_append(strout,sanitized(dsc_name)); esb_append(strout," "); if (!dtype) { if (isunsigned < 0) { esb_append_printf_i(strout,"%" DW_PR_DSd,slow); checksignv(strout,"as signed:unsigned",slow,ulow); } else { esb_append_printf_u(strout,"%" DW_PR_DUu,ulow); checksignv(strout,"as signed:unsigned",slow,ulow); } } else { if (isunsigned < 0) { esb_append_printf_i(strout,"%" DW_PR_DSd,slow); checksignv(strout,"as signed:unsigned",slow,ulow); } else { esb_append_printf_u(strout,"%" DW_PR_DUu,ulow); checksignv(strout,"as signed:unsigned",slow,ulow); } if (isunsigned < 0) { esb_append_printf_i(strout,", %" DW_PR_DSd,shigh); checksignv(strout,"as signed:unsigned", shigh,uhigh); } else { esb_append_printf_u(strout,", %" DW_PR_DUu,uhigh); checksignv(strout,"as signed:unsigned", shigh,uhigh); } } esb_append(strout,"\n"); } return DW_DLV_OK; } static int print_location_description(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, int checking, Dwarf_Half attr, int die_indent_level, struct esb_s *base, struct esb_s *details, Dwarf_Error *err) { /* The attribute is a location description or location list. */ int res = 0; Dwarf_Half theform = 0; Dwarf_Half directform = 0; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; res = get_form_values(dbg,attrib,&theform,&directform, err); if (res == DW_DLV_ERROR) { return res; } res = dwarf_get_version_of_die(die, &version,&offset_size); if (is_simple_location_expr(theform)) { res = print_location_list(dbg, die, attrib, checking, die_indent_level, TRUE,base,err); if (res == DW_DLV_ERROR) { return res; } } else if (is_location_form(theform)) { res = print_location_list(dbg, die, attrib, checking, die_indent_level, FALSE, details,err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: Cannot get location list" " data", res, *err); return res; } } else { show_attr_form_error(dbg,attr,theform,base); } return DW_DLV_OK; } /* This was inside print_attribute() */ static void check_attr_tag_combination(Dwarf_Debug dbg, Dwarf_Half tag,Dwarf_Half attr) { const char *tagname = ""; DWARF_CHECK_COUNT(attr_tag_result,1); if (legal_tag_attr_combination(tag, attr)) { /* OK */ } else { /* Report errors only if tag-attr check is on */ if (glflags.gf_check_tag_attr) { tagname = get_TAG_name(tag, pd_dwarf_names_print_on_error); tag_specific_globals_setup(dbg,tag, die_stack_indent_level); DWARF_CHECK_ERROR3(attr_tag_result,tagname, get_AT_name(attr, pd_dwarf_names_print_on_error), "check the tag-attr combination"); } } } static void remark_wrong_string_format(Dwarf_Half attr, Dwarf_Half theform, UNUSEDARG enum Dwarf_Form_Class fc) { #define VSFBUFSZ 200 char buf[VSFBUFSZ+1]; struct esb_s m; esb_constructor_fixed(&m,buf,VSFBUFSZ); esb_append_printf_s(&m, "ERROR: Cannot print the value of " "attribute %s ", get_AT_name(attr,FALSE)); esb_append_printf_s(&m, "as it has form %s which seems wrong.", get_FORM_name(theform,FALSE)); esb_append(&m," Corrupted DWARF? Continuing."); simple_err_return_msg_either_action(DW_DLV_ERROR, esb_get_string(&m)); esb_destructor(&m); return; #undef VSFBUFSZ } static int print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Half attr, Dwarf_Attribute attr_in, Dwarf_Bool print_else_name_match, int die_indent_level, char **srcfiles, Dwarf_Signed srcfiles_cnt, LoHiPc * lohipc, Dwarf_Bool *attr_duplication, Dwarf_Error *err) { Dwarf_Attribute attrib = 0; Dwarf_Unsigned uval = 0; const char * atname = 0; int tres = 0; Dwarf_Half tag = 0; int append_extra_string = 0; Dwarf_Bool found_search_attr = FALSE; Dwarf_Bool bTextFound = FALSE; Dwarf_Bool is_info = FALSE; Dwarf_Addr max_address = 0; struct esb_s valname; struct esb_s esb_extra; char valbuf[ESB_FIXED_ALLOC_SIZE*3]; char xtrabuf[ESB_FIXED_ALLOC_SIZE*3]; int res = 0; Dwarf_Bool checking = glflags.gf_do_check_dwarf; Dwarf_Half theform = 0; Dwarf_Half directform = 0; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; esb_constructor_fixed(&esb_extra,xtrabuf,sizeof(xtrabuf)); esb_constructor_fixed(&valname,valbuf,sizeof(valbuf)); is_info = dwarf_get_die_infotypes_flag(die); atname = get_AT_name(attr,pd_dwarf_names_print_on_error); res = get_address_size_and_max(dbg,0,&max_address,err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "Getting address maximum" " failed in printing attribute ",res,*err); return res; } /* The following gets the real attribute, even in the face of an incorrect doubling, or worse, of attributes. */ attrib = attr_in; res = get_form_values(dbg,attrib,&theform,&directform, err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: Cannot get form values", res, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } res = dwarf_get_version_of_die(die,&version,&offset_size); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: Cannot get DIE context version number" " for DW_AT_discr_list", DW_DLV_OK,0); esb_destructor(&valname); esb_destructor(&esb_extra); /* Returning DW_DLV_ERROR would be bogus */ return DW_DLV_NO_ENTRY; } fc = dwarf_get_form_class(version,attr,offset_size,theform); /* Do not get attr via dwarf_attr: if there are (erroneously) multiple of an attr in a DIE, dwarf_attr will not get the second, erroneous one and dwarfdump will print the first one multiple times. Oops. */ tres = dwarf_tag(die, &tag, err); if (tres != DW_DLV_OK) { print_error_and_continue(dbg, "Getting DIE tag " " failed in printing an attribute.", tres,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return tres; } if ((glflags.gf_check_tag_attr || glflags.gf_print_usage_tag_attr)&& checking_this_compiler()) { check_attr_tag_combination(dbg,tag,attr); record_attr_form_use(dbg,tag,attr,(Dwarf_Half)fc, theform, pd_dwarf_names_print_on_error, die_stack_indent_level); } switch (attr) { case DW_AT_language: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_language", &valname, get_LANG_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_language value. ", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_accessibility: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_accessibility", &valname, get_ACCESS_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_accessibility value", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_visibility: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_visibility", &valname, get_VIS_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_visibility value.", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_virtuality: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_virtuality", &valname, get_VIRTUALITY_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_virtuality", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_identifier_case: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_identifier", &valname, get_ID_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_identifier_case", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_inline: res = dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_inline", &valname, get_INL_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get DW_AT_inline", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_encoding: res =dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_encoding", &valname, get_ATE_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR:Cannot get DW_AT_encoding", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_ordering: res =dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_ordering", &valname, get_ORD_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR:Cannot get DW_AT_ordering", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_calling_convention: res =dd_get_integer_and_name(dbg, attrib, &uval, "DW_AT_calling_convention", &valname, get_CC_name, err, glflags.show_form_used); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR:Cannot get DW_AT_calling_convention", res,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } break; case DW_AT_discr_list: { /* DWARF2 */ /* This has one of the block forms. It should be in a DW_TAG_variant. Up to September 2016 it was treated as integer or name here, which was quite wrong. */ if (fc == DW_FORM_CLASS_BLOCK) { int fres = 0; Dwarf_Block *tempb = 0; /* the block is a series of entries each of one of these formats: DW_DSC_label caselabel DW_DSC_range lowvalue highvalue The values are all LEB. Signed or unsigned depending on the DW_TAG_variant_part owning the DW_TAG_variant. The DW_TAG_variant_part will have a DW_AT_type or a DW_AT_discr and that attribute will reveal the signedness of all the leb values. As a practical matter DW_DSC_label/DW_DSC_range value (zero or one, so far) can safely be read as ULEB or SLEB and one gets a valid value whereas the caselabel, lowvalue,highvalue must be decoded with the proper sign. the high level (dwarfdump in this case) is the agent that should determine the proper signedness. */ fres = dwarf_formblock(attrib, &tempb,err); if (fres == DW_DLV_OK) { struct esb_s bformstr; int isunsigned = 0; /* Meaning unknown */ Dwarf_Dsc_Head h = 0; Dwarf_Unsigned arraycount = 0; int sres = 0; char fbuf[ESB_FIXED_ALLOC_SIZE]; esb_constructor_fixed(&bformstr,fbuf, sizeof(fbuf)); show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform,&bformstr); isunsigned = determine_discr_signedness(dbg); esb_empty_string(&valname); sres = dwarf_discr_list(dbg, (Dwarf_Small *)tempb->bl_data, tempb->bl_len, &h,&arraycount,err); if (sres == DW_DLV_NO_ENTRY) { esb_append(&bformstr, ""); break; } if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: DW_AT_discr_list access fail", sres, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return sres; } sres = append_discr_array_vals(dbg,h,arraycount, isunsigned,&bformstr,err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: getting discriminant values " "failed", sres, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return sres; } if (glflags.verbose > 1) { unsigned u = 0; esb_append_printf_u(&bformstr, "\n block byte len:" "0x%" DW_PR_XZEROS DW_PR_DUx "\n ",tempb->bl_len); for (u = 0; u < tempb->bl_len; u++) { esb_append_printf_u(&bformstr, "%02x ", *(u + (unsigned char *)tempb->bl_data)); } } esb_append(&valname, esb_get_string(&bformstr)); dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); esb_destructor(&bformstr); tempb = 0; } else { print_error_and_continue(dbg, "ERROR: DW_AT_discr_list: cannot get list" "data", fres, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return fres; } } else { print_error_and_continue(dbg, "DW_AT_discr_list is not form class BLOCK", fc, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return fc; } } break; case DW_AT_const_value: case DW_AT_data_member_location: { /* Value is a constant or a location description or location list. If a constant, it could be signed or unsigned. Telling whether a constant or a reference is nontrivial since DW_FORM_data{4,8} could be either in DWARF{2,3} */ if (fc == DW_FORM_CLASS_CONSTANT) { struct esb_s classconstantstr; Dwarf_Bool chex = FALSE; int wres = 0; esb_constructor(&classconstantstr); /* Makes no sense to look at type of our DIE to determine how to print the constant. */ wres = formxdata_print_value(dbg,NULL,attrib, theform, &classconstantstr, err, chex); if (wres != DW_DLV_OK) { esb_destructor(&valname); esb_destructor(&esb_extra); return wres; } show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform, &classconstantstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&classconstantstr)); esb_destructor(&classconstantstr); break; } /* FALL THRU, this is a a location description, or a reference to one, or a mistake. */ } /* Fall Through */ case DW_AT_call_value: case DW_AT_call_data_value: case DW_AT_call_data_location: case DW_AT_frame_base: case DW_AT_GNU_call_site_value: case DW_AT_GNU_call_site_target: case DW_AT_byte_size: case DW_AT_bit_size: case DW_AT_location: case DW_AT_return_addr: case DW_AT_segment: case DW_AT_static_link: case DW_AT_string_length: case DW_AT_use_location: case DW_AT_vtable_elem_location: { Dwarf_Bool showform = glflags.show_form_used; /* If DW_FORM_block* && show_form_used get_attr_value() results in duplicating the form name (with -M). */ /* For block forms, this will show block len and bytes and if showing form, then form shown */ res = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, srcfiles_cnt, &valname, showform, glflags.verbose, err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get attr form value", res,*err); DROP_ERROR_INSTANCE(dbg,res,*err); break; } append_extra_string = TRUE; if (fc == DW_FORM_CLASS_EXPRLOC || fc == DW_FORM_CLASS_LOCLIST || fc == DW_FORM_CLASS_LOCLISTPTR) { /* Form class exprloc is set even for DWARF2&3, see libdwarf: dwarf_get_form_class(). */ res = print_location_description(dbg,attrib,die, checking, attr,die_indent_level, &valname,&esb_extra,err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get location data, attr " "(with -M also form) " "follow", res,*err); DROP_ERROR_INSTANCE(dbg,res,*err); break; } } } break; case DW_AT_SUN_func_offsets: { /* value is a location description or location list */ char buf[100]; struct esb_s funcformstr; esb_constructor_fixed(&funcformstr,buf,sizeof(buf)); get_FLAG_BLOCK_string(dbg, attrib,&funcformstr); show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform,&funcformstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&funcformstr)); esb_destructor(&funcformstr); } break; case DW_AT_SUN_cf_kind: { Dwarf_Half kind = 0; Dwarf_Unsigned tempud = 0; int wres = 0; struct esb_s cfkindstr; esb_constructor(&cfkindstr); wres = dwarf_formudata (attrib,&tempud, err); if (wres == DW_DLV_OK) { kind = tempud; esb_append(&cfkindstr, get_ATCF_name(kind, pd_dwarf_names_print_on_error)); } else if (wres == DW_DLV_NO_ENTRY) { esb_append(&cfkindstr, "?"); } else { print_error_and_continue(dbg, "Cannot get formudata length field for" " DW_AT_SUN_cf_kind ", wres,*err); esb_destructor(&valname); esb_destructor(&esb_extra); return res; } show_form_itself(glflags.show_form_used, glflags.verbose,theform, directform,&cfkindstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&cfkindstr)); esb_destructor(&cfkindstr); } break; case DW_AT_upper_bound: { int rv; struct esb_s upperboundstr; esb_constructor(&upperboundstr); switch (theform) { case DW_FORM_block1: { append_extra_string = TRUE; rv = print_location_list(dbg, die, attrib, checking, die_indent_level, TRUE, &esb_extra,err); if (rv == DW_DLV_ERROR) { esb_destructor(&valname); esb_destructor(&esb_extra); return rv; } show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform,&valname); } break; default: rv = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, srcfiles_cnt, &upperboundstr, glflags.show_form_used,glflags.verbose, err); if (rv == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: Cannot get DW_AT_upper_bound" " form value", rv, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return rv; } esb_empty_string(&valname); esb_append(&valname, esb_get_string(&upperboundstr)); break; } esb_destructor(&upperboundstr); break; } case DW_AT_low_pc: case DW_AT_high_pc: { int rv = 0; rv = print_hipc_lopc_attribute(dbg, tag, die, die_indent_level, dieprint_cu_goffset, srcfiles, srcfiles_cnt, attrib, attr, max_address, lohipc, &valname, err); if (rv != DW_DLV_OK) { esb_destructor(&valname); esb_destructor(&esb_extra); return rv; } } break; case DW_AT_ranges: { int rv; rv = get_attr_value(dbg, tag,die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &valname, glflags.show_form_used,glflags.verbose,err); if (rv == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot find Attr value" "for DW_AT_ranges", rv, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return rv; } rv = print_range_attribute(dbg, die, attr,attr_in, theform, pd_dwarf_names_print_on_error, print_else_name_match, &append_extra_string, &esb_extra,err); if (rv == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot print range attribute " "for DW_AT_ranges", rv, *err); /* We will not stop, this is an omission in libdwarf on DWARF5 rnglists */ DROP_ERROR_INSTANCE(dbg,rv,*err); } } break; case DW_AT_MIPS_linkage_name: { int ml = 0; char linknamebuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s linkagenamestr; esb_constructor_fixed(&linkagenamestr,linknamebuf, sizeof(linknamebuf)); ml = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset, attrib, srcfiles, srcfiles_cnt, &linkagenamestr, glflags.show_form_used, glflags.verbose,err); if (ml == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get value " "for DW_AT_MIPS_linkage_name ", ml, *err); esb_destructor(&valname); esb_destructor(&esb_extra); esb_destructor(&linkagenamestr); return ml; } if (fc != DW_FORM_CLASS_STRING) { remark_wrong_string_format(attr,theform,fc); esb_destructor(&valname); esb_destructor(&esb_extra); esb_destructor(&linkagenamestr); return DW_DLV_NO_ENTRY; } esb_empty_string(&valname); esb_append(&valname, esb_get_string(&linkagenamestr)); esb_destructor(&linkagenamestr); if (glflags.gf_check_locations || glflags.gf_check_ranges) { int local_show_form = 0; int local_verbose = 0; const char *name = 0; struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, local_show_form,local_verbose,err); /* Look for specific name forms, attempting to notice and report 'odd' identifiers. Used in the SNC LinkOnce feature. */ name = esb_get_string(&lesb); safe_strcpy(glflags.PU_name,sizeof(glflags.PU_name), name,strlen(name)); esb_destructor(&lesb); } } break; case DW_AT_name: case DW_AT_GNU_template_name: { char atnamebuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s templatenamestr; if (fc != DW_FORM_CLASS_STRING) { remark_wrong_string_format(attr,theform,fc); esb_destructor(&valname); esb_destructor(&esb_extra); return DW_DLV_NO_ENTRY; } esb_constructor_fixed(&templatenamestr,atnamebuf, sizeof(atnamebuf)); tres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &templatenamestr, glflags.show_form_used, glflags.verbose,err); if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get value " "for DW_AT_name/DW_AT_GNU_template_name ", tres, *err); esb_destructor(&valname); esb_destructor(&esb_extra); return tres; } if (fc != DW_FORM_CLASS_STRING) { remark_wrong_string_format(attr,theform,fc); esb_destructor(&valname); esb_destructor(&esb_extra); return DW_DLV_NO_ENTRY; } esb_empty_string(&valname); esb_append(&valname, esb_get_string(&templatenamestr)); esb_destructor(&templatenamestr); if ( glflags.gf_check_names && checking_this_compiler()) { int local_show_form = FALSE; int local_verbose = 0; struct esb_s lesb; const char *name = 0; esb_constructor(&lesb); tres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, local_show_form,local_verbose,err); /* Look for specific name forms, attempting to notice and report 'odd' identifiers. */ if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get check_names value " "for DW_AT_name/DW_AT_GNU_template_name ", tres, *err); esb_destructor(&lesb); esb_destructor(&valname); esb_destructor(&esb_extra); return tres; } name = esb_get_string(&lesb); DWARF_CHECK_COUNT(names_result,1); if (!strcmp("\"(null)\"",name)) { DWARF_CHECK_ERROR(names_result, "string attribute is \"(null)\"."); } else { if (!dot_ok_in_identifier(tag,name) && !glflags.need_CU_name && strchr(name,'.')) { /* This is a suggestion there 'might' be a surprising name, not a guarantee of an error. */ DWARF_CHECK_ERROR(names_result, "string attribute is invalid."); } } esb_destructor(&lesb); } } /* If we are in checking mode and we do not have a PU name */ if (( glflags.gf_check_locations || glflags.gf_check_ranges) && glflags.seen_PU && !glflags.PU_name[0]) { int local_show_form = FALSE; int local_verbose = 0; const char *name = 0; struct esb_s lesb; int vres = 0; esb_constructor(&lesb); vres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, local_show_form,local_verbose,err); if (vres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get check-locations value " "for DW_AT_name/DW_AT_GNU_template_name ", vres, *err); esb_destructor(&lesb); esb_destructor(&valname); esb_destructor(&esb_extra); return vres; } name = esb_get_string(&lesb); safe_strcpy(glflags.PU_name,sizeof(glflags.PU_name), name, strlen(name)); esb_destructor(&lesb); } /* If we are processing the compile unit, record the name */ if (glflags.seen_CU && glflags.need_CU_name) { /* Lets not get the form name included. */ struct esb_s lesb; int local_show_form_used = FALSE; int local_verbose = 0; int sres = 0; esb_constructor(&lesb); sres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, local_show_form_used,local_verbose, err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get CU name " "for DW_AT_name/DW_AT_GNU_template_name ", sres, *err); esb_destructor(&lesb); esb_destructor(&valname); esb_destructor(&esb_extra); return sres; } safe_strcpy(glflags.CU_name,sizeof(glflags.CU_name), esb_get_string(&lesb),esb_string_len(&lesb)); glflags.need_CU_name = FALSE; esb_destructor(&lesb); } break; case DW_AT_linkage_name: case DW_AT_comp_dir: case DW_AT_producer: { struct esb_s lesb; int pres = 0; if (fc != DW_FORM_CLASS_STRING) { remark_wrong_string_format(attr,theform,fc); esb_destructor(&valname); esb_destructor(&esb_extra); return DW_DLV_NO_ENTRY; } esb_constructor(&lesb); pres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, glflags.show_form_used,glflags.verbose, err); if (pres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get value " "for DW_AT_producer", pres, *err); esb_destructor(&lesb); esb_destructor(&valname); esb_destructor(&esb_extra); return pres; } if (fc != DW_FORM_CLASS_STRING) { remark_wrong_string_format(attr,theform,fc); esb_destructor(&lesb); esb_destructor(&valname); esb_destructor(&esb_extra); return DW_DLV_NO_ENTRY; } esb_empty_string(&valname); esb_append(&valname, esb_get_string(&lesb)); esb_destructor(&lesb); /* If we are in checking mode, identify the compiler */ if (attr == DW_AT_producer && (glflags.gf_do_check_dwarf || glflags.gf_search_is_on)) { /* Do not use show-form here! We just want the producer name, not the form name. */ int show_form_local = FALSE; int local_verbose = 0; struct esb_s local_e; esb_constructor(&local_e); pres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &local_e, show_form_local,local_verbose,err); if (pres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Cannot get checking value " "for DW_AT_producer", pres, *err); esb_destructor(&local_e); esb_destructor(&valname); esb_destructor(&esb_extra); return pres; } /* Check if this compiler version is a target */ update_compiler_target(esb_get_string(&local_e)); esb_destructor(&local_e); } } break; /* When dealing with SNC linkonce symbols, the low_pc and high_pc are associated with a specific symbol; SNC always generate a name with DW_AT_MIPS_linkage_name; GCC does not; instead gcc generates DW_AT_abstract_origin or DW_AT_specification; in that case we have to traverse this attribute in order to get the name for the linkonce */ case DW_AT_specification: case DW_AT_abstract_origin: case DW_AT_type: { char typebuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s lesb; esb_constructor_fixed(&lesb,typebuf, sizeof(typebuf)); tres = get_attr_value(dbg, tag, die, die_indent_level, dieprint_cu_goffset,attrib, srcfiles, srcfiles_cnt, &lesb, glflags.show_form_used,glflags.verbose,err); if (tres == DW_DLV_ERROR) { struct esb_s m; const char *n = get_AT_name(attr,pd_dwarf_names_print_on_error); esb_constructor(&m); esb_append(&m, "Cannot get get value for a "); esb_append(&m,n); print_error_and_continue(dbg, esb_get_string(&m), tres,*err); esb_destructor(&m); esb_destructor(&valname); esb_destructor(&esb_extra); return tres; } if (theform == DW_FORM_ref_sig8) { res = print_sig8_target(dbg,attrib, die_indent_level, srcfiles, srcfiles_cnt, &lesb,err); if (res == DW_DLV_ERROR) { esb_destructor(&lesb); return res; } } esb_empty_string(&valname); esb_append(&valname, esb_get_string(&lesb)); esb_destructor(&lesb); if (glflags.gf_check_forward_decl || glflags.gf_check_self_references || glflags.gf_search_is_on) { Dwarf_Off die_goff = 0; Dwarf_Off ref_goff = 0; int frres = 0; int suppress_check = 0; frres = dwarf_global_formref(attrib, &ref_goff, err); if (frres == DW_DLV_ERROR) { int myerr = dwarf_errno(*err); if (myerr == DW_DLE_REF_SIG8_NOT_HANDLED) { /* DW_DLE_REF_SIG8_NOT_HANDLED */ /* No offset available, it makes little sense to delve into this sort of reference unless we think a graph of self-refs *across* type-units is possible. Hmm. FIXME? */ suppress_check = 1 ; DWARF_CHECK_COUNT(self_references_result,1); DWARF_CHECK_ERROR(self_references_result, "DW_AT_ref_sig8 not handled so " "self references not fully checked"); DROP_ERROR_INSTANCE(dbg,frres,*err); } else { const char *n = get_AT_name(attr, pd_dwarf_names_print_on_error); struct esb_s m; esb_constructor(&m); esb_append(&m, "Cannot get formref global offset " "for a "); esb_append(&m,n); print_error_and_continue(dbg, esb_get_string(&m), frres,*err); esb_destructor(&m); esb_destructor(&valname); esb_destructor(&esb_extra); return frres; } } else if (frres == DW_DLV_NO_ENTRY) { const char *n = get_AT_name(attr, pd_dwarf_names_print_on_error); struct esb_s m; esb_constructor(&m); esb_append(&m, "Cannot get formref global offset for a "); esb_append(&m,n); print_error_and_continue(dbg, esb_get_string(&m), frres,*err); esb_destructor(&m); esb_destructor(&valname); esb_destructor(&esb_extra); return frres; } frres = dwarf_dieoffset(die, &die_goff, err); if (frres != DW_DLV_OK) { const char *n = get_AT_name(attr, pd_dwarf_names_print_on_error); struct esb_s m; esb_constructor(&m); esb_append(&m, "Cannot get formref dieoffset offset for a "); esb_append(&m,n); print_error_and_continue(dbg, esb_get_string(&m), frres,*err); esb_destructor(&m); esb_destructor(&valname); esb_destructor(&esb_extra); return frres; } if (!suppress_check && glflags.gf_check_self_references && form_refers_local_info(theform) ) { Dwarf_Die ref_die = 0; int ifres = 0; ResetBucketGroup(glflags.pVisitedInfo); AddEntryIntoBucketGroup(glflags.pVisitedInfo, die_goff,0,0,0, NULL,FALSE); /* Follow reference chain, looking for self references */ frres = dwarf_offdie_b(dbg,ref_goff,is_info, &ref_die,err); if (frres == DW_DLV_OK) { Dwarf_Off ref_die_cu_goff = 0; Dwarf_Off die_loff = 0; /* CU-relative. */ int fresb = 0; if (dump_visited_info) { fresb = dwarf_die_CU_offset(die, &die_loff, err); if (fresb == DW_DLV_OK) { do_dump_visited_info(die_indent_level, die_loff,die_goff, dieprint_cu_goffset, atname,esb_get_string(&valname)); } else { esb_destructor(&valname); esb_destructor(&esb_extra); return fresb; } } ++die_indent_level; fresb =dwarf_CU_dieoffset_given_die(ref_die, &ref_die_cu_goff, err); /* Check above call return status? FIXME */ if (fresb != DW_DLV_OK) { const char *n = get_AT_name(attr, pd_dwarf_names_print_on_error); struct esb_s m; esb_constructor(&m); esb_append(&m, "Cannot get CU dieoffset " "given die for a "); esb_append(&m,n); print_error_and_continue(dbg, esb_get_string(&m), frres,*err); esb_destructor(&m); esb_destructor(&valname); esb_destructor(&esb_extra); return frres; } ifres = traverse_one_die(dbg,attrib,ref_die, ref_die_cu_goff, is_info,srcfiles,srcfiles_cnt, die_indent_level, err); dwarf_dealloc_die(ref_die); ref_die = 0; --die_indent_level; if (ifres != DW_DLV_OK) { esb_destructor(&valname); esb_destructor(&esb_extra); return ifres; } } DeleteKeyInBucketGroup(glflags.pVisitedInfo, die_goff); if (frres == DW_DLV_ERROR) { esb_destructor(&valname); esb_destructor(&esb_extra); return frres; } } if (!suppress_check && glflags.gf_check_forward_decl) { if (attr == DW_AT_specification) { /* Check the DW_AT_specification does not make forward references to DIEs. DWARF4 specifications, section 2.13.2, but really they are legal, this test is probably wrong. */ DWARF_CHECK_COUNT(forward_decl_result,1); if (ref_goff > die_goff) { DWARF_CHECK_ERROR2(forward_decl_result, "Invalid forward reference to DIE: ", esb_get_string(&valname)); } } } /* When doing search, if the attribute is DW_AT_specification or DW_AT_abstract_origin, get any name associated with the DIE referenced in the offset. The 2 more typical cases are: Member functions, where 2 DIES are generated: DIE for the declaration and DIE for the definition and connected via the DW_AT_specification. Inlined functions, where 2 DIES are generated: DIE for the concrete instance and DIE for the abstract instance and connected via the DW_AT_abstract_origin. */ if ( glflags.gf_search_is_on && (attr == DW_AT_specification || attr == DW_AT_abstract_origin)) { Dwarf_Die ref_die = 0; int srcres = 0; /* Follow reference chain, looking for the DIE name */ srcres = dwarf_offdie_b(dbg,ref_goff,is_info, &ref_die,err); if (srcres == DW_DLV_OK) { /* Get the DIE name */ char *name = 0; srcres = dwarf_diename(ref_die,&name,err); if (srcres == DW_DLV_OK) { esb_empty_string(&valname); esb_append(&valname,name); } if (srcres == DW_DLV_ERROR) { glflags.gf_count_major_errors++; esb_empty_string(&valname); esb_append(&valname, "", atname, sanitized(v)); if (append_extra_string) { v = esb_get_string(&esb_extra); printf("%s", sanitized(v)); } } else { char *v = 0; printf("%-28s", atname); if (strlen(atname) >= 28) { printf(" "); } v = esb_get_string(&valname); printf("%s\n", sanitized(v)); if (append_extra_string) { v = esb_get_string(&esb_extra); printf("%s", sanitized(v)); } } } } esb_destructor(&valname); esb_destructor(&esb_extra); *attr_duplication = found_search_attr; return DW_DLV_OK; } static void alloc_skip_branch_array(Dwarf_Half no_of_ops, struct OpBranchHead_s *op_branch_checking) { op_branch_checking->opcount = 0; op_branch_checking->ops_array = 0; if (!no_of_ops) { return; } op_branch_checking->ops_array = (struct OpBranchEntry_s *) calloc(no_of_ops,sizeof(struct OpBranchEntry_s)); if (!op_branch_checking->ops_array) { return; } op_branch_checking->opcount = no_of_ops; } static Dwarf_Bool skip_branch_target_ok(struct OpBranchHead_s *op_branch_checking, Dwarf_Half index, struct OpBranchEntry_s*ein) { Dwarf_Half i = 0; struct OpBranchEntry_s*ec = 0; if (ein->target_offset == ein->offset) { /* Infinite loop! */ return FALSE; } else if (ein->target_offset < ein->offset) { ec = op_branch_checking->ops_array; for ( ; i < index; ++i,++ec) { if ( ec->offset == ein->target_offset) { return TRUE; } } return FALSE; } i = index; ec = op_branch_checking->ops_array+i; for ( ; i < op_branch_checking->opcount; ++i,++ec) { if ( ec->offset == ein->target_offset) { return TRUE; } } return FALSE; } static void check_skip_branch_offsets(struct OpBranchHead_s *op_branch_checking, struct esb_s *str) { Dwarf_Half i = 0; Dwarf_Half high = op_branch_checking->opcount; struct OpBranchEntry_s*e = op_branch_checking->ops_array; for ( ; i < high ; ++i,++e) { char *opname = "DW_OP_skip"; if (e->op != DW_OP_bra && e->op != DW_OP_skip) { continue; } if (e->op == DW_OP_bra) { opname = "DW_OP_bra"; } if (skip_branch_target_ok(op_branch_checking,i,e)){ continue; } /* Oops. An error. The skip or branch target is wrong. Corrupt dwarf */ esb_append_printf_s(str, "\nERROR: The operation %s",opname); esb_append_printf_u(str, " at expression block offset 0x%04x ",e->offset); esb_append_printf_u(str, " has target of 0x%04x which is not a valid " "expression offset in this expression block\n", e->target_offset); glflags.gf_count_major_errors++; } } static void dealloc_skip_branch_array(struct OpBranchHead_s *op_branch_checking) { if (op_branch_checking->opcount) { free(op_branch_checking->ops_array); op_branch_checking->ops_array = 0; op_branch_checking->opcount = 0; } } static Dwarf_Bool op_is_skip_or_branch(Dwarf_Debug dbg, Dwarf_Locdesc_c exprc, int index, Dwarf_Error *err) { Dwarf_Small op = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned raw1 = 0; Dwarf_Unsigned raw2 = 0; Dwarf_Unsigned raw3 = 0; Dwarf_Unsigned offsetforbranch = 0; int res = 0; res = dwarf_get_location_op_value_d(exprc, index, &op,&opd1,&opd2,&opd3, &raw1,&raw2,&raw3, &offsetforbranch, err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,*err); } return FALSE; } if (op == DW_OP_bra) { return TRUE; } if (op == DW_OP_skip) { return TRUE; } return FALSE; } int dwarfdump_print_location_operations(Dwarf_Debug dbg, Dwarf_Die die, int die_indent_level, Dwarf_Locdesc * llbuf, /* Non-zero for old interface. */ Dwarf_Locdesc_c locdesc, /* Non-zero for 2015 interface. */ UNUSEDARG Dwarf_Unsigned llent, /* Which desc we have . */ Dwarf_Unsigned entrycount, Dwarf_Small lkind, UNUSEDARG int no_ending_newlines, Dwarf_Addr baseaddr, struct esb_s *string_out, Dwarf_Error *err) { Dwarf_Half no_of_ops = 0; unsigned i = 0; Dwarf_Bool report_raw = TRUE; Dwarf_Bool has_skip_or_branch = FALSE; struct OpBranchHead_s op_branch_checking; alloc_skip_branch_array(0,&op_branch_checking); if (llbuf) { Dwarf_Locdesc *locd = 0; locd = llbuf; no_of_ops = llbuf->ld_cents; possibly_increase_esb_alloc(string_out,no_of_ops,100); for (i = 0; i < no_of_ops; i++) { Dwarf_Loc * op = &locd->ld_s[i]; int res = _dwarf_print_one_expr_op(dbg,die, lkind, die_indent_level,op,NULL,i, has_skip_or_branch, NULL, report_raw, baseaddr,string_out,err); if (res == DW_DLV_ERROR) { return res; } } return DW_DLV_OK; } /* ASSERT: locs != NULL */ no_of_ops = entrycount; possibly_increase_esb_alloc(string_out,no_of_ops,100); if (no_of_ops > 1) { for (i = 0; i < no_of_ops; i++) { if (op_is_skip_or_branch(dbg,locdesc,i,err)) { has_skip_or_branch = TRUE; break; } } } if (has_skip_or_branch) { alloc_skip_branch_array(no_of_ops,&op_branch_checking); } for (i = 0; i < no_of_ops; i++) { int res = 0; res = _dwarf_print_one_expr_op(dbg,die, lkind, die_indent_level,NULL,locdesc,i, has_skip_or_branch, &op_branch_checking, report_raw, baseaddr,string_out,err); if (res == DW_DLV_ERROR) { dealloc_skip_branch_array(&op_branch_checking); return res; } } if (has_skip_or_branch) { check_skip_branch_offsets(&op_branch_checking,string_out); } dealloc_skip_branch_array(&op_branch_checking); return DW_DLV_OK; } static int op_has_no_operands(Dwarf_Small op) { return (dwarf_opscounttab[op].oc_opcount == 0); } static void show_contents(struct esb_s *string_out, unsigned int length,const unsigned char * bp) { unsigned int i = 0; if (!length) { return; } esb_append(string_out," contents 0x"); for (; i < length; ++i,++bp) { /* Do not use DW_PR_DUx here, the value *bp is a const unsigned char. */ esb_append_printf_u(string_out,"%02x", *bp); } } int _dwarf_print_one_expr_op(Dwarf_Debug dbg, Dwarf_Die die, UNUSEDARG Dwarf_Small lkind, int die_indent_level, Dwarf_Loc * expr, Dwarf_Locdesc_c exprc, int index, Dwarf_Bool has_skip_or_branch, struct OpBranchHead_s *oparray, Dwarf_Bool report_raw, UNUSEDARG Dwarf_Addr baseaddr, struct esb_s *string_out, Dwarf_Error *err) { Dwarf_Small op = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned raw1 = 0; Dwarf_Unsigned raw2 = 0; Dwarf_Unsigned raw3 = 0; Dwarf_Unsigned offsetforbranch = 0; const char * op_name = 0; int indentprespaces = 0; int indentpostspaces = 0; Dwarf_Bool showblockoffsets = FALSE; struct OpBranchEntry_s *echecking = 0; if (!glflags.dense && !glflags.gf_expr_ops_joined) { indentprespaces = standard_indent(); indentpostspaces = 6; esb_append(string_out,"\n"); append_indent_prefix(string_out,indentprespaces, die_indent_level,indentpostspaces); } else if (index > 0) { esb_append(string_out, " "); } if (expr) { /* DWARF 2,3,4 style */ op = expr->lr_atom; opd1 = expr->lr_number; opd2 = expr->lr_number2; } else { /* DWARF 2,3,4 and DWARF5 style */ int res = 0; res = dwarf_get_location_op_value_d(exprc, index, &op,&opd1,&opd2,&opd3, &raw1,&raw2,&raw3, &offsetforbranch, err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_get_location_op_value_c " "did not get a value!", res,*err); return res; } if (report_raw) { opd1 = raw1; opd2 = raw2; opd3 = raw3; } } op_name = get_OP_name(op,pd_dwarf_names_print_on_error); if (has_skip_or_branch && glflags.verbose) { showblockoffsets = TRUE; } if (showblockoffsets ) { /* New January 2021, showing offsets relevant to DW_OP_bra and DW_OP_skip . offsetforbranch comes from a 16 bit field, so is never large. */ esb_append_printf_u(string_out, " ", offsetforbranch); } if (oparray && oparray->opcount && index < oparray->opcount) { echecking = oparray->ops_array+ index; echecking->op = op; echecking->offset = offsetforbranch; } esb_append(string_out, op_name); if (op_has_no_operands(op)) { /* Nothing to add. */ } else if (op >= DW_OP_breg0 && op <= DW_OP_breg31) { esb_append_printf_i(string_out, "%+" DW_PR_DSd , opd1); } else { switch (op) { case DW_OP_addr: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_const1s: case DW_OP_const2s: case DW_OP_const4s: case DW_OP_const8s: case DW_OP_consts: case DW_OP_fbreg: esb_append(string_out," "); formx_signed(opd1,string_out); #if 0 /* FIX */ Turn on later if (opd1) { esb_append_printf_u(string_out, " (0x%" DW_PR_XZEROS DW_PR_DUx ")", opd1); } #endif break; case DW_OP_skip: case DW_OP_bra: esb_append(string_out," "); formx_signed(opd1,string_out); if (showblockoffsets) { Dwarf_Signed targ = (Dwarf_Signed)opd1; /* offsetforbranch is the op offset, and we need the the value 1 past the bytes in the DW_OP */ Dwarf_Signed off = offsetforbranch +2+1; off = off + targ; if (off < 0 ) { esb_append_printf_i(string_out, " ", off); glflags.gf_count_major_errors++; } else { esb_append_printf_u(string_out, " ", (Dwarf_Unsigned)off); } if (echecking) { echecking->target_offset = off; } } break; case DW_OP_GNU_addr_index: /* unsigned val */ case DW_OP_addrx: /* DWARF5: unsigned val */ case DW_OP_GNU_const_index: case DW_OP_constx: /* DWARF5: unsigned val */ case DW_OP_const1u: case DW_OP_const2u: case DW_OP_const4u: case DW_OP_const8u: case DW_OP_constu: case DW_OP_pick: case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: case DW_OP_deref_size: case DW_OP_xderef_size: esb_append_printf_u(string_out, " %" DW_PR_DUu , opd1); #if 0 /* FIX */ Turn on later if (opd1 > 9) { esb_append_printf_u(string_out, " (0x%" DW_PR_XZEROS DW_PR_DUx ")", opd1); } #endif break; case DW_OP_bregx: bracket_hex(" ",opd1,"",string_out); esb_append(string_out,"+"); formx_signed(opd2,string_out); break; case DW_OP_call2: { bracket_hex(" ",opd1,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, NO_SPECIFIC_TAG,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd1,string_out); } break; case DW_OP_call4: { bracket_hex(" ",opd1,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, NO_SPECIFIC_TAG,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd1,string_out); } break; case DW_OP_call_ref: { bracket_hex(" ",opd1,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, NO_SPECIFIC_TAG,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd1,string_out); } break; case DW_OP_bit_piece: bracket_hex(" ",opd1,"",string_out); bracket_hex(" offset ",opd2,"",string_out); break; case DW_OP_implicit_value: { #define IMPLICIT_VALUE_PRINT_MAX 12 unsigned int print_len = 0; bracket_hex(" ",opd1,"",string_out); /* The other operand is a block of opd1 bytes. */ /* FIXME */ print_len = opd1; if (print_len > IMPLICIT_VALUE_PRINT_MAX) { print_len = IMPLICIT_VALUE_PRINT_MAX; } #undef IMPLICIT_VALUE_PRINT_MAX { const unsigned char *bp = 0; /* This is a really ugly cast, a way to implement DW_OP_implicit value in this libdwarf context. */ bp = (const unsigned char *)(uintptr_t) opd2; show_contents(string_out,print_len,bp); } } break; /* We do not know what the operands, if any, are. */ case DW_OP_HP_unknown: case DW_OP_HP_is_value: case DW_OP_HP_fltconst4: case DW_OP_HP_fltconst8: case DW_OP_HP_mod_range: case DW_OP_HP_unmod_range: case DW_OP_HP_tls: case DW_OP_INTEL_bit_piece: break; case DW_OP_stack_value: /* DWARF4 */ break; case DW_OP_GNU_uninit: /* DW_OP_APPLE_uninit */ /* No operands. */ break; case DW_OP_GNU_encoded_addr: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_GNU_variable_value: { bracket_hex(" ",opd1,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, NO_SPECIFIC_TAG,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd1,string_out); } break; case DW_OP_implicit_pointer: /* DWARF5 */ case DW_OP_GNU_implicit_pointer: { /* opd1 is a section offset, not a CU offset. We don't know if DW_OP_GNU_implicit_pointer allows a zero offset meaning 'generic type' but GNU C++ 4.9.x-google 20150123 (prerelease) generates zero in DWARF4. DWARF5 does not allow zero. */ bracket_hex(" ",opd1,"",string_out); esb_append(string_out, " "); formx_signed(opd2,string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, NO_SPECIFIC_TAG, op= DW_OP_implicit_pointer? ZERO_OFFSET_GENERIC_TYPE: NON_ZERO_OFFSET_REQUIRED, !WITHIN_CU,opd1,string_out); } break; case DW_OP_entry_value: /* DWARF5 */ case DW_OP_GNU_entry_value: { const unsigned char *bp = 0; unsigned int length = 0; length = opd1; bracket_hex(" ",opd1,"",string_out); bp = (Dwarf_Small *)(uintptr_t) opd2; if (!bp) { esb_append(string_out, "ERROR: Null databyte pointer " "DW_OP_entry_value "); } else { show_contents(string_out,length,bp); } } break; case DW_OP_const_type: /* DWARF5 */ case DW_OP_GNU_const_type: { const unsigned char *bp = 0; unsigned int length = 0; /* opd1 is cu-relative offset of type DIE. we have a die in the relevant CU in the arg list */ bracket_hex(" ",opd1,"",string_out); length = opd2; esb_append(string_out," const length: "); esb_append_printf_u(string_out, "%u" , length); /* Now point to the data bytes of the const. */ bp = (Dwarf_Small *)(uintptr_t)opd3; if (!bp) { esb_append(string_out, "ERROR: Null databyte pointer DW_OP_const_type "); } else { show_contents(string_out,length,bp); } check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, DW_TAG_base_type, NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd1,string_out); } break; case DW_OP_regval_type: /* DWARF5 */ case DW_OP_GNU_regval_type: { esb_append_printf_u(string_out, " 0x%" DW_PR_DUx , opd1); bracket_hex(" ",opd2,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, DW_TAG_base_type,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd2,string_out); } break; case DW_OP_xderef_type: /* DWARF5 */ case DW_OP_deref_type: /* DWARF5 */ case DW_OP_GNU_deref_type: { esb_append_printf_u(string_out, " 0x%02" DW_PR_DUx , opd1); bracket_hex(" ",opd2,"",string_out); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, DW_TAG_base_type,NON_ZERO_OFFSET_REQUIRED, WITHIN_CU,opd2,string_out); } break; case DW_OP_convert: /* DWARF5 */ case DW_OP_GNU_convert: case DW_OP_reinterpret: /* DWARF5 */ case DW_OP_GNU_reinterpret: /* For following case, unsure if non-zero opd2 is required or not. Assume not */ case DW_OP_GNU_parameter_ref: { esb_append_printf_u(string_out, " 0x%02" DW_PR_DUx , opd1); check_die_expr_op_basic_data(dbg,die,op_name, indentprespaces,die_indent_level,indentpostspaces, DW_TAG_base_type,ZERO_OFFSET_GENERIC_TYPE, WITHIN_CU,opd2,string_out); } break; default: { esb_append_printf_u(string_out, " DWARF DW_OP_ unknown 0x%x", (unsigned)op); } break; } } return DW_DLV_OK; } void loc_error_check( const char * tagname, const char * attrname, Dwarf_Addr lopcfinal, Dwarf_Addr rawlopc, Dwarf_Addr hipcfinal, Dwarf_Addr rawhipc, Dwarf_Unsigned offset, Dwarf_Addr base_address, Dwarf_Bool *bError) { DWARF_CHECK_COUNT(locations_result,1); /* Check the low_pc and high_pc are within a valid range in the .text section */ if (IsValidInBucketGroup(glflags.pRangesInfo,lopcfinal) && IsValidInBucketGroup(glflags.pRangesInfo,hipcfinal)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol */ if (IsValidInLinkonce(glflags.pLinkonceInfo, glflags.PU_name, lopcfinal,hipcfinal)) { /* Valid values; do nothing */ } else { struct esb_s m; esb_constructor(&m); *bError = TRUE; esb_append_printf_s(&m, ".debug_loc[lists]: Address outside a " "valid .text range: TAG %s",tagname); esb_append_printf_s(&m," with attribute %s.", attrname); DWARF_CHECK_ERROR(locations_result, esb_get_string(&m)); if ( glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { printf( "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx ", " "Low = 0x%" DW_PR_XZEROS DW_PR_DUx " (rawlow = 0x%" DW_PR_XZEROS DW_PR_DUx "), High = 0x%" DW_PR_XZEROS DW_PR_DUx " (rawhigh = 0x%" DW_PR_XZEROS DW_PR_DUx ")\n", offset,base_address, lopcfinal, rawlopc, hipcfinal, rawhipc); } esb_destructor(&m); } } } static void print_loclists_context_head( Dwarf_Small lkind, Dwarf_Unsigned lle_count, Dwarf_Unsigned lle_version, Dwarf_Unsigned loclists_index, Dwarf_Unsigned bytes_total_in_lle, Dwarf_Half offset_size, Dwarf_Half address_size, Dwarf_Half segment_selector_size, Dwarf_Unsigned overall_offset_of_this_context, Dwarf_Unsigned total_length_of_this_context, Dwarf_Unsigned offset_table_offset, Dwarf_Unsigned offset_table_entrycount, Dwarf_Bool loclists_base_present, Dwarf_Addr loclists_base, Dwarf_Bool loclists_base_address_present, Dwarf_Addr loclists_base_address, Dwarf_Bool loclists_debug_addr_base_present, Dwarf_Addr loclists_debug_addr_base, Dwarf_Unsigned loclists_offset_lle_set, struct esb_s *esbp) { append_local_prefix(esbp); esb_append_printf_u(esbp, "bytes total this loclist: %3u",bytes_total_in_lle); append_local_prefix(esbp); esb_append_printf_u(esbp, "number of entries : %3u", lle_count); append_local_prefix(esbp); esb_append_printf_u(esbp, "context number : %3u",loclists_index); append_local_prefix(esbp); esb_append_printf_u(esbp, "version : %3u",lle_version); append_local_prefix(esbp); esb_append_printf_u(esbp, "address size : %3u",address_size); append_local_prefix(esbp); esb_append_printf_u(esbp, "offset size : %3u",offset_size); if (segment_selector_size) { append_local_prefix(esbp); esb_append_printf_u(esbp, "segment selector size : %3u", segment_selector_size); } if (lkind == DW_LKIND_loclists) { append_local_prefix(esbp); esb_append_printf_u(esbp, "offset of context : 0x%" DW_PR_XZEROS DW_PR_DUx, overall_offset_of_this_context); append_local_prefix(esbp); esb_append_printf_u(esbp, "offset table entrycount : %3u", offset_table_entrycount); if (offset_table_entrycount) { append_local_prefix(esbp); esb_append_printf_u(esbp, "offset table offset : 0x%" DW_PR_XZEROS DW_PR_DUx, offset_table_offset); } append_local_prefix(esbp); esb_append_printf_u(esbp, "offset of this list set : 0x%" DW_PR_XZEROS DW_PR_DUx, loclists_offset_lle_set); append_local_prefix(esbp); esb_append_printf_u(esbp, "length of context : %3u", total_length_of_this_context); append_local_prefix(esbp); esb_append_printf_u(esbp, "end of context offset : 0x%" DW_PR_XZEROS DW_PR_DUx, overall_offset_of_this_context + total_length_of_this_context); } if (loclists_base_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "DW_AT_loclists_base : 0x%" DW_PR_XZEROS DW_PR_DUx, loclists_base); } if (loclists_base_address_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "DW_AT_low_pc(base addr) : 0x%" DW_PR_XZEROS DW_PR_DUx, loclists_base_address); } if (loclists_debug_addr_base_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "DW_AT_addr_base : 0x%" DW_PR_XZEROS DW_PR_DUx, loclists_debug_addr_base); } esb_append(esbp,"\n"); } /* Fill buffer with location lists data for printing. This does the details. It's up to the caller to determine which esb to put the result in. */ /*ARGSUSED*/ static int print_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Bool checking, int die_indent_level, int no_end_newline, struct esb_s *details, Dwarf_Error* llerr) { Dwarf_Locdesc *llbuf = 0; Dwarf_Locdesc **llbufarray = 0; /* Only for older interface. */ Dwarf_Unsigned no_of_elements = 0; Dwarf_Loc_Head_c loclist_head = 0; /* 2015 loclist interface */ Dwarf_Unsigned i = 0; int lres = 0; unsigned int llent = 0; /* Base address used to update entries in .debug_loc. CU_base_address is a global. Terrible way to pass in this value. FIXME. See also CU_low_address as base address is special for address ranges */ Dwarf_Addr base_address = glflags.CU_base_address; Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Bool bError = FALSE; Dwarf_Small lle_value = 0; /* DWARF5 */ Dwarf_Unsigned lle_count = 0; Dwarf_Unsigned loclists_index = 0; /* This is the section offset of the expression, not the location description prefix. */ Dwarf_Unsigned expr_section_offset = 0; Dwarf_Half address_size = 0; Dwarf_Half segment_selector_size = 0; Dwarf_Addr max_address = 0; Dwarf_Unsigned lle_version = 2; Dwarf_Half version = 2; Dwarf_Half offset_size = 4; Dwarf_Small lkind = DW_LKIND_unknown; /* old and new interfaces differ on signedness. */ Dwarf_Signed locentry_count = 0; Dwarf_Unsigned bytes_total_in_lle = 0; Dwarf_Unsigned overall_offset_of_this_context = 0; Dwarf_Unsigned total_length_of_this_context = 0; Dwarf_Bool loclists_base_present = FALSE; Dwarf_Unsigned loclists_base = 0; Dwarf_Bool loclists_base_address_present = FALSE; Dwarf_Unsigned loclists_base_address = 0; Dwarf_Bool loclists_debug_addr_base_present = FALSE; Dwarf_Unsigned loclists_debug_addr_base = 0; Dwarf_Unsigned loclists_offset_lle_set = 0; Dwarf_Unsigned offset_table_offset = 0; Dwarf_Unsigned offset_table_entrycount = 0; struct esb_s section_truename; lres = dwarf_get_version_of_die(die,&version, &offset_size); if (lres != DW_DLV_OK) { /* is DW_DLV_ERROR (see libdwarf query.c) */ simple_err_only_return_action(lres, "\nERROR: die or context bad calling " "dwarf_get_version_of_die in print_location_list." " Something is very wrong."); return DW_DLV_NO_ENTRY; } lres = get_address_size_and_max(dbg,&address_size, &max_address,llerr); if (lres != DW_DLV_OK) { print_error_and_continue(dbg,"Getting address size" " and maximum failed while getting location list", lres,*llerr); return lres; } if (version == DWVERSION5 || !glflags.gf_use_old_dwarf_loclist) { /* Preferred interface. Deals with DWARF2,3,4,5. */ lres = dwarf_get_loclist_c(attr,&loclist_head, &no_of_elements,llerr); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_get_loclist_c fails", lres, *llerr); return lres; } else if (lres == DW_DLV_NO_ENTRY) { return lres; } lres = dwarf_get_loclist_head_basics(loclist_head, &lkind, &lle_count,&lle_version, &loclists_index, &bytes_total_in_lle, &offset_size, &address_size, &segment_selector_size, &overall_offset_of_this_context, &total_length_of_this_context, &offset_table_offset, &offset_table_entrycount, &loclists_base_present,&loclists_base, &loclists_base_address_present,&loclists_base_address, &loclists_debug_addr_base_present, &loclists_debug_addr_base, &loclists_offset_lle_set,llerr); if (lres != DW_DLV_OK) { return lres; } version = lle_version; /* append_local_prefix(esbp); No, here the newline grates, causes blank line in the output. So. Just add 6 spaces. the output already has a newline. */ if (lkind != DW_LKIND_expression) { esb_append(details," "); esb_constructor(§ion_truename); if (lkind == DW_LKIND_loclists) { get_true_section_name(dbg,".debug_loclists", §ion_truename,FALSE); } else { get_true_section_name(dbg,".debug_loc", §ion_truename,FALSE); } esb_append_printf_s(details,"%-15s", esb_get_string(§ion_truename)); esb_append_printf_u(details, " offset :" " 0x%" DW_PR_XZEROS DW_PR_DUx, loclists_offset_lle_set); esb_destructor(§ion_truename); if (glflags.verbose) { print_loclists_context_head(lkind, lle_count, lle_version, loclists_index, bytes_total_in_lle, offset_size,address_size, segment_selector_size, overall_offset_of_this_context, total_length_of_this_context, offset_table_offset, offset_table_entrycount, loclists_base_present,loclists_base, loclists_base_address_present, loclists_base_address, loclists_debug_addr_base_present, loclists_debug_addr_base, loclists_offset_lle_set, details); } else { /* things look better with this... no -v */ esb_append(details,"\n "); } } } else { /* DWARF2 old loclist. Still used. Ignores DWARF5. Does not work well with DWARF4, but sort of works there. */ Dwarf_Signed sno = 0; lres = dwarf_loclist_n(attr, &llbufarray, &sno, llerr); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_loclist_n fails", lres, *llerr); return lres; } else if (lres == DW_DLV_NO_ENTRY) { return lres; } no_of_elements = sno; } possibly_increase_esb_alloc(details, no_of_elements,100); for (llent = 0; llent < no_of_elements; ++llent) { Dwarf_Unsigned locdesc_offset = 0; Dwarf_Locdesc_c locentry = 0; /* 2015 */ Dwarf_Unsigned rawlowpc = 0; Dwarf_Unsigned rawhipc = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Bool debug_addr_unavailable = FALSE; /* This has values DW_LKIND*, the same values that were in loclist source in 2019, but with the new value of DW_LKIND_loclists for DWARF5. See libdwarf.h */ Dwarf_Small loclist_source = 0; int no_ending_newline = FALSE; if (!glflags.gf_use_old_dwarf_loclist) { lres = dwarf_get_locdesc_entry_d(loclist_head, llent, &lle_value, &rawlowpc,&rawhipc, &debug_addr_unavailable, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, &expr_section_offset, &locdesc_offset, llerr); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: dwarf_get_locdesc_entry_c fails", lres, *llerr); return lres; } else if (lres == DW_DLV_NO_ENTRY) { return lres; } locentry_count = ulocentry_count; } else { llbuf = llbufarray[llent]; rawlowpc = lopc = llbuf->ld_lopc; rawhipc = hipc = llbuf->ld_hipc; loclist_source = llbuf->ld_from_loclist; if (loclist_source > 1) { printf("ERROR: Attempting to use the original " " loclist/locexpr code with " "DW_LKIND_GNU_exp_list " " or DW_LKIND_loclists is not going to work: " "loclist_source value %u\n",loclist_source); glflags.gf_count_major_errors++; } expr_section_offset = llbuf->ld_section_offset; locdesc_offset = expr_section_offset - sizeof(Dwarf_Half) - 2 * address_size; locentry_count = llbuf->ld_cents; ulocentry_count = locentry_count; if (lopc == max_address) { lle_value = DW_LLE_base_address; } else if (lopc== 0 && hipc == 0) { lle_value = DW_LLE_end_of_list; } else { lle_value = DW_LLE_start_end; } } if (loclist_source == DW_LKIND_expression && lle_value != DW_LLE_start_end) { printf("ERROR: With DW_LKIND_expression" " lle_value should be DW_LLE_start_end (7) " "not %u\n",lle_value); glflags.gf_count_major_errors++; } /* If we have a location list refering to the .debug_loc Check for specific compiler we are validating. */ if ( glflags.gf_check_locations && glflags.in_valid_code && loclist_source && checking_this_compiler()) { checking = TRUE; } if (!glflags.dense && loclist_source != DW_LKIND_expression) { if (llent == 0) { /* These messages go with the list of entries */ switch(loclist_source){ case DW_LKIND_loclist: esb_append_printf_u(details, " ", no_of_elements); break; case DW_LKIND_GNU_exp_list: esb_append_printf_u(details, " ", no_of_elements); break; case DW_LKIND_loclists: esb_append_printf_u(details, " ", no_of_elements); break; } } esb_append_printf_i(details, "\n [%2d]",llent); } else { no_ending_newline = TRUE; } /* When dwarf_debug_addr_index_to_addr() fails it is probably DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 (because no TIED file supplied) but we don't distinguish that from other errors here. */ /* We use DW_LLE names for DW_LKIND_loclist and DW_LKIND_loclists. We use LLEX names for DW_LKIND_GNU_exp_list */ if (loclist_source) { Dwarf_Half tag = 0; Dwarf_Half attrnum = 0; const char *tagname = 0; const char *attrname = 0; int res = 0; res = dwarf_tag(die,&tag,llerr); if (res != DW_DLV_OK) { return res; } res = dwarf_whatattr(attr,&attrnum,llerr); if (res != DW_DLV_OK) { return res; } attrname = get_AT_name(attrnum,FALSE); tagname = get_TAG_name(tag,FALSE); if (loclist_source == DW_LKIND_GNU_exp_list) { print_llex_linecodes(dbg, checking, tagname, attrname, llent, lle_value, base_address, rawlowpc, rawhipc, debug_addr_unavailable, lopc, hipc, locdesc_offset, details, &bError); } else if (loclist_source == DW_LKIND_loclist) { print_original_loclist_linecodes(dbg, checking, tagname, attrname, llent, lle_value, base_address, rawlowpc, rawhipc, debug_addr_unavailable, lopc, hipc, locdesc_offset, details, &bError); } else { /* loclist_source == DW_LKIND_loclists */ print_debug_loclists_linecodes(dbg, checking, tagname, attrname, llent, lle_value, base_address, rawlowpc, rawhipc, debug_addr_unavailable, lopc, hipc, locdesc_offset, details, &bError); } } lres = dwarfdump_print_location_operations(dbg, die, die_indent_level, /* Either llbuf or locentry non-zero. Not both. */ llbuf, locentry, llent, /* Which loc desc this is */ ulocentry_count, /* How many ops in this loc desc */ loclist_source, no_ending_newline, base_address, details,llerr); if (lres == DW_DLV_ERROR) { return lres; } } if (!no_end_newline) { if (bError && glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { esb_append(details,"\n"); } else if (glflags.gf_do_print_dwarf) { esb_append(details,"\n"); } } if (!glflags.gf_use_old_dwarf_loclist) { dwarf_loc_head_c_dealloc(loclist_head); } else { for (i = 0; i < no_of_elements; ++i) { dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST); } return DW_DLV_OK; } /* New October 2017. The 'decimal' representation here is questionable. */ static void formx_data16(Dwarf_Form_Data16 * u, struct esb_s *esbp, Dwarf_Bool hex_format) { unsigned i = 0; for ( ; i < sizeof(Dwarf_Form_Data16); ++i){ esb_append(esbp, "0x"); if (hex_format) { esb_append_printf_u(esbp, "%02x ", u->fd_data[i]); } else { esb_append_printf_i(esbp, "%02d ", u->fd_data[i]); } } } static void formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp, Dwarf_Bool hex_format) { if (hex_format) { esb_append_printf_u(esbp, "0x%" DW_PR_XZEROS DW_PR_DUx , u); } else { esb_append_printf_u(esbp, "%" DW_PR_DUu , u); } } static void formx_signed(Dwarf_Signed s, struct esb_s *esbp) { esb_append_printf_i(esbp, "%" DW_PR_DSd ,s); } static void formx_unsigned_and_signed_if_neg(Dwarf_Unsigned tempud, Dwarf_Signed tempd, const char *leader,Dwarf_Bool hex_format,struct esb_s*esbp) { formx_unsigned(tempud,esbp,hex_format); if (tempd < 0) { esb_append(esbp,leader); formx_signed(tempd,esbp); esb_append(esbp,")"); } } /* If the DIE DW_AT_type exists and is directly known signed/unsigned return -1 for signed 1 for unsigned. Otherwise return 0 meaning 'no information'. So we only need to a messy lookup once per type-die offset */ static int check_for_type_unsigned(Dwarf_Debug dbg, Dwarf_Die die, UNUSEDARG struct esb_s *esbp) { Dwarf_Bool is_info = 0; struct Helpertree_Base_s * helperbase = 0; struct Helpertree_Map_Entry_s *e = 0; int res = 0; Dwarf_Attribute attr = 0; Dwarf_Attribute encodingattr = 0; Dwarf_Error error = 0; Dwarf_Unsigned diegoffset = 0; Dwarf_Unsigned typedieoffset = 0; Dwarf_Die typedie = 0; Dwarf_Unsigned tempud = 0; int show_form_here = FALSE; int retval = 0; if (!die) { return 0; } is_info = dwarf_get_die_infotypes_flag(die); if (is_info) { helperbase = &helpertree_offsets_base_info; } else { helperbase = &helpertree_offsets_base_types; } res = dwarf_dieoffset(die,&diegoffset,&error); if (res == DW_DLV_ERROR) { /* esb_append(esbp,""); */ return 0; } else if (res == DW_DLV_NO_ENTRY) { /* We don't know sign. */ /*esb_append(esbp,""); */ return 0; } /* This might be wrong. See the typedieoffset check below, which is correct... */ e = helpertree_find(diegoffset,helperbase); if (e) { /*bracket_hex("",esbp); bracket_hex("hm_val,">",esbp); */ return e->hm_val; } /* We look up the DW_AT_type die, if any, and use that offset to check for signedness. */ res = dwarf_attr(die, DW_AT_type, &attr,&error); if (res == DW_DLV_ERROR) { /*bracket_hex("",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /* We don't know sign. */ /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); return 0; } res = dwarf_global_formref(attr, &typedieoffset,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ dwarf_dealloc_attribute(attr); helpertree_add_entry(diegoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*esb_append(esbp,"helper NO ENTRY FAIL "); bracket_hex( "",esbp); */ dwarf_dealloc_attribute(attr); helpertree_add_entry(diegoffset, 0,helperbase); return 0; } dwarf_dealloc_attribute(attr); attr = 0; e = helpertree_find(typedieoffset,helperbase); if (e) { /*bracket_hex("",esbp); bracket_hex("hm_val,">",esbp); */ return e->hm_val; } res = dwarf_offdie_b(dbg,typedieoffset,is_info, &typedie,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } res = dwarf_attr(typedie, DW_AT_encoding, &encodingattr,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ dwarf_dealloc_die(typedie); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*bracket_hex( "",esbp);*/ dwarf_dealloc_die(typedie); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } res = dd_get_integer_and_name(dbg, encodingattr, &tempud, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, &error,show_form_here); if (res != DW_DLV_OK) { DROP_ERROR_INSTANCE(dbg,res,error); /*bracket_hex( "",esbp);*/ /* dealloc attr *first* then die */ dwarf_dealloc_attribute(encodingattr); dwarf_dealloc_die(typedie); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } if (tempud == DW_ATE_signed || tempud == DW_ATE_signed_char) { /*esb_append(esbp,"helper small encoding SIGNED ");*/ retval = -1; } else { if (tempud == DW_ATE_unsigned || tempud == DW_ATE_unsigned_char) { retval = 1; } } /*bracket_hex( "",esbp); bracket_hex( "",esbp);*/ helpertree_add_entry(diegoffset,retval,helperbase); helpertree_add_entry(typedieoffset, retval,helperbase); /* dealloc attr *first* then die */ dwarf_dealloc_attribute(encodingattr); dwarf_dealloc_die(typedie); return retval; } /* We think this is an integer. Figure out how to print it. In case the signedness is ambiguous (such as on DW_FORM_data1 (ie, unknown signedness) print two ways. If we were to look at DW_AT_type in the base DIE we could follow it and determine if the type was unsigned or signed (usually easily) and use that information. */ static int formxdata_print_value(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attrib, Dwarf_Half theform, struct esb_s *esbp, Dwarf_Error * pverr, Dwarf_Bool hex_format) { Dwarf_Signed tempsd = 0; Dwarf_Unsigned tempud = 0; int sres = 0; int ures = 0; if (theform == DW_FORM_data16) { Dwarf_Form_Data16 v16; ures = dwarf_formdata16(attrib, &v16,pverr); if (ures == DW_DLV_OK) { formx_data16(&v16, esbp,hex_format); return DW_DLV_OK; } else if (ures == DW_DLV_NO_ENTRY) { /* impossible */ return ures; } else { return ures; } } ures = dwarf_formudata(attrib, &tempud, pverr); if (ures == DW_DLV_OK) { sres = dwarf_formsdata(attrib, &tempsd, pverr); if (sres == DW_DLV_OK) { if (tempud == (Dwarf_Unsigned)tempsd && tempsd >= 0) { /* Data is the same value and not negative, so makes no difference which we print. */ formx_unsigned(tempud,esbp,hex_format); return DW_DLV_OK; } else { /* Here we don't know if signed or not and Assuming one or the other changes the interpretation of the bits. */ int helpertree_unsigned = 0; helpertree_unsigned = check_for_type_unsigned(dbg,die,esbp); if (!die || !helpertree_unsigned) { /* Signedness unclear. */ formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hex_format,esbp); return DW_DLV_OK; } else if (helpertree_unsigned > 0) { formx_unsigned(tempud,esbp,hex_format); return DW_DLV_OK; } else { /* Value signed. */ formx_signed(tempsd,esbp); return DW_DLV_OK; } } } else if (sres == DW_DLV_NO_ENTRY) { formx_unsigned(tempud,esbp,hex_format); return DW_DLV_OK; } else /* DW_DLV_ERROR */{ formx_unsigned(tempud,esbp,hex_format); DROP_ERROR_INSTANCE(dbg,sres,*pverr); return DW_DLV_OK; } } else if (ures == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,ures,*pverr); sres = dwarf_formsdata(attrib, &tempsd, pverr); if (sres == DW_DLV_OK) { formx_signed(tempsd,esbp); return sres; } else if (sres == DW_DLV_ERROR) { esb_append_printf_u(esbp, ""); simple_err_only_return_action(sres, esb_get_string(esbp)); /* Neither worked. */ return DW_DLV_ERROR; } } /* NO_ENTRY is crazy, impossible. */ return DW_DLV_NO_ENTRY; } static void bracket_hex(const char *s1, Dwarf_Unsigned v, const char *s2, struct esb_s * esbp) { Dwarf_Bool hex_format = TRUE; esb_append(esbp,s1); formx_unsigned(v,esbp,hex_format); esb_append(esbp,s2); } /* Borrow the definition from pro_encode_nm.h */ /* Bytes needed to encode a number. Not a tight bound, just a reasonable bound. */ #ifndef ENCODE_SPACE_NEEDED #define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) #endif /* ENCODE_SPACE_NEEDED */ /* Table indexed by the attribute value; only standard attributes are included, ie. in the range [1..DW_AT_lo_user]; we waste a little bit of space, but accessing the table is fast. */ typedef struct attr_encoding { Dwarf_Unsigned entries; /* Attribute occurrences */ Dwarf_Unsigned formx; /* Space used by current encoding */ Dwarf_Unsigned leb128; /* Space used with LEB128 encoding */ } a_attr_encoding; /* The other DW_FORM_datan are lower form values than data16, so the following is safe for the unchanging static table. */ static int attributes_encoding_factor[DW_FORM_data16 + 1]; /* These must be reset for each object if we are processing an archive! see print_attributes_encoding(). */ static a_attr_encoding *attributes_encoding_table = NULL; static Dwarf_Bool attributes_encoding_do_init = TRUE; /* Check the potential amount of space wasted by attributes values that can be represented as an unsigned LEB128. Only attributes with forms: DW_FORM_data1, DW_FORM_data2, DW_FORM_data4 and DW_FORM_data are checked */ static void check_attributes_encoding(Dwarf_Half attr,Dwarf_Half theform, Dwarf_Unsigned value) { if (attributes_encoding_do_init) { /* Create table on first call */ attributes_encoding_table = (a_attr_encoding *)calloc( DW_AT_lo_user, sizeof(a_attr_encoding)); /* We use only 5 slots in the table, for quick access */ /* index 0x0b */ attributes_encoding_factor[DW_FORM_data1]=1; /* index 0x0b */ attributes_encoding_factor[DW_FORM_data2]=2; /* index 0x05 */ attributes_encoding_factor[DW_FORM_data4]=4; /* index 0x06 */ attributes_encoding_factor[DW_FORM_data8]=8; /* index 0x07 */ /* index 0x1e */ attributes_encoding_factor[DW_FORM_data16] = 16; attributes_encoding_do_init = FALSE; } /* Regardless of the encoding form, count the checks. */ DWARF_CHECK_COUNT(attr_encoding_result,1); /* For 'DW_AT_stmt_list', due to the way is generated, the value can be unknown at compile time and only the assembler can decide how to represent the offset; ignore this attribute. */ if (DW_AT_stmt_list == attr || DW_AT_macros == attr || DW_AT_GNU_macros == attr) { if (theform == DW_FORM_addr) { struct esb_s lesb; esb_constructor(&lesb); esb_append_printf_s(&lesb, "Attribute %s has form ", get_AT_name(attr,pd_dwarf_names_print_on_error)); esb_append_printf_s(&lesb, " %s, An error", get_FORM_name(theform, pd_dwarf_names_print_on_error)); DWARF_CHECK_ERROR(attr_encoding_result, esb_get_string(&lesb)); esb_destructor(&lesb); } return; } /* Only checks those attributes that have DW_FORM_dataX: DW_FORM_data1, DW_FORM_data2, DW_FORM_data4 and DW_FORM_data8 DWARF5 adds DW_FORM_data16, but we ignore data16 here as it makes no sense as a uleb. */ if (theform == DW_FORM_data1 || theform == DW_FORM_data2 || theform == DW_FORM_data4 || theform == DW_FORM_data8 ) { int res = 0; /* Size of the byte stream buffer that needs to be memcpy-ed. */ int leb128_size = 0; /* To encode the attribute value */ char encode_buffer[ENCODE_SPACE_NEEDED]; res = dwarf_encode_leb128(value,&leb128_size, encode_buffer,sizeof(encode_buffer)); if (res == DW_DLV_OK) { if (attributes_encoding_factor[theform] > leb128_size) { int wasted_bytes = attributes_encoding_factor[theform] - leb128_size; struct esb_s lesb; esb_constructor(&lesb); esb_append_printf_i(&lesb, "%" DW_PR_DSd " wasted byte(s)",wasted_bytes); DWARF_CHECK_ERROR2(attr_encoding_result, get_AT_name(attr,pd_dwarf_names_print_on_error), esb_get_string(&lesb)); esb_destructor(&lesb); /* Add the optimized size to the specific attribute, only if we are dealing with a standard attribute. */ if (attr < DW_AT_lo_user) { attributes_encoding_table[attr].entries += 1; attributes_encoding_table[attr].formx += attributes_encoding_factor[theform]; attributes_encoding_table[attr].leb128 += leb128_size; } } } /* ignoring error, it should be impossible. */ } } /* Print a detailed encoding usage per attribute -kE */ int print_attributes_encoding(Dwarf_Debug dbg, Dwarf_Error* attr_error) { if (attributes_encoding_table) { Dwarf_Bool print_header = TRUE; Dwarf_Unsigned total_entries = 0; Dwarf_Unsigned total_bytes_formx = 0; Dwarf_Unsigned total_bytes_leb128 = 0; Dwarf_Unsigned entries = 0; Dwarf_Unsigned bytes_formx = 0; Dwarf_Unsigned bytes_leb128 = 0; int index; int count = 0; float saved_rate = 0.0; for (index = 0; index < DW_AT_lo_user; ++index) { if (attributes_encoding_table[index].leb128) { if (print_header) { printf("\n*** SPACE USED BY ATTRIBUTE " "ENCODINGS ***\n"); printf("Nro Attribute Name " " Entries Data_x leb128 Rate\n"); print_header = FALSE; } entries = attributes_encoding_table[index].entries; bytes_formx = attributes_encoding_table[index].formx; bytes_leb128 = attributes_encoding_table[index].leb128; total_entries += entries; total_bytes_formx += bytes_formx; total_bytes_leb128 += bytes_leb128; saved_rate = bytes_leb128 * 100 / bytes_formx; printf("%3d %-25s " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu /* Entries */ " " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu /* FORMx */ " " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu /* LEB128 */ " " "%3.0f%%" "\n", ++count, get_AT_name(index,pd_dwarf_names_print_on_error), entries, bytes_formx, bytes_leb128, saved_rate); } } if (!print_header) { /* At least we have an entry, print summary and percentage */ Dwarf_Addr lower = 0; Dwarf_Unsigned size = 0; int infoerr = 0; saved_rate = total_bytes_leb128 * 100 / total_bytes_formx; printf("** Summary ** " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* Entries */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* FORMx */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* LEB128 */ "%3.0f%%" "\n", total_entries, total_bytes_formx, total_bytes_leb128, saved_rate); /* Get .debug_info size (Very unlikely to have an error here). */ infoerr = dwarf_get_section_info_by_name(dbg, ".debug_info",&lower, &size,attr_error); if (infoerr == DW_DLV_ERROR) { free(attributes_encoding_table); attributes_encoding_table = 0; attributes_encoding_do_init = TRUE; return infoerr; } saved_rate = (total_bytes_formx - total_bytes_leb128) * 100 / size; if (saved_rate > 0) { printf("\n** .debug_info size can be reduced " "by %.0f%% **\n", saved_rate); } } free(attributes_encoding_table); attributes_encoding_table = 0; attributes_encoding_do_init = TRUE; } return DW_DLV_OK; } static void check_decl_file_only(char **srcfiles, Dwarf_Unsigned fileindex,Dwarf_Signed srcfiles_cnt, Dwarf_Half dwversion,int attr) { /* Zero is always a legal index for DWARF2,3,4 and it means no source name provided. For DWARF 5 we've determined that the standard is wrong and zero meaning none just does not work. File numbers must start from zero. See the dwarfstd.org wiki */ DWARF_CHECK_COUNT(decl_file_result,1); if (dwversion >= DWVERSION5) { if (fileindex >= ((Dwarf_Unsigned)srcfiles_cnt)) { struct esb_s msgb; esb_constructor(&msgb); if (!srcfiles) { esb_append(&msgb, "There is a file number="); esb_append_printf_u(&msgb,"%" DW_PR_DUu,fileindex); esb_append(&msgb," but no source files"); /* Extra space char here to avoid pointless regression test issues with older versions. */ esb_append(&msgb," are known."); } else { esb_append(&msgb,"Does not index to valid DWARF5" " file name "); esb_append(&msgb,"filenum="); esb_append_printf_u(&msgb,"%" DW_PR_DUu,fileindex); esb_append(&msgb," arraysize="); esb_append_printf_i(&msgb,"%" DW_PR_DSd,srcfiles_cnt); esb_append(&msgb,"."); } DWARF_CHECK_ERROR2(decl_file_result, get_AT_name(attr, pd_dwarf_names_print_on_error), esb_get_string(&msgb)); esb_destructor(&msgb); } return; } /* zero means no file applicable */ if (fileindex && fileindex > ((Dwarf_Unsigned)srcfiles_cnt)) { struct esb_s msgb; esb_constructor(&msgb); if (!srcfiles) { esb_append(&msgb, "There is a file number="); esb_append_printf_u(&msgb,"%" DW_PR_DUu,fileindex); esb_append(&msgb," but no source files"); /* Extra space char here to avoid pointless regression test issues with older versions. */ esb_append(&msgb," are known."); } else { esb_append(&msgb,"Does not index to valid file name "); esb_append(&msgb,"filenum="); esb_append_printf_u(&msgb,"%" DW_PR_DUu,fileindex); esb_append(&msgb," arraysize="); esb_append_printf_i(&msgb,"%" DW_PR_DSd,srcfiles_cnt); esb_append(&msgb,"."); } DWARF_CHECK_ERROR2(decl_file_result, get_AT_name(attr, pd_dwarf_names_print_on_error), esb_get_string(&msgb)); esb_destructor(&msgb); } } static int expand_rnglist_entries( UNUSEDARG Dwarf_Die die, Dwarf_Rnglists_Head rnglhead, Dwarf_Unsigned rnglentriescount, Dwarf_Unsigned rnglglobal_offset, struct esb_s * esbp, UNUSEDARG int show_form, int local_verbose, Dwarf_Error *err) { Dwarf_Unsigned count = 0; Dwarf_Unsigned i = 0; int res = 0; Dwarf_Unsigned secoffset = rnglglobal_offset; Dwarf_Bool no_debug_addr_available = FALSE; count = rnglentriescount; if (local_verbose > 1) { esb_append(esbp,"\n " " " "secoff"); } for ( ; i < count; ++i) { unsigned entrylen = 0; unsigned rle_code = 0; Dwarf_Unsigned raw1 = 0; Dwarf_Unsigned raw2 = 0; Dwarf_Unsigned cooked1 = 0; Dwarf_Unsigned cooked2 = 0; res = dwarf_get_rnglists_entry_fields_a(rnglhead,i, &entrylen,&rle_code, &raw1,&raw2, &no_debug_addr_available, &cooked1,&cooked2, err); if (res != DW_DLV_OK) { return res; } if (local_verbose || no_debug_addr_available ) { const char *codename = ""; dwarf_get_RLE_name(rle_code,&codename); esb_append(esbp,"\n "); esb_append_printf_u(esbp,"[%2u] ",i); esb_append_printf_s(esbp,"%-20s ",codename); if (rle_code != DW_RLE_end_of_list) { esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,raw1); esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,raw2); } else { esb_append(esbp, " "); } if (local_verbose > 1) { esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,secoffset); } if (no_debug_addr_available) { esb_append(esbp,"no .debug_addr available"); } } if (!no_debug_addr_available) { const char *codename = "start,end"; esb_append(esbp,"\n "); esb_append_printf_u(esbp,"[%2u] ",i); if (rle_code == DW_RLE_base_addressx || rle_code == DW_RLE_base_address) { codename = "base address"; } else { if (rle_code == DW_RLE_end_of_list) { codename = "end of list"; } } esb_append_printf_s(esbp,"%-20s ",codename); if (rle_code != DW_RLE_end_of_list) { esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,cooked1); esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,cooked2); } else { esb_append(esbp, " "); } if (local_verbose > 1) { esb_append_printf_u(esbp," 0x%" DW_PR_XZEROS DW_PR_DUx ,secoffset); } } secoffset += entrylen; } esb_append(esbp,"\n"); return DW_DLV_OK; } /* DWARF5 .debug_rnglists[.dwo] only. */ static int handle_rnglists(Dwarf_Die die, Dwarf_Attribute attrib, Dwarf_Half theform, Dwarf_Unsigned attrval, Dwarf_Unsigned *output_rle_set_offset, struct esb_s * esbp, int show_form, int local_verbose, Dwarf_Error *err) { /* This is DWARF5, by definition. Not earlier. */ Dwarf_Unsigned global_offset_of_rle_set = 0; Dwarf_Unsigned count_rnglists_entries = 0; Dwarf_Rnglists_Head rnglhead = 0; int res = 0; res = dwarf_rnglists_get_rle_head(attrib, theform, attrval, /* index val or offset depending on form */ &rnglhead, &count_rnglists_entries, &global_offset_of_rle_set, err); if (res != DW_DLV_OK) { return res; } *output_rle_set_offset = global_offset_of_rle_set; /* Here we put newline at start of each line of output, different from the usual practice */ append_local_prefix(esbp); esb_append_printf_u(esbp, "Offset of rnglists entries: 0x%" DW_PR_XZEROS DW_PR_DUx, global_offset_of_rle_set); if (local_verbose > 1) { Dwarf_Unsigned version = 0; Dwarf_Unsigned context_index = 0; Dwarf_Unsigned rle_count = 0; Dwarf_Unsigned total_bytes_in_rle = 0; Dwarf_Half loffset_size = 0; Dwarf_Half laddress_size = 0; Dwarf_Half lsegment_selector_size = 0; Dwarf_Unsigned section_offset_of_context = 0; Dwarf_Unsigned length_of_context = 0; Dwarf_Bool rnglists_base_present = 0; Dwarf_Unsigned rnglists_base = 0; Dwarf_Bool rnglists_base_address_present = 0; Dwarf_Unsigned rnglists_base_address = 0; Dwarf_Bool debug_addr_base_present = 0; Dwarf_Unsigned debug_addr_base; Dwarf_Unsigned offsets_table_offset = 0; Dwarf_Unsigned offsets_table_entrycount = 0; res = dwarf_get_rnglist_head_basics(rnglhead, &rle_count, &version, &context_index, &total_bytes_in_rle, &loffset_size, &laddress_size, &lsegment_selector_size, §ion_offset_of_context, &length_of_context, &offsets_table_offset, &offsets_table_entrycount, &rnglists_base_present,&rnglists_base, &rnglists_base_address_present,&rnglists_base_address, &debug_addr_base_present,&debug_addr_base, err); if (res != DW_DLV_OK) { dwarf_dealloc_rnglists_head(rnglhead); return res; } append_local_prefix(esbp); esb_append_printf_u(esbp, "Index of rnglist head : %u", context_index); append_local_prefix(esbp); esb_append_printf_u(esbp, "rnglist head version : %u", version); append_local_prefix(esbp); esb_append_printf_u(esbp, "Record count rnglist set : %u", rle_count); append_local_prefix(esbp); esb_append_printf_u(esbp, "Bytes this rnglist set : %u", total_bytes_in_rle); append_local_prefix(esbp); esb_append_printf_u(esbp, "offset size : %u", loffset_size); append_local_prefix(esbp); esb_append_printf_u(esbp, "address size : %u", laddress_size); if (rnglists_base_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "CU DW_AT_rnglists_base : 0x%" DW_PR_XZEROS DW_PR_DUx, rnglists_base); } if (rnglists_base_address_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "CU DW_AT_low_pc (baseaddr): 0x%" DW_PR_XZEROS DW_PR_DUx, rnglists_base_address); } if (debug_addr_base_present) { append_local_prefix(esbp); esb_append_printf_u(esbp, "CU DW_AT_addr_base : 0x%" DW_PR_XZEROS DW_PR_DUx, debug_addr_base); } append_local_prefix(esbp); esb_append_printf_u(esbp, "section offset CU rnglists: 0x%" DW_PR_XZEROS DW_PR_DUx, section_offset_of_context); append_local_prefix(esbp); esb_append_printf_u(esbp, "section length CU rnglists: 0x%" DW_PR_XZEROS DW_PR_DUx, length_of_context); esb_append_printf_u(esbp, " (%u)", length_of_context); } res = expand_rnglist_entries(die,rnglhead, count_rnglists_entries, global_offset_of_rle_set, esbp, show_form,local_verbose,err); dwarf_dealloc_rnglists_head(rnglhead); return res; } /* This detects a special case attr/form compiler mistake because we have one in the regression tests. A more general approach would be better. 5 February 2021 */ static void check_sensible_addr_for_form(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Half theform) { Dwarf_Error e = 0; Dwarf_Half attrnum = 0; int res = 0; res = dwarf_whatattr(attrib,&attrnum,&e); if (res == DW_DLV_OK) { switch(attrnum) { default: return; case DW_AT_stmt_list: case DW_AT_macros: case DW_AT_GNU_macros: { struct esb_s m; esb_constructor(&m); esb_append_printf_s(&m, "Attribute %s has form ", get_AT_name(attrnum,FALSE)); esb_append(&m,get_FORM_name(theform,FALSE)); esb_append(&m," which is improper DWARF. " "Attempting to continue."); glflags.gf_count_major_errors++; printf("ERROR / WARNING: %s\n", esb_get_string(&m)); esb_destructor(&m); } } return; } /* Something crazy. Will be noted elsewhere. */ if (res == DW_DLV_ERROR) { DROP_ERROR_INSTANCE(dbg,res,e); } return; } /* Fill buffer with attribute value. We pass in tag so we can try to do the right thing with broken compiler DW_TAG_enumerator 'cnt' is signed for historical reasons (a mistake in an interface), but the value is never negative. We append to esbp's buffer. */ int get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, UNUSEDARG int die_indent_level, Dwarf_Off dieprint_cu_goffset, Dwarf_Attribute attrib, char **srcfiles, Dwarf_Signed srcfiles_cnt, struct esb_s *esbp, int show_form, int local_verbose, Dwarf_Error *err) { Dwarf_Half theform = 0; char * temps = 0; Dwarf_Block *tempb = 0; Dwarf_Signed tempsd = 0; Dwarf_Unsigned tempud = 0; Dwarf_Off off = 0; Dwarf_Die die_for_check = 0; Dwarf_Half tag_for_check = 0; Dwarf_Addr addr = 0; int fres = 0; int bres = 0; int wres = 0; int dres = 0; Dwarf_Half direct_form = 0; Dwarf_Bool is_info = TRUE; struct esb_s esb_expr; int esb_expr_alive = FALSE; is_info = dwarf_get_die_infotypes_flag(die); /* Dwarf_whatform gets the real form, DW_FORM_indir is never returned: instead the real form following DW_FORM_indir is returned. */ fres = dwarf_whatform(attrib, &theform, err); /* Depending on the form and the attribute, process the form. */ if (fres == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_whatform cannot Find Attr Form", fres, *err); return fres; } else if (fres == DW_DLV_NO_ENTRY) { return fres; } /* dwarf_whatform_direct gets the 'direct' form, so if the form is DW_FORM_indir that is what is returned. */ fres = dwarf_whatform_direct(attrib, &direct_form, err); DROP_ERROR_INSTANCE(dbg,fres,*err); /* Ignore errors in dwarf_whatform_direct() */ switch (theform) { case DW_FORM_GNU_addr_index: case DW_FORM_addrx: case DW_FORM_addrx1 : /* DWARF5 */ case DW_FORM_addrx2 : /* DWARF5 */ case DW_FORM_addrx3 : /* DWARF5 */ case DW_FORM_addrx4 : /* DWARF5 */ case DW_FORM_addr: check_sensible_addr_for_form(dbg,attrib,theform); bres = dwarf_formaddr(attrib, &addr, err); if (bres == DW_DLV_OK) { if (dwarf_addr_form_is_indexed(theform)) { Dwarf_Unsigned index = 0; int res = dwarf_get_debug_addr_index (attrib,&index,err); if (res != DW_DLV_OK) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"ERROR: getting debug addr" " index on form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," missing index?!"); print_error_and_continue(dbg, esb_get_string(&lstr), res, *err); esb_destructor(&lstr); return res; } bracket_hex("(addr_index: ",index, ")",esbp); } bracket_hex("",addr,"",esbp); } else if (bres == DW_DLV_ERROR) { if (DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION == dwarf_errno(*err)) { Dwarf_Unsigned index = 0; int res = 0; DROP_ERROR_INSTANCE(dbg,bres,*err); glflags.gf_debug_addr_missing = 1; res = dwarf_get_debug_addr_index(attrib,&index, err); if (res != DW_DLV_OK) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," missing index. ?!"); print_error_and_continue(dbg, esb_get_string(&lstr), res, *err); esb_destructor(&lstr); return res; } addr = 0; bracket_hex("(addr_index: ",index, ")",esbp); /* This is normal in a .dwo/DWP file. The .debug_addr is in a .o and in the final executable. */ } else { /* Some bad error. */ struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," form with no addr ?!"); print_error_and_continue(dbg, esb_get_string(&lstr), bres, *err); esb_destructor(&lstr); if (!glflags.gf_error_code_search_by_address) { glflags.gf_error_code_search_by_address = dwarf_errno(*err); } return bres; } } else { /* DW_DLV_NO_ENTRY */ struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," is a DW_DLV_NO_ENTRY? " "something is wrong."); print_error_and_continue(dbg, esb_get_string(&lstr), bres, *err); esb_destructor(&lstr); return bres; } break; case DW_FORM_ref_addr: { Dwarf_Half attr = 0; /* DW_FORM_ref_addr is not accessed thru formref: ** it is an address (global section offset) in ** the .debug_info section. */ bres = dwarf_global_formref(attrib, &off, err); if (bres == DW_DLV_OK) { bracket_hex("",esbp); } else { print_error_and_continue(dbg, "DW_FORM_ref_addr form with no reference?!" " Something is corrupted.", bres, *err); return bres; } wres = dwarf_whatattr(attrib, &attr, err); if (wres != DW_DLV_OK) { print_error_and_continue(dbg, "DW_FORM_ref_addr no attribute number?!" " Something is corrupted.", wres, *err); return wres; } if (attr == DW_AT_sibling) { /* The value had better be inside the current CU else there is a nasty error here, as a sibling has to be in the same CU, it seems. */ /* The target offset (off) had better be following the die's global offset else we have a serious botch. this FORM defines the value as a .debug_info global offset. */ Dwarf_Off cuoff = 0; Dwarf_Off culen = 0; Dwarf_Off die_overall_offset = 0; int res = 0; int ores = dwarf_dieoffset(die, &die_overall_offset, err); if (ores != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_dieoffsetnot available for" "DW_AT_sibling. Something is corrupted.", ores, *err); return ores; } if (die_stack_indent_level >= DIE_STACK_SIZE ) { report_die_stack_error(dbg,err); return DW_DLV_ERROR; } SET_DIE_STACK_SIBLING(off); if (die_overall_offset >= off) { struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "ERROR: Sibling DW_FORM_ref_offset 0x%" DW_PR_XZEROS DW_PR_DUx , off); esb_append_printf_s(&msg, " points %s die Global offset ", (die_overall_offset == off)?"at":"before"); esb_append_printf_u(&msg, "0x%" DW_PR_XZEROS DW_PR_DUx, die_overall_offset); simple_err_only_return_action(DW_DLV_ERROR, esb_get_string(&msg)); esb_destructor(&msg); } DWARF_CHECK_COUNT(tag_tree_result,1); res = dwarf_die_CU_offset_range(die,&cuoff, &culen,err); if (res != DW_DLV_OK) { DWARF_CHECK_ERROR(tag_tree_result, "DW_AT_sibling DW_FORM_ref_addr " "offset range of the CU " "is not available"); DROP_ERROR_INSTANCE(dbg,res,*err); } else { Dwarf_Off cuend = cuoff+culen; if (off < cuoff || off >= cuend) { DWARF_CHECK_ERROR(tag_tree_result, "DW_AT_sibling DW_FORM_ref_addr " "offset points " "outside of current CU"); } } } } break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: { int refres = 0; Dwarf_Half attr = 0; Dwarf_Off goff = 0; /* Global offset */ /* CU-relative offset returned. */ refres = dwarf_formref(attrib, &off, err); if (refres != DW_DLV_OK) { struct esb_s msg; esb_constructor(&msg); /* Report incorrect offset */ esb_append_printf_s(&msg, "reference form on attr %s has " "no valid cu_relative offset?! ", get_AT_name(attr,FALSE)); esb_append_printf_u(&msg, ", for offset=<0x%" DW_PR_XZEROS DW_PR_DUx ">", off); print_error_and_continue(dbg, esb_get_string(&msg),refres,*err); esb_destructor(&msg); return refres; } refres = dwarf_whatattr(attrib, &attr, err); if (refres != DW_DLV_OK) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,get_AT_name(attr,FALSE)); esb_append(&lstr, " is an attribute with no number? Impossible"); print_error_and_continue(dbg, esb_get_string(&lstr),refres,*err); esb_destructor(&lstr); return refres; } /* Convert the local offset 'off' into a global section offset 'goff'. */ refres = dwarf_convert_to_global_offset(attrib, off, &goff, err); if (refres != DW_DLV_OK) { /* Report incorrect offset */ struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "invalid offset" ",off=<0x%" DW_PR_XZEROS DW_PR_DUx "> ", off); esb_append(&msg,"attr: "); esb_append(&msg,get_AT_name(attr,FALSE)); esb_append(&msg,"local offset has no global offset! "); print_error_and_continue(dbg, esb_get_string(&msg), refres, *err); esb_destructor(&msg); return refres; } if (attr == DW_AT_sibling) { /* The value had better be inside the current CU else there is a nasty error here, as a sibling has to be in the same CU, it seems. The target offset (off) had better be following the die's global offset else we have a serious botch. this FORM defines the value as a .debug_info global offset. */ Dwarf_Off die_overall_offset = 0; int ores = dwarf_dieoffset(die, &die_overall_offset,err); if (ores != DW_DLV_OK) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"DW_AT_sibling attr and DIE has"); esb_append(&lstr,"no die_offset?"); print_error_and_continue(dbg, esb_get_string(&lstr), ores, *err); esb_destructor(&lstr); return ores; } SET_DIE_STACK_SIBLING(goff); if (die_overall_offset >= goff) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"ERROR in DW_AT_sibling: "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append_printf_u(&lstr, " Sibling offset 0x%" DW_PR_XZEROS DW_PR_DUx " points ", goff); esb_append(&lstr, (die_overall_offset == goff)?"at":"before"); esb_append_printf_u(&lstr, " its own die GOFF=" "0x%" DW_PR_XZEROS DW_PR_DUx, die_overall_offset); simple_err_only_return_action(DW_DLV_ERROR, esb_get_string(&lstr)); esb_destructor(&lstr); /* At present no way to create a Dwarf_Error inside dwarfdump. */ } } /* Do references inside <> to distinguish them ** from constants. In dense form this results in <<>>. Ugly for dense form, but better than ambiguous. davea 9/94 */ if (glflags.gf_show_global_offsets) { bracket_hex("<",off,"",esbp); bracket_hex(" GOFF=",goff,">",esbp); } else { bracket_hex("<",off,">",esbp); } if (glflags.gf_check_type_offset) { if (attr == DW_AT_type && form_refers_local_info(theform)) { dres = dwarf_offdie_b(dbg, goff, is_info, &die_for_check, err); if (dres != DW_DLV_OK) { struct esb_s msgc; esb_constructor(&msgc); esb_append_printf_u(&msgc, "DW_AT_type offset does not point to a DIE " "for global offset 0x%" DW_PR_XZEROS DW_PR_DUx, goff); esb_append_printf_u(&msgc, " cu off 0x%" DW_PR_XZEROS DW_PR_DUx, dieprint_cu_goffset); esb_append_printf_u(&msgc, " local offset 0x%" DW_PR_XZEROS DW_PR_DUx, off); esb_append_printf_u(&msgc, " tag 0x%x",tag); DWARF_CHECK_ERROR(type_offset_result, esb_get_string(&msgc)); DROP_ERROR_INSTANCE(dbg,dres,*err); esb_destructor(&msgc); } else { int tres2 = dwarf_tag(die_for_check, &tag_for_check, err); if (tres2 == DW_DLV_OK) { switch (tag_for_check) { case DW_TAG_array_type: case DW_TAG_class_type: case DW_TAG_enumeration_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: case DW_TAG_restrict_type: case DW_TAG_string_type: case DW_TAG_structure_type: case DW_TAG_subroutine_type: case DW_TAG_typedef: case DW_TAG_union_type: case DW_TAG_ptr_to_member_type: case DW_TAG_set_type: case DW_TAG_subrange_type: case DW_TAG_base_type: case DW_TAG_const_type: case DW_TAG_file_type: case DW_TAG_packed_type: case DW_TAG_thrown_type: case DW_TAG_volatile_type: case DW_TAG_template_type_parameter: case DW_TAG_template_value_parameter: case DW_TAG_unspecified_type: /* Template alias */ case DW_TAG_template_alias: /* OK */ break; default: { struct esb_s msga; esb_constructor(&msga); esb_append_printf_u(&msga, "DW_AT_type offset " "0x%" DW_PR_XZEROS DW_PR_DUx, goff); esb_append_printf_u(&msga, " does not point to Type" " info we got tag 0x%x ", tag_for_check); esb_append(&msga, get_TAG_name(tag_for_check, pd_dwarf_names_print_on_error)); DWARF_CHECK_ERROR(type_offset_result, esb_get_string(&msga)); esb_destructor(&msga); } break; } dwarf_dealloc_die(die_for_check); die_for_check = 0; } else { DWARF_CHECK_ERROR(type_offset_result, "DW_AT_type offset does not exist"); DROP_ERROR_INSTANCE(dbg,tres2,*err); } } } } } break; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_exprloc: fres = dwarf_formblock(attrib, &tempb, err); if (fres == DW_DLV_OK) { unsigned u = 0; esb_append_printf_u(esbp, "len 0x%04x: ", tempb->bl_len); if (tempb->bl_len) { esb_append(esbp,"0x"); } for (u = 0; u < tempb->bl_len; u++) { esb_append_printf_u(esbp, "%02x", *(u + (unsigned char *) tempb->bl_data)); } if (tempb->bl_len) { esb_append(esbp,": "); } dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); tempb = 0; } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Form form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," cannot get block"); print_error_and_continue(dbg, esb_get_string(&lstr), fres, *err); esb_destructor(&lstr); return fres; } break; case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_data16: { Dwarf_Half attr = 0; fres = dwarf_whatattr(attrib, &attr, err); if (fres != DW_DLV_OK) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," cannot get attribute"); print_error_and_continue(dbg, esb_get_string(&lstr), fres, *err); esb_destructor(&lstr); return fres; } else { switch (attr) { case DW_AT_ordering: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_inline: case DW_AT_language: case DW_AT_visibility: case DW_AT_virtuality: case DW_AT_accessibility: case DW_AT_address_class: case DW_AT_calling_convention: case DW_AT_discr_list: /* DWARF2 */ case DW_AT_encoding: case DW_AT_identifier_case: case DW_AT_MIPS_loop_unroll_factor: case DW_AT_MIPS_software_pipeline_depth: case DW_AT_decl_column: case DW_AT_decl_file: case DW_AT_decl_line: case DW_AT_call_column: case DW_AT_call_file: case DW_AT_call_line: case DW_AT_start_scope: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_count: case DW_AT_stmt_list: case DW_AT_MIPS_fde: { int show_form_here = 0; wres = dd_get_integer_and_name(dbg, attrib, &tempud, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, err,show_form_here); if (wres == DW_DLV_OK) { Dwarf_Bool hex_format = TRUE; Dwarf_Half dwversion = 0; formx_unsigned(tempud,esbp,hex_format); /* Check attribute encoding */ if (glflags.gf_check_attr_encoding) { check_attributes_encoding(attr,theform, tempud); } if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { turn_file_num_to_string(dbg,die, attrib,theform, dwversion,tempud, srcfiles, srcfiles_cnt,esbp,err); /* Validate integrity of file indices referenced in .debug_line */ if (glflags.gf_check_decl_file) { check_decl_file_only(srcfiles, tempud,srcfiles_cnt, dwversion,attr); } } /* end decl_file and call_file processing */ } else { /* not DW_DLV_OK on get small encoding */ struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"For form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," and attribute "); esb_append(&lstr,get_AT_name(attr,FALSE)); esb_append(&lstr, " Cannot get encoding attribute"); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } } break; case DW_AT_const_value: { /* Do not use hexadecimal format */ Dwarf_Bool chex = FALSE; wres = formxdata_print_value(dbg,die,attrib, theform,esbp, err, /* hex format?*/chex); if (wres == DW_DLV_OK){ /* String appended already. */ } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"For form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," and attribute "); esb_append(&lstr,get_AT_name(attr,FALSE)); esb_append(&lstr," Cannot get const value "); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } } break; case DW_AT_GNU_dwo_id: case DW_AT_GNU_odr_signature: case DW_AT_dwo_id: { Dwarf_Sig8 v; v = zerosig; wres = dwarf_formsig8_const(attrib,&v,err); if (wres == DW_DLV_OK){ struct esb_s t; esb_constructor(&t); format_sig8_string(&v,&t); esb_append(esbp,esb_get_string(&t)); esb_destructor(&t); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ esb_append(esbp,"Impossible: no entry for "); esb_append(esbp,get_FORM_name(theform,FALSE)); esb_append(esbp," dwo_id"); } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"For form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," and attribute "); esb_append(&lstr,get_AT_name(attr,FALSE)); esb_append(&lstr, " Cannot get Dwarf_Sig8 value "); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } } break; case DW_AT_upper_bound: case DW_AT_lower_bound: default: { Dwarf_Bool chex = FALSE; Dwarf_Die tdie = die; if (DW_AT_ranges == attr || DW_AT_location == attr || DW_AT_vtable_elem_location == attr || DW_AT_string_length == attr || DW_AT_return_addr == attr || DW_AT_use_location == attr || DW_AT_static_link == attr || DW_AT_frame_base == attr) { /* Do not look for data type for unsigned/signed. and do use HEX. */ chex = TRUE; tdie = NULL; } /* Do not use hexadecimal format except for DW_AT_ranges. */ wres = formxdata_print_value(dbg, tdie,attrib, theform,esbp, err, chex); if (wres == DW_DLV_OK) { /* String appended already. */ } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"For form "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," and attribute "); esb_append(&lstr,get_AT_name(attr,FALSE)); esb_append(&lstr, " Cannot get Dwarf_Sig8 value "); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } } break; } } if (glflags.gf_cu_name_flag) { if (attr == DW_AT_MIPS_fde) { if (glflags.fde_offset_for_cu_low == DW_DLV_BADOFFSET) { glflags.fde_offset_for_cu_low = glflags.fde_offset_for_cu_high = tempud; } else if (tempud < glflags.fde_offset_for_cu_low) { glflags.fde_offset_for_cu_low = tempud; } else if (tempud > glflags.fde_offset_for_cu_high) { glflags.fde_offset_for_cu_high = tempud; } } } } break; case DW_FORM_sdata: wres = dwarf_formsdata(attrib, &tempsd, err); if (wres == DW_DLV_OK) { Dwarf_Bool hxform=TRUE; tempud = tempsd; formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hxform,esbp); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error_and_continue(dbg, "Cannot get DW_FORM_sdata value..", wres, *err); return wres; } break; case DW_FORM_udata: wres = dwarf_formudata(attrib, &tempud, err); if (wres == DW_DLV_OK) { Dwarf_Bool hex_format = TRUE; formx_unsigned(tempud,esbp,hex_format); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error_and_continue(dbg, "Cannot get DW_FORM_udata value..", wres, *err); return wres; } break; /* various forms for strings. */ case DW_FORM_string: case DW_FORM_strp: case DW_FORM_strx: /* DWARF5 */ case DW_FORM_strx1: /* DWARF5 */ case DW_FORM_strx2: /* DWARF5 */ case DW_FORM_strx3: /* DWARF5 */ case DW_FORM_strx4: /* DWARF5 */ case DW_FORM_strp_sup: /* DWARF5 String in altrnt: tied file */ case DW_FORM_GNU_strp_alt: /* String in altrnt: tied file */ case DW_FORM_line_strp: /* DWARF5, offset to .debug_line_str */ /* unsigned offset in size of an offset */ case DW_FORM_GNU_str_index: { int sres = dwarf_formstring(attrib, &temps, err); if (sres == DW_DLV_OK) { if (theform == DW_FORM_strx || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 || theform == DW_FORM_GNU_str_index) { char saverbuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s saver; Dwarf_Unsigned index = 0; esb_constructor_fixed(&saver,saverbuf, sizeof(saverbuf)); sres = dwarf_get_debug_str_index(attrib,&index,err); esb_append(&saver,temps); if (sres == DW_DLV_OK) { bracket_hex("(indexed string: ",index,")",esbp); } else { DROP_ERROR_INSTANCE(dbg,sres,*err); esb_append(esbp, "(ERROR: indexed string:no " "string provided?)"); } esb_append(esbp, esb_get_string(&saver)); esb_destructor(&saver); } else { esb_append(esbp,temps); } } else if (sres == DW_DLV_NO_ENTRY) { if (theform == DW_FORM_strx || theform == DW_FORM_GNU_str_index || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 ) { esb_append(esbp, "(indexed string,no string provided?)"); } else { esb_append(esbp, ""); } } else { /* DW_DLV_ERROR */ if (theform == DW_FORM_strx || theform == DW_FORM_GNU_str_index || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 ) { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Cannot get an indexed string on "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr,"...."); print_error_and_continue(dbg, esb_get_string(&lstr), sres, *err); esb_destructor(&lstr); return sres; } { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Cannot get the form on "); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr,"...."); print_error_and_continue(dbg, esb_get_string(&lstr), sres, *err); esb_destructor(&lstr); return sres; } } } break; case DW_FORM_flag: { Dwarf_Bool tempbool = 0; wres = dwarf_formflag(attrib, &tempbool, err); if (wres == DW_DLV_OK) { if (tempbool) { esb_append_printf_i(esbp, "yes(%d)", tempbool); } else { esb_append(esbp,"no"); } } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error_and_continue(dbg, "Cannot get formflag/p....", wres, *err); return wres; } } break; case DW_FORM_indirect: /* We should not ever get here, since the true form was determined and direct_form has the DW_FORM_indirect if it is used here in this attr. */ esb_append(esbp, get_FORM_name(theform, pd_dwarf_names_print_on_error)); break; case DW_FORM_sec_offset: { /* DWARF4, DWARF5 */ char* emptyattrname = 0; int show_form_here = 0; wres = dd_get_integer_and_name(dbg, attrib, &tempud, emptyattrname, /* err_string */ NULL, (encoding_type_func) 0, err,show_form_here); if (wres == DW_DLV_NO_ENTRY) { /* Show nothing? */ } else if (wres == DW_DLV_ERROR) { print_error_and_continue(dbg, "ERROR: cannot et DW_FORM_sec_offset value content.", wres,*err); return wres; } else { bracket_hex("",tempud,"",esbp); } } break; case DW_FORM_flag_present: /* DWARF4 */ esb_append(esbp,"yes(1)"); break; case DW_FORM_ref_sig8: { /* DWARF4 */ Dwarf_Sig8 sig8data; sig8data = zerosig; wres = dwarf_formsig8(attrib,&sig8data,err); if (wres != DW_DLV_OK) { /* Show nothing? */ print_error_and_continue(dbg, "ERROR: cannot et DW_FORM_ref_sig8 value content.", wres,*err); return wres; } else { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(&sig8data,&sig8str); esb_append(esbp,esb_get_string(&sig8str)); esb_destructor(&sig8str); if (!show_form) { esb_append(esbp," "); } } } break; /* DWARF5, attr val is signed uleb */ case DW_FORM_implicit_const: { wres = dwarf_formsdata(attrib, &tempsd, err); if (wres == DW_DLV_OK) { Dwarf_Bool hxform=TRUE; tempud = tempsd; formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hxform,esbp); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error_and_continue(dbg, "ERROR: cannot get signed value of " "DW_FORM_implicit_const", wres,*err); return wres; } } break; case DW_FORM_loclistx: /* DWARF5, index into .debug_loclists */ wres = dwarf_formudata(attrib, &tempud, err); if (wres == DW_DLV_OK) { /* Fall through to end to show the form details. */ Dwarf_Bool hex_format = TRUE; esb_append(esbp,""); break; } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Cannot get formudata on "); esb_append(&lstr,"DW_FORM_loclistx"); esb_append(&lstr,"...."); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } break; case DW_FORM_rnglistx: { /* DWARF5, index into .debug_rnglists Can appear only on DW_AT_ranges attribute.*/ wres = dwarf_formudata(attrib, &tempud, err); if (wres == DW_DLV_OK) { /* Fall through to end to show the form details. */ Dwarf_Bool hex_format = TRUE; esb_append(esbp,""); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,"Cannot get formudata on "); esb_append(&lstr,"DW_FORM_rnglistx"); esb_append(&lstr,"...."); print_error_and_continue(dbg, esb_get_string(&lstr), wres, *err); esb_destructor(&lstr); return wres; } } break; case DW_FORM_ref_sup4: /* DWARF5 */ case DW_FORM_ref_sup8: /* DWARF5 */ case DW_FORM_GNU_ref_alt: { bres = dwarf_global_formref(attrib, &off, err); if (bres == DW_DLV_OK) { bracket_hex("",off,"",esbp); } else { struct esb_s lstr; esb_constructor(&lstr); esb_append(&lstr,get_FORM_name(theform,FALSE)); esb_append(&lstr," form with no reference?!"); print_error_and_continue(dbg, esb_get_string(&lstr), bres,*err); esb_destructor(&lstr); return wres; } } break; default: { struct esb_s lstr; esb_constructor(&lstr); esb_append_printf_u(&lstr, "ERROR: dwarf_whatform unexpected value, " "form code 0x%04x", theform); simple_err_only_return_action(DW_DLV_ERROR, esb_get_string(&lstr)); esb_destructor(&lstr); } break; } /* end switch on theform */ show_form_itself(show_form,local_verbose,theform, direct_form,esbp); if (esb_expr_alive) { /* So the expr ops follow the FORM of the attribute if indeed FORMs shown. */ esb_append(esbp,esb_get_string(&esb_expr)); esb_destructor(&esb_expr); } return DW_DLV_OK; } void format_sig8_string(Dwarf_Sig8*data, struct esb_s *out) { unsigned i = 0; esb_append(out,"0x"); for (; i < sizeof(data->signature); ++i) { esb_append_printf_u(out, "%02x", (unsigned char)(data->signature[i])); } } static int get_form_values( UNUSEDARG Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Half * theform, Dwarf_Half * directform, Dwarf_Error *err) { int res = 0; res = dwarf_whatform(attrib, theform, err); if (res != DW_DLV_OK) { return res; } res = dwarf_whatform_direct(attrib, directform, err); return res; } static void show_form_itself(int local_show_form, int local_verbose, int theform, int directform, struct esb_s *esbp) { if (local_show_form && directform && directform == DW_FORM_indirect) { char *form_indir = " (used DW_FORM_indirect"; char *form_indir2 = ") "; esb_append(esbp, form_indir); if (local_verbose) { esb_append_printf_i(esbp," %d",DW_FORM_indirect); } esb_append(esbp, form_indir2); } if (local_show_form) { esb_append(esbp,"
"); } } libdwarf-20210528/dwarfdump/print_strings.c0000664000175000017500000000623213764006205015544 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2012 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" static void print_sec_name(Dwarf_Debug dbg) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_str", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } /* print data in .debug_str */ int print_strings(Dwarf_Debug dbg,Dwarf_Error *err) { Dwarf_Signed length = 0; char* name = 0; Dwarf_Off offset = 0; int sres = 0; unsigned loopct = 0; glflags.current_section_id = DEBUG_STR; for (loopct = 0; (sres = dwarf_get_str(dbg, offset, &name, &length, err)) == DW_DLV_OK; ++loopct) { if (!loopct) { print_sec_name(dbg); } if (glflags.gf_display_offsets) { printf("name at offset 0x%" DW_PR_XZEROS DW_PR_DUx ", length %4" DW_PR_DSd " is '%s'\n", (Dwarf_Unsigned)offset, length, sanitized(name)); } else { printf("name: length %4" DW_PR_DSd " is '%s'\n", length, sanitized(name)); } offset += length + 1; } if (!loopct) { print_sec_name(dbg); } /* An inability to find the section is not necessarily a real error, so do not report error unless we've seen a real record. */ if (sres == DW_DLV_ERROR) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "\nERROR: Getting a .debug_str section string failed " " at string number %u",loopct); esb_append_printf_u(&m,",section offset 0x%." DW_PR_DUx ".",offset); simple_err_only_return_action(sres,esb_get_string(&m)); esb_destructor(&m); } return sres; } libdwarf-20210528/dwarfdump/attr_form.h0000664000175000017500000000523214013267005014633 00000000000000/* Copyright (C) 2021 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef ATTR_FORM_H #define ATTR_FORM_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define AF_STD 1 #define AF_EXTEN 2 struct Three_Key_Entry_s { Dwarf_Half key1; /* usually AT number */ Dwarf_Half key2; /* usually FORM_CLASS number */ Dwarf_Half key3; /* usually actual DW_FORM number, but for a record from the preset table, this is zero as there the actual FORM is unknown. */ Dwarf_Small std_or_exten; /* 1: std 2: extension */ Dwarf_Small from_tables; /* 1 if found in preset table else 0 meaning found only in the DWARF. */ Dwarf_Unsigned count; /* The number actually encountered */ }; typedef struct Three_Key_Entry_s Three_Key_Entry; /* Returns DW_DLV_ERROR if out of memory, else DW_DLV_OK */ int make_3key(Dwarf_Half k1, Dwarf_Half k2, Dwarf_Half k3, Dwarf_Small std_or_exten, Dwarf_Small from_preset, Dwarf_Unsigned count, Three_Key_Entry ** out); Dwarf_Unsigned three_key_entry_count(void *base); void free_func_3key_entry(void *keystructptr); int std_compare_3key_entry(const void *l, const void *r); int build_attr_form_base_tree(int*errnum); void destroy_attr_form_trees(void); void record_attr_form_use(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Half attr, Dwarf_Half fclass, Dwarf_Half form, int pd_dwarf_names_print_on_error, int die_stack_indent_level); /* The standard main tree for attr_form data. Starting out as simple global variables. */ extern void * threekey_attr_form_base; /* for attr-form combos */ void print_attr_form_usage(int poe); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ATTR_FORM_H */ libdwarf-20210528/dwarfdump/README0000664000175000017500000000614313644370703013360 00000000000000I would prefer you try using ../dwarfdump2, not this source. If you must use this for some reason, could you let me know why? Thanks. To build dwarfdump, first build libdwarf in the neighboring directory then type ./configure make Installation is a bit primitive. sudo make install may or may not work. Some or all of the following might be required on Unix or Linux or MacOS: sudo mkdir -p /usr/local/share/man/man1/ sudo mkdir -p /usr/local/lib sudo mkdir -p /usr/local/bin Then retry the 'sudo make install' and (if necessary) try sudo chmod a+x /usr/local/bin/dwarfdump sudo chmod a+r /usr/local/share/man/man1/dwarfdump.1 sudo chmod a+r /usr/local/lib/dwarfdump.conf You don't really need the dwarfdump.1 man page, but you might as well have it. If the man page is not visible with 'man dwarfdump' try 'man manpath' for hints. If you don't need others using dwarfdump on your computer, just cp dwarfdump $HOME/bin/dwarfdump (by convention many people put personal executables in $HOME/bin and fix up $PATH to refer there) which suffices as 'installation'. Also cp dwarfdump.conf $HOME To use dwarf or libdwarf, you may want to install dwarf.h and libdwarf.h somewhere convenient. You can just copy those two headers to /usr/local/include by hand (or anywhere, really, that you have permission to copy to) (you may need to use -I/usr/local/include on compile lines to reference them there, but see below on configure and make). Notice that dwarf_names.c and dwarf_names.h are supplied by the release though the Makefile can and may rebuild them. Some users find it difficult to get a reliable awk(1) program, so for them these prebuilt versions may be useful. If your headers or libelf/libdwarf are not in the expected places, use the make command line to add flags and include directories. For example ./configure PREINCS="-I /usr/local/include" POSTINCS="-I /home/x/include" make PREINCS content is inserted before CFLAGS as make(1) is running. POSTINCS content is added after the CFLAGS value. To set LDFLAGS, do so at configure time, for example: ./configure LDFLAGS="-L /some/dir" And/or use PRELIBS and/or POSTLIBS at 'make' time similar to the use of PREINCS and POSTINCS. If the libdwarf directory has both libdwarf.so and libdwarf.a, the libdwarf.so will be picked up and "./tag_tree_build: error while loading shared libraries: libdwarf.so: cannot open shared object file: No such file or directory" will probably result. Either: remove libdwarf.so and rebuild or set the environment variable LD_LIBRARY_PATH to the directory containing the .so or use LDFLAGS to set rpath (see just below). It is perhaps simpler to ensure that the libdwarf directory only has an archive, not a shared-library. But sometimes one wants a shared library. In that case one can set ld's -rpath on the gcc command line like this: LDFLAGS="-Wl,-rpath=/some/path/libdir" so the shared library can be found at run time automatically. The same problem may arise with libelf, and the same approach will solve the problem. David Anderson. davea42 at earthlink dot net. libdwarf-20210528/dwarfdump/attr_form_build.c0000664000175000017500000002326714015310455016015 00000000000000/* Copyright (C) 2021 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include #include /* For va_start va_arg va_list */ #include /* For errno declaration. */ #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_ */ #ifdef HAVE_STDLIB_H #include /* For exit() declaration etc. */ #endif /* HAVE_STDLIB_H */ #include #include "libdwarf.h" #include "common.h" #include "esb.h" #include "tag_common.h" #include "dwgetopt.h" #define DW_TSHASHTYPE long /* we are not using hash tree */ #include "dwarf_tsearch.h" #include "attr_form.h" #include "libdwarf_version.h" Dwarf_Bool ellipsis = FALSE; /* So we can use dwarf_names.c */ /* Expected input format 0xffffffff DW_AT_something (a number as seen here) name of a form-class enum entry ... 0xffffffff DW_AT_something_else (a number as seen here) name of a form-class enum entry ... 0xffffffff ... We generate a text list of numbers as a C header file. The array there is used #include "dwarf_tsearch.h" by dwarfdump at runtime if attr/form checking is requested. The file is named dwarfump/dwarfdump-af-table.h and is intended to be included in exactly one place in dwarfdump source. The list is N entries (N is not limited) of attribute# formclass# std1/extended2 flag followed by a space and the # and then names. For example: {0x02,10, 1}, DW_AT_location, DW_FORM_CLASS_REFERENCE, Std with the names in a C comment block (which we do not show quite right here). See dwarfdump/dwarfdump-af-table.h The Standard vs Extended table indication is a rough indication. dwarfdump will know what are extension ATtributes and extension FORMs by the valuing being at or above the formal AT DW_AT_lo_user and the FORM being above 0x2c (ie the highest defined by any DWARF standard, lacking a DW_FORM_lo_user value) Lines beggining with a # character are ignored by the code in dwarfdump reading this output. Any lines commented with C comments are stripped by the initial C pre-processor invocation. */ #define AF_STANDARD 1 #define AF_EXTENDED 2 static const char *usage[] = { "Usage: attr_form_build ", " -i input-table-path", " -o output-table-path", " -s (Generate standard attr-formclass table)", " -e (Generate extended attr-formclass table " "(common extensions))", "" }; const char *program_name = 0; char *input_name = 0; char *output_name = 0; int standard_flag = FALSE; int extended_flag = FALSE; /* process arguments */ static void process_args(int argc, char *argv[]) { int c = 0; Dwarf_Bool usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:se")) != EOF) { switch (c) { case 'i': input_name = dwoptarg; break; case 'o': output_name = dwoptarg; break; case 'e': extended_flag = TRUE; break; case 's': standard_flag = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(argv[0],usage); exit(FAILED); } } void *attr_check_dups; void check_for_dup_attr(unsigned attr) { Three_Key_Entry *e = 0; Three_Key_Entry *re = 0; int kres = 0; void *ret = 0; kres = make_3key(attr,0,0,1,1,0,&e); if (kres != DW_DLV_OK) { printf("FAIL malloc in check_for_dup_attr line %d\n", __LINE__); exit(1); } #if 0 ret = dwarf_tfind(e,&attr_check_dups, std_compare_3key_entry); if (ret) { printf("FAIL as attribute 0x%x is duplicated\n", attr); exit(1); } #endif ret = dwarf_tsearch(e,&attr_check_dups, std_compare_3key_entry); if (!ret) { printf("FAIL malloc in check_for_dup_attr line %d\n", __LINE__); exit(1); } re = *(Three_Key_Entry **)ret; if (re != e) { printf("FAIL as attribute 0x%x is duplicated\n", attr); /* If we did not exit we would free e here */ exit(1); } } int main(int argc, char **argv) { unsigned int num = 0; int input_eof = 0; unsigned current_row = 0; FILE * fileInp = 0; FILE * fileOut = 0; print_version_details(argv[0],FALSE); print_args(argc,argv); process_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename," " could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"a"); if (!fileOut) { fprintf(stderr,"Invalid output filename," " could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } if (standard_flag) { fprintf(fileOut,"/* Generated table, do not edit. */\n"); fprintf(fileOut,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR ); fprintf(fileOut,"\n"); fprintf(fileOut,"%s\n", "#ifndef DWARFDUMP_AF_TABLE_H"); fprintf(fileOut,"%s\n", "#define DWARFDUMP_AF_TABLE_H"); fprintf(fileOut,"\n"); fprintf(fileOut,"%s\n", "#ifdef __cplusplus"); fprintf(fileOut,"%s\n", "extern \"C\" {"); fprintf(fileOut,"%s\n", "#endif /* __cplusplus */"); fprintf(fileOut,"struct af_table_s {\n"); fprintf(fileOut," Dwarf_Half attr;\n"); fprintf(fileOut," Dwarf_Half formclass;\n"); fprintf(fileOut," unsigned char section;\n"); fprintf(fileOut,"} attr_formclass_table[] = {\n"); } while (!feof(stdin)) { unsigned int attr = 0; input_eof = read_value(&attr,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } check_for_dup_attr(attr); input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } while (num != MAGIC_TOKEN_VALUE) { int res = 0; const char *name = 0; fprintf(fileOut,"{0x%02x,%2u,%d},", attr,num, standard_flag? AF_STANDARD:AF_EXTENDED); res = dwarf_get_AT_name(attr,&name); if (res != DW_DLV_OK) { printf("Unknown attribute number of 0x%x," " Giving up\n",num); exit(1); } fprintf(fileOut,"/*%s ",name); res = dwarf_get_FORM_CLASS_name(num,&name); if (res != DW_DLV_OK) { printf("Unknown form class number of 0x%x," " Giving up\n",num); exit(1); } fprintf(fileOut,"%s ",name); fprintf(fileOut,"%s*/\n", standard_flag?"Std":"Ext"); input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } ++current_row; } if (extended_flag) { fprintf(fileOut,"{ 0,0,0 }\n"); fprintf(fileOut,"}; /* end af_table extended */\n"); fprintf(fileOut,"%s\n", "#ifdef __cplusplus"); fprintf(fileOut,"%s\n", "extern \"C\" {"); fprintf(fileOut,"%s\n", "#endif /* __cplusplus */"); fprintf(fileOut,"%s\n", "#endif /* DWARFDUMP_AF_TABLE_H */"); } else { fprintf(fileOut,"/* end af_table standard */\n"); } dwarf_tdestroy(attr_check_dups,free_func_3key_entry); attr_check_dups = 0; fclose(fileInp); fclose(fileOut); return (0); } /* A fake so we can use dwarf_names.c */ void print_error (UNUSEDARG Dwarf_Debug dbg, UNUSEDARG const char * msg, UNUSEDARG int res, UNUSEDARG Dwarf_Error localerr) { } libdwarf-20210528/dwarfdump/helpertree.c0000664000175000017500000001060113764006205014771 00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "helpertree.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ /* For .debug_info (not for tied file) */ struct Helpertree_Base_s helpertree_offsets_base_info; /* For .debug_types (not for tied file) */ struct Helpertree_Base_s helpertree_offsets_base_types; static struct Helpertree_Map_Entry_s * helpertree_map_create_entry(Dwarf_Unsigned offset, int val) { struct Helpertree_Map_Entry_s *mp = (struct Helpertree_Map_Entry_s *) calloc(1,sizeof(struct Helpertree_Map_Entry_s)); if (!mp) { return 0; } mp->hm_key = offset; mp->hm_val = val; return mp; } static void helpertree_map_free_func(void *mx) { struct Helpertree_Map_Entry_s *m = mx; free(m); } static int helpertree_map_compare_func(const void *l, const void *r) { const struct Helpertree_Map_Entry_s *ml = l; const struct Helpertree_Map_Entry_s *mr = r; if (ml->hm_key < mr->hm_key) { return -1; } if (ml->hm_key > mr->hm_key) { return 1; } return 0; } static void helpertree_map_destroy(void *map) { /* tdestroy is not part of Posix. */ dwarf_tdestroy(map,helpertree_map_free_func); } /* Globally-visible functions follow this line. */ struct Helpertree_Map_Entry_s * helpertree_add_entry(Dwarf_Unsigned offset, int val,struct Helpertree_Base_s *base) { void *retval = 0; struct Helpertree_Map_Entry_s *re = 0; struct Helpertree_Map_Entry_s *e; void **tree1 = 0; tree1 = &base->hb_base; e = helpertree_map_create_entry(offset,val); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, helpertree_map_compare_func); if (retval) { re = *(struct Helpertree_Map_Entry_s **)retval; if (re != e) { /* We returned an existing record, e not needed. Set val. */ re->hm_val = val; helpertree_map_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } return retval; } return NULL; } struct Helpertree_Map_Entry_s * helpertree_find(Dwarf_Unsigned offset,struct Helpertree_Base_s *base) { void *retval = 0; struct Helpertree_Map_Entry_s *re = 0; struct Helpertree_Map_Entry_s *e = 0; e = helpertree_map_create_entry(offset,0); retval = dwarf_tfind(e,&base->hb_base, helpertree_map_compare_func); if (retval) { re = *(struct Helpertree_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ helpertree_map_free_func(e); return re; } void helpertree_clear_statistics(struct Helpertree_Base_s *base) { if (!base) { return; } if (!base->hb_base) { return; } helpertree_map_destroy(base->hb_base); base->hb_base = 0; } libdwarf-20210528/dwarfdump/dwconf_using_functions.h0000644000175000017500000000304113743575426017427 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWCONF_USING_FUNCTIONS_H #define DWCONF_USING_FUNCTIONS_H #ifdef __cplusplus extern "C" { #endif int print_frames (Dwarf_Debug dbg,int want_eh, struct dwconf_s *, Dwarf_Die *, void **, void **,Dwarf_Error *); void printreg(Dwarf_Unsigned reg,struct dwconf_s *config_data); #ifdef __cplusplus } #endif #endif /* DWCONF_USING_FUNCTIONS_H */ libdwarf-20210528/dwarfdump/attr_formclass.list0000664000175000017500000002155314013312210016376 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include 0xffffffff DW_AT_abstract_origin DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_accessibility DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_addr_base DW_FORM_CLASS_ADDRPTR 0xffffffff DW_AT_address_class DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_alignment DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_allocated DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_artificial DW_FORM_CLASS_FLAG 0xffffffff DW_AT_associated DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_base_types DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_binary_scale DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_bit_offset DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_BLOCK DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_bit_size DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_BLOCK DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_bit_stride DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_byte_size DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_byte_stride DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_call_all_calls DW_FORM_CLASS_FLAG 0xffffffff DW_AT_call_all_source_calls DW_FORM_CLASS_FLAG 0xffffffff DW_AT_call_all_tail_calls DW_FORM_CLASS_FLAG 0xffffffff DW_AT_call_column DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_call_data_location DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_call_data_value DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_call_file DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_calling_convention DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_call_line DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_call_origin DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_call_parameter DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_call_pc DW_FORM_CLASS_ADDRESS 0xffffffff DW_AT_call_return_pc DW_FORM_CLASS_ADDRESS 0xffffffff DW_AT_call_tail_call DW_FORM_CLASS_FLAG 0xffffffff DW_AT_call_target DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_call_target_clobbered DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_call_value DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_common_reference DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_comp_dir DW_FORM_CLASS_STRING 0xffffffff DW_AT_const_expr DW_FORM_CLASS_FLAG 0xffffffff DW_AT_const_value DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_BLOCK DW_FORM_CLASS_STRING 0xffffffff DW_AT_containing_type DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_count DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_data_bit_offset DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_data_location DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_data_member_location DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_decimal_scale DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_decimal_sign DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_declaration DW_FORM_CLASS_FLAG 0xffffffff DW_AT_decl_column DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_decl_file DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_decl_line DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_defaulted DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_default_value 0xffffffff DW_AT_deleted DW_FORM_CLASS_FLAG 0xffffffff DW_AT_description DW_FORM_CLASS_STRING 0xffffffff DW_AT_digit_count DW_FORM_CLASS_CONSTANT /* DWARF2,3,4,5 */ 0xffffffff DW_AT_discr DW_FORM_CLASS_REFERENCE /* DWARF5 */ 0xffffffff DW_AT_discr_list DW_FORM_CLASS_BLOCK /* DWARF2,3,4,5 */ 0xffffffff DW_AT_discr_value DW_FORM_CLASS_CONSTANT /* An experiment in some DWARF4. Not DWARF2, nor 3 nor 5 Expect a DW_FORM_ref_sig8. */ 0xffffffff DW_AT_dwo_id DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_dwo_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_elemental DW_FORM_CLASS_FLAG /* DWARF1. Do not use */ 0xffffffff DW_AT_element_list 0xffffffff DW_AT_encoding DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_endianity DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_entry_pc DW_FORM_CLASS_ADDRESS DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_enum_class DW_FORM_CLASS_FLAG 0xffffffff DW_AT_explicit DW_FORM_CLASS_FLAG 0xffffffff DW_AT_export_symbols DW_FORM_CLASS_FLAG 0xffffffff DW_AT_extension DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_external DW_FORM_CLASS_FLAG 0xffffffff DW_AT_frame_base DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_friend DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_high_pc DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_ADDRESS 0xffffffff DW_AT_hi_user 0xffffffff DW_AT_identifier_case DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_import DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_inline DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_is_optional DW_FORM_CLASS_FLAG 0xffffffff DW_AT_language DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_linkage_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_location DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST DW_FORM_CLASS_LOCLISTPTR 0xffffffff DW_AT_loclists_base DW_FORM_CLASS_LOCLISTSPTR 0xffffffff DW_AT_lower_bound DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_low_pc DW_FORM_CLASS_ADDRESS 0xffffffff DW_AT_macro_info DW_FORM_CLASS_MACPTR 0xffffffff DW_AT_macros DW_FORM_CLASS_MACROPTR 0xffffffff DW_AT_main_subprogram DW_FORM_CLASS_STRING /* DWARF1, Reserved, unused */ 0xffffffff DW_AT_member 0xffffffff DW_AT_mutable DW_FORM_CLASS_FLAG 0xffffffff DW_AT_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_namelist_item DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_noreturn DW_FORM_CLASS_FLAG 0xffffffff DW_AT_object_pointer DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_ordering DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_picture_string DW_FORM_CLASS_STRING 0xffffffff DW_AT_priority DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_producer DW_FORM_CLASS_STRING 0xffffffff DW_AT_prototyped DW_FORM_CLASS_FLAG 0xffffffff DW_AT_pure DW_FORM_CLASS_FLAG 0xffffffff DW_AT_ranges DW_FORM_CLASS_RNGLIST DW_FORM_CLASS_RANGELISTPTR /* DWARF4 */ DW_FORM_CLASS_RNGLISTSPTR /* DWARF5 */ 0xffffffff DW_AT_rank DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_recursive DW_FORM_CLASS_FLAG 0xffffffff DW_AT_reference DW_FORM_CLASS_FLAG 0xffffffff DW_AT_return_addr DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_rnglists_base DW_FORM_CLASS_RNGLISTSPTR 0xffffffff DW_AT_rvalue_reference DW_FORM_CLASS_FLAG 0xffffffff DW_AT_segment DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_sibling DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_signature DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_small DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_specification DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_start_scope DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_RNGLIST 0xffffffff DW_AT_static_link DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_stmt_list DW_FORM_CLASS_LINEPTR 0xffffffff DW_AT_string_length DW_FORM_CLASS_BLOCK DW_FORM_CLASS_LOCLISTPTR 0xffffffff DW_AT_string_length_bit_size DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_string_length_byte_size DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_str_offsets_base DW_FORM_CLASS_STROFFSETSPTR 0xffffffff /* Not defined in DWARF 2,3,4, or 5. Probably was DWARF1 */ DW_AT_subscr_data 0xffffffff DW_AT_threads_scaled DW_FORM_CLASS_FLAG 0xffffffff DW_AT_trampoline DW_FORM_CLASS_REFERENCE DW_FORM_CLASS_ADDRESS DW_FORM_CLASS_FLAG DW_FORM_CLASS_STRING 0xffffffff DW_AT_type DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_upper_bound DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_REFERENCE 0xffffffff DW_AT_use_location DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff DW_AT_use_UTF8 DW_FORM_CLASS_FLAG 0xffffffff DW_AT_variable_parameter DW_FORM_CLASS_FLAG 0xffffffff DW_AT_virtuality DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_visibility DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_vtable_elem_location DW_FORM_CLASS_EXPRLOC DW_FORM_CLASS_LOCLIST 0xffffffff libdwarf-20210528/dwarfdump/ChangeLog20080000664000175000017500000001175413644370703014570 000000000000002008-12-30 David Anderson * tag_attr.list: Mark DW_AT_artificial as sensible on DW_TAG_variable. * dwarfdump.1: Document -N option to print .debug_ranges. * Makefile.in: add new source header files * dwarfdump.c: Implement -N to print .debug_ranges. * print_sections.c: Allow more flexible printing of function names for .debug_frame section. With -N, print .debug_ranges. * print_die.c: Print .debug_ranges details. * print_frames.c: Delete useless comment. * globals.h: Allow re-use of debug_ranges formatting code. * Makefile.in: Make the header dependency list more complete. * makename.h: Comment tweaked. 2008-12-08 David Anderson * print_die.c: the -M option now also prints the form number (after the form name). And -v prints the DIE abbreviation code, the index into the relevant abbreviation table. * globals.h: Removed unused global variable. * dwarfdump.c: Removed unused global variable. * dwarfdump.1: document -M and the new -v features. 2008-12-07 David Anderson * print_reloc.c (print_relocinfo): Removed unused local variable. 2008-11-19 David Anderson * globals.h: Added new boolean to support -M. * dwarfdump.1: Mentioning the -M option. * dwarfdump.c: Implementing -M, which has each attribute line show the name of the form. * print_die.c: Implementing -M option. 2008-10-12 David Anderson * dwarfdump.conf: Adding power pc register names and table size for use with -x abi=ppc . 2008-08-13 David Anderson * dwarfdump.1: When no options (just object files) present all sections print, now we say that. Renamed fields in synopsis for readability. 2008-06-23 David Anderson * print_reloc.c (print_reloc_information_64): Was testing sym_data_entry_count one place where sym_data_64_entry_count should have been tested. Thanks to Carlos Alberto Enciso for noticing. 2008-06-17 David Anderson * print_die.c: Add to dwarf_formstring failure message. * README: Correct email: the old sgi.com address is no longer correct. 2008-06-13 David Anderson * dwconf.c: Fix an off-by-one condition where we could index off the end of the cf_regs array in printing a register name. 2008-04-12 David Anderson * print_reloc.c: Verify stringtab exists and is large enough before indexing into it to get a string in printing relocations. (Providing default name "" so it's evident from the output that we used a default name string). 2008-04-09 David Anderson * print_sections.c (get_fde_proc_name): Initialize some local variables at declaration. The function is very slow and needs a replacement. * print_die.c: Fixes a typo in a comment. * dwarfdump.c: Added -n option to suppress function name search when printing FDEs. Current dwarfdump is n-squared at least getting those names, this is a bandage-type-workaround when there are so many FDEs the slowness is painful. * globals.h: Support for -n option. * print_frames.c: Support for -n option. 2008-04-08 David Anderson * dwarfdump.c: Added -H option for testing (it limits the run length). And the support for -H in printing DIEs. * globals.h: Added extern for -H option declaration. * print_sections.c: Added -H option support to limit frames printing. 2008-04-04 David Anderson * print_die.c (tag_tree_combination, tag_attr_combination): Ensure we do not index off the end of the -k checking arrays. * print_sections.c: Increase the size of a local variable,. 2008-03-03 David Anderson * dwarfdump.1: Add description of -ka option. * print_frames.h print_sections.c testesb.c print_die.c print_reloc.c dwarfdump.c tag_tree.c tag_attr.c esb.c esb.h makename.c dwconf.c makename.h dwconf.h globals.h print_frames.c: Change tabs to spaces with expand(1). 2008-03-03 David Anderson * print_die.c: Now check that DW_AT_decl_file and DW_AT_call_file indexes are valid and count instances of the attribute and errors found in it. * dwarfdump.c: With -ka and -ky now check that DW_AT_decl_file and DW_AT_call_file indexes are valid and warn if bad. Thanks to Carlos Alberto Enciso for the suggestion. * globals.h: Declare new fields for the DW_AT_decl_file DW_AT_call_file checks. 2008-02-26 David Anderson * print_die.c (get_attr_value): Print DW_AT_call_file, DW_AT_call_line, DW_AT_call_column nicely. libdwarf-20210528/dwarfdump/NEWS0000664000175000017500000003240114020536706013167 00000000000000March 5, 2021 "dwarfdump found no file !" is a message one might see in dwarfdump before March 2021. It means dwarfdump cannot find a dwarfdump.conf . For several months dwarfdump has required a dwarfdump.conf be present in one of the defined standard places. $HOME/dwarfdump.conf and $HOME/.dwarfdump.conf are good choices. dwarfdump.conf is in every release. In years past dwarfdump.conf was only required if printing frames, but now dwarfdump needs to know appropriate register names in a variety of situations, hence a dwarfdump.conf is needed. As of the March 6 2021 release the basic error for this case is "dwarfdump found no dwarfdump.conf file in any of the standard places!" February 15, 2021 dwarfdump given -ku now prints brief lists counting the uses of each TAG, each ATtribute, and each FORM at the end.. These new lists report on all standard and extension attributes and forms used in the object file. November 16, 2020 dwarfdump now prints DWARF expression ops on indivdidual lines which makes it much easier to read the contents of a DWARF expression. dwarfdump.conf now implements support of 'option: --format-expr-ops-joined' which gets you the older format without specifying --format-expr-ops-joined on the command line. May 23, 2020 dwarfdump now takes much less malloc() to work, as measured by valgrind --tool=massif and massif-visualizer. A dwarfdump run that did 2.2Gib of malloc/free before the changes now does 1.4GiB. If you add --suppress-de-alloc-tree to the dwarfdump options dwarfdump uses 1.1GB on the test run. December 24, 2018 Any - or -- option on the dwarfdump command line turns off the default set of things to print. So, for example, instead of 'dwarfdump -v a.out' or 'dwarfdump -x abi=mips a.out' (which do nothing) do 'dwarfdump -v -a a.out' or 'dwarfdump -f -x abi=mips a.out'. Or maybe 'dwarfdump a.out' suffices for you. Or use other print or check options depending on your needs. June 14, 2018 A small simplification of build options simplifies building across different environments. If your environment needs to use the non-standard elf_open() call instead of plain open() then at configure time do --enable-elf-open. May 17, 2017 Now dwarfdump understands both split-dwarf and COMDAT sections (it calls the section-groups 'Groups') so it is possible to properly print all such. A traditional DWARF2,3,4,5 consumer can ignore section groups. To print in more complicate situations the -x groupnumber=3 (3 as an example) lets you choose a specific group/comdat to print. Dwarfdump prints out a section-groupnumber table when appropriate a making it easy to know what groups are present. March 24, 2017 dwarfdump: Now argv[0] is checked before setting the program_name global variable. If it contains '/dwarfdump.O' that part of the string is shortened to '/dwarfdump'. Doing this removes a need for the regressiontests to use sed and shortens the regressiontests runtime on one machine from 77 minutes to 23 minutes. September 20, 2016 dwarfdump now frees all memory it used when it terminates normally. No malloc space left behind. It gets a clean report from valgrind --leak-check=full --show-leak-kinds=all May 5, 2016 By default dwarfdump sanitizes strings, so if a corrupted DWARF file has non-printable bytes in a string they are each turned into %xx (% followed by two hex digits for a single string character). This is safe for terminals to print and shows the actual value. The '-x nosanitizestrings' option turns off this feature so bytes are shown as printf and your system show them. The same format as uri style, but only using % on characters that may have bad effects if printed to a terminal (not, for example, space or tab characters). Nor are normal '%' in a string altered (in uri such would be turned to %25 or to %%). February 25, 2015 Copied dwgetopt.c dwgetopt.h from libdwarf so dwarfdump can use dwgetopt() and still build without necessarily having the libdwarfsource easily available. Some environments do not have a getopt() so copying dwgetopt.h,.h here ensures we have this functionality for everyone. January 08, 2015 dwarfdump does new checking. See options -kD -kG -ku -kuf. In addition, dwarfdump output can be written to a file without using redirection by using the new -O file= option. January 29, 2014 Now using dwarf_tsearch() so tsearch is available on every platform. November 17, 2012 Added new checking options. To get good relocation-handling dwarfdump now expects to read headers from libdwarf with the relocation numbers. That means building dwarfdump separate from the libdwarf source is no longer as useful as it was. It is best to build libdwarf and dwarfdump together for decent handling of relocatable objects. December 13, 2011 Now prints missing line table column number as 0 (now matching the DWARF spec), the previous practice of printing -1 was always wrong. And prints the DWARF3/4 new line table fields (when present). October 29, 2011 Added support for printing .debug_types (type unit) data. October 26, 2011 Added new features to Makefile.in and documented in README how to build dwarfdump with headers or libraries in non-standard places. October 23, 2011 By default the various places with string option values and file paths all use URI transformation on input and if the transformation does anything at all dwarfdump reports the input and transformed strings. This makes it easy to deal with strings and expressions and file paths that are difficult to express in a shell (or that getopt mangles). Options -q and -U give you control over this process. October 07, 2011 The -x abi=mips frame register abi in dwarfdump.conf is now usable with modern MIPS objects as well as old IRIX objects. There are other mips-* frame register setups described in dwarfdump.conf for anyone testing that nothing new has been added that conflicts with old IRIX/MIPS frame generation. June 04, 2011 Error checking is now distinct from section printing, making error checking (the -k options) much easier to work with on large objects. So compiler-created errors can be found, the error reporting now prints context information. March 29, 2011 Added many new correctness tests. Changed the format of various items (line data prints in a more compact form, numbers are more uniformly hexadecimal fixed length where that makes sense). All the source files are uniformly indented to a multiple of 4 characters and all intent-tabs in the source have been removed. Major logic changes involved changing error-reporting to be more detailed and adding new tests for incorrect DWARF. Now reports error summary by the compiler name, not just overall. January 26, 2010 Changed the default frame-data register names from MIPS to a generic set of registers. Try '-x abi=mips' to get the traditional old MIPS register naming. June 22, 2009 Added the -S option to dwarfdump. June 10, 2009 Moved the gennames.c code to libdwarf. May 4, 2009 Replaced awk source-generation of certain functions with new gennames.c code. Now we can print an object with an address_size that varies by compilation unit. April 4, 2009 Corrected aspects of the frame-printing by ensuring we pass all the information libdwarf needs for fully consistent behavior. Three newly defined libdwarf calls calls made to ensure that better behavior (specifically having dwarfdump consistently recognize when registers are the cfa, undefined-value or same-value pseudo registers). Updated dwarfdump.conf to set these same things consistently. Mar 22, 2009 The -f and -F flags no longer also imply -i (it just did not make sense to tie them (cannot recall why it might have been tied before). Mar 20, 2009 Moved print_* functions from print_sections.c to individual source files. Hopefully making the code a bit easier to read. Feb 16, 2009 Added the -C option. It is a sort of 'pedantic' option as it turns on warnings about certain commonly used non-standard tag->tag and tag->attr relationships. Added the tag_attr_ext.list tag_tree_ext.list files which define the 'common use' extensions. Feb 14, 2009 Added configure option --enable-nonstandardprintf which makes it easy to get printf of Dwarf_Unsigned (etc) types correct even for non-standard compilers. December 30, 2008 Now we print the .debug_ranges section (with -N) and the data for DW_AT_ranges (with -i). December 8, 2008 The -M option now causes printing of FORM details. And -v adds details about abbreviation 'indexes' into an abbreviation table (.debug_abbrev) providing more detail for folks debugging or improving their understanding of DWARF data. April 9, 2008 Added -H to limit the number of compilation-units/FDEs dwarfdump prints in one run. Added -n to eliminate function-name printing in .debug_frame output (with a large-enough debug_info section function-name printing is too slow). The function name printing will be fixed in another release. December 8, 2007 Had to add an ugly configure conditional as libelf has unconditional use of off64_t in recent libelf.h July 3, 2007 Now with -v dwarf expression blocks in frame operations are printed expanded out. July 2, 2007 Added a new abi -x abi=general usable for any cpu with up to 1000 registers. May 7, 2007 Sun Microsystems contributes new dwarf.h extensions and a new -G option to dwarfdump -i (so one can see the 'global' offset to DIEs). Thanks to Chris Quenelle of Sun. April 17, 2006 New -x name= -x abi= and configuration file enable sensible printing of a wide range of .debug_frame eh_frame correctly without recompiling dwarfdump or touching libdwarf.h or dwarf.h. March 29, 2005 Now handles DWARF3. For non-MIPS objects, the list of register names in print_sections.c is not appropriate, #define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES to turn off the MIPS names. December 1, 2005 Added new DWARF3 TAGs and ATtributes to the -k lists, clarified the -k reporting, and made the build more robust in the face of errors in the *.list relationship-spec-files. August 1, 2005 Now print_die.c deals with long loclists without a coredump. Added esb.h esb.c (and testesb.c for testing) to encapsulate getting space for possibly-long strings. Now print_die.c uses snprintf() not sprintf (hopefully this will not inconvenience anyone, snprintf() has been available on most systems for years now). Altered print of location lists a little bit - for better appearance. July 15, 2005 Now completely frees all allocated memory. Various routines were not calling dealloc() code and new libdwarf dealloc routines are now used where those are needed. Now prints DWARF3 .debug_pubtypes section (with -a or -y). The .debug_pubtypes section and SGI-specific .debug_typenames are equivalent so they are treated alike. Mar 21, 2005 The -f flag now prints only .debug_frame data. The .eh_frame section (GNU exceptions data) now prints with -F (not -a). Printing gcc 3.3 or 3.4 .eh_frame with zR augmentation does not work at this time, so do not use -F to print such an object. The line section print now prints a CU-DIE offset for each such DIEs line information. This makes it much easier to correctly associate -l (or -v -l) output with -v -v -l when debugging a faulty linetable in an executable. With -v -v -l (two -v) the output of line info continues to be a completely different format than zero or one -v, the two-v form showing the detailed line table opcodes. With g++ 3.3.3 one sees bad line addresses at times as the DW_LNE_set_address address for header files do not always get their relocations applied. I am told this is fixed in 3.4.x. Mar 18, 2005 In correcting printing of macro information the format of the macro (-m) output has changed substantially. Much more complete now. Still could use enhancement. Oct 28, 2004 Updated contact address in copyright: SGI moved 1/4 mile to a new address: 1500 Crittenden Lane. Oct 02, 2003 Now fully supports .debug_loc section. June 14, 2001 Now calling a new function dwarf_get_arange_cu_header_offset() in libdwarf and printing the returned cu header offset for aranges entries. Making it easier to track down internal errors in the dwarf2 data. Also added small other consistency checks, printing a message and exit()ing on error. April 14, 2000 The libdwarf copyright has changed to version 2.1 of the GNU Lesser General Public License. Anyone holding a version of libdwarf that was published before this new copyright is allowed to use the copyright published in that earlier libdwarf source on the earlier source or to use this new copyright on the earlier source, at their option. July 21, 1999 Added gnu extensions to the frame information printer and handling for egcs eh_frame printing. libdwarf changes mean this now can print little-endian object dwarf on a big-endian system and vice-versa. December, 1998 added dwarfdump to the dwarf public source distribution. June, 1994 libdwarf consumer interface changed completely so updated to match. May, 1993 Initial version of dwarfdump for dwarf version 2 written at sgi. libdwarf-20210528/dwarfdump/dwarf_names.c0000664000175000017500000032543714054205616015140 00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #include "dwarf.h" #include "libdwarf.h" /* ARGSUSED */ int dwarf_get_TAG_name (unsigned int val, const char ** s_out) { switch (val) { case DW_TAG_array_type: *s_out = "DW_TAG_array_type"; return DW_DLV_OK; case DW_TAG_class_type: *s_out = "DW_TAG_class_type"; return DW_DLV_OK; case DW_TAG_entry_point: *s_out = "DW_TAG_entry_point"; return DW_DLV_OK; case DW_TAG_enumeration_type: *s_out = "DW_TAG_enumeration_type"; return DW_DLV_OK; case DW_TAG_formal_parameter: *s_out = "DW_TAG_formal_parameter"; return DW_DLV_OK; case DW_TAG_imported_declaration: *s_out = "DW_TAG_imported_declaration"; return DW_DLV_OK; case DW_TAG_label: *s_out = "DW_TAG_label"; return DW_DLV_OK; case DW_TAG_lexical_block: *s_out = "DW_TAG_lexical_block"; return DW_DLV_OK; case DW_TAG_member: *s_out = "DW_TAG_member"; return DW_DLV_OK; case DW_TAG_pointer_type: *s_out = "DW_TAG_pointer_type"; return DW_DLV_OK; case DW_TAG_reference_type: *s_out = "DW_TAG_reference_type"; return DW_DLV_OK; case DW_TAG_compile_unit: *s_out = "DW_TAG_compile_unit"; return DW_DLV_OK; case DW_TAG_string_type: *s_out = "DW_TAG_string_type"; return DW_DLV_OK; case DW_TAG_structure_type: *s_out = "DW_TAG_structure_type"; return DW_DLV_OK; case DW_TAG_subroutine_type: *s_out = "DW_TAG_subroutine_type"; return DW_DLV_OK; case DW_TAG_typedef: *s_out = "DW_TAG_typedef"; return DW_DLV_OK; case DW_TAG_union_type: *s_out = "DW_TAG_union_type"; return DW_DLV_OK; case DW_TAG_unspecified_parameters: *s_out = "DW_TAG_unspecified_parameters"; return DW_DLV_OK; case DW_TAG_variant: *s_out = "DW_TAG_variant"; return DW_DLV_OK; case DW_TAG_common_block: *s_out = "DW_TAG_common_block"; return DW_DLV_OK; case DW_TAG_common_inclusion: *s_out = "DW_TAG_common_inclusion"; return DW_DLV_OK; case DW_TAG_inheritance: *s_out = "DW_TAG_inheritance"; return DW_DLV_OK; case DW_TAG_inlined_subroutine: *s_out = "DW_TAG_inlined_subroutine"; return DW_DLV_OK; case DW_TAG_module: *s_out = "DW_TAG_module"; return DW_DLV_OK; case DW_TAG_ptr_to_member_type: *s_out = "DW_TAG_ptr_to_member_type"; return DW_DLV_OK; case DW_TAG_set_type: *s_out = "DW_TAG_set_type"; return DW_DLV_OK; case DW_TAG_subrange_type: *s_out = "DW_TAG_subrange_type"; return DW_DLV_OK; case DW_TAG_with_stmt: *s_out = "DW_TAG_with_stmt"; return DW_DLV_OK; case DW_TAG_access_declaration: *s_out = "DW_TAG_access_declaration"; return DW_DLV_OK; case DW_TAG_base_type: *s_out = "DW_TAG_base_type"; return DW_DLV_OK; case DW_TAG_catch_block: *s_out = "DW_TAG_catch_block"; return DW_DLV_OK; case DW_TAG_const_type: *s_out = "DW_TAG_const_type"; return DW_DLV_OK; case DW_TAG_constant: *s_out = "DW_TAG_constant"; return DW_DLV_OK; case DW_TAG_enumerator: *s_out = "DW_TAG_enumerator"; return DW_DLV_OK; case DW_TAG_file_type: *s_out = "DW_TAG_file_type"; return DW_DLV_OK; case DW_TAG_friend: *s_out = "DW_TAG_friend"; return DW_DLV_OK; case DW_TAG_namelist: *s_out = "DW_TAG_namelist"; return DW_DLV_OK; case DW_TAG_namelist_item: *s_out = "DW_TAG_namelist_item"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2c. DW_TAG_namelist_items */ case DW_TAG_packed_type: *s_out = "DW_TAG_packed_type"; return DW_DLV_OK; case DW_TAG_subprogram: *s_out = "DW_TAG_subprogram"; return DW_DLV_OK; case DW_TAG_template_type_parameter: *s_out = "DW_TAG_template_type_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2f. DW_TAG_template_type_param */ case DW_TAG_template_value_parameter: *s_out = "DW_TAG_template_value_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x30. DW_TAG_template_value_param */ case DW_TAG_thrown_type: *s_out = "DW_TAG_thrown_type"; return DW_DLV_OK; case DW_TAG_try_block: *s_out = "DW_TAG_try_block"; return DW_DLV_OK; case DW_TAG_variant_part: *s_out = "DW_TAG_variant_part"; return DW_DLV_OK; case DW_TAG_variable: *s_out = "DW_TAG_variable"; return DW_DLV_OK; case DW_TAG_volatile_type: *s_out = "DW_TAG_volatile_type"; return DW_DLV_OK; case DW_TAG_dwarf_procedure: *s_out = "DW_TAG_dwarf_procedure"; return DW_DLV_OK; case DW_TAG_restrict_type: *s_out = "DW_TAG_restrict_type"; return DW_DLV_OK; case DW_TAG_interface_type: *s_out = "DW_TAG_interface_type"; return DW_DLV_OK; case DW_TAG_namespace: *s_out = "DW_TAG_namespace"; return DW_DLV_OK; case DW_TAG_imported_module: *s_out = "DW_TAG_imported_module"; return DW_DLV_OK; case DW_TAG_unspecified_type: *s_out = "DW_TAG_unspecified_type"; return DW_DLV_OK; case DW_TAG_partial_unit: *s_out = "DW_TAG_partial_unit"; return DW_DLV_OK; case DW_TAG_imported_unit: *s_out = "DW_TAG_imported_unit"; return DW_DLV_OK; case DW_TAG_mutable_type: *s_out = "DW_TAG_mutable_type"; return DW_DLV_OK; case DW_TAG_condition: *s_out = "DW_TAG_condition"; return DW_DLV_OK; case DW_TAG_shared_type: *s_out = "DW_TAG_shared_type"; return DW_DLV_OK; case DW_TAG_type_unit: *s_out = "DW_TAG_type_unit"; return DW_DLV_OK; case DW_TAG_rvalue_reference_type: *s_out = "DW_TAG_rvalue_reference_type"; return DW_DLV_OK; case DW_TAG_template_alias: *s_out = "DW_TAG_template_alias"; return DW_DLV_OK; case DW_TAG_coarray_type: *s_out = "DW_TAG_coarray_type"; return DW_DLV_OK; case DW_TAG_generic_subrange: *s_out = "DW_TAG_generic_subrange"; return DW_DLV_OK; case DW_TAG_dynamic_type: *s_out = "DW_TAG_dynamic_type"; return DW_DLV_OK; case DW_TAG_atomic_type: *s_out = "DW_TAG_atomic_type"; return DW_DLV_OK; case DW_TAG_call_site: *s_out = "DW_TAG_call_site"; return DW_DLV_OK; case DW_TAG_call_site_parameter: *s_out = "DW_TAG_call_site_parameter"; return DW_DLV_OK; case DW_TAG_skeleton_unit: *s_out = "DW_TAG_skeleton_unit"; return DW_DLV_OK; case DW_TAG_immutable_type: *s_out = "DW_TAG_immutable_type"; return DW_DLV_OK; case DW_TAG_lo_user: *s_out = "DW_TAG_lo_user"; return DW_DLV_OK; case DW_TAG_MIPS_loop: *s_out = "DW_TAG_MIPS_loop"; return DW_DLV_OK; case DW_TAG_HP_array_descriptor: *s_out = "DW_TAG_HP_array_descriptor"; return DW_DLV_OK; case DW_TAG_format_label: *s_out = "DW_TAG_format_label"; return DW_DLV_OK; case DW_TAG_function_template: *s_out = "DW_TAG_function_template"; return DW_DLV_OK; case DW_TAG_class_template: *s_out = "DW_TAG_class_template"; return DW_DLV_OK; case DW_TAG_GNU_BINCL: *s_out = "DW_TAG_GNU_BINCL"; return DW_DLV_OK; case DW_TAG_GNU_EINCL: *s_out = "DW_TAG_GNU_EINCL"; return DW_DLV_OK; case DW_TAG_GNU_template_template_parameter: *s_out = "DW_TAG_GNU_template_template_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x4106. DW_TAG_GNU_template_template_param */ case DW_TAG_GNU_template_parameter_pack: *s_out = "DW_TAG_GNU_template_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_formal_parameter_pack: *s_out = "DW_TAG_GNU_formal_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_call_site: *s_out = "DW_TAG_GNU_call_site"; return DW_DLV_OK; case DW_TAG_GNU_call_site_parameter: *s_out = "DW_TAG_GNU_call_site_parameter"; return DW_DLV_OK; case DW_TAG_SUN_function_template: *s_out = "DW_TAG_SUN_function_template"; return DW_DLV_OK; case DW_TAG_SUN_class_template: *s_out = "DW_TAG_SUN_class_template"; return DW_DLV_OK; case DW_TAG_SUN_struct_template: *s_out = "DW_TAG_SUN_struct_template"; return DW_DLV_OK; case DW_TAG_SUN_union_template: *s_out = "DW_TAG_SUN_union_template"; return DW_DLV_OK; case DW_TAG_SUN_indirect_inheritance: *s_out = "DW_TAG_SUN_indirect_inheritance"; return DW_DLV_OK; case DW_TAG_SUN_codeflags: *s_out = "DW_TAG_SUN_codeflags"; return DW_DLV_OK; case DW_TAG_SUN_memop_info: *s_out = "DW_TAG_SUN_memop_info"; return DW_DLV_OK; case DW_TAG_SUN_omp_child_func: *s_out = "DW_TAG_SUN_omp_child_func"; return DW_DLV_OK; case DW_TAG_SUN_rtti_descriptor: *s_out = "DW_TAG_SUN_rtti_descriptor"; return DW_DLV_OK; case DW_TAG_SUN_dtor_info: *s_out = "DW_TAG_SUN_dtor_info"; return DW_DLV_OK; case DW_TAG_SUN_dtor: *s_out = "DW_TAG_SUN_dtor"; return DW_DLV_OK; case DW_TAG_SUN_f90_interface: *s_out = "DW_TAG_SUN_f90_interface"; return DW_DLV_OK; case DW_TAG_SUN_fortran_vax_structure: *s_out = "DW_TAG_SUN_fortran_vax_structure"; return DW_DLV_OK; case DW_TAG_SUN_hi: *s_out = "DW_TAG_SUN_hi"; return DW_DLV_OK; case DW_TAG_ALTIUM_circ_type: *s_out = "DW_TAG_ALTIUM_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_mwa_circ_type: *s_out = "DW_TAG_ALTIUM_mwa_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rev_carry_type: *s_out = "DW_TAG_ALTIUM_rev_carry_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rom: *s_out = "DW_TAG_ALTIUM_rom"; return DW_DLV_OK; case DW_TAG_ghs_namespace: *s_out = "DW_TAG_ghs_namespace"; return DW_DLV_OK; case DW_TAG_ghs_using_namespace: *s_out = "DW_TAG_ghs_using_namespace"; return DW_DLV_OK; case DW_TAG_ghs_using_declaration: *s_out = "DW_TAG_ghs_using_declaration"; return DW_DLV_OK; case DW_TAG_ghs_template_templ_param: *s_out = "DW_TAG_ghs_template_templ_param"; return DW_DLV_OK; case DW_TAG_upc_shared_type: *s_out = "DW_TAG_upc_shared_type"; return DW_DLV_OK; case DW_TAG_upc_strict_type: *s_out = "DW_TAG_upc_strict_type"; return DW_DLV_OK; case DW_TAG_upc_relaxed_type: *s_out = "DW_TAG_upc_relaxed_type"; return DW_DLV_OK; case DW_TAG_PGI_kanji_type: *s_out = "DW_TAG_PGI_kanji_type"; return DW_DLV_OK; case DW_TAG_PGI_interface_block: *s_out = "DW_TAG_PGI_interface_block"; return DW_DLV_OK; case DW_TAG_BORLAND_property: *s_out = "DW_TAG_BORLAND_property"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_string: *s_out = "DW_TAG_BORLAND_Delphi_string"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_dynamic_array: *s_out = "DW_TAG_BORLAND_Delphi_dynamic_array"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_set: *s_out = "DW_TAG_BORLAND_Delphi_set"; return DW_DLV_OK; case DW_TAG_BORLAND_Delphi_variant: *s_out = "DW_TAG_BORLAND_Delphi_variant"; return DW_DLV_OK; case DW_TAG_hi_user: *s_out = "DW_TAG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_children_name (unsigned int val, const char ** s_out) { switch (val) { case DW_children_no: *s_out = "DW_children_no"; return DW_DLV_OK; case DW_children_yes: *s_out = "DW_children_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FORM_name (unsigned int val, const char ** s_out) { switch (val) { case DW_FORM_addr: *s_out = "DW_FORM_addr"; return DW_DLV_OK; case DW_FORM_block2: *s_out = "DW_FORM_block2"; return DW_DLV_OK; case DW_FORM_block4: *s_out = "DW_FORM_block4"; return DW_DLV_OK; case DW_FORM_data2: *s_out = "DW_FORM_data2"; return DW_DLV_OK; case DW_FORM_data4: *s_out = "DW_FORM_data4"; return DW_DLV_OK; case DW_FORM_data8: *s_out = "DW_FORM_data8"; return DW_DLV_OK; case DW_FORM_string: *s_out = "DW_FORM_string"; return DW_DLV_OK; case DW_FORM_block: *s_out = "DW_FORM_block"; return DW_DLV_OK; case DW_FORM_block1: *s_out = "DW_FORM_block1"; return DW_DLV_OK; case DW_FORM_data1: *s_out = "DW_FORM_data1"; return DW_DLV_OK; case DW_FORM_flag: *s_out = "DW_FORM_flag"; return DW_DLV_OK; case DW_FORM_sdata: *s_out = "DW_FORM_sdata"; return DW_DLV_OK; case DW_FORM_strp: *s_out = "DW_FORM_strp"; return DW_DLV_OK; case DW_FORM_udata: *s_out = "DW_FORM_udata"; return DW_DLV_OK; case DW_FORM_ref_addr: *s_out = "DW_FORM_ref_addr"; return DW_DLV_OK; case DW_FORM_ref1: *s_out = "DW_FORM_ref1"; return DW_DLV_OK; case DW_FORM_ref2: *s_out = "DW_FORM_ref2"; return DW_DLV_OK; case DW_FORM_ref4: *s_out = "DW_FORM_ref4"; return DW_DLV_OK; case DW_FORM_ref8: *s_out = "DW_FORM_ref8"; return DW_DLV_OK; case DW_FORM_ref_udata: *s_out = "DW_FORM_ref_udata"; return DW_DLV_OK; case DW_FORM_indirect: *s_out = "DW_FORM_indirect"; return DW_DLV_OK; case DW_FORM_sec_offset: *s_out = "DW_FORM_sec_offset"; return DW_DLV_OK; case DW_FORM_exprloc: *s_out = "DW_FORM_exprloc"; return DW_DLV_OK; case DW_FORM_flag_present: *s_out = "DW_FORM_flag_present"; return DW_DLV_OK; case DW_FORM_strx: *s_out = "DW_FORM_strx"; return DW_DLV_OK; case DW_FORM_addrx: *s_out = "DW_FORM_addrx"; return DW_DLV_OK; case DW_FORM_ref_sup4: *s_out = "DW_FORM_ref_sup4"; return DW_DLV_OK; case DW_FORM_strp_sup: *s_out = "DW_FORM_strp_sup"; return DW_DLV_OK; case DW_FORM_data16: *s_out = "DW_FORM_data16"; return DW_DLV_OK; case DW_FORM_line_strp: *s_out = "DW_FORM_line_strp"; return DW_DLV_OK; case DW_FORM_ref_sig8: *s_out = "DW_FORM_ref_sig8"; return DW_DLV_OK; case DW_FORM_implicit_const: *s_out = "DW_FORM_implicit_const"; return DW_DLV_OK; case DW_FORM_loclistx: *s_out = "DW_FORM_loclistx"; return DW_DLV_OK; case DW_FORM_rnglistx: *s_out = "DW_FORM_rnglistx"; return DW_DLV_OK; case DW_FORM_ref_sup8: *s_out = "DW_FORM_ref_sup8"; return DW_DLV_OK; case DW_FORM_strx1: *s_out = "DW_FORM_strx1"; return DW_DLV_OK; case DW_FORM_strx2: *s_out = "DW_FORM_strx2"; return DW_DLV_OK; case DW_FORM_strx3: *s_out = "DW_FORM_strx3"; return DW_DLV_OK; case DW_FORM_strx4: *s_out = "DW_FORM_strx4"; return DW_DLV_OK; case DW_FORM_addrx1: *s_out = "DW_FORM_addrx1"; return DW_DLV_OK; case DW_FORM_addrx2: *s_out = "DW_FORM_addrx2"; return DW_DLV_OK; case DW_FORM_addrx3: *s_out = "DW_FORM_addrx3"; return DW_DLV_OK; case DW_FORM_addrx4: *s_out = "DW_FORM_addrx4"; return DW_DLV_OK; case DW_FORM_GNU_addr_index: *s_out = "DW_FORM_GNU_addr_index"; return DW_DLV_OK; case DW_FORM_GNU_str_index: *s_out = "DW_FORM_GNU_str_index"; return DW_DLV_OK; case DW_FORM_GNU_ref_alt: *s_out = "DW_FORM_GNU_ref_alt"; return DW_DLV_OK; case DW_FORM_GNU_strp_alt: *s_out = "DW_FORM_GNU_strp_alt"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_AT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_AT_sibling: *s_out = "DW_AT_sibling"; return DW_DLV_OK; case DW_AT_location: *s_out = "DW_AT_location"; return DW_DLV_OK; case DW_AT_name: *s_out = "DW_AT_name"; return DW_DLV_OK; case DW_AT_ordering: *s_out = "DW_AT_ordering"; return DW_DLV_OK; case DW_AT_subscr_data: *s_out = "DW_AT_subscr_data"; return DW_DLV_OK; case DW_AT_byte_size: *s_out = "DW_AT_byte_size"; return DW_DLV_OK; case DW_AT_bit_offset: *s_out = "DW_AT_bit_offset"; return DW_DLV_OK; case DW_AT_bit_size: *s_out = "DW_AT_bit_size"; return DW_DLV_OK; case DW_AT_element_list: *s_out = "DW_AT_element_list"; return DW_DLV_OK; case DW_AT_stmt_list: *s_out = "DW_AT_stmt_list"; return DW_DLV_OK; case DW_AT_low_pc: *s_out = "DW_AT_low_pc"; return DW_DLV_OK; case DW_AT_high_pc: *s_out = "DW_AT_high_pc"; return DW_DLV_OK; case DW_AT_language: *s_out = "DW_AT_language"; return DW_DLV_OK; case DW_AT_member: *s_out = "DW_AT_member"; return DW_DLV_OK; case DW_AT_discr: *s_out = "DW_AT_discr"; return DW_DLV_OK; case DW_AT_discr_value: *s_out = "DW_AT_discr_value"; return DW_DLV_OK; case DW_AT_visibility: *s_out = "DW_AT_visibility"; return DW_DLV_OK; case DW_AT_import: *s_out = "DW_AT_import"; return DW_DLV_OK; case DW_AT_string_length: *s_out = "DW_AT_string_length"; return DW_DLV_OK; case DW_AT_common_reference: *s_out = "DW_AT_common_reference"; return DW_DLV_OK; case DW_AT_comp_dir: *s_out = "DW_AT_comp_dir"; return DW_DLV_OK; case DW_AT_const_value: *s_out = "DW_AT_const_value"; return DW_DLV_OK; case DW_AT_containing_type: *s_out = "DW_AT_containing_type"; return DW_DLV_OK; case DW_AT_default_value: *s_out = "DW_AT_default_value"; return DW_DLV_OK; case DW_AT_inline: *s_out = "DW_AT_inline"; return DW_DLV_OK; case DW_AT_is_optional: *s_out = "DW_AT_is_optional"; return DW_DLV_OK; case DW_AT_lower_bound: *s_out = "DW_AT_lower_bound"; return DW_DLV_OK; case DW_AT_producer: *s_out = "DW_AT_producer"; return DW_DLV_OK; case DW_AT_prototyped: *s_out = "DW_AT_prototyped"; return DW_DLV_OK; case DW_AT_return_addr: *s_out = "DW_AT_return_addr"; return DW_DLV_OK; case DW_AT_start_scope: *s_out = "DW_AT_start_scope"; return DW_DLV_OK; case DW_AT_bit_stride: *s_out = "DW_AT_bit_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2e. DW_AT_stride_size */ case DW_AT_upper_bound: *s_out = "DW_AT_upper_bound"; return DW_DLV_OK; case DW_AT_abstract_origin: *s_out = "DW_AT_abstract_origin"; return DW_DLV_OK; case DW_AT_accessibility: *s_out = "DW_AT_accessibility"; return DW_DLV_OK; case DW_AT_address_class: *s_out = "DW_AT_address_class"; return DW_DLV_OK; case DW_AT_artificial: *s_out = "DW_AT_artificial"; return DW_DLV_OK; case DW_AT_base_types: *s_out = "DW_AT_base_types"; return DW_DLV_OK; case DW_AT_calling_convention: *s_out = "DW_AT_calling_convention"; return DW_DLV_OK; case DW_AT_count: *s_out = "DW_AT_count"; return DW_DLV_OK; case DW_AT_data_member_location: *s_out = "DW_AT_data_member_location"; return DW_DLV_OK; case DW_AT_decl_column: *s_out = "DW_AT_decl_column"; return DW_DLV_OK; case DW_AT_decl_file: *s_out = "DW_AT_decl_file"; return DW_DLV_OK; case DW_AT_decl_line: *s_out = "DW_AT_decl_line"; return DW_DLV_OK; case DW_AT_declaration: *s_out = "DW_AT_declaration"; return DW_DLV_OK; case DW_AT_discr_list: *s_out = "DW_AT_discr_list"; return DW_DLV_OK; case DW_AT_encoding: *s_out = "DW_AT_encoding"; return DW_DLV_OK; case DW_AT_external: *s_out = "DW_AT_external"; return DW_DLV_OK; case DW_AT_frame_base: *s_out = "DW_AT_frame_base"; return DW_DLV_OK; case DW_AT_friend: *s_out = "DW_AT_friend"; return DW_DLV_OK; case DW_AT_identifier_case: *s_out = "DW_AT_identifier_case"; return DW_DLV_OK; case DW_AT_macro_info: *s_out = "DW_AT_macro_info"; return DW_DLV_OK; case DW_AT_namelist_item: *s_out = "DW_AT_namelist_item"; return DW_DLV_OK; case DW_AT_priority: *s_out = "DW_AT_priority"; return DW_DLV_OK; case DW_AT_segment: *s_out = "DW_AT_segment"; return DW_DLV_OK; case DW_AT_specification: *s_out = "DW_AT_specification"; return DW_DLV_OK; case DW_AT_static_link: *s_out = "DW_AT_static_link"; return DW_DLV_OK; case DW_AT_type: *s_out = "DW_AT_type"; return DW_DLV_OK; case DW_AT_use_location: *s_out = "DW_AT_use_location"; return DW_DLV_OK; case DW_AT_variable_parameter: *s_out = "DW_AT_variable_parameter"; return DW_DLV_OK; case DW_AT_virtuality: *s_out = "DW_AT_virtuality"; return DW_DLV_OK; case DW_AT_vtable_elem_location: *s_out = "DW_AT_vtable_elem_location"; return DW_DLV_OK; case DW_AT_allocated: *s_out = "DW_AT_allocated"; return DW_DLV_OK; case DW_AT_associated: *s_out = "DW_AT_associated"; return DW_DLV_OK; case DW_AT_data_location: *s_out = "DW_AT_data_location"; return DW_DLV_OK; case DW_AT_byte_stride: *s_out = "DW_AT_byte_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x51. DW_AT_stride */ case DW_AT_entry_pc: *s_out = "DW_AT_entry_pc"; return DW_DLV_OK; case DW_AT_use_UTF8: *s_out = "DW_AT_use_UTF8"; return DW_DLV_OK; case DW_AT_extension: *s_out = "DW_AT_extension"; return DW_DLV_OK; case DW_AT_ranges: *s_out = "DW_AT_ranges"; return DW_DLV_OK; case DW_AT_trampoline: *s_out = "DW_AT_trampoline"; return DW_DLV_OK; case DW_AT_call_column: *s_out = "DW_AT_call_column"; return DW_DLV_OK; case DW_AT_call_file: *s_out = "DW_AT_call_file"; return DW_DLV_OK; case DW_AT_call_line: *s_out = "DW_AT_call_line"; return DW_DLV_OK; case DW_AT_description: *s_out = "DW_AT_description"; return DW_DLV_OK; case DW_AT_binary_scale: *s_out = "DW_AT_binary_scale"; return DW_DLV_OK; case DW_AT_decimal_scale: *s_out = "DW_AT_decimal_scale"; return DW_DLV_OK; case DW_AT_small: *s_out = "DW_AT_small"; return DW_DLV_OK; case DW_AT_decimal_sign: *s_out = "DW_AT_decimal_sign"; return DW_DLV_OK; case DW_AT_digit_count: *s_out = "DW_AT_digit_count"; return DW_DLV_OK; case DW_AT_picture_string: *s_out = "DW_AT_picture_string"; return DW_DLV_OK; case DW_AT_mutable: *s_out = "DW_AT_mutable"; return DW_DLV_OK; case DW_AT_threads_scaled: *s_out = "DW_AT_threads_scaled"; return DW_DLV_OK; case DW_AT_explicit: *s_out = "DW_AT_explicit"; return DW_DLV_OK; case DW_AT_object_pointer: *s_out = "DW_AT_object_pointer"; return DW_DLV_OK; case DW_AT_endianity: *s_out = "DW_AT_endianity"; return DW_DLV_OK; case DW_AT_elemental: *s_out = "DW_AT_elemental"; return DW_DLV_OK; case DW_AT_pure: *s_out = "DW_AT_pure"; return DW_DLV_OK; case DW_AT_recursive: *s_out = "DW_AT_recursive"; return DW_DLV_OK; case DW_AT_signature: *s_out = "DW_AT_signature"; return DW_DLV_OK; case DW_AT_main_subprogram: *s_out = "DW_AT_main_subprogram"; return DW_DLV_OK; case DW_AT_data_bit_offset: *s_out = "DW_AT_data_bit_offset"; return DW_DLV_OK; case DW_AT_const_expr: *s_out = "DW_AT_const_expr"; return DW_DLV_OK; case DW_AT_enum_class: *s_out = "DW_AT_enum_class"; return DW_DLV_OK; case DW_AT_linkage_name: *s_out = "DW_AT_linkage_name"; return DW_DLV_OK; case DW_AT_string_length_bit_size: *s_out = "DW_AT_string_length_bit_size"; return DW_DLV_OK; case DW_AT_string_length_byte_size: *s_out = "DW_AT_string_length_byte_size"; return DW_DLV_OK; case DW_AT_rank: *s_out = "DW_AT_rank"; return DW_DLV_OK; case DW_AT_str_offsets_base: *s_out = "DW_AT_str_offsets_base"; return DW_DLV_OK; case DW_AT_addr_base: *s_out = "DW_AT_addr_base"; return DW_DLV_OK; case DW_AT_rnglists_base: *s_out = "DW_AT_rnglists_base"; return DW_DLV_OK; case DW_AT_dwo_id: *s_out = "DW_AT_dwo_id"; return DW_DLV_OK; case DW_AT_dwo_name: *s_out = "DW_AT_dwo_name"; return DW_DLV_OK; case DW_AT_reference: *s_out = "DW_AT_reference"; return DW_DLV_OK; case DW_AT_rvalue_reference: *s_out = "DW_AT_rvalue_reference"; return DW_DLV_OK; case DW_AT_macros: *s_out = "DW_AT_macros"; return DW_DLV_OK; case DW_AT_call_all_calls: *s_out = "DW_AT_call_all_calls"; return DW_DLV_OK; case DW_AT_call_all_source_calls: *s_out = "DW_AT_call_all_source_calls"; return DW_DLV_OK; case DW_AT_call_all_tail_calls: *s_out = "DW_AT_call_all_tail_calls"; return DW_DLV_OK; case DW_AT_call_return_pc: *s_out = "DW_AT_call_return_pc"; return DW_DLV_OK; case DW_AT_call_value: *s_out = "DW_AT_call_value"; return DW_DLV_OK; case DW_AT_call_origin: *s_out = "DW_AT_call_origin"; return DW_DLV_OK; case DW_AT_call_parameter: *s_out = "DW_AT_call_parameter"; return DW_DLV_OK; case DW_AT_call_pc: *s_out = "DW_AT_call_pc"; return DW_DLV_OK; case DW_AT_call_tail_call: *s_out = "DW_AT_call_tail_call"; return DW_DLV_OK; case DW_AT_call_target: *s_out = "DW_AT_call_target"; return DW_DLV_OK; case DW_AT_call_target_clobbered: *s_out = "DW_AT_call_target_clobbered"; return DW_DLV_OK; case DW_AT_call_data_location: *s_out = "DW_AT_call_data_location"; return DW_DLV_OK; case DW_AT_call_data_value: *s_out = "DW_AT_call_data_value"; return DW_DLV_OK; case DW_AT_noreturn: *s_out = "DW_AT_noreturn"; return DW_DLV_OK; case DW_AT_alignment: *s_out = "DW_AT_alignment"; return DW_DLV_OK; case DW_AT_export_symbols: *s_out = "DW_AT_export_symbols"; return DW_DLV_OK; case DW_AT_deleted: *s_out = "DW_AT_deleted"; return DW_DLV_OK; case DW_AT_defaulted: *s_out = "DW_AT_defaulted"; return DW_DLV_OK; case DW_AT_loclists_base: *s_out = "DW_AT_loclists_base"; return DW_DLV_OK; case DW_AT_ghs_namespace_alias: *s_out = "DW_AT_ghs_namespace_alias"; return DW_DLV_OK; case DW_AT_ghs_using_namespace: *s_out = "DW_AT_ghs_using_namespace"; return DW_DLV_OK; case DW_AT_ghs_using_declaration: *s_out = "DW_AT_ghs_using_declaration"; return DW_DLV_OK; case DW_AT_HP_block_index: *s_out = "DW_AT_HP_block_index"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ case DW_AT_MIPS_fde: *s_out = "DW_AT_MIPS_fde"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2001. DW_AT_HP_unmodifiable */ /* Skipping alternate spelling of value 0x2001. DW_AT_CPQ_discontig_ranges */ case DW_AT_MIPS_loop_begin: *s_out = "DW_AT_MIPS_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2002. DW_AT_CPQ_semantic_events */ case DW_AT_MIPS_tail_loop_begin: *s_out = "DW_AT_MIPS_tail_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2003. DW_AT_CPQ_split_lifetimes_var */ case DW_AT_MIPS_epilog_begin: *s_out = "DW_AT_MIPS_epilog_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ case DW_AT_MIPS_loop_unroll_factor: *s_out = "DW_AT_MIPS_loop_unroll_factor"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2005. DW_AT_HP_prologue */ /* Skipping alternate spelling of value 0x2005. DW_AT_CPQ_prologue_length */ case DW_AT_MIPS_software_pipeline_depth: *s_out = "DW_AT_MIPS_software_pipeline_depth"; return DW_DLV_OK; case DW_AT_MIPS_linkage_name: *s_out = "DW_AT_MIPS_linkage_name"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2007. DW_AT_ghs_mangled */ case DW_AT_MIPS_stride: *s_out = "DW_AT_MIPS_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2008. DW_AT_HP_epilogue */ case DW_AT_MIPS_abstract_name: *s_out = "DW_AT_MIPS_abstract_name"; return DW_DLV_OK; case DW_AT_MIPS_clone_origin: *s_out = "DW_AT_MIPS_clone_origin"; return DW_DLV_OK; case DW_AT_MIPS_has_inlines: *s_out = "DW_AT_MIPS_has_inlines"; return DW_DLV_OK; case DW_AT_MIPS_stride_byte: *s_out = "DW_AT_MIPS_stride_byte"; return DW_DLV_OK; case DW_AT_MIPS_stride_elem: *s_out = "DW_AT_MIPS_stride_elem"; return DW_DLV_OK; case DW_AT_MIPS_ptr_dopetype: *s_out = "DW_AT_MIPS_ptr_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_allocatable_dopetype: *s_out = "DW_AT_MIPS_allocatable_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_assumed_shape_dopetype: *s_out = "DW_AT_MIPS_assumed_shape_dopetype"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2010. DW_AT_HP_actuals_stmt_list */ case DW_AT_MIPS_assumed_size: *s_out = "DW_AT_MIPS_assumed_size"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2011. DW_AT_HP_proc_per_section */ case DW_AT_HP_raw_data_ptr: *s_out = "DW_AT_HP_raw_data_ptr"; return DW_DLV_OK; case DW_AT_HP_pass_by_reference: *s_out = "DW_AT_HP_pass_by_reference"; return DW_DLV_OK; case DW_AT_HP_opt_level: *s_out = "DW_AT_HP_opt_level"; return DW_DLV_OK; case DW_AT_HP_prof_version_id: *s_out = "DW_AT_HP_prof_version_id"; return DW_DLV_OK; case DW_AT_HP_opt_flags: *s_out = "DW_AT_HP_opt_flags"; return DW_DLV_OK; case DW_AT_HP_cold_region_low_pc: *s_out = "DW_AT_HP_cold_region_low_pc"; return DW_DLV_OK; case DW_AT_HP_cold_region_high_pc: *s_out = "DW_AT_HP_cold_region_high_pc"; return DW_DLV_OK; case DW_AT_HP_all_variables_modifiable: *s_out = "DW_AT_HP_all_variables_modifiable"; return DW_DLV_OK; case DW_AT_HP_linkage_name: *s_out = "DW_AT_HP_linkage_name"; return DW_DLV_OK; case DW_AT_HP_prof_flags: *s_out = "DW_AT_HP_prof_flags"; return DW_DLV_OK; case DW_AT_HP_unit_name: *s_out = "DW_AT_HP_unit_name"; return DW_DLV_OK; case DW_AT_HP_unit_size: *s_out = "DW_AT_HP_unit_size"; return DW_DLV_OK; case DW_AT_HP_widened_byte_size: *s_out = "DW_AT_HP_widened_byte_size"; return DW_DLV_OK; case DW_AT_HP_definition_points: *s_out = "DW_AT_HP_definition_points"; return DW_DLV_OK; case DW_AT_HP_default_location: *s_out = "DW_AT_HP_default_location"; return DW_DLV_OK; case DW_AT_INTEL_other_endian: *s_out = "DW_AT_INTEL_other_endian"; return DW_DLV_OK; case DW_AT_HP_is_result_param: *s_out = "DW_AT_HP_is_result_param"; return DW_DLV_OK; case DW_AT_ghs_rsm: *s_out = "DW_AT_ghs_rsm"; return DW_DLV_OK; case DW_AT_ghs_frsm: *s_out = "DW_AT_ghs_frsm"; return DW_DLV_OK; case DW_AT_ghs_frames: *s_out = "DW_AT_ghs_frames"; return DW_DLV_OK; case DW_AT_ghs_rso: *s_out = "DW_AT_ghs_rso"; return DW_DLV_OK; case DW_AT_ghs_subcpu: *s_out = "DW_AT_ghs_subcpu"; return DW_DLV_OK; case DW_AT_ghs_lbrace_line: *s_out = "DW_AT_ghs_lbrace_line"; return DW_DLV_OK; case DW_AT_sf_names: *s_out = "DW_AT_sf_names"; return DW_DLV_OK; case DW_AT_src_info: *s_out = "DW_AT_src_info"; return DW_DLV_OK; case DW_AT_mac_info: *s_out = "DW_AT_mac_info"; return DW_DLV_OK; case DW_AT_src_coords: *s_out = "DW_AT_src_coords"; return DW_DLV_OK; case DW_AT_body_begin: *s_out = "DW_AT_body_begin"; return DW_DLV_OK; case DW_AT_body_end: *s_out = "DW_AT_body_end"; return DW_DLV_OK; case DW_AT_GNU_vector: *s_out = "DW_AT_GNU_vector"; return DW_DLV_OK; case DW_AT_GNU_guarded_by: *s_out = "DW_AT_GNU_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded_by: *s_out = "DW_AT_GNU_pt_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_guarded: *s_out = "DW_AT_GNU_guarded"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded: *s_out = "DW_AT_GNU_pt_guarded"; return DW_DLV_OK; case DW_AT_GNU_locks_excluded: *s_out = "DW_AT_GNU_locks_excluded"; return DW_DLV_OK; case DW_AT_GNU_exclusive_locks_required: *s_out = "DW_AT_GNU_exclusive_locks_required"; return DW_DLV_OK; case DW_AT_GNU_shared_locks_required: *s_out = "DW_AT_GNU_shared_locks_required"; return DW_DLV_OK; case DW_AT_GNU_odr_signature: *s_out = "DW_AT_GNU_odr_signature"; return DW_DLV_OK; case DW_AT_GNU_template_name: *s_out = "DW_AT_GNU_template_name"; return DW_DLV_OK; case DW_AT_GNU_call_site_value: *s_out = "DW_AT_GNU_call_site_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_data_value: *s_out = "DW_AT_GNU_call_site_data_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_target: *s_out = "DW_AT_GNU_call_site_target"; return DW_DLV_OK; case DW_AT_GNU_call_site_target_clobbered: *s_out = "DW_AT_GNU_call_site_target_clobbered"; return DW_DLV_OK; case DW_AT_GNU_tail_call: *s_out = "DW_AT_GNU_tail_call"; return DW_DLV_OK; case DW_AT_GNU_all_tail_call_sites: *s_out = "DW_AT_GNU_all_tail_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_call_sites: *s_out = "DW_AT_GNU_all_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_source_call_sites: *s_out = "DW_AT_GNU_all_source_call_sites"; return DW_DLV_OK; case DW_AT_GNU_macros: *s_out = "DW_AT_GNU_macros"; return DW_DLV_OK; case DW_AT_GNU_deleted: *s_out = "DW_AT_GNU_deleted"; return DW_DLV_OK; case DW_AT_GNU_dwo_name: *s_out = "DW_AT_GNU_dwo_name"; return DW_DLV_OK; case DW_AT_GNU_dwo_id: *s_out = "DW_AT_GNU_dwo_id"; return DW_DLV_OK; case DW_AT_GNU_ranges_base: *s_out = "DW_AT_GNU_ranges_base"; return DW_DLV_OK; case DW_AT_GNU_addr_base: *s_out = "DW_AT_GNU_addr_base"; return DW_DLV_OK; case DW_AT_GNU_pubnames: *s_out = "DW_AT_GNU_pubnames"; return DW_DLV_OK; case DW_AT_GNU_pubtypes: *s_out = "DW_AT_GNU_pubtypes"; return DW_DLV_OK; case DW_AT_GNU_discriminator: *s_out = "DW_AT_GNU_discriminator"; return DW_DLV_OK; case DW_AT_GNU_locviews: *s_out = "DW_AT_GNU_locviews"; return DW_DLV_OK; case DW_AT_GNU_entry_view: *s_out = "DW_AT_GNU_entry_view"; return DW_DLV_OK; case DW_AT_SUN_template: *s_out = "DW_AT_SUN_template"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2201. DW_AT_VMS_rtnbeg_pd_address */ case DW_AT_SUN_alignment: *s_out = "DW_AT_SUN_alignment"; return DW_DLV_OK; case DW_AT_SUN_vtable: *s_out = "DW_AT_SUN_vtable"; return DW_DLV_OK; case DW_AT_SUN_count_guarantee: *s_out = "DW_AT_SUN_count_guarantee"; return DW_DLV_OK; case DW_AT_SUN_command_line: *s_out = "DW_AT_SUN_command_line"; return DW_DLV_OK; case DW_AT_SUN_vbase: *s_out = "DW_AT_SUN_vbase"; return DW_DLV_OK; case DW_AT_SUN_compile_options: *s_out = "DW_AT_SUN_compile_options"; return DW_DLV_OK; case DW_AT_SUN_language: *s_out = "DW_AT_SUN_language"; return DW_DLV_OK; case DW_AT_SUN_browser_file: *s_out = "DW_AT_SUN_browser_file"; return DW_DLV_OK; case DW_AT_SUN_vtable_abi: *s_out = "DW_AT_SUN_vtable_abi"; return DW_DLV_OK; case DW_AT_SUN_func_offsets: *s_out = "DW_AT_SUN_func_offsets"; return DW_DLV_OK; case DW_AT_SUN_cf_kind: *s_out = "DW_AT_SUN_cf_kind"; return DW_DLV_OK; case DW_AT_SUN_vtable_index: *s_out = "DW_AT_SUN_vtable_index"; return DW_DLV_OK; case DW_AT_SUN_omp_tpriv_addr: *s_out = "DW_AT_SUN_omp_tpriv_addr"; return DW_DLV_OK; case DW_AT_SUN_omp_child_func: *s_out = "DW_AT_SUN_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_func_offset: *s_out = "DW_AT_SUN_func_offset"; return DW_DLV_OK; case DW_AT_SUN_memop_type_ref: *s_out = "DW_AT_SUN_memop_type_ref"; return DW_DLV_OK; case DW_AT_SUN_profile_id: *s_out = "DW_AT_SUN_profile_id"; return DW_DLV_OK; case DW_AT_SUN_memop_signature: *s_out = "DW_AT_SUN_memop_signature"; return DW_DLV_OK; case DW_AT_SUN_obj_dir: *s_out = "DW_AT_SUN_obj_dir"; return DW_DLV_OK; case DW_AT_SUN_obj_file: *s_out = "DW_AT_SUN_obj_file"; return DW_DLV_OK; case DW_AT_SUN_original_name: *s_out = "DW_AT_SUN_original_name"; return DW_DLV_OK; case DW_AT_SUN_hwcprof_signature: *s_out = "DW_AT_SUN_hwcprof_signature"; return DW_DLV_OK; case DW_AT_SUN_amd64_parmdump: *s_out = "DW_AT_SUN_amd64_parmdump"; return DW_DLV_OK; case DW_AT_SUN_part_link_name: *s_out = "DW_AT_SUN_part_link_name"; return DW_DLV_OK; case DW_AT_SUN_link_name: *s_out = "DW_AT_SUN_link_name"; return DW_DLV_OK; case DW_AT_SUN_pass_with_const: *s_out = "DW_AT_SUN_pass_with_const"; return DW_DLV_OK; case DW_AT_SUN_return_with_const: *s_out = "DW_AT_SUN_return_with_const"; return DW_DLV_OK; case DW_AT_SUN_import_by_name: *s_out = "DW_AT_SUN_import_by_name"; return DW_DLV_OK; case DW_AT_SUN_f90_pointer: *s_out = "DW_AT_SUN_f90_pointer"; return DW_DLV_OK; case DW_AT_SUN_pass_by_ref: *s_out = "DW_AT_SUN_pass_by_ref"; return DW_DLV_OK; case DW_AT_SUN_f90_allocatable: *s_out = "DW_AT_SUN_f90_allocatable"; return DW_DLV_OK; case DW_AT_SUN_f90_assumed_shape_array: *s_out = "DW_AT_SUN_f90_assumed_shape_array"; return DW_DLV_OK; case DW_AT_SUN_c_vla: *s_out = "DW_AT_SUN_c_vla"; return DW_DLV_OK; case DW_AT_SUN_return_value_ptr: *s_out = "DW_AT_SUN_return_value_ptr"; return DW_DLV_OK; case DW_AT_SUN_dtor_start: *s_out = "DW_AT_SUN_dtor_start"; return DW_DLV_OK; case DW_AT_SUN_dtor_length: *s_out = "DW_AT_SUN_dtor_length"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_initial: *s_out = "DW_AT_SUN_dtor_state_initial"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_final: *s_out = "DW_AT_SUN_dtor_state_final"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_deltas: *s_out = "DW_AT_SUN_dtor_state_deltas"; return DW_DLV_OK; case DW_AT_SUN_import_by_lname: *s_out = "DW_AT_SUN_import_by_lname"; return DW_DLV_OK; case DW_AT_SUN_f90_use_only: *s_out = "DW_AT_SUN_f90_use_only"; return DW_DLV_OK; case DW_AT_SUN_namelist_spec: *s_out = "DW_AT_SUN_namelist_spec"; return DW_DLV_OK; case DW_AT_SUN_is_omp_child_func: *s_out = "DW_AT_SUN_is_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_fortran_main_alias: *s_out = "DW_AT_SUN_fortran_main_alias"; return DW_DLV_OK; case DW_AT_SUN_fortran_based: *s_out = "DW_AT_SUN_fortran_based"; return DW_DLV_OK; case DW_AT_ALTIUM_loclist: *s_out = "DW_AT_ALTIUM_loclist"; return DW_DLV_OK; case DW_AT_use_GNAT_descriptive_type: *s_out = "DW_AT_use_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNAT_descriptive_type: *s_out = "DW_AT_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNU_numerator: *s_out = "DW_AT_GNU_numerator"; return DW_DLV_OK; case DW_AT_GNU_denominator: *s_out = "DW_AT_GNU_denominator"; return DW_DLV_OK; case DW_AT_GNU_bias: *s_out = "DW_AT_GNU_bias"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2305. DW_AT_GNU_bias */ case DW_AT_go_kind: *s_out = "DW_AT_go_kind"; return DW_DLV_OK; case DW_AT_go_key: *s_out = "DW_AT_go_key"; return DW_DLV_OK; case DW_AT_go_elem: *s_out = "DW_AT_go_elem"; return DW_DLV_OK; case DW_AT_go_embedded_field: *s_out = "DW_AT_go_embedded_field"; return DW_DLV_OK; case DW_AT_go_runtime_type: *s_out = "DW_AT_go_runtime_type"; return DW_DLV_OK; case DW_AT_upc_threads_scaled: *s_out = "DW_AT_upc_threads_scaled"; return DW_DLV_OK; case DW_AT_IBM_wsa_addr: *s_out = "DW_AT_IBM_wsa_addr"; return DW_DLV_OK; case DW_AT_IBM_home_location: *s_out = "DW_AT_IBM_home_location"; return DW_DLV_OK; case DW_AT_IBM_alt_srcview: *s_out = "DW_AT_IBM_alt_srcview"; return DW_DLV_OK; case DW_AT_PGI_lbase: *s_out = "DW_AT_PGI_lbase"; return DW_DLV_OK; case DW_AT_PGI_soffset: *s_out = "DW_AT_PGI_soffset"; return DW_DLV_OK; case DW_AT_PGI_lstride: *s_out = "DW_AT_PGI_lstride"; return DW_DLV_OK; case DW_AT_BORLAND_property_read: *s_out = "DW_AT_BORLAND_property_read"; return DW_DLV_OK; case DW_AT_BORLAND_property_write: *s_out = "DW_AT_BORLAND_property_write"; return DW_DLV_OK; case DW_AT_BORLAND_property_implements: *s_out = "DW_AT_BORLAND_property_implements"; return DW_DLV_OK; case DW_AT_BORLAND_property_index: *s_out = "DW_AT_BORLAND_property_index"; return DW_DLV_OK; case DW_AT_BORLAND_property_default: *s_out = "DW_AT_BORLAND_property_default"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_unit: *s_out = "DW_AT_BORLAND_Delphi_unit"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_class: *s_out = "DW_AT_BORLAND_Delphi_class"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_record: *s_out = "DW_AT_BORLAND_Delphi_record"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_metaclass: *s_out = "DW_AT_BORLAND_Delphi_metaclass"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_constructor: *s_out = "DW_AT_BORLAND_Delphi_constructor"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_destructor: *s_out = "DW_AT_BORLAND_Delphi_destructor"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_anonymous_method: *s_out = "DW_AT_BORLAND_Delphi_anonymous_method"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_interface: *s_out = "DW_AT_BORLAND_Delphi_interface"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_ABI: *s_out = "DW_AT_BORLAND_Delphi_ABI"; return DW_DLV_OK; case DW_AT_BORLAND_Delphi_frameptr: *s_out = "DW_AT_BORLAND_Delphi_frameptr"; return DW_DLV_OK; case DW_AT_BORLAND_closure: *s_out = "DW_AT_BORLAND_closure"; return DW_DLV_OK; case DW_AT_LLVM_include_path: *s_out = "DW_AT_LLVM_include_path"; return DW_DLV_OK; case DW_AT_LLVM_config_macros: *s_out = "DW_AT_LLVM_config_macros"; return DW_DLV_OK; case DW_AT_LLVM_sysroot: *s_out = "DW_AT_LLVM_sysroot"; return DW_DLV_OK; case DW_AT_LLVM_tag_offset: *s_out = "DW_AT_LLVM_tag_offset"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3e03. DW_AT_LLVM_apinotes */ case DW_AT_APPLE_optimized: *s_out = "DW_AT_APPLE_optimized"; return DW_DLV_OK; case DW_AT_APPLE_flags: *s_out = "DW_AT_APPLE_flags"; return DW_DLV_OK; case DW_AT_APPLE_isa: *s_out = "DW_AT_APPLE_isa"; return DW_DLV_OK; case DW_AT_APPLE_block: *s_out = "DW_AT_APPLE_block"; return DW_DLV_OK; case DW_AT_APPLE_major_runtime_vers: *s_out = "DW_AT_APPLE_major_runtime_vers"; return DW_DLV_OK; case DW_AT_APPLE_runtime_class: *s_out = "DW_AT_APPLE_runtime_class"; return DW_DLV_OK; case DW_AT_APPLE_omit_frame_ptr: *s_out = "DW_AT_APPLE_omit_frame_ptr"; return DW_DLV_OK; case DW_AT_APPLE_property_name: *s_out = "DW_AT_APPLE_property_name"; return DW_DLV_OK; case DW_AT_APPLE_property_getter: *s_out = "DW_AT_APPLE_property_getter"; return DW_DLV_OK; case DW_AT_APPLE_property_setter: *s_out = "DW_AT_APPLE_property_setter"; return DW_DLV_OK; case DW_AT_APPLE_property_attribute: *s_out = "DW_AT_APPLE_property_attribute"; return DW_DLV_OK; case DW_AT_APPLE_objc_complete_type: *s_out = "DW_AT_APPLE_objc_complete_type"; return DW_DLV_OK; case DW_AT_APPLE_property: *s_out = "DW_AT_APPLE_property"; return DW_DLV_OK; case DW_AT_APPLE_objc_direct: *s_out = "DW_AT_APPLE_objc_direct"; return DW_DLV_OK; case DW_AT_APPLE_sdk: *s_out = "DW_AT_APPLE_sdk"; return DW_DLV_OK; case DW_AT_hi_user: *s_out = "DW_AT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_OP_name (unsigned int val, const char ** s_out) { switch (val) { case DW_OP_addr: *s_out = "DW_OP_addr"; return DW_DLV_OK; case DW_OP_deref: *s_out = "DW_OP_deref"; return DW_DLV_OK; case DW_OP_const1u: *s_out = "DW_OP_const1u"; return DW_DLV_OK; case DW_OP_const1s: *s_out = "DW_OP_const1s"; return DW_DLV_OK; case DW_OP_const2u: *s_out = "DW_OP_const2u"; return DW_DLV_OK; case DW_OP_const2s: *s_out = "DW_OP_const2s"; return DW_DLV_OK; case DW_OP_const4u: *s_out = "DW_OP_const4u"; return DW_DLV_OK; case DW_OP_const4s: *s_out = "DW_OP_const4s"; return DW_DLV_OK; case DW_OP_const8u: *s_out = "DW_OP_const8u"; return DW_DLV_OK; case DW_OP_const8s: *s_out = "DW_OP_const8s"; return DW_DLV_OK; case DW_OP_constu: *s_out = "DW_OP_constu"; return DW_DLV_OK; case DW_OP_consts: *s_out = "DW_OP_consts"; return DW_DLV_OK; case DW_OP_dup: *s_out = "DW_OP_dup"; return DW_DLV_OK; case DW_OP_drop: *s_out = "DW_OP_drop"; return DW_DLV_OK; case DW_OP_over: *s_out = "DW_OP_over"; return DW_DLV_OK; case DW_OP_pick: *s_out = "DW_OP_pick"; return DW_DLV_OK; case DW_OP_swap: *s_out = "DW_OP_swap"; return DW_DLV_OK; case DW_OP_rot: *s_out = "DW_OP_rot"; return DW_DLV_OK; case DW_OP_xderef: *s_out = "DW_OP_xderef"; return DW_DLV_OK; case DW_OP_abs: *s_out = "DW_OP_abs"; return DW_DLV_OK; case DW_OP_and: *s_out = "DW_OP_and"; return DW_DLV_OK; case DW_OP_div: *s_out = "DW_OP_div"; return DW_DLV_OK; case DW_OP_minus: *s_out = "DW_OP_minus"; return DW_DLV_OK; case DW_OP_mod: *s_out = "DW_OP_mod"; return DW_DLV_OK; case DW_OP_mul: *s_out = "DW_OP_mul"; return DW_DLV_OK; case DW_OP_neg: *s_out = "DW_OP_neg"; return DW_DLV_OK; case DW_OP_not: *s_out = "DW_OP_not"; return DW_DLV_OK; case DW_OP_or: *s_out = "DW_OP_or"; return DW_DLV_OK; case DW_OP_plus: *s_out = "DW_OP_plus"; return DW_DLV_OK; case DW_OP_plus_uconst: *s_out = "DW_OP_plus_uconst"; return DW_DLV_OK; case DW_OP_shl: *s_out = "DW_OP_shl"; return DW_DLV_OK; case DW_OP_shr: *s_out = "DW_OP_shr"; return DW_DLV_OK; case DW_OP_shra: *s_out = "DW_OP_shra"; return DW_DLV_OK; case DW_OP_xor: *s_out = "DW_OP_xor"; return DW_DLV_OK; case DW_OP_bra: *s_out = "DW_OP_bra"; return DW_DLV_OK; case DW_OP_eq: *s_out = "DW_OP_eq"; return DW_DLV_OK; case DW_OP_ge: *s_out = "DW_OP_ge"; return DW_DLV_OK; case DW_OP_gt: *s_out = "DW_OP_gt"; return DW_DLV_OK; case DW_OP_le: *s_out = "DW_OP_le"; return DW_DLV_OK; case DW_OP_lt: *s_out = "DW_OP_lt"; return DW_DLV_OK; case DW_OP_ne: *s_out = "DW_OP_ne"; return DW_DLV_OK; case DW_OP_skip: *s_out = "DW_OP_skip"; return DW_DLV_OK; case DW_OP_lit0: *s_out = "DW_OP_lit0"; return DW_DLV_OK; case DW_OP_lit1: *s_out = "DW_OP_lit1"; return DW_DLV_OK; case DW_OP_lit2: *s_out = "DW_OP_lit2"; return DW_DLV_OK; case DW_OP_lit3: *s_out = "DW_OP_lit3"; return DW_DLV_OK; case DW_OP_lit4: *s_out = "DW_OP_lit4"; return DW_DLV_OK; case DW_OP_lit5: *s_out = "DW_OP_lit5"; return DW_DLV_OK; case DW_OP_lit6: *s_out = "DW_OP_lit6"; return DW_DLV_OK; case DW_OP_lit7: *s_out = "DW_OP_lit7"; return DW_DLV_OK; case DW_OP_lit8: *s_out = "DW_OP_lit8"; return DW_DLV_OK; case DW_OP_lit9: *s_out = "DW_OP_lit9"; return DW_DLV_OK; case DW_OP_lit10: *s_out = "DW_OP_lit10"; return DW_DLV_OK; case DW_OP_lit11: *s_out = "DW_OP_lit11"; return DW_DLV_OK; case DW_OP_lit12: *s_out = "DW_OP_lit12"; return DW_DLV_OK; case DW_OP_lit13: *s_out = "DW_OP_lit13"; return DW_DLV_OK; case DW_OP_lit14: *s_out = "DW_OP_lit14"; return DW_DLV_OK; case DW_OP_lit15: *s_out = "DW_OP_lit15"; return DW_DLV_OK; case DW_OP_lit16: *s_out = "DW_OP_lit16"; return DW_DLV_OK; case DW_OP_lit17: *s_out = "DW_OP_lit17"; return DW_DLV_OK; case DW_OP_lit18: *s_out = "DW_OP_lit18"; return DW_DLV_OK; case DW_OP_lit19: *s_out = "DW_OP_lit19"; return DW_DLV_OK; case DW_OP_lit20: *s_out = "DW_OP_lit20"; return DW_DLV_OK; case DW_OP_lit21: *s_out = "DW_OP_lit21"; return DW_DLV_OK; case DW_OP_lit22: *s_out = "DW_OP_lit22"; return DW_DLV_OK; case DW_OP_lit23: *s_out = "DW_OP_lit23"; return DW_DLV_OK; case DW_OP_lit24: *s_out = "DW_OP_lit24"; return DW_DLV_OK; case DW_OP_lit25: *s_out = "DW_OP_lit25"; return DW_DLV_OK; case DW_OP_lit26: *s_out = "DW_OP_lit26"; return DW_DLV_OK; case DW_OP_lit27: *s_out = "DW_OP_lit27"; return DW_DLV_OK; case DW_OP_lit28: *s_out = "DW_OP_lit28"; return DW_DLV_OK; case DW_OP_lit29: *s_out = "DW_OP_lit29"; return DW_DLV_OK; case DW_OP_lit30: *s_out = "DW_OP_lit30"; return DW_DLV_OK; case DW_OP_lit31: *s_out = "DW_OP_lit31"; return DW_DLV_OK; case DW_OP_reg0: *s_out = "DW_OP_reg0"; return DW_DLV_OK; case DW_OP_reg1: *s_out = "DW_OP_reg1"; return DW_DLV_OK; case DW_OP_reg2: *s_out = "DW_OP_reg2"; return DW_DLV_OK; case DW_OP_reg3: *s_out = "DW_OP_reg3"; return DW_DLV_OK; case DW_OP_reg4: *s_out = "DW_OP_reg4"; return DW_DLV_OK; case DW_OP_reg5: *s_out = "DW_OP_reg5"; return DW_DLV_OK; case DW_OP_reg6: *s_out = "DW_OP_reg6"; return DW_DLV_OK; case DW_OP_reg7: *s_out = "DW_OP_reg7"; return DW_DLV_OK; case DW_OP_reg8: *s_out = "DW_OP_reg8"; return DW_DLV_OK; case DW_OP_reg9: *s_out = "DW_OP_reg9"; return DW_DLV_OK; case DW_OP_reg10: *s_out = "DW_OP_reg10"; return DW_DLV_OK; case DW_OP_reg11: *s_out = "DW_OP_reg11"; return DW_DLV_OK; case DW_OP_reg12: *s_out = "DW_OP_reg12"; return DW_DLV_OK; case DW_OP_reg13: *s_out = "DW_OP_reg13"; return DW_DLV_OK; case DW_OP_reg14: *s_out = "DW_OP_reg14"; return DW_DLV_OK; case DW_OP_reg15: *s_out = "DW_OP_reg15"; return DW_DLV_OK; case DW_OP_reg16: *s_out = "DW_OP_reg16"; return DW_DLV_OK; case DW_OP_reg17: *s_out = "DW_OP_reg17"; return DW_DLV_OK; case DW_OP_reg18: *s_out = "DW_OP_reg18"; return DW_DLV_OK; case DW_OP_reg19: *s_out = "DW_OP_reg19"; return DW_DLV_OK; case DW_OP_reg20: *s_out = "DW_OP_reg20"; return DW_DLV_OK; case DW_OP_reg21: *s_out = "DW_OP_reg21"; return DW_DLV_OK; case DW_OP_reg22: *s_out = "DW_OP_reg22"; return DW_DLV_OK; case DW_OP_reg23: *s_out = "DW_OP_reg23"; return DW_DLV_OK; case DW_OP_reg24: *s_out = "DW_OP_reg24"; return DW_DLV_OK; case DW_OP_reg25: *s_out = "DW_OP_reg25"; return DW_DLV_OK; case DW_OP_reg26: *s_out = "DW_OP_reg26"; return DW_DLV_OK; case DW_OP_reg27: *s_out = "DW_OP_reg27"; return DW_DLV_OK; case DW_OP_reg28: *s_out = "DW_OP_reg28"; return DW_DLV_OK; case DW_OP_reg29: *s_out = "DW_OP_reg29"; return DW_DLV_OK; case DW_OP_reg30: *s_out = "DW_OP_reg30"; return DW_DLV_OK; case DW_OP_reg31: *s_out = "DW_OP_reg31"; return DW_DLV_OK; case DW_OP_breg0: *s_out = "DW_OP_breg0"; return DW_DLV_OK; case DW_OP_breg1: *s_out = "DW_OP_breg1"; return DW_DLV_OK; case DW_OP_breg2: *s_out = "DW_OP_breg2"; return DW_DLV_OK; case DW_OP_breg3: *s_out = "DW_OP_breg3"; return DW_DLV_OK; case DW_OP_breg4: *s_out = "DW_OP_breg4"; return DW_DLV_OK; case DW_OP_breg5: *s_out = "DW_OP_breg5"; return DW_DLV_OK; case DW_OP_breg6: *s_out = "DW_OP_breg6"; return DW_DLV_OK; case DW_OP_breg7: *s_out = "DW_OP_breg7"; return DW_DLV_OK; case DW_OP_breg8: *s_out = "DW_OP_breg8"; return DW_DLV_OK; case DW_OP_breg9: *s_out = "DW_OP_breg9"; return DW_DLV_OK; case DW_OP_breg10: *s_out = "DW_OP_breg10"; return DW_DLV_OK; case DW_OP_breg11: *s_out = "DW_OP_breg11"; return DW_DLV_OK; case DW_OP_breg12: *s_out = "DW_OP_breg12"; return DW_DLV_OK; case DW_OP_breg13: *s_out = "DW_OP_breg13"; return DW_DLV_OK; case DW_OP_breg14: *s_out = "DW_OP_breg14"; return DW_DLV_OK; case DW_OP_breg15: *s_out = "DW_OP_breg15"; return DW_DLV_OK; case DW_OP_breg16: *s_out = "DW_OP_breg16"; return DW_DLV_OK; case DW_OP_breg17: *s_out = "DW_OP_breg17"; return DW_DLV_OK; case DW_OP_breg18: *s_out = "DW_OP_breg18"; return DW_DLV_OK; case DW_OP_breg19: *s_out = "DW_OP_breg19"; return DW_DLV_OK; case DW_OP_breg20: *s_out = "DW_OP_breg20"; return DW_DLV_OK; case DW_OP_breg21: *s_out = "DW_OP_breg21"; return DW_DLV_OK; case DW_OP_breg22: *s_out = "DW_OP_breg22"; return DW_DLV_OK; case DW_OP_breg23: *s_out = "DW_OP_breg23"; return DW_DLV_OK; case DW_OP_breg24: *s_out = "DW_OP_breg24"; return DW_DLV_OK; case DW_OP_breg25: *s_out = "DW_OP_breg25"; return DW_DLV_OK; case DW_OP_breg26: *s_out = "DW_OP_breg26"; return DW_DLV_OK; case DW_OP_breg27: *s_out = "DW_OP_breg27"; return DW_DLV_OK; case DW_OP_breg28: *s_out = "DW_OP_breg28"; return DW_DLV_OK; case DW_OP_breg29: *s_out = "DW_OP_breg29"; return DW_DLV_OK; case DW_OP_breg30: *s_out = "DW_OP_breg30"; return DW_DLV_OK; case DW_OP_breg31: *s_out = "DW_OP_breg31"; return DW_DLV_OK; case DW_OP_regx: *s_out = "DW_OP_regx"; return DW_DLV_OK; case DW_OP_fbreg: *s_out = "DW_OP_fbreg"; return DW_DLV_OK; case DW_OP_bregx: *s_out = "DW_OP_bregx"; return DW_DLV_OK; case DW_OP_piece: *s_out = "DW_OP_piece"; return DW_DLV_OK; case DW_OP_deref_size: *s_out = "DW_OP_deref_size"; return DW_DLV_OK; case DW_OP_xderef_size: *s_out = "DW_OP_xderef_size"; return DW_DLV_OK; case DW_OP_nop: *s_out = "DW_OP_nop"; return DW_DLV_OK; case DW_OP_push_object_address: *s_out = "DW_OP_push_object_address"; return DW_DLV_OK; case DW_OP_call2: *s_out = "DW_OP_call2"; return DW_DLV_OK; case DW_OP_call4: *s_out = "DW_OP_call4"; return DW_DLV_OK; case DW_OP_call_ref: *s_out = "DW_OP_call_ref"; return DW_DLV_OK; case DW_OP_form_tls_address: *s_out = "DW_OP_form_tls_address"; return DW_DLV_OK; case DW_OP_call_frame_cfa: *s_out = "DW_OP_call_frame_cfa"; return DW_DLV_OK; case DW_OP_bit_piece: *s_out = "DW_OP_bit_piece"; return DW_DLV_OK; case DW_OP_implicit_value: *s_out = "DW_OP_implicit_value"; return DW_DLV_OK; case DW_OP_stack_value: *s_out = "DW_OP_stack_value"; return DW_DLV_OK; case DW_OP_implicit_pointer: *s_out = "DW_OP_implicit_pointer"; return DW_DLV_OK; case DW_OP_addrx: *s_out = "DW_OP_addrx"; return DW_DLV_OK; case DW_OP_constx: *s_out = "DW_OP_constx"; return DW_DLV_OK; case DW_OP_entry_value: *s_out = "DW_OP_entry_value"; return DW_DLV_OK; case DW_OP_const_type: *s_out = "DW_OP_const_type"; return DW_DLV_OK; case DW_OP_regval_type: *s_out = "DW_OP_regval_type"; return DW_DLV_OK; case DW_OP_deref_type: *s_out = "DW_OP_deref_type"; return DW_DLV_OK; case DW_OP_xderef_type: *s_out = "DW_OP_xderef_type"; return DW_DLV_OK; case DW_OP_convert: *s_out = "DW_OP_convert"; return DW_DLV_OK; case DW_OP_reinterpret: *s_out = "DW_OP_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_push_tls_address: *s_out = "DW_OP_GNU_push_tls_address"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xe0. DW_OP_lo_user */ /* Skipping alternate spelling of value 0xe0. DW_OP_HP_unknown */ case DW_OP_HP_is_value: *s_out = "DW_OP_HP_is_value"; return DW_DLV_OK; case DW_OP_HP_fltconst4: *s_out = "DW_OP_HP_fltconst4"; return DW_DLV_OK; case DW_OP_HP_fltconst8: *s_out = "DW_OP_HP_fltconst8"; return DW_DLV_OK; case DW_OP_HP_mod_range: *s_out = "DW_OP_HP_mod_range"; return DW_DLV_OK; case DW_OP_HP_unmod_range: *s_out = "DW_OP_HP_unmod_range"; return DW_DLV_OK; case DW_OP_HP_tls: *s_out = "DW_OP_HP_tls"; return DW_DLV_OK; case DW_OP_INTEL_bit_piece: *s_out = "DW_OP_INTEL_bit_piece"; return DW_DLV_OK; case DW_OP_WASM_location: *s_out = "DW_OP_WASM_location"; return DW_DLV_OK; case DW_OP_WASM_location_int: *s_out = "DW_OP_WASM_location_int"; return DW_DLV_OK; case DW_OP_GNU_uninit: *s_out = "DW_OP_GNU_uninit"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xf0. DW_OP_APPLE_uninit */ case DW_OP_GNU_encoded_addr: *s_out = "DW_OP_GNU_encoded_addr"; return DW_DLV_OK; case DW_OP_GNU_implicit_pointer: *s_out = "DW_OP_GNU_implicit_pointer"; return DW_DLV_OK; case DW_OP_GNU_entry_value: *s_out = "DW_OP_GNU_entry_value"; return DW_DLV_OK; case DW_OP_GNU_const_type: *s_out = "DW_OP_GNU_const_type"; return DW_DLV_OK; case DW_OP_GNU_regval_type: *s_out = "DW_OP_GNU_regval_type"; return DW_DLV_OK; case DW_OP_GNU_deref_type: *s_out = "DW_OP_GNU_deref_type"; return DW_DLV_OK; case DW_OP_GNU_convert: *s_out = "DW_OP_GNU_convert"; return DW_DLV_OK; case DW_OP_PGI_omp_thread_num: *s_out = "DW_OP_PGI_omp_thread_num"; return DW_DLV_OK; case DW_OP_GNU_reinterpret: *s_out = "DW_OP_GNU_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_parameter_ref: *s_out = "DW_OP_GNU_parameter_ref"; return DW_DLV_OK; case DW_OP_GNU_addr_index: *s_out = "DW_OP_GNU_addr_index"; return DW_DLV_OK; case DW_OP_GNU_const_index: *s_out = "DW_OP_GNU_const_index"; return DW_DLV_OK; case DW_OP_GNU_variable_value: *s_out = "DW_OP_GNU_variable_value"; return DW_DLV_OK; case DW_OP_hi_user: *s_out = "DW_OP_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ATE_address: *s_out = "DW_ATE_address"; return DW_DLV_OK; case DW_ATE_boolean: *s_out = "DW_ATE_boolean"; return DW_DLV_OK; case DW_ATE_complex_float: *s_out = "DW_ATE_complex_float"; return DW_DLV_OK; case DW_ATE_float: *s_out = "DW_ATE_float"; return DW_DLV_OK; case DW_ATE_signed: *s_out = "DW_ATE_signed"; return DW_DLV_OK; case DW_ATE_signed_char: *s_out = "DW_ATE_signed_char"; return DW_DLV_OK; case DW_ATE_unsigned: *s_out = "DW_ATE_unsigned"; return DW_DLV_OK; case DW_ATE_unsigned_char: *s_out = "DW_ATE_unsigned_char"; return DW_DLV_OK; case DW_ATE_imaginary_float: *s_out = "DW_ATE_imaginary_float"; return DW_DLV_OK; case DW_ATE_packed_decimal: *s_out = "DW_ATE_packed_decimal"; return DW_DLV_OK; case DW_ATE_numeric_string: *s_out = "DW_ATE_numeric_string"; return DW_DLV_OK; case DW_ATE_edited: *s_out = "DW_ATE_edited"; return DW_DLV_OK; case DW_ATE_signed_fixed: *s_out = "DW_ATE_signed_fixed"; return DW_DLV_OK; case DW_ATE_unsigned_fixed: *s_out = "DW_ATE_unsigned_fixed"; return DW_DLV_OK; case DW_ATE_decimal_float: *s_out = "DW_ATE_decimal_float"; return DW_DLV_OK; case DW_ATE_UTF: *s_out = "DW_ATE_UTF"; return DW_DLV_OK; case DW_ATE_UCS: *s_out = "DW_ATE_UCS"; return DW_DLV_OK; case DW_ATE_ASCII: *s_out = "DW_ATE_ASCII"; return DW_DLV_OK; case DW_ATE_ALTIUM_fract: *s_out = "DW_ATE_ALTIUM_fract"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_ATE_lo_user */ /* Skipping alternate spelling of value 0x80. DW_ATE_HP_float80 */ case DW_ATE_ALTIUM_accum: *s_out = "DW_ATE_ALTIUM_accum"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x81. DW_ATE_HP_complex_float80 */ case DW_ATE_HP_float128: *s_out = "DW_ATE_HP_float128"; return DW_DLV_OK; case DW_ATE_HP_complex_float128: *s_out = "DW_ATE_HP_complex_float128"; return DW_DLV_OK; case DW_ATE_HP_floathpintel: *s_out = "DW_ATE_HP_floathpintel"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float80: *s_out = "DW_ATE_HP_imaginary_float80"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float128: *s_out = "DW_ATE_HP_imaginary_float128"; return DW_DLV_OK; case DW_ATE_SUN_interval_float: *s_out = "DW_ATE_SUN_interval_float"; return DW_DLV_OK; case DW_ATE_SUN_imaginary_float: *s_out = "DW_ATE_SUN_imaginary_float"; return DW_DLV_OK; case DW_ATE_hi_user: *s_out = "DW_ATE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DEFAULTED_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DEFAULTED_no: *s_out = "DW_DEFAULTED_no"; return DW_DLV_OK; case DW_DEFAULTED_in_class: *s_out = "DW_DEFAULTED_in_class"; return DW_DLV_OK; case DW_DEFAULTED_out_of_class: *s_out = "DW_DEFAULTED_out_of_class"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_IDX_name (unsigned int val, const char ** s_out) { switch (val) { case DW_IDX_compile_unit: *s_out = "DW_IDX_compile_unit"; return DW_DLV_OK; case DW_IDX_type_unit: *s_out = "DW_IDX_type_unit"; return DW_DLV_OK; case DW_IDX_die_offset: *s_out = "DW_IDX_die_offset"; return DW_DLV_OK; case DW_IDX_parent: *s_out = "DW_IDX_parent"; return DW_DLV_OK; case DW_IDX_type_hash: *s_out = "DW_IDX_type_hash"; return DW_DLV_OK; case DW_IDX_hi_user: *s_out = "DW_IDX_hi_user"; return DW_DLV_OK; case DW_IDX_lo_user: *s_out = "DW_IDX_lo_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLEX_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LLEX_end_of_list_entry: *s_out = "DW_LLEX_end_of_list_entry"; return DW_DLV_OK; case DW_LLEX_base_address_selection_entry: *s_out = "DW_LLEX_base_address_selection_entry"; return DW_DLV_OK; case DW_LLEX_start_end_entry: *s_out = "DW_LLEX_start_end_entry"; return DW_DLV_OK; case DW_LLEX_start_length_entry: *s_out = "DW_LLEX_start_length_entry"; return DW_DLV_OK; case DW_LLEX_offset_pair_entry: *s_out = "DW_LLEX_offset_pair_entry"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LLE_end_of_list: *s_out = "DW_LLE_end_of_list"; return DW_DLV_OK; case DW_LLE_base_addressx: *s_out = "DW_LLE_base_addressx"; return DW_DLV_OK; case DW_LLE_startx_endx: *s_out = "DW_LLE_startx_endx"; return DW_DLV_OK; case DW_LLE_startx_length: *s_out = "DW_LLE_startx_length"; return DW_DLV_OK; case DW_LLE_offset_pair: *s_out = "DW_LLE_offset_pair"; return DW_DLV_OK; case DW_LLE_default_location: *s_out = "DW_LLE_default_location"; return DW_DLV_OK; case DW_LLE_base_address: *s_out = "DW_LLE_base_address"; return DW_DLV_OK; case DW_LLE_start_end: *s_out = "DW_LLE_start_end"; return DW_DLV_OK; case DW_LLE_start_length: *s_out = "DW_LLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_RLE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_RLE_end_of_list: *s_out = "DW_RLE_end_of_list"; return DW_DLV_OK; case DW_RLE_base_addressx: *s_out = "DW_RLE_base_addressx"; return DW_DLV_OK; case DW_RLE_startx_endx: *s_out = "DW_RLE_startx_endx"; return DW_DLV_OK; case DW_RLE_startx_length: *s_out = "DW_RLE_startx_length"; return DW_DLV_OK; case DW_RLE_offset_pair: *s_out = "DW_RLE_offset_pair"; return DW_DLV_OK; case DW_RLE_base_address: *s_out = "DW_RLE_base_address"; return DW_DLV_OK; case DW_RLE_start_end: *s_out = "DW_RLE_start_end"; return DW_DLV_OK; case DW_RLE_start_length: *s_out = "DW_RLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_GNUIVIS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_GNUIVIS_global: *s_out = "DW_GNUIVIS_global"; return DW_DLV_OK; case DW_GNUIVIS_static: *s_out = "DW_GNUIVIS_static"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_GNUIKIND_name (unsigned int val, const char ** s_out) { switch (val) { case DW_GNUIKIND_none: *s_out = "DW_GNUIKIND_none"; return DW_DLV_OK; case DW_GNUIKIND_type: *s_out = "DW_GNUIKIND_type"; return DW_DLV_OK; case DW_GNUIKIND_variable: *s_out = "DW_GNUIKIND_variable"; return DW_DLV_OK; case DW_GNUIKIND_function: *s_out = "DW_GNUIKIND_function"; return DW_DLV_OK; case DW_GNUIKIND_other: *s_out = "DW_GNUIKIND_other"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_UT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_UT_compile: *s_out = "DW_UT_compile"; return DW_DLV_OK; case DW_UT_type: *s_out = "DW_UT_type"; return DW_DLV_OK; case DW_UT_partial: *s_out = "DW_UT_partial"; return DW_DLV_OK; case DW_UT_skeleton: *s_out = "DW_UT_skeleton"; return DW_DLV_OK; case DW_UT_split_compile: *s_out = "DW_UT_split_compile"; return DW_DLV_OK; case DW_UT_split_type: *s_out = "DW_UT_split_type"; return DW_DLV_OK; case DW_UT_lo_user: *s_out = "DW_UT_lo_user"; return DW_DLV_OK; case DW_UT_hi_user: *s_out = "DW_UT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_SECT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_SECT_INFO: *s_out = "DW_SECT_INFO"; return DW_DLV_OK; case DW_SECT_TYPES: *s_out = "DW_SECT_TYPES"; return DW_DLV_OK; case DW_SECT_ABBREV: *s_out = "DW_SECT_ABBREV"; return DW_DLV_OK; case DW_SECT_LINE: *s_out = "DW_SECT_LINE"; return DW_DLV_OK; case DW_SECT_LOCLISTS: *s_out = "DW_SECT_LOCLISTS"; return DW_DLV_OK; case DW_SECT_STR_OFFSETS: *s_out = "DW_SECT_STR_OFFSETS"; return DW_DLV_OK; case DW_SECT_MACRO: *s_out = "DW_SECT_MACRO"; return DW_DLV_OK; case DW_SECT_RNGLISTS: *s_out = "DW_SECT_RNGLISTS"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DS_unsigned: *s_out = "DW_DS_unsigned"; return DW_DLV_OK; case DW_DS_leading_overpunch: *s_out = "DW_DS_leading_overpunch"; return DW_DLV_OK; case DW_DS_trailing_overpunch: *s_out = "DW_DS_trailing_overpunch"; return DW_DLV_OK; case DW_DS_leading_separate: *s_out = "DW_DS_leading_separate"; return DW_DLV_OK; case DW_DS_trailing_separate: *s_out = "DW_DS_trailing_separate"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_END_name (unsigned int val, const char ** s_out) { switch (val) { case DW_END_default: *s_out = "DW_END_default"; return DW_DLV_OK; case DW_END_big: *s_out = "DW_END_big"; return DW_DLV_OK; case DW_END_little: *s_out = "DW_END_little"; return DW_DLV_OK; case DW_END_lo_user: *s_out = "DW_END_lo_user"; return DW_DLV_OK; case DW_END_hi_user: *s_out = "DW_END_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATCF_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ATCF_lo_user: *s_out = "DW_ATCF_lo_user"; return DW_DLV_OK; case DW_ATCF_SUN_mop_bitfield: *s_out = "DW_ATCF_SUN_mop_bitfield"; return DW_DLV_OK; case DW_ATCF_SUN_mop_spill: *s_out = "DW_ATCF_SUN_mop_spill"; return DW_DLV_OK; case DW_ATCF_SUN_mop_scopy: *s_out = "DW_ATCF_SUN_mop_scopy"; return DW_DLV_OK; case DW_ATCF_SUN_func_start: *s_out = "DW_ATCF_SUN_func_start"; return DW_DLV_OK; case DW_ATCF_SUN_end_ctors: *s_out = "DW_ATCF_SUN_end_ctors"; return DW_DLV_OK; case DW_ATCF_SUN_branch_target: *s_out = "DW_ATCF_SUN_branch_target"; return DW_DLV_OK; case DW_ATCF_SUN_mop_stack_probe: *s_out = "DW_ATCF_SUN_mop_stack_probe"; return DW_DLV_OK; case DW_ATCF_SUN_func_epilog: *s_out = "DW_ATCF_SUN_func_epilog"; return DW_DLV_OK; case DW_ATCF_hi_user: *s_out = "DW_ATCF_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ACCESS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ACCESS_public: *s_out = "DW_ACCESS_public"; return DW_DLV_OK; case DW_ACCESS_protected: *s_out = "DW_ACCESS_protected"; return DW_DLV_OK; case DW_ACCESS_private: *s_out = "DW_ACCESS_private"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_VIS_local: *s_out = "DW_VIS_local"; return DW_DLV_OK; case DW_VIS_exported: *s_out = "DW_VIS_exported"; return DW_DLV_OK; case DW_VIS_qualified: *s_out = "DW_VIS_qualified"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIRTUALITY_name (unsigned int val, const char ** s_out) { switch (val) { case DW_VIRTUALITY_none: *s_out = "DW_VIRTUALITY_none"; return DW_DLV_OK; case DW_VIRTUALITY_virtual: *s_out = "DW_VIRTUALITY_virtual"; return DW_DLV_OK; case DW_VIRTUALITY_pure_virtual: *s_out = "DW_VIRTUALITY_pure_virtual"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LANG_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LANG_C89: *s_out = "DW_LANG_C89"; return DW_DLV_OK; case DW_LANG_C: *s_out = "DW_LANG_C"; return DW_DLV_OK; case DW_LANG_Ada83: *s_out = "DW_LANG_Ada83"; return DW_DLV_OK; case DW_LANG_C_plus_plus: *s_out = "DW_LANG_C_plus_plus"; return DW_DLV_OK; case DW_LANG_Cobol74: *s_out = "DW_LANG_Cobol74"; return DW_DLV_OK; case DW_LANG_Cobol85: *s_out = "DW_LANG_Cobol85"; return DW_DLV_OK; case DW_LANG_Fortran77: *s_out = "DW_LANG_Fortran77"; return DW_DLV_OK; case DW_LANG_Fortran90: *s_out = "DW_LANG_Fortran90"; return DW_DLV_OK; case DW_LANG_Pascal83: *s_out = "DW_LANG_Pascal83"; return DW_DLV_OK; case DW_LANG_Modula2: *s_out = "DW_LANG_Modula2"; return DW_DLV_OK; case DW_LANG_Java: *s_out = "DW_LANG_Java"; return DW_DLV_OK; case DW_LANG_C99: *s_out = "DW_LANG_C99"; return DW_DLV_OK; case DW_LANG_Ada95: *s_out = "DW_LANG_Ada95"; return DW_DLV_OK; case DW_LANG_Fortran95: *s_out = "DW_LANG_Fortran95"; return DW_DLV_OK; case DW_LANG_PLI: *s_out = "DW_LANG_PLI"; return DW_DLV_OK; case DW_LANG_ObjC: *s_out = "DW_LANG_ObjC"; return DW_DLV_OK; case DW_LANG_ObjC_plus_plus: *s_out = "DW_LANG_ObjC_plus_plus"; return DW_DLV_OK; case DW_LANG_UPC: *s_out = "DW_LANG_UPC"; return DW_DLV_OK; case DW_LANG_D: *s_out = "DW_LANG_D"; return DW_DLV_OK; case DW_LANG_Python: *s_out = "DW_LANG_Python"; return DW_DLV_OK; case DW_LANG_OpenCL: *s_out = "DW_LANG_OpenCL"; return DW_DLV_OK; case DW_LANG_Go: *s_out = "DW_LANG_Go"; return DW_DLV_OK; case DW_LANG_Modula3: *s_out = "DW_LANG_Modula3"; return DW_DLV_OK; case DW_LANG_Haskel: *s_out = "DW_LANG_Haskel"; return DW_DLV_OK; case DW_LANG_C_plus_plus_03: *s_out = "DW_LANG_C_plus_plus_03"; return DW_DLV_OK; case DW_LANG_C_plus_plus_11: *s_out = "DW_LANG_C_plus_plus_11"; return DW_DLV_OK; case DW_LANG_OCaml: *s_out = "DW_LANG_OCaml"; return DW_DLV_OK; case DW_LANG_Rust: *s_out = "DW_LANG_Rust"; return DW_DLV_OK; case DW_LANG_C11: *s_out = "DW_LANG_C11"; return DW_DLV_OK; case DW_LANG_Swift: *s_out = "DW_LANG_Swift"; return DW_DLV_OK; case DW_LANG_Julia: *s_out = "DW_LANG_Julia"; return DW_DLV_OK; case DW_LANG_Dylan: *s_out = "DW_LANG_Dylan"; return DW_DLV_OK; case DW_LANG_C_plus_plus_14: *s_out = "DW_LANG_C_plus_plus_14"; return DW_DLV_OK; case DW_LANG_Fortran03: *s_out = "DW_LANG_Fortran03"; return DW_DLV_OK; case DW_LANG_Fortran08: *s_out = "DW_LANG_Fortran08"; return DW_DLV_OK; case DW_LANG_RenderScript: *s_out = "DW_LANG_RenderScript"; return DW_DLV_OK; case DW_LANG_BLISS: *s_out = "DW_LANG_BLISS"; return DW_DLV_OK; case DW_LANG_lo_user: *s_out = "DW_LANG_lo_user"; return DW_DLV_OK; case DW_LANG_Mips_Assembler: *s_out = "DW_LANG_Mips_Assembler"; return DW_DLV_OK; case DW_LANG_Upc: *s_out = "DW_LANG_Upc"; return DW_DLV_OK; case DW_LANG_SUN_Assembler: *s_out = "DW_LANG_SUN_Assembler"; return DW_DLV_OK; case DW_LANG_ALTIUM_Assembler: *s_out = "DW_LANG_ALTIUM_Assembler"; return DW_DLV_OK; case DW_LANG_hi_user: *s_out = "DW_LANG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ID_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ID_case_sensitive: *s_out = "DW_ID_case_sensitive"; return DW_DLV_OK; case DW_ID_up_case: *s_out = "DW_ID_up_case"; return DW_DLV_OK; case DW_ID_down_case: *s_out = "DW_ID_down_case"; return DW_DLV_OK; case DW_ID_case_insensitive: *s_out = "DW_ID_case_insensitive"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CC_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CC_normal: *s_out = "DW_CC_normal"; return DW_DLV_OK; case DW_CC_program: *s_out = "DW_CC_program"; return DW_DLV_OK; case DW_CC_nocall: *s_out = "DW_CC_nocall"; return DW_DLV_OK; case DW_CC_pass_by_reference: *s_out = "DW_CC_pass_by_reference"; return DW_DLV_OK; case DW_CC_pass_by_value: *s_out = "DW_CC_pass_by_value"; return DW_DLV_OK; case DW_CC_lo_user: *s_out = "DW_CC_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x40. DW_CC_GNU_renesas_sh */ case DW_CC_GNU_borland_fastcall_i386: *s_out = "DW_CC_GNU_borland_fastcall_i386"; return DW_DLV_OK; case DW_CC_ALTIUM_interrupt: *s_out = "DW_CC_ALTIUM_interrupt"; return DW_DLV_OK; case DW_CC_ALTIUM_near_system_stack: *s_out = "DW_CC_ALTIUM_near_system_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_near_user_stack: *s_out = "DW_CC_ALTIUM_near_user_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_huge_user_stack: *s_out = "DW_CC_ALTIUM_huge_user_stack"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_safecall: *s_out = "DW_CC_GNU_BORLAND_safecall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_stdcall: *s_out = "DW_CC_GNU_BORLAND_stdcall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_pascal: *s_out = "DW_CC_GNU_BORLAND_pascal"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_msfastcall: *s_out = "DW_CC_GNU_BORLAND_msfastcall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_msreturn: *s_out = "DW_CC_GNU_BORLAND_msreturn"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_thiscall: *s_out = "DW_CC_GNU_BORLAND_thiscall"; return DW_DLV_OK; case DW_CC_GNU_BORLAND_fastcall: *s_out = "DW_CC_GNU_BORLAND_fastcall"; return DW_DLV_OK; case DW_CC_LLVM_vectorcall: *s_out = "DW_CC_LLVM_vectorcall"; return DW_DLV_OK; case DW_CC_LLVM_Win64: *s_out = "DW_CC_LLVM_Win64"; return DW_DLV_OK; case DW_CC_LLVM_X86_64SysV: *s_out = "DW_CC_LLVM_X86_64SysV"; return DW_DLV_OK; case DW_CC_LLVM_AAPCS: *s_out = "DW_CC_LLVM_AAPCS"; return DW_DLV_OK; case DW_CC_LLVM_AAPCS_VFP: *s_out = "DW_CC_LLVM_AAPCS_VFP"; return DW_DLV_OK; case DW_CC_LLVM_IntelOclBicc: *s_out = "DW_CC_LLVM_IntelOclBicc"; return DW_DLV_OK; case DW_CC_LLVM_SpirFunction: *s_out = "DW_CC_LLVM_SpirFunction"; return DW_DLV_OK; case DW_CC_LLVM_OpenCLKernel: *s_out = "DW_CC_LLVM_OpenCLKernel"; return DW_DLV_OK; case DW_CC_LLVM_Swift: *s_out = "DW_CC_LLVM_Swift"; return DW_DLV_OK; case DW_CC_LLVM_PreserveMost: *s_out = "DW_CC_LLVM_PreserveMost"; return DW_DLV_OK; case DW_CC_LLVM_PreserveAll: *s_out = "DW_CC_LLVM_PreserveAll"; return DW_DLV_OK; case DW_CC_LLVM_X86RegCall: *s_out = "DW_CC_LLVM_X86RegCall"; return DW_DLV_OK; case DW_CC_GDB_IBM_OpenCL: *s_out = "DW_CC_GDB_IBM_OpenCL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xff. DW_CC_hi_user */ } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_INL_name (unsigned int val, const char ** s_out) { switch (val) { case DW_INL_not_inlined: *s_out = "DW_INL_not_inlined"; return DW_DLV_OK; case DW_INL_inlined: *s_out = "DW_INL_inlined"; return DW_DLV_OK; case DW_INL_declared_not_inlined: *s_out = "DW_INL_declared_not_inlined"; return DW_DLV_OK; case DW_INL_declared_inlined: *s_out = "DW_INL_declared_inlined"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ORD_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ORD_row_major: *s_out = "DW_ORD_row_major"; return DW_DLV_OK; case DW_ORD_col_major: *s_out = "DW_ORD_col_major"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DSC_name (unsigned int val, const char ** s_out) { switch (val) { case DW_DSC_label: *s_out = "DW_DSC_label"; return DW_DLV_OK; case DW_DSC_range: *s_out = "DW_DSC_range"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNCT_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNCT_path: *s_out = "DW_LNCT_path"; return DW_DLV_OK; case DW_LNCT_directory_index: *s_out = "DW_LNCT_directory_index"; return DW_DLV_OK; case DW_LNCT_timestamp: *s_out = "DW_LNCT_timestamp"; return DW_DLV_OK; case DW_LNCT_size: *s_out = "DW_LNCT_size"; return DW_DLV_OK; case DW_LNCT_MD5: *s_out = "DW_LNCT_MD5"; return DW_DLV_OK; case DW_LNCT_GNU_subprogram_name: *s_out = "DW_LNCT_GNU_subprogram_name"; return DW_DLV_OK; case DW_LNCT_GNU_decl_file: *s_out = "DW_LNCT_GNU_decl_file"; return DW_DLV_OK; case DW_LNCT_GNU_decl_line: *s_out = "DW_LNCT_GNU_decl_line"; return DW_DLV_OK; case DW_LNCT_lo_user: *s_out = "DW_LNCT_lo_user"; return DW_DLV_OK; case DW_LNCT_LLVM_source: *s_out = "DW_LNCT_LLVM_source"; return DW_DLV_OK; case DW_LNCT_hi_user: *s_out = "DW_LNCT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNS_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNS_copy: *s_out = "DW_LNS_copy"; return DW_DLV_OK; case DW_LNS_advance_pc: *s_out = "DW_LNS_advance_pc"; return DW_DLV_OK; case DW_LNS_advance_line: *s_out = "DW_LNS_advance_line"; return DW_DLV_OK; case DW_LNS_set_file: *s_out = "DW_LNS_set_file"; return DW_DLV_OK; case DW_LNS_set_column: *s_out = "DW_LNS_set_column"; return DW_DLV_OK; case DW_LNS_negate_stmt: *s_out = "DW_LNS_negate_stmt"; return DW_DLV_OK; case DW_LNS_set_basic_block: *s_out = "DW_LNS_set_basic_block"; return DW_DLV_OK; case DW_LNS_const_add_pc: *s_out = "DW_LNS_const_add_pc"; return DW_DLV_OK; case DW_LNS_fixed_advance_pc: *s_out = "DW_LNS_fixed_advance_pc"; return DW_DLV_OK; case DW_LNS_set_prologue_end: *s_out = "DW_LNS_set_prologue_end"; return DW_DLV_OK; case DW_LNS_set_epilogue_begin: *s_out = "DW_LNS_set_epilogue_begin"; return DW_DLV_OK; case DW_LNS_set_isa: *s_out = "DW_LNS_set_isa"; return DW_DLV_OK; case DW_LNS_set_address_from_logical: *s_out = "DW_LNS_set_address_from_logical"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xd. DW_LNS_set_subprogram */ case DW_LNS_inlined_call: *s_out = "DW_LNS_inlined_call"; return DW_DLV_OK; case DW_LNS_pop_context: *s_out = "DW_LNS_pop_context"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNE_name (unsigned int val, const char ** s_out) { switch (val) { case DW_LNE_end_sequence: *s_out = "DW_LNE_end_sequence"; return DW_DLV_OK; case DW_LNE_set_address: *s_out = "DW_LNE_set_address"; return DW_DLV_OK; case DW_LNE_define_file: *s_out = "DW_LNE_define_file"; return DW_DLV_OK; case DW_LNE_set_discriminator: *s_out = "DW_LNE_set_discriminator"; return DW_DLV_OK; case DW_LNE_HP_negate_is_UV_update: *s_out = "DW_LNE_HP_negate_is_UV_update"; return DW_DLV_OK; case DW_LNE_HP_push_context: *s_out = "DW_LNE_HP_push_context"; return DW_DLV_OK; case DW_LNE_HP_pop_context: *s_out = "DW_LNE_HP_pop_context"; return DW_DLV_OK; case DW_LNE_HP_set_file_line_column: *s_out = "DW_LNE_HP_set_file_line_column"; return DW_DLV_OK; case DW_LNE_HP_set_routine_name: *s_out = "DW_LNE_HP_set_routine_name"; return DW_DLV_OK; case DW_LNE_HP_set_sequence: *s_out = "DW_LNE_HP_set_sequence"; return DW_DLV_OK; case DW_LNE_HP_negate_post_semantics: *s_out = "DW_LNE_HP_negate_post_semantics"; return DW_DLV_OK; case DW_LNE_HP_negate_function_exit: *s_out = "DW_LNE_HP_negate_function_exit"; return DW_DLV_OK; case DW_LNE_HP_negate_front_end_logical: *s_out = "DW_LNE_HP_negate_front_end_logical"; return DW_DLV_OK; case DW_LNE_HP_define_proc: *s_out = "DW_LNE_HP_define_proc"; return DW_DLV_OK; case DW_LNE_HP_source_file_correlation: *s_out = "DW_LNE_HP_source_file_correlation"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_LNE_lo_user */ case DW_LNE_hi_user: *s_out = "DW_LNE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ISA_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ISA_UNKNOWN: *s_out = "DW_ISA_UNKNOWN"; return DW_DLV_OK; case DW_ISA_ARM_thumb: *s_out = "DW_ISA_ARM_thumb"; return DW_DLV_OK; case DW_ISA_ARM_arm: *s_out = "DW_ISA_ARM_arm"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACRO_name (unsigned int val, const char ** s_out) { switch (val) { case DW_MACRO_define: *s_out = "DW_MACRO_define"; return DW_DLV_OK; case DW_MACRO_undef: *s_out = "DW_MACRO_undef"; return DW_DLV_OK; case DW_MACRO_start_file: *s_out = "DW_MACRO_start_file"; return DW_DLV_OK; case DW_MACRO_end_file: *s_out = "DW_MACRO_end_file"; return DW_DLV_OK; case DW_MACRO_define_strp: *s_out = "DW_MACRO_define_strp"; return DW_DLV_OK; case DW_MACRO_undef_strp: *s_out = "DW_MACRO_undef_strp"; return DW_DLV_OK; case DW_MACRO_import: *s_out = "DW_MACRO_import"; return DW_DLV_OK; case DW_MACRO_define_sup: *s_out = "DW_MACRO_define_sup"; return DW_DLV_OK; case DW_MACRO_undef_sup: *s_out = "DW_MACRO_undef_sup"; return DW_DLV_OK; case DW_MACRO_import_sup: *s_out = "DW_MACRO_import_sup"; return DW_DLV_OK; case DW_MACRO_define_strx: *s_out = "DW_MACRO_define_strx"; return DW_DLV_OK; case DW_MACRO_undef_strx: *s_out = "DW_MACRO_undef_strx"; return DW_DLV_OK; case DW_MACRO_lo_user: *s_out = "DW_MACRO_lo_user"; return DW_DLV_OK; case DW_MACRO_hi_user: *s_out = "DW_MACRO_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACINFO_name (unsigned int val, const char ** s_out) { switch (val) { case DW_MACINFO_define: *s_out = "DW_MACINFO_define"; return DW_DLV_OK; case DW_MACINFO_undef: *s_out = "DW_MACINFO_undef"; return DW_DLV_OK; case DW_MACINFO_start_file: *s_out = "DW_MACINFO_start_file"; return DW_DLV_OK; case DW_MACINFO_end_file: *s_out = "DW_MACINFO_end_file"; return DW_DLV_OK; case DW_MACINFO_vendor_ext: *s_out = "DW_MACINFO_vendor_ext"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CFA_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CFA_extended: *s_out = "DW_CFA_extended"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_CFA_nop */ case DW_CFA_set_loc: *s_out = "DW_CFA_set_loc"; return DW_DLV_OK; case DW_CFA_advance_loc1: *s_out = "DW_CFA_advance_loc1"; return DW_DLV_OK; case DW_CFA_advance_loc2: *s_out = "DW_CFA_advance_loc2"; return DW_DLV_OK; case DW_CFA_advance_loc4: *s_out = "DW_CFA_advance_loc4"; return DW_DLV_OK; case DW_CFA_offset_extended: *s_out = "DW_CFA_offset_extended"; return DW_DLV_OK; case DW_CFA_restore_extended: *s_out = "DW_CFA_restore_extended"; return DW_DLV_OK; case DW_CFA_undefined: *s_out = "DW_CFA_undefined"; return DW_DLV_OK; case DW_CFA_same_value: *s_out = "DW_CFA_same_value"; return DW_DLV_OK; case DW_CFA_register: *s_out = "DW_CFA_register"; return DW_DLV_OK; case DW_CFA_remember_state: *s_out = "DW_CFA_remember_state"; return DW_DLV_OK; case DW_CFA_restore_state: *s_out = "DW_CFA_restore_state"; return DW_DLV_OK; case DW_CFA_def_cfa: *s_out = "DW_CFA_def_cfa"; return DW_DLV_OK; case DW_CFA_def_cfa_register: *s_out = "DW_CFA_def_cfa_register"; return DW_DLV_OK; case DW_CFA_def_cfa_offset: *s_out = "DW_CFA_def_cfa_offset"; return DW_DLV_OK; case DW_CFA_def_cfa_expression: *s_out = "DW_CFA_def_cfa_expression"; return DW_DLV_OK; case DW_CFA_expression: *s_out = "DW_CFA_expression"; return DW_DLV_OK; case DW_CFA_offset_extended_sf: *s_out = "DW_CFA_offset_extended_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_sf: *s_out = "DW_CFA_def_cfa_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_offset_sf: *s_out = "DW_CFA_def_cfa_offset_sf"; return DW_DLV_OK; case DW_CFA_val_offset: *s_out = "DW_CFA_val_offset"; return DW_DLV_OK; case DW_CFA_val_offset_sf: *s_out = "DW_CFA_val_offset_sf"; return DW_DLV_OK; case DW_CFA_val_expression: *s_out = "DW_CFA_val_expression"; return DW_DLV_OK; case DW_CFA_lo_user: *s_out = "DW_CFA_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ case DW_CFA_MIPS_advance_loc8: *s_out = "DW_CFA_MIPS_advance_loc8"; return DW_DLV_OK; case DW_CFA_GNU_window_save: *s_out = "DW_CFA_GNU_window_save"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2d. DW_CFA_AARCH64_negate_ra_state */ case DW_CFA_GNU_args_size: *s_out = "DW_CFA_GNU_args_size"; return DW_DLV_OK; case DW_CFA_GNU_negative_offset_extended: *s_out = "DW_CFA_GNU_negative_offset_extended"; return DW_DLV_OK; case DW_CFA_METAWARE_info: *s_out = "DW_CFA_METAWARE_info"; return DW_DLV_OK; case DW_CFA_high_user: *s_out = "DW_CFA_high_user"; return DW_DLV_OK; case DW_CFA_advance_loc: *s_out = "DW_CFA_advance_loc"; return DW_DLV_OK; case DW_CFA_offset: *s_out = "DW_CFA_offset"; return DW_DLV_OK; case DW_CFA_restore: *s_out = "DW_CFA_restore"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_EH_name (unsigned int val, const char ** s_out) { switch (val) { case DW_EH_PE_absptr: *s_out = "DW_EH_PE_absptr"; return DW_DLV_OK; case DW_EH_PE_uleb128: *s_out = "DW_EH_PE_uleb128"; return DW_DLV_OK; case DW_EH_PE_udata2: *s_out = "DW_EH_PE_udata2"; return DW_DLV_OK; case DW_EH_PE_udata4: *s_out = "DW_EH_PE_udata4"; return DW_DLV_OK; case DW_EH_PE_udata8: *s_out = "DW_EH_PE_udata8"; return DW_DLV_OK; case DW_EH_PE_sleb128: *s_out = "DW_EH_PE_sleb128"; return DW_DLV_OK; case DW_EH_PE_sdata2: *s_out = "DW_EH_PE_sdata2"; return DW_DLV_OK; case DW_EH_PE_sdata4: *s_out = "DW_EH_PE_sdata4"; return DW_DLV_OK; case DW_EH_PE_sdata8: *s_out = "DW_EH_PE_sdata8"; return DW_DLV_OK; case DW_EH_PE_pcrel: *s_out = "DW_EH_PE_pcrel"; return DW_DLV_OK; case DW_EH_PE_textrel: *s_out = "DW_EH_PE_textrel"; return DW_DLV_OK; case DW_EH_PE_datarel: *s_out = "DW_EH_PE_datarel"; return DW_DLV_OK; case DW_EH_PE_funcrel: *s_out = "DW_EH_PE_funcrel"; return DW_DLV_OK; case DW_EH_PE_aligned: *s_out = "DW_EH_PE_aligned"; return DW_DLV_OK; case DW_EH_PE_omit: *s_out = "DW_EH_PE_omit"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FRAME_name (unsigned int val, const char ** s_out) { switch (val) { case DW_FRAME_CFA_COL: *s_out = "DW_FRAME_CFA_COL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_FRAME_LAST_REG_NUM */ /* Skipping alternate spelling of value 0x0. DW_FRAME_RA_COL */ /* Skipping alternate spelling of value 0x0. DW_FRAME_STATIC_LINK */ case DW_FRAME_REG1: *s_out = "DW_FRAME_REG1"; return DW_DLV_OK; case DW_FRAME_REG2: *s_out = "DW_FRAME_REG2"; return DW_DLV_OK; case DW_FRAME_REG3: *s_out = "DW_FRAME_REG3"; return DW_DLV_OK; case DW_FRAME_REG4: *s_out = "DW_FRAME_REG4"; return DW_DLV_OK; case DW_FRAME_REG5: *s_out = "DW_FRAME_REG5"; return DW_DLV_OK; case DW_FRAME_REG6: *s_out = "DW_FRAME_REG6"; return DW_DLV_OK; case DW_FRAME_REG7: *s_out = "DW_FRAME_REG7"; return DW_DLV_OK; case DW_FRAME_REG8: *s_out = "DW_FRAME_REG8"; return DW_DLV_OK; case DW_FRAME_REG9: *s_out = "DW_FRAME_REG9"; return DW_DLV_OK; case DW_FRAME_REG10: *s_out = "DW_FRAME_REG10"; return DW_DLV_OK; case DW_FRAME_REG11: *s_out = "DW_FRAME_REG11"; return DW_DLV_OK; case DW_FRAME_REG12: *s_out = "DW_FRAME_REG12"; return DW_DLV_OK; case DW_FRAME_REG13: *s_out = "DW_FRAME_REG13"; return DW_DLV_OK; case DW_FRAME_REG14: *s_out = "DW_FRAME_REG14"; return DW_DLV_OK; case DW_FRAME_REG15: *s_out = "DW_FRAME_REG15"; return DW_DLV_OK; case DW_FRAME_REG16: *s_out = "DW_FRAME_REG16"; return DW_DLV_OK; case DW_FRAME_REG17: *s_out = "DW_FRAME_REG17"; return DW_DLV_OK; case DW_FRAME_REG18: *s_out = "DW_FRAME_REG18"; return DW_DLV_OK; case DW_FRAME_REG19: *s_out = "DW_FRAME_REG19"; return DW_DLV_OK; case DW_FRAME_REG20: *s_out = "DW_FRAME_REG20"; return DW_DLV_OK; case DW_FRAME_REG21: *s_out = "DW_FRAME_REG21"; return DW_DLV_OK; case DW_FRAME_REG22: *s_out = "DW_FRAME_REG22"; return DW_DLV_OK; case DW_FRAME_REG23: *s_out = "DW_FRAME_REG23"; return DW_DLV_OK; case DW_FRAME_REG24: *s_out = "DW_FRAME_REG24"; return DW_DLV_OK; case DW_FRAME_REG25: *s_out = "DW_FRAME_REG25"; return DW_DLV_OK; case DW_FRAME_REG26: *s_out = "DW_FRAME_REG26"; return DW_DLV_OK; case DW_FRAME_REG27: *s_out = "DW_FRAME_REG27"; return DW_DLV_OK; case DW_FRAME_REG28: *s_out = "DW_FRAME_REG28"; return DW_DLV_OK; case DW_FRAME_REG29: *s_out = "DW_FRAME_REG29"; return DW_DLV_OK; case DW_FRAME_REG30: *s_out = "DW_FRAME_REG30"; return DW_DLV_OK; case DW_FRAME_REG31: *s_out = "DW_FRAME_REG31"; return DW_DLV_OK; case DW_FRAME_FREG0: *s_out = "DW_FRAME_FREG0"; return DW_DLV_OK; case DW_FRAME_FREG1: *s_out = "DW_FRAME_FREG1"; return DW_DLV_OK; case DW_FRAME_FREG2: *s_out = "DW_FRAME_FREG2"; return DW_DLV_OK; case DW_FRAME_FREG3: *s_out = "DW_FRAME_FREG3"; return DW_DLV_OK; case DW_FRAME_FREG4: *s_out = "DW_FRAME_FREG4"; return DW_DLV_OK; case DW_FRAME_FREG5: *s_out = "DW_FRAME_FREG5"; return DW_DLV_OK; case DW_FRAME_FREG6: *s_out = "DW_FRAME_FREG6"; return DW_DLV_OK; case DW_FRAME_FREG7: *s_out = "DW_FRAME_FREG7"; return DW_DLV_OK; case DW_FRAME_FREG8: *s_out = "DW_FRAME_FREG8"; return DW_DLV_OK; case DW_FRAME_FREG9: *s_out = "DW_FRAME_FREG9"; return DW_DLV_OK; case DW_FRAME_FREG10: *s_out = "DW_FRAME_FREG10"; return DW_DLV_OK; case DW_FRAME_FREG11: *s_out = "DW_FRAME_FREG11"; return DW_DLV_OK; case DW_FRAME_FREG12: *s_out = "DW_FRAME_FREG12"; return DW_DLV_OK; case DW_FRAME_FREG13: *s_out = "DW_FRAME_FREG13"; return DW_DLV_OK; case DW_FRAME_FREG14: *s_out = "DW_FRAME_FREG14"; return DW_DLV_OK; case DW_FRAME_FREG15: *s_out = "DW_FRAME_FREG15"; return DW_DLV_OK; case DW_FRAME_FREG16: *s_out = "DW_FRAME_FREG16"; return DW_DLV_OK; case DW_FRAME_FREG17: *s_out = "DW_FRAME_FREG17"; return DW_DLV_OK; case DW_FRAME_FREG18: *s_out = "DW_FRAME_FREG18"; return DW_DLV_OK; case DW_FRAME_FREG19: *s_out = "DW_FRAME_FREG19"; return DW_DLV_OK; case DW_FRAME_FREG20: *s_out = "DW_FRAME_FREG20"; return DW_DLV_OK; case DW_FRAME_FREG21: *s_out = "DW_FRAME_FREG21"; return DW_DLV_OK; case DW_FRAME_FREG22: *s_out = "DW_FRAME_FREG22"; return DW_DLV_OK; case DW_FRAME_FREG23: *s_out = "DW_FRAME_FREG23"; return DW_DLV_OK; case DW_FRAME_FREG24: *s_out = "DW_FRAME_FREG24"; return DW_DLV_OK; case DW_FRAME_FREG25: *s_out = "DW_FRAME_FREG25"; return DW_DLV_OK; case DW_FRAME_FREG26: *s_out = "DW_FRAME_FREG26"; return DW_DLV_OK; case DW_FRAME_FREG27: *s_out = "DW_FRAME_FREG27"; return DW_DLV_OK; case DW_FRAME_FREG28: *s_out = "DW_FRAME_FREG28"; return DW_DLV_OK; case DW_FRAME_FREG29: *s_out = "DW_FRAME_FREG29"; return DW_DLV_OK; case DW_FRAME_FREG30: *s_out = "DW_FRAME_FREG30"; return DW_DLV_OK; case DW_FRAME_FREG31: *s_out = "DW_FRAME_FREG31"; return DW_DLV_OK; case DW_FRAME_FREG32: *s_out = "DW_FRAME_FREG32"; return DW_DLV_OK; case DW_FRAME_FREG33: *s_out = "DW_FRAME_FREG33"; return DW_DLV_OK; case DW_FRAME_FREG34: *s_out = "DW_FRAME_FREG34"; return DW_DLV_OK; case DW_FRAME_FREG35: *s_out = "DW_FRAME_FREG35"; return DW_DLV_OK; case DW_FRAME_FREG36: *s_out = "DW_FRAME_FREG36"; return DW_DLV_OK; case DW_FRAME_FREG37: *s_out = "DW_FRAME_FREG37"; return DW_DLV_OK; case DW_FRAME_FREG38: *s_out = "DW_FRAME_FREG38"; return DW_DLV_OK; case DW_FRAME_FREG39: *s_out = "DW_FRAME_FREG39"; return DW_DLV_OK; case DW_FRAME_FREG40: *s_out = "DW_FRAME_FREG40"; return DW_DLV_OK; case DW_FRAME_FREG41: *s_out = "DW_FRAME_FREG41"; return DW_DLV_OK; case DW_FRAME_FREG42: *s_out = "DW_FRAME_FREG42"; return DW_DLV_OK; case DW_FRAME_FREG43: *s_out = "DW_FRAME_FREG43"; return DW_DLV_OK; case DW_FRAME_FREG44: *s_out = "DW_FRAME_FREG44"; return DW_DLV_OK; case DW_FRAME_FREG45: *s_out = "DW_FRAME_FREG45"; return DW_DLV_OK; case DW_FRAME_FREG46: *s_out = "DW_FRAME_FREG46"; return DW_DLV_OK; case DW_FRAME_FREG47: *s_out = "DW_FRAME_FREG47"; return DW_DLV_OK; case DW_FRAME_FREG48: *s_out = "DW_FRAME_FREG48"; return DW_DLV_OK; case DW_FRAME_FREG49: *s_out = "DW_FRAME_FREG49"; return DW_DLV_OK; case DW_FRAME_FREG50: *s_out = "DW_FRAME_FREG50"; return DW_DLV_OK; case DW_FRAME_FREG51: *s_out = "DW_FRAME_FREG51"; return DW_DLV_OK; case DW_FRAME_FREG52: *s_out = "DW_FRAME_FREG52"; return DW_DLV_OK; case DW_FRAME_FREG53: *s_out = "DW_FRAME_FREG53"; return DW_DLV_OK; case DW_FRAME_FREG54: *s_out = "DW_FRAME_FREG54"; return DW_DLV_OK; case DW_FRAME_FREG55: *s_out = "DW_FRAME_FREG55"; return DW_DLV_OK; case DW_FRAME_FREG56: *s_out = "DW_FRAME_FREG56"; return DW_DLV_OK; case DW_FRAME_FREG57: *s_out = "DW_FRAME_FREG57"; return DW_DLV_OK; case DW_FRAME_FREG58: *s_out = "DW_FRAME_FREG58"; return DW_DLV_OK; case DW_FRAME_FREG59: *s_out = "DW_FRAME_FREG59"; return DW_DLV_OK; case DW_FRAME_FREG60: *s_out = "DW_FRAME_FREG60"; return DW_DLV_OK; case DW_FRAME_FREG61: *s_out = "DW_FRAME_FREG61"; return DW_DLV_OK; case DW_FRAME_FREG62: *s_out = "DW_FRAME_FREG62"; return DW_DLV_OK; case DW_FRAME_FREG63: *s_out = "DW_FRAME_FREG63"; return DW_DLV_OK; case DW_FRAME_FREG64: *s_out = "DW_FRAME_FREG64"; return DW_DLV_OK; case DW_FRAME_FREG65: *s_out = "DW_FRAME_FREG65"; return DW_DLV_OK; case DW_FRAME_FREG66: *s_out = "DW_FRAME_FREG66"; return DW_DLV_OK; case DW_FRAME_FREG67: *s_out = "DW_FRAME_FREG67"; return DW_DLV_OK; case DW_FRAME_FREG68: *s_out = "DW_FRAME_FREG68"; return DW_DLV_OK; case DW_FRAME_FREG69: *s_out = "DW_FRAME_FREG69"; return DW_DLV_OK; case DW_FRAME_FREG70: *s_out = "DW_FRAME_FREG70"; return DW_DLV_OK; case DW_FRAME_FREG71: *s_out = "DW_FRAME_FREG71"; return DW_DLV_OK; case DW_FRAME_FREG72: *s_out = "DW_FRAME_FREG72"; return DW_DLV_OK; case DW_FRAME_FREG73: *s_out = "DW_FRAME_FREG73"; return DW_DLV_OK; case DW_FRAME_FREG74: *s_out = "DW_FRAME_FREG74"; return DW_DLV_OK; case DW_FRAME_FREG75: *s_out = "DW_FRAME_FREG75"; return DW_DLV_OK; case DW_FRAME_FREG76: *s_out = "DW_FRAME_FREG76"; return DW_DLV_OK; case DW_FRAME_HIGHEST_NORMAL_REGISTER: *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CHILDREN_name (unsigned int val, const char ** s_out) { switch (val) { case DW_CHILDREN_no: *s_out = "DW_CHILDREN_no"; return DW_DLV_OK; case DW_CHILDREN_yes: *s_out = "DW_CHILDREN_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ADDR_name (unsigned int val, const char ** s_out) { switch (val) { case DW_ADDR_none: *s_out = "DW_ADDR_none"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* END FILE */ libdwarf-20210528/dwarfdump/glflags.c0000664000175000017500000003374514020777024014267 00000000000000/* Copyright (C) 2017-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* All the dwarfdump flags are gathered into a single global struct as it has been hard to know how many there were or what they were all for. */ #include "globals.h" #include #include "esb.h" /* For flexible string buffer. */ #include "dwconf.h" #ifdef HAVE_REGEX regex_t _search_re; #endif #ifdef TRIVIAL_NAMING /* For scripts/buildstandardsource.sh */ struct glflags_s glflags; void safe_strcpy(char *out, long outlen, const char *in, long inlen) { if (inlen >= (outlen - 1)) { strncpy(out, in, outlen - 1); out[outlen - 1] = 0; } else { strcpy(out, in); } } #endif /*TRIVIAL_NAMING*/ static struct section_high_offsets_s _section_high_offsets_global; static struct dwconf_s _config_file_data; /* used in special_program_name() only */ static struct esb_s _newprogname; static struct esb_s _cu_name; static struct esb_s _config_file_path; static struct esb_s _config_file_tiedpath; void init_global_flags(void) { glflags.gf_debug_names_flag = FALSE; glflags.gf_info_flag = FALSE; glflags.gf_use_old_dwarf_loclist = FALSE; /* This so both dwarf_loclist_n() and dwarf_get_loclist_c() and the dwarf_loclist_from_expr variations can be tested. Defaults to new dwarf_get_loclist_c(). See -g option. The original IRIX dwarf_loclist() no longer tested as of October 2015. */ glflags.gf_line_flag_selection = s2l; glflags.gf_line_flag = FALSE; /* Setting this FALSE tells dwarfdump to use the old line-table interfaces. using: -x line5=no The new interfaces allow for both two-level line tables and access to line table headers in case we have a DWARF5 skeleton line table (a line table header with no lines). */ glflags.gf_line_skeleton_flag = TRUE; glflags.gf_line_print_pc = TRUE; /* Print addresses. */ glflags.gf_abbrev_flag = FALSE; glflags.gf_frame_flag = FALSE; /* .debug_frame section. */ glflags.gf_eh_frame_flag = FALSE; /* GNU .eh_frame section. */ glflags.gf_pubnames_flag = FALSE; /* DWARF2,3,4. Old macro section*/ glflags.gf_macinfo_flag = FALSE; /* DWARF5(and DWARF4 extension) new macro section */ glflags.gf_macro_flag = FALSE; glflags.gf_loc_flag = FALSE; glflags.gf_aranges_flag = FALSE; /* .debug_aranges section. */ glflags.gf_ranges_flag = FALSE; /* .debug_ranges section. */ glflags.gf_string_flag = FALSE; glflags.gf_reloc_flag = FALSE; glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_types_flag = FALSE; glflags.gf_weakname_flag = FALSE; /* Control printing of Elf header. */ glflags.gf_header_flag = FALSE; glflags.gf_gdbindex_flag = FALSE; /* List of CUs per compiler */ glflags.gf_producer_children_flag = FALSE; glflags.gf_check_abbrev_code = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_reloc_offset = FALSE; glflags.gf_check_tag_attr = FALSE; glflags.gf_check_tag_tree = FALSE; glflags.gf_check_type_offset = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_macros = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_fdes = FALSE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_harmless = FALSE; glflags.gf_check_abbreviations = FALSE; glflags.gf_check_dwarf_constants = FALSE; glflags.gf_check_di_gaps = FALSE; glflags.gf_check_forward_decl = FALSE; glflags.gf_check_self_references = FALSE; /* Attributes encoding */ glflags.gf_check_attr_encoding = FALSE; glflags.gf_generic_1200_regs = FALSE; glflags.gf_suppress_check_extensions_tables = FALSE; glflags.gf_check_duplicated_attributes = FALSE; glflags.gf_no_sanitize_strings = FALSE; /* lots of checks make no sense on a dwp debugfission object. */ glflags.gf_suppress_checking_on_dwp = FALSE; glflags.gf_file_use_no_libelf = FALSE; /* suppress_nested_name_search is a band-aid. A workaround. A real fix for N**2 behavior is needed. */ glflags.gf_suppress_nested_name_search = FALSE; glflags.gf_uri_options_translation = TRUE; glflags.gf_do_print_uri_in_input = TRUE; glflags.gf_print_unique_errors = FALSE; glflags.gf_found_error_message = FALSE; /* if TRUE, use old behavior of all expr ops joined on one line*/ glflags.gf_expr_ops_joined = FALSE; glflags.gf_print_raw_rnglists = FALSE; glflags.gf_check_names = FALSE; /* During '-k' mode, display errors */ glflags.gf_check_verbose_mode = TRUE; glflags.gf_check_frames = FALSE; /* Extensive frames check */ glflags.gf_check_frames_extended = FALSE; glflags.gf_check_locations = FALSE; glflags.gf_print_usage_tag_attr = FALSE; glflags.gf_print_usage_tag_attr_full = FALSE; glflags.gf_check_all_compilers = TRUE; glflags.gf_check_snc_compiler = FALSE; glflags.gf_check_gcc_compiler = FALSE; glflags.gf_print_summary_all = FALSE; /* The check and print flags here make it easy to allow check-only or print-only. We no longer support check-and-print in a single run. */ glflags.gf_do_check_dwarf = FALSE; glflags.gf_do_print_dwarf = FALSE; glflags.gf_check_show_results = FALSE; glflags.gf_record_dwarf_error = FALSE; /* A test has failed, this is normally set FALSE shortly after being set TRUE, it is a short-range hint we should print something we might not otherwise print (under the circumstances). */ glflags.gf_check_debug_names = FALSE; /* Display parent/children when in wide format? */ glflags.gf_display_parent_tree = FALSE; glflags.gf_display_children_tree = FALSE; glflags.gf_stop_indent_level = 0; /* 10 is sort of arbitrary, it tries to keep the indentation sane ( a 500 level DIE tree is just too much to represent with prefix spaces).*/ glflags.gf_max_space_indent = 10; /* Print search results in wide format? */ glflags.gf_search_wide_format = FALSE; /* -S option: strings for 'any' and 'match' */ glflags.gf_search_is_on = FALSE; glflags.gf_search_print_results = FALSE; glflags.gf_cu_name_flag = FALSE; glflags.gf_show_global_offsets = FALSE; glflags.gf_display_offsets = TRUE; /* Means we need to search by addr. Split Dwarf. */ glflags.gf_debug_addr_missing = 0; glflags.gf_error_code_search_by_address = 0; glflags.gf_all_cus_seen_search_by_address = 0; /* Base address has a special meaning in DWARF4 relative to address ranges. */ glflags.seen_PU = FALSE; /* Detected a PU */ glflags.seen_CU = FALSE; /* Detected a CU */ glflags.need_CU_name = TRUE; /* Need CU name */ glflags.need_CU_base_address = TRUE; /* Need CU Base address */ glflags.need_CU_high_address = TRUE; /* Need CU High address */ glflags.need_PU_valid_code = TRUE; /* Need PU valid code */ /* Involved with need_PU_valid_code (set in dwarfdump.c), in_valid_code set when subprogram DIE or CU DIE has lowpc and highpc. */ glflags.in_valid_code = FALSE; /* Detected a Base address for PU */ glflags.seen_PU_base_address = FALSE; /* Detected a High address for PU */ glflags.seen_PU_high_address = FALSE; glflags.PU_base_address = 0; /* PU Base address */ glflags.PU_high_address = 0; /* PU High address */ glflags.DIE_offset = 0; /* DIE offset in compile unit */ glflags.DIE_overall_offset = 0; /* DIE offset in .debug_info */ /* These globals enable better error reporting. */ /* CU DIE offset in compile unit */ glflags.DIE_CU_offset = 0; /* CU DIE offset in .debug_info */ glflags.DIE_CU_overall_offset = 0; glflags.current_section_id = 0; /* Section being process */ /* Base Address is needed for range lists and must come from a CU. Low address is for information and can come from a function or something in the CU. */ glflags.CU_base_address = 0; /* CU Base address */ glflags.CU_low_address = 0; /* CU low address */ glflags.CU_high_address = 0; /* CU High address */ glflags.fde_offset_for_cu_low = DW_DLV_BADOFFSET; glflags.fde_offset_for_cu_high = DW_DLV_BADOFFSET; glflags.program_name = NULL; glflags.program_fullname = NULL; /* Able to generate report on search */ glflags.search_any_text = 0; glflags.search_match_text = 0; glflags.search_regex_text = 0; glflags.search_occurrences = 0; #ifdef HAVE_REGEX glflags.search_re = &_search_re; #endif /* Start verbose at zero. verbose can be incremented with -v but not decremented. */ glflags.verbose = 0; glflags.gf_show_dwarfdump_conf = 0; glflags.dense = FALSE; glflags.ellipsis = FALSE; glflags.show_form_used = FALSE; /* break_after_n_units is mainly for testing. It enables easy limiting of output size/running time when one wants the output limited. For example, -H 2 limits the -i output to 2 compilation units and the -f or -F output to 2 FDEs and 2 CIEs. */ glflags.break_after_n_units = INT_MAX; glflags.section_high_offsets_global = &_section_high_offsets_global; glflags.pRangesInfo = NULL; glflags.pLinkonceInfo = NULL; glflags.pVisitedInfo = NULL; /* These names make diagnostic messages more complete, the fixed length is safe, though ultra long names will get truncated. */ glflags.PU_name[0] = 0; glflags.CU_name[0] = 0; glflags.CU_producer[0] = 0; /* Options to enable debug tracing. */ { int i = 0; for ( ; i <= MAX_TRACE_LEVEL; ++i) { glflags.nTrace[i] = 0; } } /* Output filename */ glflags.output_file = 0; glflags.group_number = 0; /* Global esb-buffers. */ glflags.newprogname = &_newprogname; esb_constructor(glflags.newprogname); glflags.cu_name = &_cu_name; esb_constructor(glflags.cu_name); glflags.config_file_path = &_config_file_path; esb_constructor(glflags.config_file_path); glflags.config_file_tiedpath = &_config_file_tiedpath; esb_constructor(glflags.config_file_tiedpath); glflags.config_file_data = &_config_file_data; /* Check errors. */ glflags.check_error = 0; glflags.gf_print_alloc_sums = 0; } void reset_global_flags(void) { esb_destructor(glflags.newprogname); esb_destructor(glflags.cu_name); esb_destructor(glflags.config_file_path); esb_destructor(glflags.config_file_tiedpath); } /* When we add a 'print' option after an option requests one or more checks we turn off all checking, putting it back to default checking state. */ void set_checks_off(void) { glflags.gf_check_abbrev_code = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_reloc_offset = FALSE; glflags.gf_check_tag_attr = FALSE; glflags.gf_check_tag_tree = FALSE; glflags.gf_check_type_offset = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_fdes = FALSE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_harmless = FALSE; glflags.gf_check_abbreviations = FALSE; glflags.gf_check_dwarf_constants = FALSE; glflags.gf_check_di_gaps = FALSE; glflags.gf_check_forward_decl = FALSE; glflags.gf_check_self_references = FALSE; glflags.gf_check_attr_encoding = FALSE; glflags.gf_check_duplicated_attributes = FALSE; glflags.gf_check_debug_names = FALSE; } /* Making this a named string makes it simpler to change what the reset,or 'I do not know' value is for CU name or producer name for PRINT_CU_INFO. different string string is seen in dwarfdump.c when getting producer name for the list of CUs shown by -P --print-producers and in 'Compilers detected' output. */ static const char * default_cu_producer = ""; void reset_overall_CU_error_data(void) { safe_strcpy(glflags.CU_name,sizeof(glflags.CU_name), default_cu_producer,strlen(default_cu_producer)); safe_strcpy(glflags.CU_producer,sizeof(glflags.CU_producer), default_cu_producer,strlen(default_cu_producer)); glflags.DIE_offset = 0; glflags.DIE_overall_offset = 0; glflags.DIE_CU_offset = 0; glflags.DIE_CU_overall_offset = 0; glflags.CU_base_address = 0; glflags.CU_high_address = 0; glflags.CU_low_address = 0; } Dwarf_Bool cu_data_is_set(void) { if (strcmp(glflags.CU_name,default_cu_producer) || strcmp(glflags.CU_producer,default_cu_producer)) { return 1; } if (glflags.DIE_offset || glflags.DIE_overall_offset) { return 1; } if (glflags.CU_base_address || glflags.CU_low_address || glflags.CU_high_address) { return 1; } return 0; } libdwarf-20210528/dwarfdump/ChangeLog20060000664000175000017500000003350113644370703014560 000000000000002006-12-24 David Anderson * DWARFDUMPCOPYRIGHT: Added GPL copyright text with explanation of the intended content. * COPYING: added text explaining confusion of GPL vs LGPL. Thanks to Chris Quenelle for pointing out the disconnect between DWARFDUMPCOPYRIGHT and the source files in dwarfdump. 2006-12-21 David Anderson * tag_tree.list: add tags to make allowed list more complete. Omission noticed by Marcel Mettes. 2006-06-14 David Anderson * print_frames.c: Clean up printing of augmentation data by eliminating dangling 0x (for eh_frame). 2006-04-28 David Anderson * dwarfdump.conf: Now has x86_64 register names. x86_64 with help from Tom Hughes (verified from independent sources). Added m68k register names and refined x86 list by looking at various information-sources. 2006-04-18 David Anderson * *.c: Ran indent so all now follow a standard look. * dwconf.c: Added fclose(conf_stream). 2006-04-18 David Anderson * dwarfdump.c: Forgot to call key new functions for handling variable-size frame data and different frame rule initialization value. * dwconf.c: Add a default print for CFA in case of an omission in dwarfdump.conf. * dwarfdump.conf: Move setup and rename the ABIs slightly. 2006-04-17 David Anderson * dwarfdump.conf: Correct typos. Remove some register names. * dwarfdump.c: Fix compiler warnings, fix -x option usage message. * dwconf.h: Fix compiler warnings by changing types. * dwconf.c: Change error checking so we check all errors, do not stop at first error. Ran indent. Added code to check for extra junk after operand(s). * print_frames.c: Fix compiler warnings. * Makefile.in: get used in install rule and creating places to search for dwarfdump.conf 2006-04-16 David Anderson * dwarfdump.conf: New dwarfdump configuration file. Makes using frame information easy to read and correct for any ABI/ISA without rebuilding dwarfdump. * Makefile.in: Added new files dwconf.h dwconf.c * dwconf.h dwconf.c: New files implement reading dwarfdump.conf and help print_frames.c print frame information correctly for ABIs specified at runtime. * dwarfdump.1: document -x commands. * globals.h: Minor changes to support dwarfdump.conf * print_frames.c: Major changes to support a run-time description of the frames info and dwarfdump.conf. * print_frames.h: Changes to support a run-time description of the frames info and dwarfdump.conf. * print_sections.c: Minor tweaks to support a run-time description of the frames info and dwarfdump.conf. 2006-03-31 David Anderson * Makefile.in globals.h print_sections.c: Refer to new print_frames.h print_frames.c. * print_frames.h print_frames.c: Extract cie, fde printing to separate file, separating loop logic from the printing of an entry from the loop. 2006-03-31 David Anderson * dwarfdump.c global.h print_sections.c: Preparing for dwarf3 frame interface. * print_die.c: Corrects handling of DW_AT_encoding (etc) value. 2006-03-29 David Anderson * print_sections.c: define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES at compile time to turn off the MIPS register names printing. Instead (aside from cfa) use a name like r4 (where the DWARF register number follows the letter 'r'). Indent. Initialize some local variables at declarations. 2006-03-13 David Anderson * print_sections.c: Now gets gnu eh_augmentation data by calling dwarf_get_cie_augmentation_data() or dwarf_get_fde_augmentation_data() and prints it (use -v to see cie data). Now prints DWARF3 frame information. 2006-03-08 David Anderson * print_sections.c: Add 'break;' at line 710. Thanks to Richard Stuckey for noticing. 2005-12-01 David Anderson * dwarf_names.awk: use snprintf instead of sprintf for safety. 2005-12-01 David Anderson * Makefile.in: Build attr/tag trees with individual commands to catch build errors. * tag_attr.c,tag_tree.c: Verify that tables fit in the generated C code and check for format errors in the *.list files. * tag_attr.list, tag_tree.list: Added some valid entries. * globals.h: add DWARF_ERROR3 macro for better diagnostics. * print_die.c: Show both sides of questionable tag relation in CHECK -k diagnostic output. 2005-11-25 David Anderson * print_die.c: DW_AT_stride_size changed to DW_AT_bit_stride, added DW_AT_byte_stride. * tag_attr.c,tag_tree.c: fixed array size now a #define for readability. * tag_attr.list: Added DWARF3 attributes, also new TAGs. * tag_tree.list: Added DWARF3 TAGs. 2005-11-08 David Anderson * makename.c: remove non-standard malloc.h include, stdlib.h suffices and is already included. 2005-10-24 David Anderson * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array. 2005-08-01 David Anderson * Makefile.in: Add esb.o and test rule (test code for esb.c). * dwarfdump.c: Remove old static buffer initialization. * print_die.c: Use esb now, avoid crash due to long loclist overrunning static buffer. Uses snprintf now, not sprintf. snprintf is for safety. * esb.h esb.c: Adding extensible string buffer (esb) code. * testesb.c: Test code for esb.c. * print_reloc.c: size field is now Elf64_Xword for Elf64 as Elf64_Word is only 32 bits. 2005-07-15 David Anderson * dwarfdump.c: Add print of .debug_pubtypes, remove erroneous dealloc after dwarf_formstring() call. * globals.h: Add declarations for .debug_pubtypes print. Add declaration for full dealloc. * print_die.c: Remove erroneous dealloc after dwarf_formstring() call. * print_exception_tables.c: Call dwarf_fde_cie_list_dealloc() for complete dealloc. * print_sections.c: Remove incorrect dealloc() call. Add calls to new dealloc routines. Add support of .debug_pubtypes print. 2005-07-14 David Anderson * print_sections.c (print_line_numbers_this_cu): Use new dwarf_srclines_dealloc() for deallocation after dwarf_srclines() called. 2005-04-13 David Anderson * print_sections.c: Factors out common print code into a new routine. Avoid indexing past end of register names array. Adds checks and prints so that certain errors in pubnames-like sections are printed usefully (and dwarfdump then stops if libdwarf gave an error). 2005-03-21 David Anderson * dwarfdump.c: Add -F flag to request .eh_frame section print. Changed -f flag meaning to print .debug_frame only. -a flag no longer prints .debug_frame by default. * print_sections.c: avoid printing an eh_frame we don't understand. Add new information per CU when printing line info: specifically the line section offset. * globals.h: Added arguments to print_frames() for -F flag. 2005-03-18 David Anderson * print_sections.c: Correct macro section printing. 2004-10-28 David Anderson * DWARFDUMPCOPYRIGHT config.h defs.h dwarfdump.c globals.h makename.c makename.h print_die.c print_exception_tables.c print_reloc.c print_sections.c tag_attr.c tag_attr.list tag_tree.c tag_tree.list: Copyright update, SGI corporate address change. 2004-10-26 David Anderson * acconfig.h: removed. Was old style autoconf usage. * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. * config.guess: Updated. timestamp='2004-06-11'. * config.sub: Updated. timestamp='2004-03-12'. * configure config.h.in: regenerated with autoconf 2.58. 2004-05-14 David Anderson * print_die.c (print_die_and_children): Change to iteration on siblings (still recursing on children). 2004-03-30 David Anderson * dwarfdump.c (main): getopt() string should contain k:g not kg: Thanks to Peter Seiderer for pointing this out. 2003-12-31 David Anderson * README: Added configure example. * Makefile.in: Removed bogus LIBS line, updated copyright date. * acconfig.h: Added LGPL copyright to match libdwarf Silly, but it matches libdwarf version boilerplate. * config.guess config.sub: new versions from automake-1.6. * config.h.in configure: Regenerated. 2003-10-06 David Anderson * dwarfdump.c print_sections.c: applied indent(1). * print_die.c: applied indent and added ; after invocations of macros PUSH_DIE_STACK POP_DIE_STACK SPACE as these were confusing indent a bit. The indent control file .indent.pro contained: -bad -bap -nbbo -br -ce -brs -l72 -lc72 -hnl -nprs -fca -i4 -lp -psl -npcs 2003-10-02 David Anderson * dwarfdump.c: Add -g to indicate use of older location entry code in libdwarf. So dwarf_loclist and dwarf_loclist_n are testable. * globals.h: Added use_old_dwarf_loclist flag so one can choose the old dwarf_loclist() interface. For testing. * print_die.c: Rearranged to avoid code duplication. Now supports .debug_loc fully. * print_sections.c: Prints .debug_loc now. 2003-09-29 David Anderson * print_die.c: with -v, print 'loclist' start and end addr and also a hint that DW_FORM_indirect is used. No change for normal output (for now). 2003-05-19 David Anderson * dwarfdump.c call dwarf_srcfiles() to get file names per cu and pass down to die print routines. Removed incorrect tests for when to print ".debug_info", leaving simpler test. * print_die.c globals.h: print file name (from line info) with DW_AT_decl_file, adding data from dwarf_srcfiles to argument list of a few routines to make that possible. * print_sections.c: moved "line number info" string print so it prints for -v as well as normal line ouput. 2002-10-23 Amaury Le Leyzour amaury@sgi.com * print_sections.c (print_weaknames): Changed DW_DLA_TYPENAME to DW_DLA_WEAK at dwarf_dealloc(). 2002-10-22 Tom Hughes * print_sections.c: macro printing now supported. * dwarfdump.c: removed erroneous dwarf_dealloc() of string returned by dwarf_errmsg(). 2002-11-22 David Anderson * dwarf_names.awk at_list.awk: Allow an name to have two spellings so the historical name preserved yet the dwarf3 version is supported. First name seen is used/reported by dwarfdump. * dwarf.h: DW_TAG_template_type_param(eter) DW_TAG_template_value_param(eter) DW_AT_namelist_itm(s) are the ones with alternate spellings now. Added Universal Parallel C TAGs/Attributes in user namespace. * tag_attr.c tag_attr.list tag_tree.c tag_tree.list: Use the DW_TAG_template_* dwarf3 spellings. 2002-05-08 David Anderson * tag_attr.list dwarf.h: DW_AT_namelist_items is wrong, changed to DW_AT_namelist_item 2002-04-29 Stephen Clarke * dwarfdump.c (main): #ifdef for __CYGWIN__ on open(). 2001-06-14 David Anderson * print_sections.c: Calling the new libdwarf function dwarf_get_arange_cu_header_offset() so we can print the cu header offset for aranges. 2000-07-14 Fred Fish * configure.in (LOCATION_OF_LIBELFHEADER): Fix typo for configure variable to be tested and enclose libelf/libelf.h in <>. * configure: Regenerated. 2000-07-10 Fred Fish * Makefile.in (install): Install dwarfdump.1 from $(srcdir). 2000 June 12 davea@sgi.com print_sections.c the DW_CFA_offset_extended print did not multiply by data-alignment factor in the -v -v detailed output. And the offsets used %2d when the values were unsigned int, so now %2u. And not all cfa prints of values had necessarily a type to match %llu or %lld where required. Depended on the size of Dwarf_Signed and Dwarf_Unsigned. So now explicitly use cast to the right type to match the % format. 2000 April 13 davea@sgi.com print_sections.c - 1.56 - A single byte of zero is a perfectly legitmate null abbreviation entry (in .debug_abbrev) now we print those directly and avoid a warning from dwarfdump print_die.c - 1.42 - Explain what combo checker is doing and make it more maintainable (and fix bug which would not be hit, but was real enough (in combo checker), using too large a number as highest tag number). tag_tree.list - 1.2 - Add valid parent/child relationships so checker does not report valid entries as bogus. 2000 Feb 24 Jason Merrill noticed that gcc did not like gcc -E foo.list, so incorporated his fix so now the Makefile.in makes a link and does gcc -E _tmp.c 2000 Jan 26 elena.demikhovsky@intel.com noticed that 3 statements in print_sections.c got warnings from the compiler she was using. Simple casts (provided by her) fixed these. 1999 July 21 davea@sgi.com print_sections changed to allow printing of dwarf-ish egcs c++ .eh_frame data 1999 June 14 Fred Fish fnf@ninemoons.com contributed autoconf'ing of the libdwarf and dwarfdump source. 1999 June 10 ChangeLog started. davea@sgi.com David Anderson libdwarf-20210528/dwarfdump/testobjLE32PE.exe0000775000175000017500000016164414046606335015503 00000000000000MZÿÿ¸@€º´ Í!¸LÍ!This program cannot be run in DOS mode. $PELÊÕ”]´Øà ,Fà@@P<é €¨ $Ô.text¤+,`P`.data@0@0À.rdataäP2@0@/4¼ ` 6@0@.bsspp€0À.idata¨€@@0À.CRTF@0À.tls  H@0À/14X°J@@B/29&À L@B/41øàl@B/55Ìðn@B/678r@0B/80?@t@Bƒì‹D$ ‹‹=‘ÀwN=Às`=À…ÌÇD$Ç$ è*ƒø„H…À…ç´&1ÀƒÄ´&=”ÀtI=–À„‰=“Àu×ÇD$Ç$è»)ƒø„­…Àt¶Ç$ÿиÿÿÿÿ먶ÇD$Ç$è„)ƒøuÍÇD$Ç$èk)¸ÿÿÿÿékÿÿÿ‰ö¼'=À…UÿÿÿÇD$Ç$è9)ƒøtY…À„4ÿÿÿÇ$ÿиÿÿÿÿé#ÿÿÿÇ$ ÿиÿÿÿÿéÿÿÿÇD$Ç$èñ(Ç$èݸÿÿÿÿéåþÿÿÇD$Ç$èÇ(ƒÈÿéÉþÿÿÇD$Ç$ è«(ƒÈÿé­þÿÿt&¼'U‰åSƒì¡dP@…ÀtÇD$ÇD$Ç$ÿЃì Ç$@è)ƒìèp¡@@‰$èC辡 p@…ÀtB‹ @£ @@‰D$‹C‰$ès(¡ p@‰D$‹C0‰$è_(¡ p@‰D$‹CP‰$èK(èn(‹ @@‰èá ƒäðèYè\(‹‰D$¡p@‰D$¡p@‰$èå‰Ãè)(‰$è¹(‰ö¼'ƒì€úuä…À…<¶WƒÇëÓv¶W€ú]„•¾Ú…Ûtp‹L$ wá@9݉t$$‰è‰Îë‹D$(<(…ÿt)9ë‰ètl…öhuè‰$è-‰Ç‹D$‰$è)Ç…ÿu׋T$ ‹t$$ƒâ ¶<]ta<tCƒÆ„ÀuîƒÄ<1À[^_]Ãf;\$tO¾_ƒÇé–þÿÿ½-‰÷éæþÿÿf‹t$$éÂþÿÿ´&…Òu ¶FƒÆë°vƒÆ¶<]uŸƒÄQ@t ‰ðèCñÿÿÇQ@‰4$‹M‰ú‰Øè.÷ÿÿƒø‰Áteô‰È[^_]ÃÇF ëÂt&ƒçtä‰Eà‰eä‰$èå ƒÀÁèÁàè¯ïÿÿ‹Mà)Ä|$‰úëfƒÂƒÃ„ÀˆBÿt¶<uì¶CƒÃƒÂƒÃ„ÀˆBÿuå‰Mà‰<$èÍ …À‹eä‹Mà„xÿÿÿ‰ò‰Mäèåõÿÿ‹Mäéfÿÿÿ¶¼'WVSƒì‹t$ >Q@tƒÄ[^_ô&‹F‹V …Àxÿ•~‹Fƒï‹ƒÃ‰$èh ƒÿÿuç‹F‰D$ ƒÄ[^_éQ U‰åWVSƒì,ÇD$Ç$è …À‰Ãt ‰$è ‰ÃÇD$(Q@Ç$èß‹u…öt‹E€8uqÇD$ÇD$*Q@Ç$è„p‰t$¡hp@‰$訣hp@‰t$ÇD$*Q@‰$èW‰\$Ç$èw‰$蟋5hp@eô[‰ð^_]ÉeÜÇD$‹EÇ$‰D$èY‰ÂDÁèÁàèðíÿÿ)ĉT$‹E|$ ‰<$‰D$è/1ɉE؃øf‰ G·‰}äf‰Eâvfƒø/„fƒø\„fƒ:„O·Eâf…À„á‹Mä‰Â‰Îëv¼'fƒú\‰Èt·PHf…Òt6fƒú/uæ·‰Èfƒú/u ƒÀ·fƒú/tôfƒú\tîf…Òt·P‰ÆHf…ÒuÊ9uä‚·Eâfƒø/„áfƒø\„׋uä¹.‰ðf‰ƒÀ1Òf‰ÇD$‰|$Ç$èøP‰T$¡hp@‰Uä‰$è‹Uä£hp@‰Æ‰|$‰$‰T$èÇé‹eÜéþÿÿv¼'Fþ9Eäƒa·Vþ‰Æfƒú/tèfƒú\tâ1Ò‰ùf‰P·fƒú/tfƒú\…´&ƒÁ·fƒø/tôfƒø\tî‰È)øƒøŽÞ‰ù‰Èf…Òt!ƒÁfƒú/f‰Qþtbfƒ8\ptW·P‰ðf…Òuß‹EØ1öf‰1‰|$‰D$‹E‰$è ƒøÿ‹utƉ\$Ç$è ‰$èH‹eÜeô‰ð[^_]Éð·fƒú\tfƒú/…yÿÿÿ¶ƒÀ·fƒú/tôfƒú\tîé\ÿÿÿ·Eâf;G…ëýÿÿfƒ…àýÿÿ‰\$Ç$è°‰$èØ‹uë‹f9W…ÿÿÿ·éÿÿÿG‰Eä·Gf‰Eâéžýÿÿ‹EäƒÀé.þÿÿ…«þÿÿ·Mâfƒù/t fƒù\…—þÿÿ·Mâf9H…‰þÿÿ·Pfƒú/„{þÿÿfƒú\„qþÿÿ‰ðéjþÿÿVS‰ÓìTT$‰$‰T$èöƒìƒøÿ‰ÆtZ1ÀK f‰C1Àë·CƒÀf=f‰CƒÑ·À¶D<„Àˆuà‹D$$XƒøvÇCÄT‰ð[^Ãf‰CÄT‰ð[^Ãèý‰Ãèfƒø‰t1èê8 tè݃8t»èÓÇë®èÆÇë¡è¹Çë”VS‰ÓìTT$‰$‰T$èƒì…À‰Æt_1ÀK f‰C1Àë·CƒÀf=f‰CƒÑ·À¶D<„Àˆuà‹D$$Xƒøw‰CÄT‰ð[^ô&ÇCÄT‰ð[^Ã虃øtÒèÇÄT‰ð[^ô&¼'UWVSì,‹„$@…À„ƒ€8„^|$ÇD$‰D$‰<$è¾€|$‰øtM‹ƒÀ‘ÿþþþ÷Ñ!Ê €€té÷€€„ ‰ÑуØ)ø¶T€ú/tC€ú\t>¹\f‰ ƒÀë0t&‹ƒÀ‘ÿþþþ÷Ñ!Ê €€té÷€€„­‰ÑуØ)øº*‰ûf‰‹ƒÃ‚ÿþþþ÷Ò!Ð%€€€€tê©€€uÁèƒÃ‰ÁÁƒÛ)ûƒ‰$è¿…À‰Æ„„¨ƒÃ‰|$‰\$‰,$茉ò‰èèSýÿÿƒøÿ‰†ts¸džÇf‰FÄ,‰ð[^_]ÃfÁêƒÀéHÿÿÿt&ÁêƒÀéëþÿÿt&è{1öÇëÂèlÇ ëµè_1öÇ릉4$1öè뚉ö¼'Sƒì‹\$…Ût+‹ƒP…À‰“~‹ƒ‰Úèdýÿÿ…Àt‰ØƒÄ[ÃèÇ 1Àëìv¼'Sƒì‹\$ …Ût$‹ƒ‰$ènƒì…Àt‰$è—1ÀƒÄ[Ãè»Ç ¸ÿÿÿÿëé´&¼'Sƒì‹\$ …Ût‹ƒ‰$èƒì…ÀuèzÇ ƒÄ[ÉÚèâûÿÿƒøÿ‰ƒtãǃƒÄ[ô&ƒì ‹D$…Àt ‹€ƒÄ Ãè&Ç ¸ÿÿÿÿëê‰ö¼'VSƒì‹t$$‹\$ …öxO‰$èWÿÿÿ…öt7ƒ»ÿuë,´&‹ƒ‰Úè#üÿÿ…Àt‹ƒƒÀ9Ɖƒ܃Ä[^öè«ÇƒÄ[^Ãÿ%ð@ÿ%ì@ÿ%è@ÿ%ä@ÿ%à@ÿ%Ü@ÿ%Ø@ÿ%Ô@ÿ%Ð@ÿ%Ì@ÿ%È@ÿ%Ä@ÿ%À@ÿ%¼@ÿ%´@ÿ%°@ÿ%¤@ÿ%œ@ÿ%”@ÿ%@ÿ%ˆ@ÿ%„@ÿ%|@ÿ%h@ÿ%d@ÿ%`@ÿ%\@ÿ%X@ÿ%T@ÿ%P@ÿ%L@ÿ%H@ÿ%D@ÿ%@@ÿ%<@ÿ%8@ÿ%4@ÿ%0@ÿ%,@ÿ%(@ÿ%$@ÿ%t@ÿ%p@ffffU‰å]é·×ÿÿÿÿÿÿ€;@ÿÿÿÿýÿÿÿ@ ;@ÿÿÿÿlibgcc_s_dw2-1.dll__register_frame_info__deregister_frame_infolibgcj-16.dll_Jv_RegisterClasses0@Mingw runtime failure: VirtualQuery failed for %d bytes at address %p Unknown pseudo relocation protocol version %d. Unknown pseudo relocation bit size %d. .glob-1.0-mingw32.GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (MinGW.org GCC-6.3.0-1) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 5.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0zR| ˆà¯ÿÿ¥C R K 8t±ÿÿçA…B DƒTH²ÿÿ?C@{lp²ÿÿC €|²ÿÿC ”ˆ²ÿÿ¨„²ÿÿzR| ˆ(h²ÿÿáA…B E†ƒ ÃAÆAÅ D H,³ÿÿ.A…B jÅ zR| ˆ$³ÿÿ A…B IÅ <³ÿÿJA…B FÅ zR| ˆ<,³ÿÿŸA…B F‡†ƒ- ÃAÆAÇAÅ G É ÃAÆAÇAÅ A zR| ˆt¶ÿÿÜ^ƒ¤ÃBƒzR| ˆ·ÿÿ,N\ 44·ÿÿFAƒC j AÃA X`·ÿÿzR| ˆT·ÿÿCC U H `8<„·ÿÿƒA†A ƒC d  FÃAÆC h  FÃAÆC xØ·ÿÿzR| ˆ8¼·ÿÿ`A†A ƒC LI PC jC C AÃAÆDXà·ÿÿ‚A†A ƒE L  CÃAÆI sH UC E  AÃAÆA < (¸ÿÿ›AƒC P CÃI LI gC C CÃK ZC (àˆ¸ÿÿ—C a A iC ] B LC zR| ˆä¸ÿÿJA†A ƒC d<¹ÿÿðA…A ‡C†AƒG`XTC`i AÃAÆ AÇAÅK dPC`FPC`C AÃAÆ AÇAÅA 4¤œ¹ÿÿËj‡A †AƒC0ä Aà AÆAÇJ zR| ˆL»ÿÿlC A A zR| ˆ4ˆ»ÿÿ“I†A ƒI ÃAÆA sÃAÆF ƒ†(Tð»ÿÿcE†A ƒE H AÃAÆl€4¼ÿÿµA…A ‡C†AƒCPn CÃAÆ AÇAÅC M DÃAÆ AÇAÅA C DÃAÆ AÇAÅA Tð„¾ÿÿA…A ‡C†AƒC@  AÃAÆ AÇAÅC K AÃAÆ AÇAÅA DHLÀÿÿ\A‡A †CƒE @ Cà AÆAÇA CFà AÆAÇ(dÀÿÿIA†A ƒG o  AÃAÆF ,¼ˆÀÿÿƒA…B C‡†ƒd ÃAÆAÇAÅ C ,ìèÈÿÿãA…B F‡†ƒF ÃAÆAÇAÅ A @¨Éÿÿ_A‡A †AƒC O Aà AÆAÇH wAà AÆAÇzR| ˆ<¬ÉÿÿôA…B F‡†ƒ² ÃCÆAÇAÅ A P ÃAÆAÇAÅ A zR| ˆ@TÍÿÿÏA†A ƒHàPØCàL  CÃAÆC I  CÃAÆA L`àÍÿÿ¢A†A ƒHàPØCàG  CÃAÆH M  CÃAÆA [ CÃAÆ@°@Îÿÿ·A…A ‡A†AƒFÀM CÃAÆ AÇAÅC ô¼ÏÿÿFAƒCq AÃA (èÏÿÿBAƒC VC Q AÃA ,D ÐÿÿXAƒC VC R AÃA eAÃt<Ðÿÿ'CQ A 4PÐÿÿqA†A ƒC R  AÃAÆG N AÃAÆzR| ˆÜÑÿÿ A…B AÅ P€…$œ€…p¨€œ…|ø‚(‚6‚B‚T‚d‚r‚„‚”‚¨‚º‚Ö‚î‚þ‚ƒ*ƒ<ƒLƒVƒbƒrƒ‚ƒ’ƒ ƒ²ƒ¼ƒÆƒÒƒÞƒæƒòƒüƒ„„„$„.„6„@„J„V„`„j„v„€„Š„”„ž„ª„ø‚(‚6‚B‚T‚d‚r‚„‚”‚¨‚º‚Ö‚î‚þ‚ƒ*ƒ<ƒLƒVƒbƒrƒ‚ƒ’ƒ ƒ²ƒ¼ƒÆƒÒƒÞƒæƒòƒüƒ„„„$„.„6„@„J„V„`„j„v„€„Š„”„ž„ª„ÐDeleteCriticalSectioníEnterCriticalSectionExitProcess-FindClose1FindFirstFileABFindNextFileAaFreeLibrary…GetCommandLineAÿGetLastErrorGetModuleHandleABGetProcAddressßInitializeCriticalSection/LeaveCriticalSection2LoadLibraryAuSetUnhandledExceptionFilter–TlsGetValue¾VirtualProtectÀVirtualQueryP_strdupR_stricollY__getmainargsx__mb_cur_max„__p__environ†__p__fmodeš__set_app_typeÜ_cexit_errnoE_fpreset__fullpath¢_iob§_isctype²_onexit»_pctypeò_setmode<abortDatexitKcalloclfreewfwrite¤malloc«mbstowcs°memcpyÅreallocÌsetlocaleÎsignalÛstrcollâstrlenþtolowervfprintf.wcstombs€€€€€€€€€€€€€€€€€€KERNEL32.dll€€msvcrt.dll(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€(€msvcrt.dll0@à@ @ @8p@@`@W' @*Î#GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 c:/Users/dandelot/test.c`@Wunsigned intshort unsigned intlong intlong long intintchar_iobuf ÒC_ptrÔC_cntÕ­_baseÖC_flag×­ _fileØ­_charbufÙ­_bufsizÚ­_tmpfnameÛC´FILEܼI` _iobïUsomething“a­bj main­m@Jœñ argc­‘ argvñ‘ x­t y­t soltC buffle ­`@ œ  v ‘l£É @: @../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S/home/keith/src/mingw/gcc-build/gcc-6.3.0-mingw32-cross-native/mingw32/libgccGNU AS 2.28€TÝGNU C11 6.3.0 -mtune=generic -march=i586 -g -g -g -O2 -O2 -O2 -fbuilding-libgcc -fno-stack-protector ../../../src/gcc-6.3.0/libgcc/libgcc2.c/home/keith/src/mingw/gcc-build/gcc-6.3.0-mingw32-cross-native/mingw32/libgccuintìunsigned intshort unsigned intlong long int long doublechar>long int_iobuf ÒÞ_ptrÔÞ_cntÕì_baseÖÞ_flag×ì _fileØì_charbufÙì_bufsizÚì_tmpfnameÛÞ>FILEÜWäû _iobïðshort intlong unsigned int _argccì _argvdCÞ __mb_cur_maxŽì _sys_nerrÊìÞy _sys_errlistãn _osverúø _winverûø _winmajorüø _winminorýø _fmodeEìsizetype optind<ì optopt=ì opterr>ì optargAÞ _daylight\ì _timezone]KÞS Û _tzname^C daylight}ì timezone~K tznameChashval_t*øhtab_hash/¶¼ ”ËËÑhtab_eq6áç ìûËË htab_hash_pointer»¥ htab_eq_pointer¾Òunsigned charstringop_algøèno_stringoplibcallrep_prefix_1_byterep_prefix_4_byterep_prefix_8_byteloop_1_byteloopunrolled_loopvector_looplast_alg <ø íFý unspec_stringsBø unspecv_strings‡østringop_strategy ÃzmaxÄóalgÅènoalignÆì7stringop_algs4À¸unknown_sizeÂèsizeÇÈzÈ Û¸processor_costsÌ¥ addÍóleaÎóshift_varÏóshift_constÐó mult_initѺ mult_bitÓó$divideÔº (movsxÖì<movzx×ì@large_insnØóDmove_ratioÙóHmovzbl_loadÛóLint_loadÜÏ Pint_storeßÏ \fp_moveáóhfp_loadâÏ lfp_storeäÏ xmmx_moveæó„mmx_loadçä ˆmmx_storeéä sse_moveëó˜sse_loadìÏ œsse_storeîÏ ¨mmxsse_to_integerðó´l1_cache_sizeòó¸l2_cache_sizeóó¼prefetch_blockôóÀsimultaneous_prefetchesõóÄbranch_cost÷óÈfaddøóÌfmulùóÐfdivúóÔfabsûóØfchsüóÜfsqrtýóàmemcpyé ämemseté èscalar_stmt_costóìscalar_load_costóðscalar_store_costóôvec_stmt_costóøvec_to_scalar_costóüscalar_to_vec_cost óvec_align_load_cost óvec_unalign_load_cost óvec_store_cost ó cond_taken_branch_cost ócond_not_taken_branch_costóÍóº Ûª óÏ Û¿ óä ÛÔ  ix86_cost ¥ ix86_size_cost¥ ix86_tune_indicesøkZX86_TUNE_SCHEDULEX86_TUNE_PARTIAL_REG_DEPENDENCYX86_TUNE_SSE_PARTIAL_REG_DEPENDENCYX86_TUNE_SSE_SPLIT_REGSX86_TUNE_PARTIAL_FLAG_REG_STALLX86_TUNE_MOVXX86_TUNE_MEMORY_MISMATCH_STALLX86_TUNE_FUSE_CMP_AND_BRANCH_32X86_TUNE_FUSE_CMP_AND_BRANCH_64X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS X86_TUNE_FUSE_ALU_AND_BRANCH X86_TUNE_REASSOC_INT_TO_PARALLEL X86_TUNE_REASSOC_FP_TO_PARALLEL X86_TUNE_ACCUMULATE_OUTGOING_ARGS X86_TUNE_PROLOGUE_USING_MOVEX86_TUNE_EPILOGUE_USING_MOVEX86_TUNE_USE_LEAVEX86_TUNE_PUSH_MEMORYX86_TUNE_SINGLE_PUSHX86_TUNE_DOUBLE_PUSHX86_TUNE_SINGLE_POPX86_TUNE_DOUBLE_POPX86_TUNE_PAD_SHORT_FUNCTIONX86_TUNE_PAD_RETURNSX86_TUNE_FOUR_JUMP_LIMITX86_TUNE_SOFTWARE_PREFETCHING_BENEFICIALX86_TUNE_LCP_STALLX86_TUNE_READ_MODIFYX86_TUNE_USE_INCDECX86_TUNE_INTEGER_DFMODE_MOVESX86_TUNE_OPT_AGUX86_TUNE_AVOID_LEA_FOR_ADDRX86_TUNE_SLOW_IMUL_IMM32_MEM X86_TUNE_SLOW_IMUL_IMM8!X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE"X86_TUNE_SINGLE_STRINGOP#X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES$X86_TUNE_USE_SAHF%X86_TUNE_USE_CLTD&X86_TUNE_USE_BT'X86_TUNE_USE_HIMODE_FIOP(X86_TUNE_USE_SIMODE_FIOP)X86_TUNE_USE_FFREEP*X86_TUNE_EXT_80387_CONSTANTS+X86_TUNE_VECTORIZE_DOUBLE,X86_TUNE_GENERAL_REGS_SSE_SPILL-X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL.X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL/X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL0X86_TUNE_SSE_TYPELESS_STORES1X86_TUNE_SSE_LOAD0_BY_PXOR2X86_TUNE_INTER_UNIT_MOVES_TO_VEC3X86_TUNE_INTER_UNIT_MOVES_FROM_VEC4X86_TUNE_INTER_UNIT_CONVERSIONS5X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS6X86_TUNE_USE_VECTOR_FP_CONVERTS7X86_TUNE_USE_VECTOR_CONVERTS8X86_TUNE_SLOW_PSHUFB9X86_TUNE_VECTOR_PARALLEL_EXECUTION:X86_TUNE_AVOID_4BYTE_PREFIXES;X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL<X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL=X86_TUNE_AVX128_OPTIMAL>X86_TUNE_DOUBLE_WITH_ADD?X86_TUNE_ALWAYS_FANCY_MATH_387@X86_TUNE_UNROLL_STRLENAX86_TUNE_SHIFT1BX86_TUNE_ZERO_EXTEND_WITH_ANDCX86_TUNE_PROMOTE_HIMODE_IMULDX86_TUNE_FAST_PREFIXEX86_TUNE_READ_MODIFY_WRITEFX86_TUNE_MOVE_M1_VIA_ORGX86_TUNE_NOT_UNPAIRABLEHX86_TUNE_PARTIAL_REG_STALLIX86_TUNE_PROMOTE_QIMODEJX86_TUNE_PROMOTE_HI_REGSKX86_TUNE_HIMODE_MATHLX86_TUNE_SPLIT_LONG_MOVESMX86_TUNE_USE_XCHGBNX86_TUNE_USE_MOV0OX86_TUNE_NOT_VECTORMODEPX86_TUNE_AVOID_VECTOR_DECODEQX86_TUNE_AVOID_FALSE_DEP_FOR_BMIRX86_TUNE_BRANCH_PREDICTION_HINTSSX86_TUNE_QIMODE_MATHTX86_TUNE_PROMOTE_QI_REGSUX86_TUNE_ADJUST_UNROLLVX86_TUNE_ONE_IF_CONV_INSNWX86_TUNE_LASTX+j ÛW ix86_tune_featuressZix86_arch_indicesøúX86_ARCH_CMOVX86_ARCH_CMPXCHGX86_ARCH_CMPXCHG8BX86_ARCH_XADDX86_ARCH_BSWAPX86_ARCH_LAST+ Û ix86_arch_features x86_prefetch_sse+_dont_use_tree_here_ x86_mfence1{Rreg_classø;]NO_REGSAREGDREGCREGBREGSIREGDIREGAD_REGSCLOBBERED_REGSQ_REGS NON_Q_REGS INDEX_REGS LEGACY_REGS GENERAL_REGS FP_TOP_REGFP_SECOND_REGFLOAT_REGSSSE_FIRST_REGNO_REX_SSE_REGSSSE_REGSEVEX_SSE_REGSBND_REGSALL_SSE_REGSMMX_REGSFP_TOP_SSE_REGSFP_SECOND_SSE_REGSFLOAT_SSE_REGSFLOAT_INT_REGSINT_SSE_REGSFLOAT_INT_SSE_REGSMASK_EVEX_REGSMASK_REGSALL_REGS LIM_REG_CLASSES!ór ÛPb dbx_register_mapcr dbx64_register_mapdr svr4_dbx_register_maperóÙ Û É x86_64_ms_sysv_extra_clobbered_registersgÙprocessor_typeø÷qPROCESSOR_GENERICPROCESSOR_I386PROCESSOR_I486PROCESSOR_PENTIUMPROCESSOR_LAKEMONTPROCESSOR_PENTIUMPROPROCESSOR_PENTIUM4PROCESSOR_NOCONAPROCESSOR_CORE2PROCESSOR_NEHALEM PROCESSOR_SANDYBRIDGE PROCESSOR_HASWELL PROCESSOR_BONNELL PROCESSOR_SILVERMONT PROCESSOR_KNLPROCESSOR_SKYLAKE_AVX512PROCESSOR_INTELPROCESSOR_GEODEPROCESSOR_K6PROCESSOR_ATHLONPROCESSOR_K8PROCESSOR_AMDFAM10PROCESSOR_BDVER1PROCESSOR_BDVER2PROCESSOR_BDVER3PROCESSOR_BDVER4PROCESSOR_BTVER1PROCESSOR_BTVER2PROCESSOR_ZNVER1PROCESSOR_max ix86_tune  ix86_arch  ix86_preferred_stack_boundary! ø ix86_incoming_stack_boundary" ø]ð ÛPà regclass_map% ðsigned charUQItype u+long long unsigned intfloatcomplex floatdoublecomplex doublecomplex long double__float128 __unknown__(Á Ûÿ± __popcount_tab ëÁ __clz_tab ñÁfunc_ptr *ÿï __CTOR_LIST__ / __DTOR_LIST__ 0  ;@&  œ;@% ™B$ >  : ;  : ; I8  I: ; II! 4: ; I?< .?: ; 'I@–B : ; I 4: ; I .?: ; 'I@—B%% $ > &I : ;  : ; I8  I: ; II ! 4: ; I?< 4: ;I?< !I/ 'II& I: ; (  : ;  : ;I8  : ;I8 I: ;<'4G: ;àû c:/Users/dandelotc:/mingw/includec:/mingw/lib/gcc/mingw32/6.3.0/includec:/mingw/include/systest.cstdio.h_mingw.hmsvcrtver.hw32api.hsdkddkver.hstddef.htypes.hstdarg.h`@ =„1Zƒ…ƒó!mIû ../../../src/gcc-6.3.0/libgcc/config/i386cygwin.S @¢""YK0g=YY0/>""SMû /home/keith/mingw32-gcc-6.3.0/include../../../src/gcc-6.3.0/libgcc/../include../.././gcc../../../src/gcc-6.3.0/libgcc/../gcc/config/i386../../../src/gcc-6.3.0/libgccstdio.hstdlib.hgetopt.htime.hhashtab.hinsn-constants.hi386.hi386-opts.hlibgcc2.hgbl-ctors.hlibgcc2.cÿÿÿÿ| ˆ  @*AA €fÀAÁ__STDC__ 1__STDC_VERSION__ 201112L__STDC_UTF_16__ 1__STDC_UTF_32__ 1__STDC_HOSTED__ 1__GNUC__ 6__GNUC_MINOR__ 3__GNUC_PATCHLEVEL__ 0__VERSION__ "6.3.0"__ATOMIC_RELAXED 0__ATOMIC_SEQ_CST 5__ATOMIC_ACQUIRE 2__ATOMIC_RELEASE 3__ATOMIC_ACQ_REL 4__ATOMIC_CONSUME 1__FINITE_MATH_ONLY__ 0__SIZEOF_INT__ 4__SIZEOF_LONG__ 4__SIZEOF_LONG_LONG__ 8__SIZEOF_SHORT__ 2__SIZEOF_FLOAT__ 4__SIZEOF_DOUBLE__ 8__SIZEOF_LONG_DOUBLE__ 12__SIZEOF_SIZE_T__ 4__CHAR_BIT__ 8__BIGGEST_ALIGNMENT__ 16__ORDER_LITTLE_ENDIAN__ 1234__ORDER_BIG_ENDIAN__ 4321__ORDER_PDP_ENDIAN__ 3412__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN____FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN____SIZEOF_POINTER__ 4__SIZE_TYPE__ unsigned int__PTRDIFF_TYPE__ int__WCHAR_TYPE__ short unsigned int__WINT_TYPE__ short unsigned int__INTMAX_TYPE__ long long int__UINTMAX_TYPE__ long long unsigned int__CHAR16_TYPE__ short unsigned int__CHAR32_TYPE__ unsigned int__SIG_ATOMIC_TYPE__ int__INT8_TYPE__ signed char__INT16_TYPE__ short int__INT32_TYPE__ int__INT64_TYPE__ long long int__UINT8_TYPE__ unsigned char__UINT16_TYPE__ short unsigned int__UINT32_TYPE__ unsigned int__UINT64_TYPE__ long long unsigned int__INT_LEAST8_TYPE__ signed char__INT_LEAST16_TYPE__ short int__INT_LEAST32_TYPE__ int__INT_LEAST64_TYPE__ long long int__UINT_LEAST8_TYPE__ unsigned char__UINT_LEAST16_TYPE__ short unsigned int__UINT_LEAST32_TYPE__ unsigned int__UINT_LEAST64_TYPE__ long long unsigned int__INT_FAST8_TYPE__ signed char__INT_FAST16_TYPE__ short int__INT_FAST32_TYPE__ int__INT_FAST64_TYPE__ long long int__UINT_FAST8_TYPE__ unsigned char__UINT_FAST16_TYPE__ short unsigned int__UINT_FAST32_TYPE__ unsigned int__UINT_FAST64_TYPE__ long long unsigned int__INTPTR_TYPE__ int__UINTPTR_TYPE__ unsigned int__has_include(STR) __has_include__(STR)__has_include_next(STR) __has_include_next__(STR)__GXX_ABI_VERSION 1010__SCHAR_MAX__ 0x7f__SHRT_MAX__ 0x7fff__INT_MAX__ 0x7fffffff__LONG_MAX__ 0x7fffffffL__LONG_LONG_MAX__ 0x7fffffffffffffffLL__WCHAR_MAX__ 0xffff__WCHAR_MIN__ 0__WINT_MAX__ 0xffff__WINT_MIN__ 0__PTRDIFF_MAX__ 0x7fffffff__SIZE_MAX__ 0xffffffffU__INTMAX_MAX__ 0x7fffffffffffffffLL__INTMAX_C(c) c ## LL__UINTMAX_MAX__ 0xffffffffffffffffULL__UINTMAX_C(c) c ## ULL__SIG_ATOMIC_MAX__ 0x7fffffff__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)__INT8_MAX__ 0x7f__INT16_MAX__ 0x7fff__INT32_MAX__ 0x7fffffff__INT64_MAX__ 0x7fffffffffffffffLL__UINT8_MAX__ 0xff__UINT16_MAX__ 0xffff__UINT32_MAX__ 0xffffffffU__UINT64_MAX__ 0xffffffffffffffffULL__INT_LEAST8_MAX__ 0x7f__INT8_C(c) c__INT_LEAST16_MAX__ 0x7fff__INT16_C(c) c__INT_LEAST32_MAX__ 0x7fffffff__INT32_C(c) c__INT_LEAST64_MAX__ 0x7fffffffffffffffLL__INT64_C(c) c ## LL__UINT_LEAST8_MAX__ 0xff__UINT8_C(c) c__UINT_LEAST16_MAX__ 0xffff__UINT16_C(c) c__UINT_LEAST32_MAX__ 0xffffffffU__UINT32_C(c) c ## U__UINT_LEAST64_MAX__ 0xffffffffffffffffULL__UINT64_C(c) c ## ULL__INT_FAST8_MAX__ 0x7f__INT_FAST16_MAX__ 0x7fff__INT_FAST32_MAX__ 0x7fffffff__INT_FAST64_MAX__ 0x7fffffffffffffffLL__UINT_FAST8_MAX__ 0xff__UINT_FAST16_MAX__ 0xffff__UINT_FAST32_MAX__ 0xffffffffU__UINT_FAST64_MAX__ 0xffffffffffffffffULL__INTPTR_MAX__ 0x7fffffff__UINTPTR_MAX__ 0xffffffffU__GCC_IEC_559 2__GCC_IEC_559_COMPLEX 2__FLT_EVAL_METHOD__ 2__DEC_EVAL_METHOD__ 2__FLT_RADIX__ 2__FLT_MANT_DIG__ 24__FLT_DIG__ 6__FLT_MIN_EXP__ (-125)__FLT_MIN_10_EXP__ (-37)__FLT_MAX_EXP__ 128__FLT_MAX_10_EXP__ 38__FLT_DECIMAL_DIG__ 9__FLT_MAX__ 3.40282346638528859812e+38F__FLT_MIN__ 1.17549435082228750797e-38F__FLT_EPSILON__ 1.19209289550781250000e-7F__FLT_DENORM_MIN__ 1.40129846432481707092e-45F__FLT_HAS_DENORM__ 1__FLT_HAS_INFINITY__ 1__FLT_HAS_QUIET_NAN__ 1__DBL_MANT_DIG__ 53__DBL_DIG__ 15__DBL_MIN_EXP__ (-1021)__DBL_MIN_10_EXP__ (-307)__DBL_MAX_EXP__ 1024__DBL_MAX_10_EXP__ 308__DBL_DECIMAL_DIG__ 17__DBL_MAX__ ((double)1.79769313486231570815e+308L)__DBL_MIN__ ((double)2.22507385850720138309e-308L)__DBL_EPSILON__ ((double)2.22044604925031308085e-16L)__DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L)__DBL_HAS_DENORM__ 1__DBL_HAS_INFINITY__ 1__DBL_HAS_QUIET_NAN__ 1__LDBL_MANT_DIG__ 64__LDBL_DIG__ 18__LDBL_MIN_EXP__ (-16381)__LDBL_MIN_10_EXP__ (-4931)__LDBL_MAX_EXP__ 16384__LDBL_MAX_10_EXP__ 4932__DECIMAL_DIG__ 21__LDBL_MAX__ 1.18973149535723176502e+4932L__LDBL_MIN__ 3.36210314311209350626e-4932L__LDBL_EPSILON__ 1.08420217248550443401e-19L__LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L__LDBL_HAS_DENORM__ 1__LDBL_HAS_INFINITY__ 1__LDBL_HAS_QUIET_NAN__ 1__DEC32_MANT_DIG__ 7__DEC32_MIN_EXP__ (-94)__DEC32_MAX_EXP__ 97__DEC32_MIN__ 1E-95DF__DEC32_MAX__ 9.999999E96DF__DEC32_EPSILON__ 1E-6DF__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF__DEC64_MANT_DIG__ 16__DEC64_MIN_EXP__ (-382)__DEC64_MAX_EXP__ 385__DEC64_MIN__ 1E-383DD__DEC64_MAX__ 9.999999999999999E384DD__DEC64_EPSILON__ 1E-15DD__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD__DEC128_MANT_DIG__ 34__DEC128_MIN_EXP__ (-6142)__DEC128_MAX_EXP__ 6145__DEC128_MIN__ 1E-6143DL__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL__DEC128_EPSILON__ 1E-33DL__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL__REGISTER_PREFIX__ __USER_LABEL_PREFIX__ ___GNUC_STDC_INLINE__ 1__NO_INLINE__ 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1__GCC_ATOMIC_BOOL_LOCK_FREE 2__GCC_ATOMIC_CHAR_LOCK_FREE 2__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2__GCC_ATOMIC_SHORT_LOCK_FREE 2__GCC_ATOMIC_INT_LOCK_FREE 2__GCC_ATOMIC_LONG_LOCK_FREE 2__GCC_ATOMIC_LLONG_LOCK_FREE 2__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1__GCC_ATOMIC_POINTER_LOCK_FREE 2__GCC_HAVE_DWARF2_CFI_ASM 1__PRAGMA_REDEFINE_EXTNAME 1__SIZEOF_WCHAR_T__ 2__SIZEOF_WINT_T__ 2__SIZEOF_PTRDIFF_T__ 4__i386 1__i386__ 1i386 1__SIZEOF_FLOAT80__ 12__SIZEOF_FLOAT128__ 16__ATOMIC_HLE_ACQUIRE 65536__ATOMIC_HLE_RELEASE 131072__GCC_ASM_FLAG_OUTPUTS__ 1__i586 1__i586__ 1__pentium 1__pentium__ 1__code_model_32__ 1__SEG_FS 1__SEG_GS 1_X86_ 1__stdcall __attribute__((__stdcall__))__fastcall __attribute__((__fastcall__))__thiscall __attribute__((__thiscall__))__cdecl __attribute__((__cdecl__))_stdcall __attribute__((__stdcall__))_fastcall __attribute__((__fastcall__))_thiscall __attribute__((__thiscall__))_cdecl __attribute__((__cdecl__))__GXX_MERGED_TYPEINFO_NAMES 0__GXX_TYPEINFO_EQUALITY_INLINE 0__MSVCRT__ 1__MINGW32__ 1_WIN32 1__WIN32 1__WIN32__ 1WIN32 1__WINNT 1__WINNT__ 1WINNT 1_INTEGRAL_MAX_BITS 64__declspec(x) __attribute__((x))__DECIMAL_BID_FORMAT__ 13_STDIO_H 8"__MINGW_H 1__MINGW32_VERSION 5000001L2__MINGW32_MAJOR_VERSION 53__MINGW32_MINOR_VERSION 04__MINGW32_PATCHLEVEL 1B"_MSVCRTVER_H *__MSVCR60_DLL 0x0600+__MSVCR61_DLL 0x0601,__MSVCR70_DLL 0x0700-__MSVCR71_DLL 0x0701.__MSVCR80_DLL 0x0800/__MSVCR90_DLL 0x09000__MSVCR100_DLL 0x10001__MSVCR110_DLL 0x11002__MSVCR120_DLL 0x1200D__MSVCRT_VERSION__ __MSVCR60_DLLI"_W32API_H 3__W32API_VERSION 5000001L4__W32API_MAJOR_VERSION 55__W32API_MINOR_VERSION 06__W32API_PATCHLEVEL 1;"_SDKDDKVER_H )OSVERSION_MASK 0xFFFF0000*SPVERSION_MASK 0x0000FF00+SUBVERSION_MASK 0x000000FF0OSVER(ver) ((ver) & OSVERSION_MASK)1SPVER(ver) (((ver) & SPVERSION_MASK) >> 8)2SUBVER(ver) ((ver) & SUBVERSION_MASK)3WINNTVER(ver) ((ver) >> 16)7NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT(ver)8_NTDDI_VERSION_FROM_WIN32_WINNT(ver) ver ##0000>_WIN32_WINNT_NT4 0x0400?_WIN32_WINNT_NT4E 0x0401@_WIN32_WINNT_NT4SP3 0x0403A_WIN32_WINDOWS_95 0x0400B_WIN32_WINDOWS_98 0x0410C_WIN32_WINDOWS_ME 0x0490D_WIN32_WINNT_WIN2K 0x0500E_WIN32_WINNT_WINXP 0x0501F_WIN32_WINNT_WS03 0x0502G_WIN32_WINNT_WIN6 0x0600H_WIN32_WINNT_VISTA 0x0600I_WIN32_WINNT_WS08 0x0600J_WIN32_WINNT_LONGHORN 0x0600K_WIN32_WINNT_WIN7 0x0601L_WIN32_WINNT_WIN8 0x0602M_WIN32_WINNT_WINBLUE 0x0603R_WIN32_IE_IE50 0x0500S_WIN32_IE_IE501 0x0501T_WIN32_IE_IE55 0x0550U_WIN32_IE_IE56 0x0560V_WIN32_IE_IE60 0x0600W_WIN32_IE_IE60SP1 0x0601X_WIN32_IE_IE60SP2 0x0603Y_WIN32_IE_IE70 0x0700Z_WIN32_IE_IE80 0x0800\_WIN32_IE_IE30 0x0300]_WIN32_IE_IE301 0x0301^_WIN32_IE_IE302 0x0302__WIN32_IE_IE40 0x0400`_WIN32_IE_IE401 0x0401e__NTDDI_WIN5 0x05000000f__NTDDI_WIN51 0x05010000g__NTDDI_WIN52 0x05020000h__NTDDI_WIN6 0x06000000i__NTDDI_WIN61 0x06010000j__NTDDI_WIN62 0x06020000k__NTDDI_WIN63 0x06030000l__NTDDI_SP0 0x00000000m__NTDDI_SP1 0x00000100n__NTDDI_SP2 0x00000200o__NTDDI_SP3 0x00000300p__NTDDI_SP4 0x00000400rNTDDI_WIN2K __NTDDI_WIN5 + __NTDDI_SP0sNTDDI_WIN2KSP1 __NTDDI_WIN5 + __NTDDI_SP1tNTDDI_WIN2KSP2 __NTDDI_WIN5 + __NTDDI_SP2uNTDDI_WIN2KSP3 __NTDDI_WIN5 + __NTDDI_SP3vNTDDI_WIN2KSP4 __NTDDI_WIN5 + __NTDDI_SP4xNTDDI_WINXP __NTDDI_WIN51 + __NTDDI_SP0yNTDDI_WINXPSP1 __NTDDI_WIN51 + __NTDDI_SP1zNTDDI_WINXPSP2 __NTDDI_WIN51 + __NTDDI_SP2{NTDDI_WINXPSP3 __NTDDI_WIN51 + __NTDDI_SP3}NTDDI_WS03 __NTDDI_WIN52 + __NTDDI_SP0~NTDDI_WS03SP1 __NTDDI_WIN52 + __NTDDI_SP1NTDDI_WS03SP2 __NTDDI_WIN52 + __NTDDI_SP2NTDDI_VISTA __NTDDI_WIN6 + __NTDDI_SP0‚NTDDI_VISTASP1 __NTDDI_WIN6 + __NTDDI_SP1ƒNTDDI_VISTASP2 __NTDDI_WIN6 + __NTDDI_SP2…NTDDI_LONGHORN NTDDI_VISTA‡NTDDI_WIN6 NTDDI_VISTAˆNTDDI_WIN6SP1 NTDDI_VISTASP1‰NTDDI_WIN6SP2 NTDDI_VISTASP2‹NTDDI_WS08 __NTDDI_WIN6 + __NTDDI_SP1NTDDI_WIN7 __NTDDI_WIN61 + __NTDDI_SP0NTDDI_WIN8 __NTDDI_WIN62 + __NTDDI_SP0‘NTDDI_WINBLUE __NTDDI_WIN63 + __NTDDI_SP0¹_WIN32_WINNT _WIN32_WINNT_WIN2K¾WINVER _WIN32_WINNTÉNTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)Ü_M_IX86 500†_M_IX86_FP 0OWindows95 _WIN32_WINDOWS_95PWindows98 _WIN32_WINDOWS_98QWindowsME _WIN32_WINDOWS_MEYWindowsNT4 _WIN32_WINNT_NT4ZWindows2000 _WIN32_WINNT_WIN2K[WindowsXP _WIN32_WINNT_WINXP\Windows2003 _WIN32_WINNT_WS03]WindowsVista _WIN32_WINNT_VISTAeIE3 _WIN32_IE_IE30fIE301 _WIN32_IE_IE301gIE302 _WIN32_IE_IE302hIE4 _WIN32_IE_IE40iIE401 _WIN32_IE_IE401jIE5 _WIN32_IE_IE50kIE5a _WIN32_IE_IE50lIE5b _WIN32_IE_IE50mIE501 _WIN32_IE_IE501nIE55 _WIN32_IE_IE55oIE56 _WIN32_IE_IE56pIE6 _WIN32_IE_IE60qIE601 _WIN32_IE_IE60SP1rIE602 _WIN32_IE_IE60SP2sIE7 _WIN32_IE_IE70š__AW_SUFFIXED__(__NAME__) __NAME__ ##A __AW_EXTENDED__(__NAME__) __AW_SUFFIXED__(__NAME__ ##_)©__AW_STRING_A__(__TEXT__) __TEXT__ª__AW__WCHAR_T__(__TEXT__) __AW_STRING_A__(L ##__TEXT__)«__AW_STRING_W__(__TEXT__) __AW__WCHAR_T__(__TEXT__)²__AW_ALIAS__(__NAME__) __AW_SUFFIXED__(__NAME__) __NAME__³__AW_ALIAS_EX__(__NAME__) __AW_EXTENDED__(__NAME__) __NAME__Á_EXTERN_C externÂ_BEGIN_C_DECLS Ã_END_C_DECLS m__CRT_GLOB_USE_MSVCRT__ 0x0001r__CRT_GLOB_USE_MINGW__ 0x0002—__CRT_GLOB_USE_SINGLE_QUOTE__ 0x0010˜__CRT_GLOB_BRACKET_GROUPS__ 0x0020¡__CRT_GLOB_ESCAPE_CHAR__ (char)(127)§__MINGW_ANSI_STDIO__ 0x0000000000000001ULL¬__MINGW_LC_EXTENSIONS__ 0x0000000000000050ULL­__MINGW_LC_MESSAGES__ 0x0000000000000010ULL®__MINGW_LC_ENVVARS__ 0x0000000000000040ULL³__attribute__á__MINGW_IMPORT extern __attribute__((__dllimport__))ç_CRTIMP ê__DECLSPEC_SUPPORTED þ__int64 long long__int32 long„__int16 short‡__int8 charŠ__small char__hyper long long›__MINGW_GNUC_PREREQ(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))¦__CRT_INLINE extern inline __attribute__((__gnu_inline__))²_CRTALIAS __CRT_INLINE __attribute__((__always_inline__))³__CRT_ALIAS __CRT_INLINE __attribute__((__always_inline__))Á__JMPSTUB__(__BUILD_HINT__) Â__LIBIMPL__(__BUILD_HINT__) È__UNUSED_PARAM(x) x __attribute__((__unused__))Ï__MINGW_ATTRIB_NORETURN __attribute__((__noreturn__))Ð__MINGW_ATTRIB_CONST __attribute__((__const__))×__MINGW_ATTRIB_MALLOC __attribute__((__malloc__))Ø__MINGW_ATTRIB_PURE __attribute__((__pure__))â__MINGW_ATTRIB_NONNULL(arg) __attribute__((__nonnull__(arg)))è__MINGW_ATTRIB_DEPRECATED __attribute__((__deprecated__))î__MINGW_NOTHROW __attribute__((__nothrow__))__USE_MINGW_ANSI_STDIO (__MINGW_FEATURES__ & __MINGW_ANSI_STDIO__)›__paste(prefix,suffix) prefix ## suffixœ__valueless(token) ((token - 0) == 0) && (__paste(token,10) == 10)Î_POSIX_C_SOURCE 200809LÕ_EMULATE_GLIBC 1õ_ISOC99_SOURCE 0x07ž_MINGW32_SOURCE_EXTENDED 1A__need_NULL B__need_size_t C__need_wchar_t D__need_wint_t E»__size_t__ ¼__SIZE_T__ ½_SIZE_T ¾_SYS_SIZE_T_H ¿_T_SIZE_ À_T_SIZE Á__SIZE_T Â_SIZE_T_ Ã_BSD_SIZE_T_ Ä_SIZE_T_DEFINED_ Å_SIZE_T_DEFINED Æ_BSD_SIZE_T_DEFINED_ Ç_SIZE_T_DECLARED È___int_size_t_h É_GCC_SIZE_T Ê_SIZET_ Ò__size_t î__need_size_t‹__wchar_t__ Œ__WCHAR_T__ _WCHAR_T Ž_T_WCHAR_ _T_WCHAR __WCHAR_T ‘_WCHAR_T_ ’_BSD_WCHAR_T_ “_WCHAR_T_DEFINED_ ”_WCHAR_T_DEFINED •_WCHAR_T_H –___int_wchar_t_h —__INT_WCHAR_T_H ˜_GCC_WCHAR_T ™_WCHAR_T_DECLARED ¦_BSD_WCHAR_T_Û__need_wchar_tà_WINT_T ç__need_wint_t‘NULL–NULL ((void *)0)œ__need_NULLK__need_off_t L__need_ssize_t S__need___off64_t ^T__need_off_tl__need___off64_t„__need_ssize_t£__need_time_te__need___va_list f "__need___va_list'__GNUC_VA_LIST g__VALIST __builtin_va_listq_IOREAD 1r_IOWRT 2s_IORW 0x0080xSTDIN_FILENO 0ySTDOUT_FILENO 1zSTDERR_FILENO 2~EOF (-1)FILENAME_MAX (260)“FOPEN_MAX (20)—TMP_MAX 32767ž_P_tmpdir "\\" P_tmpdir _P_tmpdir¢_wP_tmpdir L"\\"©L_tmpnam (16)«_IOFBF 0x0000¬_IOLBF 0x0040­_IONBF 0x0004¯_IOMYBUF 0x0008°_IOEOF 0x0010±_IOERR 0x0020²_IOSTRG 0x0040ºBUFSIZ 512ÀSEEK_SET 0ÁSEEK_CUR 1ÂSEEK_END 2óstdin (&_iob[STDIN_FILENO])ôstdout (&_iob[STDOUT_FILENO])õstderr (&_iob[STDERR_FILENO])¯__mingw_stdio_redirect__°__mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F)±__Wformat_mingw_printf(F,A) __attribute__((__format__(__mingw_printf__,F,A)))·__Wformat(F) __Wformat_ ##F __mingw_ ##FÉ__Wformat_printf __Wformat_mingw_printf(1,2)Ê__Wformat_fprintf __Wformat_mingw_printf(2,3)Ë__Wformat_sprintf __Wformat_mingw_printf(2,3)Ì__Wformat_vprintf __Wformat_mingw_printf(1,0)Í__Wformat_vfprintf __Wformat_mingw_printf(2,0)Î__Wformat_vsprintf __Wformat_mingw_printf(2,0)Ó__Wformat_snprintf __Wformat_mingw_printf(3,4)Ô__Wformat_vsnprintf __Wformat_mingw_printf(3,0)ã_MSVC_PRINTF_QUIRKS 0x0100Uä_QUERY_MSVC_PRINTF_QUIRKS ~0U, 0Uå_DISABLE_MSVC_PRINTF_QUIRKS ~_MSVC_PRINTF_QUIRKS, 0Uæ_ENABLE_MSVC_PRINTF_QUIRKS ~0U, _MSVC_PRINTF_QUIRKSÑ__WformatÒ__mingw_stdio_redirect__Ó__mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F)Ô__Wformat_msvcrt_printf(F,A) __attribute__((__format__(__ms_printf__,F,A)))Õ__Wformat(F) __Wformat_ms_ ##F __msvcrt_ ##F×__Wformat_ms_printf __Wformat_msvcrt_printf(1,2)Ø__Wformat_ms_fprintf __Wformat_msvcrt_printf(2,3)Ù__Wformat_ms_sprintf __Wformat_msvcrt_printf(2,3)Ú__Wformat_ms_vprintf __Wformat_msvcrt_printf(1,0)Û__Wformat_ms_vfprintf __Wformat_msvcrt_printf(2,0)Ü__Wformat_ms_vsprintf __Wformat_msvcrt_printf(2,0)å__mingw_stdio_redirect__æ__Wformat¤feof(__F) ((__F)->_flag & _IOEOF)¥ferror(__F) ((__F)->_flag & _IOERR)Í_TWO_DIGIT_EXPONENT 1Ô_THREE_DIGIT_EXPONENT 0Ù_EXPONENT_DIGIT_MASK (_TWO_DIGIT_EXPONENT | _THREE_DIGIT_EXPONENT)‹__USE_MINGW_PRINTF 0œ_fileno(__F) ((__F)->_file)žfileno(__F) ((__F)->_file)]  uà … _atexit  __onexit0 .text6*.bss.fileþÿgcygming-crtbegin.c_obj˜­»@ Ñ0 .text@.data.bssé¸d.rdatacóD.jcr.fileiþÿgtest.c_buffle` _mainm .text`W.data.bss þ '  É  '?4 óX#éX@À .textÀŸJ` .text`Ü .bss$_@  rp  ___mainÀ  .text@ œ .data.bss(…0  ˜À  .textà ã.bss,.CRT$XDZ.CRT$XDA.CRT$XLA.tls$ZZZ.tls$AAA¥0  ÃÀ  ä`  .textÐ '#.bss< ù@ .text  !.bss\.rdatahª.file{þÿgfakeþ' § É 4 q.text*.data.bssh   8.file þÿglibgcc2.c.text<.data.bsshþÎ X Ý @ 4u Wól!@ .text@l.data+à 9Ð  .text°4.rdataK0! .text0!ô.bssh.rdata(\°& mp( ~À( ) £p) ´ ) .text0%á.idata$5ð.idata$6ª.idata$5ì.idata$6ž.idata$5è.idata$6”.idata$5ä.idata$6Š.idata$5à.idata$6€.idata$5Ü.idata$6v.idata$5Ø.idata$6j.idata$5Ô.idata$6`.idata$5Ð.idata$6V.idata$5Ì.idata$6J.idata$5È.idata$6@.idata$5Ä.idata$66.idata$5À.idata$6..idata$5¼.idata$6$.idata$6.idata$5´.idata$6.idata$5°.idata$6.idata$6ü.idata$6ò.idata$5¤.idata$6æ.idata$6Þ.idata$5œ.idata$6Ò.idata$5”.idata$6¼.idata$5.idata$6².idata$5ˆ.idata$6’.idata$5„.idata$6‚.idata$6r.idata$5|.idata$6b.idata$4¨.idata$5|.idata$5h.idata$6<.idata$5d.idata$6*.idata$5`.idata$6.idata$5\.idata$6þ.idata$5X.idata$6î.idata$5T.idata$6Ö.idata$5P.idata$6º.idata$5L.idata$6¨.idata$5H.idata$6”.idata$5D.idata$6„.idata$5@.idata$6r.idata$5<.idata$6d.idata$58.idata$6T.idata$54.idata$6B.idata$50.idata$66.idata$5,.idata$6(.idata$5(.idata$6.idata$5$.idata$6ø.idata$4P.idata$5$.idata$5t.idata$6V.idata$5p.idata$6L.idata$4œ.idata$5p.file$þÿgcygming-crtend.cÅ€ Ôá€+ .textx+.data.bsslé€ <.jcrö€+ ”+óÐ.idata$5˜.idata$6Æ.idata$5Œ.idata$6 4__cexit¸* )à* <ä[œl@+ ~°Ž0+ ¬œ+_free€* »dÔ¨ãÀ* ïDð* $h;8Ra`vœŠP__errno°* ­`+ ÆäÚ´___xl_cçÿÿÿÿÿ ÿÿ2ÿÿN`r‚t___xl_z ’€¦ + ¶„Ê¬ÙØ* ê4 + # :Pl]ÿÿŽpœ¤¬ºäÝÿÿçÿÿÿ” È* L3+ EWð_strcoll@* g(+ zŠÜ__dll__ÿÿ˜ÿÿ_fwritex* ­¸»ÌË(Þ@ÿÿí * ÷ÿÿ ø*  * '<_memcpy`* <øH]ä{P* †ˆ__argc˜¤P+ ³àÂÏÐ* ÞH+ _tolower0* ___xl_a___xl_dë+ùh*  ÿÿ__CRT_MTd p + ; 8G _strdupp+ __argvY +_callocˆ* __fmode h ÿÿ{ Љ 8+ š ÿÿ­ T_reallocX* Ë ÈÙ ¸í ÿÿ Ô $ h+ ) __end__3 H_signalH* _mallocp* M œ+[ ˜k ÿÿž X+ ¶ ¨* Á ÿÿÚ ì @ÿÿù ÿÿ ä ÿÿD O ¼_abort* ] r |‡ ” ,© ,Á + Þ $î Àú \ 8 ÿÿP ÿÿa èp { ˜* … ’ § ä¹ Ç ÿÿã 0ö ÿÿ ì_strlen8*  Œ4 0L è* [ $z + ’ @« XÁ ØÒ äô  d#.>(* H(fÄt.eh_frame.debug_aranges.debug_info.debug_abbrev.debug_line.debug_frame.debug_macro__mingw32_init_mainargs_mainCRTStartup_WinMainCRTStartup_deregister_frame_fn___JCR_LIST_____gcc_register_frame___gcc_deregister_frame.eh_frame.rdata$zzz.debug_info.debug_abbrev.debug_aranges.debug_macro.debug_line__setargv___cpu_features_init___do_global_dtors___do_global_ctors___dyn_tls_init@12___tlregdtor____w64_mingwthr_add_key_dtor____w64_mingwthr_remove_key_dtor___mingw_TLScallback__pei386_runtime_relocator.debug_frame_fesetenv___mingw_glob___mingw_globfree___mingw_dirname___mingw_opendir___mingw_readdir___mingw_closedir___mingw_rewinddir___mingw_telldir___mingw_seekdir___FRAME_END_____JCR_END___register_frame_ctor.text.startup.ctors.65535__imp__FindFirstFileA@8_VirtualProtect@16___RUNTIME_PSEUDO_RELOC_LIST____imp___fullpath_FindFirstFileA@8__imp___setmode__data_start___FreeLibrary@4___DTOR_LIST____imp__VirtualProtect@16__imp___onexit___p__fmode__imp__GetLastError@0_SetUnhandledExceptionFilter@4__imp__VirtualQuery@12__imp__FindNextFileA@8___tls_start____imp__TlsGetValue@4__libmsvcrt_a_iname__imp__InitializeCriticalSection@4_DeleteCriticalSection@4__rt_psrelocs_start__imp__abort__dll_characteristics____size_of_stack_commit____size_of_stack_reserve____major_subsystem_version_____crt_xl_start_____crt_xi_start_____crt_xi_end____imp__stricoll__imp____mb_cur_max_GetLastError@0__imp____p__environ__imp___pctype_VirtualQuery@12_mingw_initltsdrot_force__imp___iob_GetModuleHandleA@4___register_frame_info__libmoldname_a_iname_hmod_libgcc.weak.___register_frame_info.___EH_FRAME_BEGIN____imp__strdup__imp___isctype__bss_start_____RUNTIME_PSEUDO_RELOC_LIST_END____fpreset__size_of_heap_commit____imp___errno___p__environ__imp__GetProcAddress@8_GetProcAddress@8___crt_xp_start____imp__wcstombs_GetCommandLineA@0___crt_xp_end____imp__signal__minor_os_version____imp__atexit__imp__mbstowcs__head_libmsvcrt_a__image_base____isctype__section_alignment___LoadLibraryA@4_wcstombs__imp__FreeLibrary@4__IAT_end____head_libmoldname_a__RUNTIME_PSEUDO_RELOC_LIST___setlocale__imp____p__fmode__tls_start_ExitProcess@4__imp__strcoll__data_end_____getmainargs_FindClose@4__CTOR_LIST___mbstowcs___set_app_type__bss_end____CRT_fmode___crt_xc_end____tls_index___crt_xc_start_____CTOR_LIST____rt_psrelocs_size__imp__memcpy_FindNextFileA@8__file_alignment____imp__LeaveCriticalSection@4__imp__malloc___EH_FRAME_BEGIN____major_os_version____imp__realloc__IAT_start___stricoll__tls_end__imp__GetModuleHandleA@4__DTOR_LIST____imp___fpreset.weak.___deregister_frame_info.___EH_FRAME_BEGIN___EnterCriticalSection@4__fullpath__size_of_heap_reserve_____crt_xt_start_____ImageBase__subsystem____imp__strlen.weak.__Jv_RegisterClasses.___EH_FRAME_BEGIN____CRT_fenv__imp__calloc__Jv_RegisterClasses__imp____getmainargs___tls_end____imp__ExitProcess@4_mingw_initltssuo_force_InitializeCriticalSection@4___cpu_features__imp__free__imp__SetUnhandledExceptionFilter@4___deregister_frame_info__major_image_version____loader_flags____imp__tolower__CRT_glob__setmode___chkstk_ms__head_libkernel32_a__rt_psrelocs_end__imp___cexit__minor_subsystem_version____imp__FindClose@4__minor_image_version____imp__vfprintf__imp____set_app_type_mingw_initltsdyn_force_TlsGetValue@4__imp__DeleteCriticalSection@4_LeaveCriticalSection@4__imp__GetCommandLineA@0__imp__LoadLibraryA@4__imp__setlocale__RUNTIME_PSEUDO_RELOC_LIST_END____libkernel32_a_iname___dyn_tls_init_callback__tls_used___crt_xt_end___vfprintf__imp__EnterCriticalSection@4__imp__fwritelibdwarf-20210528/dwarfdump/dwgetopt.c0000664000175000017500000002627714003122360014473 00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). renamed to make it clear this is a private version. Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* This does not presently handle the option string leading + or leading - features. Such are not used by by libdwarfdump. Nor does it understand the GNU Env var POSIXLY_CORRECT . It does know of the leading ":" in the option string. See BADCH below. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include "dwgetopt.h" #define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a)) int dwopterr = 1, /* if error message should be printed */ dwoptind = 1, /* index into parent argv vector */ dwoptopt, /* character checked for validity */ dwoptreset; /* reset getopt */ char *dwoptarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING ONLY */ /* Use for testing dwgetopt only. Not a standard function. */ void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } #endif /* FOR DEBUGGING ONLY */ static const char *place = EMSG;/* option letter processing */ /* Post Condition: if return FALSE then *argerr is set false. */ static int dwoptnamematches( const struct dwoption *dwlopt, const char *iplace, const char **argloc, int *argerr) { const char *eq = 0; unsigned namelen = 0; unsigned arglen = 0; int d = 0; for (eq = iplace; *eq; ++eq) { if (*eq != '=') { continue; } /* Found =, arg should follow */ namelen = (eq - iplace); if (namelen != (unsigned)strlen(dwlopt->name)) { return FALSE; } eq++; arglen = strlen(eq); break; } if (namelen) { d = strncmp(iplace,dwlopt->name,namelen); if (d) { return FALSE; } if (dwlopt->has_arg == 0) { *argerr = TRUE; return TRUE; } if (arglen) { /* Discarding const, avoiding warning. Data is in user space, so this is ok. */ dwoptarg = (char *)eq; *argloc = (const char *)eq; } else { /* Has arg = but arg is empty. */ dwoptarg = 0; } return TRUE; } else { d = strcmp(iplace,dwlopt->name); if (d) { return FALSE; } if (dwlopt->has_arg == 1) { *argerr = TRUE; return TRUE; } dwoptarg = 0; return TRUE; } } /* dwgetopt_long A reimplemention of a portion of the getopt(3) GNU/Linux getopt_long(). See dwgetopt.h for more details. */ int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex) { char *lplace = 0; if (dwoptreset) { /* Not really supported. */ place = EMSG; return (-1); } if (*place) { int v = dwgetopt(nargc,nargv,ostr); return v; } /* Use local lplace in case we need to call getopt() just below. */ lplace = nargv[dwoptind]; if (dwoptind >= nargc || *lplace++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } if (*lplace != '-') { /* Notice place not disturbed. */ int v = dwgetopt(nargc,nargv,ostr); return v; } /* Starts with two dashes. Now we set the global place */ place = lplace+1; if (!*place) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } /* We think this is a longopt. */ { int lo_num = 0; for (;;lo_num++) { const struct dwoption *dwlopt = longopts +lo_num; const char * argloc = 0; int argerr = 0; int resmatch = 0; if (!dwlopt->name) { dwoptind++; (void)fprintf(stderr, "%s: invalid long option '--%s'\n", nargv[0]?nargv[0]:"", place); /* Leave longindex unchanged. */ place = EMSG; return (BADCH); } resmatch= dwoptnamematches(dwlopt,place, &argloc,&argerr); if (resmatch) { dwoptarg = 0; if (argloc) { /* Must drop const here. Ugh. */ dwoptarg = (char *)argloc; } } if (argerr) { /* resmatch == TRUE arg option missing if required, present but not allowed. GNU Behavior not well documented. Had to experiment. if argument-not-allowed, and we have one, do ??? If argument-required, then here GNU would take the next argv as the argument. we are not currently doing that. */ /**longindex = lo_num; */ if (dwlopt->has_arg) { /* Missing required arg, this does not match GNU getopt_long behavior of taking next argv as the arg value. and thus making getopt_long succeed. */ (void)fprintf(stderr, "%s: missing required long option " "argument '--%s'\n", nargv[0]?nargv[0]:"", place); } else { /* has arg but should not */ (void)fprintf(stderr, "%s: option '--%s' does not allow an argument\n", nargv[0]?nargv[0]:"", dwlopt->name); } dwoptind++; place = EMSG; return (BADCH); } if (resmatch) { *longindex = lo_num; place = EMSG; dwoptind++; return dwlopt->val; } } /* Can never get here */ place = EMSG; dwoptind++; return (-1); } } /* * getopt -- * Parse argc/argv argument vector. * a: means * -afoo * -a foo * and 'foo' is returned in dwoptarg * b:: means * -b * and dwoptarg is null * -bother * and dwoptarg is 'other' */ int dwgetopt(int nargc, char * const nargv[], const char *ostr) { char *oli; /* option letter list index */ if (dwoptreset || *place == 0) { /* update scanning pointer */ dwoptreset = 0; place = nargv[dwoptind]; if (dwoptind >= nargc || *place++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } dwoptopt = *place++; if (dwoptopt == '-' && *place == 0) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } if (dwoptopt == 0) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ place = EMSG; if (strchr(ostr, '-') == NULL) { return -1; } dwoptopt = '-'; } } else { dwoptopt = *place++; } /* See if option letter is one the caller wanted... */ if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) { if (*place == 0) { ++dwoptind; } if (dwopterr && *ostr != ':') { (void)fprintf(stderr, "%s: invalid option -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ dwoptarg = NULL; if (*place == 0) { ++dwoptind; } } else { int reqnextarg = 1; if (oli[1] && (oli[2] == ':')) { /* Pair of :: means special treatment of dwoptarg */ reqnextarg = 0; } /* Option-argument is either the rest of this argument or the entire next argument. */ if (*place ) { /* Whether : or :: */ dwoptarg = STRIP_OFF_CONSTNESS(place); } else if (reqnextarg) { /* ! *place */ if (nargc > (++dwoptind)) { dwoptarg = nargv[dwoptind]; } else { place=EMSG; /* Next arg required, but is missing */ if (*ostr == ':') { /* Leading : in ostr calls for BADARG return. */ return (BADARG); } if (dwopterr) { (void)fprintf(stderr, "%s: option requires an argument. -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } } else { /* ! *place */ /* The key part of :: treatment. */ dwoptarg = NULL; } place = EMSG; ++dwoptind; } return (dwoptopt); /* return option letter */ } libdwarf-20210528/dwarfdump/print_weaknames.c0000664000175000017500000000703213764006205016025 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" /* Get all the data in .debug_weaknames */ extern int print_weaknames(Dwarf_Debug dbg,Dwarf_Error *err) { Dwarf_Weak *globbuf = NULL; Dwarf_Signed count = 0; int wkres = 0; struct esb_s sanitname; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; glflags.current_section_id = DEBUG_WEAKNAMES; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_weaknames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused, there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ dwarf_return_empty_pubnames(dbg,1,err); } wkres = dwarf_get_weaks(dbg, &globbuf, &count, err); if (wkres == DW_DLV_ERROR) { printf("\n%s\n",esb_get_string(&sanitname)); esb_destructor(&sanitname); return wkres; } else if (wkres == DW_DLV_NO_ENTRY) { Dwarf_Error berr = 0; esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&berr); /* no weaknames */ return wkres; } else { int printed = 0; if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); printed = 1; } wkres = print_all_pubnames_style_records(dbg, "weakname", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, err); esb_destructor(&sanitname); /* globbuf should be zero, count 0 in case of DW_DLV_ERROR. That's ok */ dwarf_weaks_dealloc(dbg, globbuf, count); dwarf_return_empty_pubnames(dbg,0,err); if (wkres == DW_DLV_ERROR) { if (!printed) { printf("\n%s\n",esb_get_string(&sanitname)); } return wkres; } } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,err); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/ChangeLog0000664000175000017500000002710414054251245014245 000000000000002021-05-28 David Anderson * dwarf_names.c,dwarf_names.h,dwarfdump-af-table.h, dwarfdump-ta-ext-table.h,dwarfdump-ta-table.h, dwarfdump-tt-ext-table.h,dwarfdump-tt-table.h: Regenerated with new version string. 2021-05-25 David Anderson * attr_form.c,command_options.c,compiler_info.c,dwarfdump.c, dwconf.c,print_tag_attributes_usage.c: Fixed indents, removed trailing whitespace. 2021-05-20 David Anderson * print_die.c: If a DW_OP_skip or DW_OP_bra went to a previous offset the correctness check did not find it and issued an erroneous error. 2021-05-16 David Anderson * runtests.sh: A few small temporary files were overlooked and left behind. Now they are deleted. 2021-03-06 David Anderson * command_options.c,dwconf.c: When a dwarfdump.conf is not findable the messages are now more meaningful and not quite so mysterious. Added new option --show-dwarfdump-conf to show the .dwarfdump.conf in use. The old and broken depencence on -v is gone. * glflags.c,glflags.h: New flag gf_show_dwarfdump_conf for the new option. * dwarfdump.1: Documented new option --show-dwarfdump-conf 2021-03-05 David Anderson * dwarf_names.c,dwarf_names.h,dwarfdump-af-table.h, dwarfdump-ta-ext-table.h,dwarfdump-ta-table.h, dwarfdump-tt-ext-table.h,dwarfdump-tt-table.h: Regenerated with new version string. 2021-03-05 David Anderson * dwconf.c: In case no dwarfdump.conf file found in one of the standard places (such as $HOME) the message printed is much clearer and more specific. 2021-02-24 David Anderson * attr_form_build.c: Catastophic error texts now all have a trailing newline. * attr_formclass_ext.list: The _ghs_ attributes are now properly named as GreenHillls spells them * dwarf_names.c: Regenerated with the proper _ghs_ names. * dwarfdump-af-table.h,dwarfdump-ta-ext-table.h: Regenerated with the proper _ghs_ names. 2021-02-20 David Anderson * tag_attr.c,tag_tree.c: When creating the tables below insert the precise array length in the array declarations so the compiler can check them. * dwarfdump-ta-table.h,dwarfdump-tt-table.h: Regenerated, now with precise array sizes everywhere. 2021-02-19 David Anderson * attr_form.c: Now checks attr/form-class combinations and reports on them. The -ku option lets one see interesting counts without details cluttering the output. * attr_form.h: Argument list updates to support latest functionality. * attr_formclass.list,attr_formclass_ext.list: New declarations of attr/formclass combinations one expects to see. No doubt there will be more such to do. * attr_form_build.c: Deleted unused locals, fixing some compiler warnings. * dwarf_names.h: Regenerated. * dwarfdump-af-table.h: Regenerated the attr/formclass table. * dwarfdump-ta-ext-table.h: New extensions added. * dwarfdump-tt-table.h: Regenerated with explicit array sizes so compilers can check array references. * dwarfdump.c: Added calls to certain cleanups that have long been needed for correct -ku output when reading an Elf Archive * glflags.h: Added a new Dwarf_Check_Catetories entry of attr_formclass_result. * globals.h: New function declarations for form_class and tag-tree tag-attr counts in the Elf archive case. * print_die.c: Added arguments to record_attr_form_use now that we check and count usages. * print_tag_attributes_usage.c(reset_usage_rate_tag_tree): added reset function so printing of Elf archive member objects usages are correct. * tag_attr_ext.list: Added GHS attributes to list. * tag_common.h: Increased column counts due to adding the GHS attributes to tag_attr_ext.list. * tag_tree.c: Added array size to emitted C source so compiler can check references when that emitted source is built into dwarfdump. 2021-02-16 David Anderson * command_options.c,compiler_info.c,glflags.c, glflags.h,print_tag_attributes_usage.c: sed 's/gf_check_attr_tag/gf_check_tag_attr/' fixed the ever-confusing name reversal unique to this flag. * print_die.c,dwarfdump.c: The above plus correcting minor mistakes in handling of -ku -kuf options. * dwarfdump.1: Clarified the meaning and use of -kr -ku -kuf -C as the descriptions have been misleading for a long time. 2021-02-16 David Anderson * attr_form.c: Fixed indents and trailing whitespace. * dwarfdump.c: Fixed trailing whitespace. * print_die.c(append_useful_die_name): was not doing proper dealloc (which only mattered if one had turned off automatic cleanup at dwarf_finish()), but now it deallocs as desired. 2021-02-15 David Anderson * dwarf_names.c,dwarf_names.h,dwarfdump-af-table.h, dwarfdump-ta-ext-table.h,dwarfdump-ta-table.h, dwarfdump-tt-ext-table.h,dwarfdump-tt-table.h: Regenerated with new version string. 2021-02-15 David Anderson * CMakeLists.txt: Added the new source files. * Makefile.am: Added the new list and build files so they get into releases and the build. * Makefile.in: Regenerated. * attr_form.c: Added printing of attr/form/formclass reports with the existing -kE option. * globals.h: Renamed tag_specific_checks_setup() to tag_specific_globals_setup() to better reflect the meaning of the function. * attr_form.h: Added declaration so dwarfdump.c can call attr_form.c functions. Added idempotency in include and __cplusplus ifdefs. * attr_form_build.c: now we add idempotency code when generating dwarfdump-af-table.h. * dwarf_tsearch.h: Commentary improvements. * dwarfdump-af-table.h: Regenerated. * dwarfdump.c: When doing checks, set up the 3key tables using attr_form.c functions. * naming.c,naming.h: Added new function get_FORM_CLASS_name() to both. * print_abbrevs.c: Renaming per globals.h function rename. * print_die.c: Include attr_form.h, call record_attr_form_use(). Renamin here too per the globals.h function rename. * attr_form_build.c: Added idempotency and __cplusplus guards to the output file generated: dwarfdump-af-table.h. * print_tag_attributes_usage.c: Improvements in the specificity of some summary header lines. Now calls print_attr_form_usage() to print the attr/formclass/form tables (option -kE or -ka ). * tag_common.c: Removed unused local variables. * test-mach-o-32.base,testobjLE32PE.base,testuriLE64ELf.base, New baseline based on recent changes. 2021-02-14 David Anderson * print_die.c: Move the last few hundred lines to the new file print_tag_attributes_usage.c. * tag_common.c: Fixed large indent botch. * globals.h: Now with print_tag_attributes_usage, record_tag_usage, legal_tag_attr_combination, legal_tag_tree_combination public for access from print_die.c. * dwarfdump.c: Reflects the simpler arguments to call print_tag_attributes_usage(). 2021-02-14 David Anderson * Makefile.am: Added print_tag_attributes_usage.c * print_tag_attributes_usage.c: New file. Extracted this code (which prints a summary of tag/attr use) from print_die.c and put in this new file. * Makefile.in: Regenerated. * dwarfdump.1: Made the description of -kE a bit more specific. 2021-02-14 David Anderson * command_options.c: Improved some commentary. * attr_form.c, attr_form_build.c: Fixed indents, trailing whitespace. 2021-02-14 David Anderson * attr_form.c,attr_form.h,attr_form_build.c: Code to build and use date for recording and checking attr/form combinations. Not yet used by dwarfdump. * attr_formclass.list: List of standard attr/form-class combinations. * attr_formclass_ext.list: List of extension attr/form-class combinations. * dwarfdump-af-table.h: Generated C array of attr/form-class combinations in easy-to-use form for dwarfdump. * dwarfdump-af-table.h: New, a table to quickly load attr/form(class) standard matches. * tag_common.c: Added code to turn FORM_CLASS names into their enum values. * tag_common.h: Added define of HAVE_USAGE_ATTR_FORMCLASS (not strictly necessary at this point). 2021-02-13 David Anderson * print_die.c: Somehow hundreds of lines got indented 4 spaces for no reason. Fixed that mistake. Added a trailing > where intended in printing DW_AT_decl_file when the file name is unavailable. 2021-02-06 David Anderson * print_die.c: Refactoring for clarity and adding following DW_FORM_ref_sig8 links to find DW_AT_type targets. Also reporting line table file numbers as file names. 2021-01-31 David Anderson * dwarfdump.c: Ensures ERROR printf appear in the error count (A couple errors printed at the end were not counted.) * globals.h: Defining LoHiPc_s struct so we can calculate the high_pc from low_pc and offset-from-low-pc values. Simpler and better type checking than before. * print_die.c: Eliminate sets of 4 arguments, replace with LoHiPc pointer. * print_hipc_lopc_attr.c: Implement filling in LoHiPc_s and printing the calculated high_pc when appropriate. Much easier to understand than the earlier use of bSawLowp etc. 2021-01-29 David Anderson * tag_attr_ext.list: Added some DW_AT_GNU entries to DW_TAG_skeleton unit as common extensions. 2021-01-29 David Anderson * dwarfdump.c: Added commentary and slightly modified the producer names produced on CU DIE issues with the producer string. * glflags.c: Added commentary about the default producer name. 2021-01-28 David Anderson * print_die.c: Cleared out dead #if 0 and fixed indents. * compiler_info.c,getopttest.c,makename_test.c, print_hipc_lopc_attr.c,testesb.c: Cleared out dead code and fixed indents. 2021-01-28 David Anderson * compiler_info.c: Added comments about an unusual aspect of a couple arrays here. * dwarfdump.c: Removed a stray back-quote from a comment. * print_die.c: Revised printing of dwarf expressions and ensured such appear in more places. Revised error detection of attributes requiring a string yet that do not have any sort of string FORM. Some #if 0 present to be removed shortly. * print_hipc_lopc_attr.c: A new #if 0 here is a non-functional improvment in printing high-pc. Not ready for prime time. * print_origloclist_codes.c: added DW_LLE_start_end case seen in test object. 2021-01-23 David Anderson * buildopscounttab.c,checkutil.c,command_options.c,common.c, dwarf_tsearch.h,dwarf_tsearchbal.c,dwarfdump-tt-table.h,dwarfdump.c, dwconf.c,dwgetopt.c,esb.c,esb.h,getopttest.c,glflags.h,globals.h, makename.c,naming.c,opscounttab.h,print_die.c,print_frames.c, print_gdbindex.c,print_macro.c,print_pubnames.c,print_ranges.c, print_reloc.c,sanitize.c,section_bitmaps.c,tag_attr.c, tag_common.c,tag_tree.c,testesb.c: Fixed indentation errors. 2021-01-23 David Anderson * print_die.c: Now checks all instances of DW_OP_bra and DW_OP_skip to be sure the target offset actually is a valid target in this expression block. 2021-01-22 David Anderson * glflags.h: Moved _dwarf_print_one_expr_op() out, it is now static in print_die.c * print_die.c: Now notices if DW_OP_skip or DW_OP_bra is in a set of operations and prefixes each operation with its block offset so its easy to understand the target offset. libdwarf-20210528/dwarfdump/compiler_info.c0000664000175000017500000004060414053210174015457 00000000000000/* Copyright 2010-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "makename.h" #include "sanitized.h" #include "command_options.h" #include "compiler_info.h" /* Record compilers whose CU names have been seen. Full CU names recorded here, though only a portion of the name may have been checked to cause the compiler data to be entered here. The detected/targeted arrays leave index 0 unused. There is no particularly good reason for this. current_compiler starts at -1, and is legitimately 1 through COMPILER_TABLE_MAX-1. compilers_targeted_count and compilers_detected_count are the actual count, so loops use things like for (i = 1 ; i <= compilers_detected_count; ++1) for example. */ static Compiler compilers_detected[COMPILER_TABLE_MAX]; static int compilers_detected_count = 0; /* compilers_targeted is a list of indications of compilers on which we wish error checking (and the counts of checks made and errors found). We do substring comparisons, so the compilers_targeted name might be simply a compiler version number or a short substring of a CU producer name. The +1 guarantees we do not overstep the array. */ static Compiler compilers_targeted[COMPILER_TABLE_MAX]; static int compilers_targeted_count = 0; static int current_compiler = -1; /* Indicates if the current CU is a target */ static Dwarf_Bool current_cu_is_checked_compiler = TRUE; static int hasprefix(const char *sample, const char *prefix) { unsigned prelen = strlen(prefix); if (strncmp(sample,prefix,prelen) == 0) { return TRUE; } return FALSE; } static void PRINT_CHECK_RESULT(char *str, Compiler *pCompiler, Dwarf_Check_Categories category) { Dwarf_Check_Result result = pCompiler->results[category]; printf("%-24s%10d %10d\n", str, result.checks, result.errors); } /* Print checks and errors for a specific compiler */ static void print_specific_checks_results(Compiler *pCompiler) { printf("\nDWARF CHECK RESULT\n"); printf(" \n"); if (glflags.gf_check_pubname_attr) { PRINT_CHECK_RESULT("pubname_attr", pCompiler, pubname_attr_result); } if (glflags.gf_check_tag_attr) { PRINT_CHECK_RESULT("attr_tag", pCompiler, attr_tag_result); PRINT_CHECK_RESULT("attr_formclass", pCompiler, attr_formclass_result); } if (glflags.gf_check_tag_tree) { PRINT_CHECK_RESULT("tag_tree", pCompiler, tag_tree_result); } if (glflags.gf_check_type_offset) { PRINT_CHECK_RESULT("type_offset", pCompiler, type_offset_result); } if (glflags.gf_check_decl_file) { PRINT_CHECK_RESULT("decl_file", pCompiler, decl_file_result); } if (glflags.gf_check_ranges) { PRINT_CHECK_RESULT("ranges", pCompiler, ranges_result); } if (glflags.gf_check_lines) { PRINT_CHECK_RESULT("line_table", pCompiler, lines_result); } if (glflags.gf_check_fdes) { PRINT_CHECK_RESULT("fde_table", pCompiler, fde_duplication); } if (glflags.gf_check_aranges) { PRINT_CHECK_RESULT("aranges", pCompiler, aranges_result); } if (glflags.gf_check_names) { PRINT_CHECK_RESULT("names",pCompiler, names_result); } if (glflags.gf_check_frames) { PRINT_CHECK_RESULT("frames",pCompiler, frames_result); } if (glflags.gf_check_locations) { PRINT_CHECK_RESULT("locations",pCompiler, locations_result); } if (glflags.gf_check_harmless) { PRINT_CHECK_RESULT("harmless_errors", pCompiler, harmless_result); } if (glflags.gf_check_abbreviations) { PRINT_CHECK_RESULT("abbreviations", pCompiler, abbreviations_result); } if (glflags.gf_check_dwarf_constants) { PRINT_CHECK_RESULT("dwarf_constants", pCompiler, dwarf_constants_result); } if (glflags.gf_check_di_gaps) { PRINT_CHECK_RESULT("debug_info_gaps", pCompiler, di_gaps_result); } if (glflags.gf_check_forward_decl) { PRINT_CHECK_RESULT("forward_declarations", pCompiler, forward_decl_result); } if (glflags.gf_check_self_references) { PRINT_CHECK_RESULT("self_references", pCompiler, self_references_result); } /* Display attributes encoding results */ if (glflags.gf_check_attr_encoding) { PRINT_CHECK_RESULT("attr_encoding", pCompiler, attr_encoding_result); } /* Duplicated attributes */ if (glflags.gf_check_duplicated_attributes) { PRINT_CHECK_RESULT("duplicated_attributes", pCompiler, duplicated_attributes_result); } PRINT_CHECK_RESULT("** Summarize **",pCompiler, total_check_result); fflush(stdout); } /* Add a CU name to the current compiler entry, specified by the 'current_compiler'; the name is added to the 'compilers_detected' table and is printed if the '-P' or '--print-producers' option is specified in the command line. */ void add_cu_name_compiler_target(char *name) { a_name_chain *cu_last = 0; a_name_chain *nc = 0; Compiler *pCompiler = 0; if (current_compiler < 1) { fprintf(stderr,"Current compiler set to %d, cannot add " "Compilation unit name. Giving up.",current_compiler); exit(FAILED); } pCompiler = &compilers_detected[current_compiler]; cu_last = pCompiler->cu_last; /* Record current cu name */ nc = (a_name_chain *)malloc(sizeof(a_name_chain)); nc->item = makename(name); nc->next = NULL; if (cu_last) { cu_last->next = nc; } else { pCompiler->cu_list = nc; } pCompiler->cu_last = nc; } /* Reset a compiler entry, so all fields are properly set */ void reset_compiler_entry(Compiler *compiler) { memset(compiler,0,sizeof(Compiler)); } /* Record which compiler was used (or notice we saw it before) and set a couple variables as a side effect (which are used all over in this one source file): current_cu_is_checked_compiler (used in checking_this_compiler() ) current_compiler The compiler/producer name is from DW_AT_producer. */ void update_compiler_target(const char *producer_name) { Dwarf_Bool cFound = FALSE; int index = 0; safe_strcpy(glflags.CU_producer,sizeof(glflags.CU_producer), producer_name, strlen(producer_name)); current_cu_is_checked_compiler = FALSE; /* This list of compilers is just a start: GCC id : "GNU" SNC id : "SN Systems" */ /* Find a compiler version to check */ if (compilers_targeted_count) { for (index = 1; index <= compilers_targeted_count; ++index) { if (is_strstrnocase(glflags.CU_producer, compilers_targeted[index].name)) { compilers_targeted[index].verified = TRUE; current_cu_is_checked_compiler = TRUE; break; } } } else { /* Internally the strings do not include quotes */ Dwarf_Bool snc_compiler = hasprefix(glflags.CU_producer,"SN") ? TRUE : FALSE; Dwarf_Bool gcc_compiler = hasprefix(glflags.CU_producer,"GNU") ? TRUE : FALSE; current_cu_is_checked_compiler = glflags.gf_check_all_compilers || (snc_compiler && glflags.gf_check_snc_compiler) || (gcc_compiler && glflags.gf_check_gcc_compiler) ; } /* Check for already detected compiler */ for (index = 1; index <= compilers_detected_count; ++index) { const char *name = compilers_detected[index].name; if ( #if _WIN32 !stricmp(name,glflags.CU_producer) #else !strcmp(name, glflags.CU_producer) #endif /* _WIN32 */ ) { /* Set current compiler index */ current_compiler = index; cFound = TRUE; break; } else { } } if (!cFound) { /* Record a new detected compiler name. */ if ((compilers_detected_count + 1) < COMPILER_TABLE_MAX) { Compiler *pCompiler = 0; char *cmp = makename(glflags.CU_producer); /* Set current compiler index, first compiler at position [1] */ current_compiler = ++compilers_detected_count; pCompiler = &compilers_detected[current_compiler]; reset_compiler_entry(pCompiler); pCompiler->name = cmp; } } } void clean_up_compilers_detected(void) { memset(&compilers_detected[0],0, COMPILER_TABLE_MAX*sizeof(Compiler)); compilers_detected_count = 0; } /* Are we checking for errors from the compiler of the current compilation unit? */ Dwarf_Bool checking_this_compiler(void) { /* This flag has been update by 'update_compiler_target()' and indicates if the current CU is in a targeted compiler specified by the user. Default value is TRUE, which means test all compilers until a CU is detected. */ return current_cu_is_checked_compiler; } static int qsort_compare_compiler(const void *elem1,const void *elem2) { Compiler cmp1 = *(Compiler *)elem1; Compiler cmp2 = *(Compiler *)elem2; int cnt1 = cmp1.results[total_check_result].errors; int cnt2 = cmp2.results[total_check_result].errors; if (cnt1 < cnt2) { return 1; } else if (cnt1 > cnt2) { return -1; } /* When error counts match, sort on name. */ { int v = strcmp(cmp2.name, cmp1.name); return v; } } /* Print a summary of checks and errors */ void print_checks_results(void) { int index = 0; Compiler *pCompilers; Compiler *pCompiler; /* Sort based on errors detected; the first entry is reserved and unused count started at 1 */ pCompilers = &compilers_detected[1]; if (compilers_detected_count > 1) { qsort((void *)pCompilers,compilers_detected_count, sizeof(Compiler),qsort_compare_compiler); } /* Print list of CUs for each compiler detected */ if (glflags.gf_producer_children_flag) { a_name_chain *nc = 0; a_name_chain *nc_next = 0; int count = 0; int total = 0; printf("\n*** CU NAMES PER COMPILER ***\n"); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; printf("\n%02d: %s",index,sanitized(pCompiler->name)); count = 0; for (nc = pCompiler->cu_list; nc; nc = nc_next) { printf("\n %02d: '%s'",++count, sanitized(nc->item)); nc_next = nc->next; free(nc); } total += count; printf("\n"); } printf("\nDetected %d CU names\n",total); } /* Print error report only if errors have been detected */ /* Print error report if the -kd option */ if ((glflags.gf_do_check_dwarf && glflags.check_error) || glflags.gf_check_show_results) { int count = 0; int compilers_not_detected = 0; int compilers_verified = 0; /* Find out how many compilers have been verified. */ for (index = 1; index <= compilers_detected_count; ++index) { if (compilers_detected[index].verified) { ++compilers_verified; } } /* Find out how many compilers have been not detected. */ for (index = 1; index <= compilers_targeted_count; ++index) { if (!compilers_targeted[index].verified) { ++compilers_not_detected; } } /* Print compilers detected list */ printf( "\n%d Compilers detected:\n",compilers_detected_count); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; printf("%02d: %s\n",index,sanitized(pCompiler->name)); } /* Print compiler list specified by the user with the '-c', that were not detected. */ if (compilers_not_detected) { count = 0; printf( "\n%d Compilers not detected:\n", compilers_not_detected); for (index = 1; index <= compilers_targeted_count; ++index) { if (!compilers_targeted[index].verified) { printf( "%02d: '%s'\n", ++count, sanitized(compilers_targeted[index].name)); } } } count = 0; printf("\n%d Compilers verified:\n",compilers_verified); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; if (pCompiler->verified) { printf("%02d: errors = %5d, %s\n", ++count, pCompiler->results[total_check_result].errors, sanitized(pCompiler->name)); } } /* Print summary if we have verified compilers or if the -kd option used. */ if (compilers_verified || glflags.gf_check_show_results) { /* Print compilers detected summary*/ if (glflags.gf_print_summary_all) { count = 0; printf("\n*** ERRORS PER COMPILER ***\n"); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; if (pCompiler->verified) { printf("\n%02d: %s", ++count,sanitized(pCompiler->name)); print_specific_checks_results(pCompiler); } } } /* Print general summary (all compilers checked) */ printf("\n*** TOTAL ERRORS FOR ALL COMPILERS ***\n"); print_specific_checks_results(&compilers_detected[0]); } } fflush(stdout); } void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc) { Compiler * c = 0; c = &compilers_detected[0]; c->results[category].checks += inc; c->results[total_check_result].checks += inc; if (current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) { c = &compilers_detected[current_compiler]; c->results[category].checks += inc; c->results[total_check_result].checks += inc; c->verified = TRUE; } } void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc) { Compiler * c = 0; c = &compilers_detected[0]; c->results[category].errors += inc; c->results[total_check_result].errors += inc; if (current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) { c = &compilers_detected[current_compiler]; c->results[category].errors += inc; c->results[total_check_result].errors += inc; } } Dwarf_Bool record_producer(char *name) { Dwarf_Bool recorded = FALSE; if ((compilers_targeted_count+1) < COMPILER_TABLE_MAX) { Compiler *pCompiler = 0; const char *cmp = 0; cmp = do_uri_translation(name,"-c"); /* First compiler at position [1] */ compilers_targeted_count++; pCompiler = &compilers_targeted[compilers_targeted_count]; reset_compiler_entry(pCompiler); pCompiler->name = cmp; glflags.gf_check_all_compilers = FALSE; recorded = TRUE; } return recorded; } libdwarf-20210528/dwarfdump/print_debug_gnu.c0000664000175000017500000004242113764006205016012 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* To print .debug_gnu_pubnames, .debug_gnu_typenames */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "print_debug_gnu.h" #define TRUE 1 #define FALSE 0 char *ikind_types[8] = { "none", "type", "variable", "function", "other", "unknown5", "unknown6", "unknown7" }; static int print_block_entries( UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Bool for_pubnames, UNUSEDARG struct esb_s * secname, Dwarf_Gnu_Index_Head head, Dwarf_Unsigned blocknum, Dwarf_Unsigned entrycount, Dwarf_Error *error) { Dwarf_Unsigned i = 0; int res = 0; printf(" [ ] offset Kind Name\n"); for ( ; i < entrycount; ++i) { Dwarf_Unsigned offset_in_debug_info = 0; const char *name = 0; unsigned char flag = 0; unsigned char staticorglobal = 0; unsigned char typeofentry = 0; /* flag is all 8 bits and staticorglobal and typeofentry were extracted from the flag. Present here so we can check all 8 bits are correct (lowest 4 should be zero). */ res = dwarf_get_gnu_index_block_entry(head, blocknum,i,&offset_in_debug_info, &name,&flag,&staticorglobal,&typeofentry, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { printf(" ERROR: Block %" DW_PR_DUu " entry %" DW_PR_DUu " does not exist though entry count" " is %" DW_PR_DUu ", something is wrong\n", blocknum, i,entrycount); glflags.gf_count_major_errors++; return res; } printf(" [%3" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx, i,offset_in_debug_info); printf(" %s,%-8s", staticorglobal?"s":"g", ikind_types[0x7 & typeofentry]); printf(" %s",sanitized(name)); printf("\n"); if (flag&0xf) { printf(" ERROR: Block %" DW_PR_DUu " entry %" DW_PR_DUu " flag 0x%x. " "The lower bits are non-zero " "so there may be a corruption problem.", blocknum,i, flag); glflags.gf_count_major_errors++; printf("\n"); } } return DW_DLV_OK; } int attrlist[] = { DW_AT_GNU_dwo_name, DW_AT_dwo_name, DW_AT_comp_dir, DW_AT_GNU_dwo_id, 0 }; static void error_report(int errcode, const char *text, Dwarf_Error *error) { if (errcode == DW_DLV_ERROR) { printf(" ERROR: %s" ", ignoring other attributes here: %s\n", text, dwarf_errmsg(*error)); glflags.gf_count_major_errors++; return; } else { printf(" ERROR impossible DW_DLV_NO_ENTRY: %s" ", ignoringother attributes here. \n", text); } return; } static void print_selected_attributes(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half version, Dwarf_Half offset_size, Dwarf_Error *error) { int res = 0; int i = 0; for ( ; attrlist[i]; ++i) { Dwarf_Attribute attr = 0; int attrid = 0; const char * atname = 0; Dwarf_Half form = 0; enum Dwarf_Form_Class fclass = 0; char *formstring = 0; int print_str = FALSE; struct esb_s m; Dwarf_Sig8 sig; attrid = attrlist[i]; res = dwarf_attr(die,attrid,&attr,error); if (res == DW_DLV_ERROR) { error_report(res,"dwarf_attr() returned error",error); dwarf_dealloc_error(dbg,*error); *error = 0; return; } if (res == DW_DLV_NO_ENTRY) { continue; } /* ok, this attribute is present */ atname = get_AT_name(attrid,FALSE); res = dwarf_whatform(attr,&form,error); if (res != DW_DLV_OK) { error_report(res,"dwarf_whatform() problem: ",error); dwarf_dealloc_error(dbg,*error); dwarf_dealloc_attribute(attr); *error = 0; return; } if (res == DW_DLV_NO_ENTRY) { /* impossible, cannot get here */ dwarf_dealloc_attribute(attr); continue; } esb_constructor(&m); fclass = dwarf_get_form_class(version,attrid, offset_size,form); if (fclass == DW_FORM_CLASS_STRING) { res = dwarf_formstring(attr,&formstring,error); if (res == DW_DLV_OK) { print_str = TRUE; esb_append(&m,formstring); } else { error_report(res,"dwarf_formstring() returned error", error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } dwarf_dealloc_attribute(attr); esb_destructor(&m); break; } } else if (fclass == DW_FORM_CLASS_CONSTANT) { if (form == DW_FORM_data8) { res = dwarf_formsig8_const(attr,&sig,error); if (res == DW_DLV_OK) { print_str = TRUE; format_sig8_string(&sig,&m); } else { error_report(res,"dwarf_formsig8_const() " "returned error",error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } esb_destructor(&m); dwarf_dealloc_attribute(attr); break; } } } else if (fclass == DW_FORM_CLASS_REFERENCE) { /* includes DW_FORM_ref_sig8, DW_FORM_ref* */ if (form == DW_FORM_ref_sig8) { res = dwarf_formsig8(attr,&sig,error); if (res == DW_DLV_OK) { print_str = TRUE; esb_constructor(&m); format_sig8_string(&sig,&m); } else { error_report(res,"dwarf_formsig8() " "problem error",error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } esb_destructor(&m); dwarf_dealloc_attribute(attr); break; } } } if (print_str) { printf(" %-18s : %s\n", atname,esb_get_string(&m)); } dwarf_dealloc_attribute(attr); esb_destructor(&m); } } static int print_die_basics(Dwarf_Debug dbg, Dwarf_Die die, UNUSEDARG Dwarf_Unsigned cudie_goff, Dwarf_Error *error) { int res = 0; Dwarf_Half tag = 0; Dwarf_Half version = 0; Dwarf_Bool is_info = 0; Dwarf_Bool is_dwo = 0; Dwarf_Half offset_size = 0; Dwarf_Half address_size = 0; Dwarf_Half extension_size = 0; Dwarf_Sig8 *signature = 0; Dwarf_Off offset_of_length = 0; Dwarf_Unsigned total_byte_length = 0; res = dwarf_cu_header_basics(die, &version, &is_info,&is_dwo, &offset_size,&address_size,&extension_size, &signature,&offset_of_length,&total_byte_length,error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { printf("ERROR: Cannot access compilation unit data: %s", dwarf_errmsg(*error)); dwarf_dealloc_error(dbg,*error); *error = 0; } else { printf("ERROR: Cannot access compilation unit data" "No such found"); } glflags.gf_count_major_errors++; return DW_DLV_OK; } printf(" Compilation unit data follows\n"); printf(" CU version : %d\n",version); if (!is_info) { printf(" CU section is .debug_types"); } printf(" CU section is dwo? : %s\n", is_dwo?"yes":"no"); printf(" CU offset size : %u\n", offset_size); printf(" CU extension size : %u\n", extension_size); printf(" CU address size : %u\n", address_size); printf(" CU beginning offset : 0x%" DW_PR_XZEROS DW_PR_DUx "\n", offset_of_length); printf(" CU total length : 0x%" DW_PR_XZEROS DW_PR_DUx "\n", total_byte_length); if (signature) { struct esb_s m; char buf[24]; esb_constructor_fixed(&m,buf,sizeof(buf)); printf(" CU signature : "); format_sig8_string(signature,&m); printf("%s\n", esb_get_string(&m)); esb_destructor(&m); } res = dwarf_tag(die,&tag,error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { printf("ERROR: Cannot access DIE tag ERROR: %s\n", dwarf_errmsg(*error)); dwarf_dealloc_error(dbg,*error); *error = 0; } else { printf("ERROR: Cannot access DIE tag " "No such found\n"); } printf("\n"); glflags.gf_count_major_errors++; } else { const char *actual_tag_name = 0; actual_tag_name = get_TAG_name(tag,FALSE); printf(" CU die TAG : " "%s\n", actual_tag_name); } print_selected_attributes(dbg,die,version,offset_size,error); return DW_DLV_OK; } static int print_all_blocks(Dwarf_Debug dbg, Dwarf_Bool for_pubnames, struct esb_s *secname, Dwarf_Gnu_Index_Head head, Dwarf_Unsigned block_count, Dwarf_Error *error) { Dwarf_Unsigned i = 0; int res = 0; for ( ; i < block_count; ++i) { Dwarf_Unsigned block_length = 0; Dwarf_Half version = 0; Dwarf_Unsigned offset_into_debug_info = 0; Dwarf_Unsigned size_of_debug_info_area = 0; Dwarf_Unsigned entrycount = 0; res = dwarf_get_gnu_index_block(head,i, &block_length,&version, &offset_into_debug_info, &size_of_debug_info_area, &entrycount,error); if (res == DW_DLV_NO_ENTRY) { printf(" ERROR: Block %" DW_PR_DUu " does not exist though block count" " is %" DW_PR_DUu ", something is wrong\n", i,block_count); glflags.gf_count_major_errors++; return res; } if (res == DW_DLV_ERROR) { return res; } printf(" Blocknumber : " "%" DW_PR_DUu "\n",i); printf(" Block length : " "%" DW_PR_DUu "\n",block_length); printf(" Version : " "%u\n",version); printf(" Offset into .debug_info section : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n",offset_into_debug_info); printf(" Size of area in .debug_info section : " "%" DW_PR_DUu "\n",size_of_debug_info_area); printf(" Number of entries in block : " "%" DW_PR_DUu "\n",entrycount); /* The CU offsets appear to be those in the executable here. Not in any dwo object. The offsets within the entries in a block are a different story and some of that seems odd, the content names many things in libraries, not just the executable or its dwo. ? */ res = dwarf_get_cu_die_offset_given_cu_header_offset_b( dbg,offset_into_debug_info,/*is_info = */ TRUE, &offset_into_debug_info,error); if (res != DW_DLV_OK) { printf(" ERROR: Block %" DW_PR_DUu " has an invalid .debug_info offset of " "0x%" DW_PR_DUx ", something is wrong\n", i,offset_into_debug_info); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } glflags.gf_count_major_errors++; } else { Dwarf_Die die = 0; Dwarf_Bool is_info = TRUE; res = dwarf_offdie_b(dbg,offset_into_debug_info, is_info, &die,error); if (res != DW_DLV_OK) { printf(" ERROR: Block %" DW_PR_DUu " cu DIE offset 0x%" DW_PR_DUx " is not a valid DIE offset in .debug_info\n", i, offset_into_debug_info); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,*error); *error = 0; } glflags.gf_count_major_errors++; } else { /* Always returns DW_DLV_OK */ print_die_basics(dbg, die, offset_into_debug_info, error); printf("\n"); dwarf_dealloc_die(die); } } res = print_block_entries(dbg,for_pubnames, secname,head,i,entrycount,error); if (res == DW_DLV_ERROR) { return res; } } return DW_DLV_OK; } /* November 25,2020: gdb 10.2 binutils source can print these sections but gdb does not, AFAICT, use this at all. (binutils can print it, as can we). The Block offset is part of the skeleton, and refers to the skeleton CU DIEs (when that is involved) but the individual item offsets are referring to I-do-not-know-what. Block zero refers to the single CU_DIE in the .dwo file. The others....? Nothing suggests how things actually connect up. */ int print_debug_gnu(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; Dwarf_Gnu_Index_Head head = 0; Dwarf_Bool for_pubnames = TRUE; Dwarf_Unsigned block_count = 0; const char *stdname = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s truename; unsigned int i = 0; for (i = 0; i < 2; i++) { esb_constructor_fixed(&truename,buf, DWARF_SECNAME_BUFFER_SIZE); if (!i) { glflags.current_section_id = DEBUG_GNU_PUBNAMES; for_pubnames = TRUE; stdname = ".debug_gnu_pubnames"; } else { for_pubnames = FALSE; glflags.current_section_id = DEBUG_GNU_PUBTYPES; stdname = ".debug_gnu_pubtypes"; } get_true_section_name(dbg,stdname, &truename,TRUE); res = dwarf_get_gnu_index_head(dbg,for_pubnames, &head, &block_count,error); if (res == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: problem reading %s. %s\n", sanitized(esb_get_string(&truename)), dwarf_errmsg(*error)); dwarf_dealloc_error(dbg,*error); *error = 0; continue; } else if (res == DW_DLV_NO_ENTRY) { continue; } printf("\n%s with %" DW_PR_DUu " blocks of names\n", sanitized(esb_get_string(&truename)), block_count); res = print_all_blocks(dbg,for_pubnames, &truename, head,block_count,error); if (res == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: problem reading %s. %s\n", sanitized(esb_get_string(&truename)), dwarf_errmsg(*error)); dwarf_dealloc_error(dbg,*error); *error = 0; } else if (res == DW_DLV_NO_ENTRY) { /* impossible */ } else { /* normal */ } dwarf_gnu_index_dealloc(head); esb_destructor(&truename); } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/dwarf_names.h0000664000175000017500000000704314054205616015133 00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #ifndef DWARF_NAMES_H #define DWARF_NAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIVIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_GNUIKIND_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_NAMES_H */ /* END FILE */ libdwarf-20210528/dwarfdump/test-mach-o-32.dSYM0000664000175000017500000016413113644370703015603 00000000000000Îúíþ ¨é’óÚô0\€ü|‰Ynð(Û18__PAGEZEROÐ__TEXT __text__TEXTÀ%”è€__symbol_stub__TEXTTê€__stub_helper__TEXT@’€__cstring__TEXTÒÍž__const__TEXTŸ¯ __unwind_info__TEXT¬¯HÐ__DATA°__nl_symbol_ptr__DATA°('__la_symbol_ptr__DATA(°œ1__const__DATAİ”__data__DATAX´$__common__DATA|¼__bss__DATA˜¼á8__LINKEDITÀËJh__DWARFP`Yˆ __debug_line__DWARFPÑ`__debug_pubnames__DWARFÑj8Ñz__debug_pubtypes__DWARF o¾ __debug_aranges__DWARFÇv(dž__debug_info__DWARFïwê-ï‡__debug_frame__DWARFÙ¥ÀÙµ__debug_abbrev__DWARF™©™¹__debug_str__DWARF›«l›»__apple_names__DWARFÇœ×__apple_namespac__DWARF£Ì$£Ü__apple_types__DWARFÇÌn ÇÜ__apple_objc__DWARF5Ø$5èà4Ð51°6GP7SÐ7a:q< ?›PC¬@DÀ`EÖ°Gå€H÷ðL NV(XA`YV Zb[là`y€a‡ðaŸÀbµàbÌcä cý@cPf*`hF€i]mnÐmynP‚Ÿ@ƒ· …Ï ›ì¥0¹º5Ä@Ê_€Î{0Ï—ÀÔ¬0Ú¿ÀìÐPïßþÿ@p#à :`D°Y€"gp0€¤š·¶·Øà¼î ½`À!ðÚ7píVpîs0þ€þšàþ·0 Å€ Ô°í 0€#Ð<6=F€=\ BjðB{EŽàE¬@HºNÈàVâ€[öÐl`r+€s>ðs_pt~ u¨ДÀ—Ú€—øà@ž¡,¨? ²^€æxpú‘Ð6¡?½€H΀IÛ@]ù°c @m0  nM  oY Ðoz ðp£ Ày¸ ‚Ý 0†ï À† pˆ Àˆ% ð­; p·_  ¼‡ @Öª @ÝÍ Ðää íø 0í àí6  ñG pó_ €ôo `÷~ @ü‘  ý§  þ´ Pÿ Õ  "õ °3  > €R( SJ `W_ 0[~ ¡¯— £¯¯ ¥¯Æ §¯Ü ¨¯÷ ª¯  İ  à°+  P±B  P´_  X´j  \´t  `´ƒ  d´‹  ”º™  Ⱥ®  ̺Æ  кÞ  Ôº »* /»S ;»{ ¨»ƒ P¼™ T¼§ ˜¼¶ œ¼È  ¼Ö ¤¼å ¨¼í ¬¼õ °¼ ´¼ ¸¼" ¼¼. À¼; P¾F X¾U `¾c h¾x l¾† p¾¦ q¾³àFÍÐCåЧ §5Àé^°yÖ”°²àAÒÀDñÀ¤ `¢) ECðZ@êjðC p´@«P4àeÜ ´W8pSf h´}ðÛ”ðÔ¯p×üÀ$P§C@D^€ÚxÀÛ‘@.¹°i×`Fò Ô)à<G /`àcr0Ðh¢àPÆ`qã ¼@Ü àqA@Ûh¥‡ÀŸÐÑÂÐ^ßñþ;p<P$d02…ðꟀ%»,Þ@Gÿ€G-7 -P`Ye ¾„0lžpl·0$Ñ tñ@  ^)ð^M€#o0ëŒð=¶€D×§Àn&`ú6 ýGðóU ùcë‚ ö’Ðû FºàÕ@5ñ0C „¼# €¼5 |¼G @»V°9tâ†ð©’ðâ¥ÀµÐáÆpáÕáå`ÄòPÖ  Œ¼#p)C ïf‰°f˜ðkµ°(×@»÷0ýû: ÿa0öz@ð•à±Ôàó÷Õò1øHí` •u°—€ä°`äÇËçÀ«—0¨) ¬8P”I@Ð_ tP‰ ›€/°à/Ì`!Ú!çðÒ !$PÕ>@N N_Àar`B‚*‘àI¢À1²0È`YÚàHëðÙ  ð×, ðÅ@ à}S 0åf `õz p “  Í­ ðèÁ àÕÔ üç ÐÖû  u!ðþ&!àÍ:!`äM!ça!Àðu!0ÜŠ!`ÏŸ!Pг!€éÈ! íÜ!€ëð!@ô"€ñ"À®1"`èE"°ÑY" Ôn"`‚"ðÒ•"pÛ°"°ÚÄ" ’Ü"Ð!ü"t#ðÖ6#§K#P±_#@²u# ¦‹#P8»#9í#à= $?$$poD$ÀYd$0“€$Pož$p̺$@ÍØ$pÏí$ ×%а,%°©C%P´d%°½†% ɧ% ÊÊ%ðÀæ%@Ä&PÅ"&ÀÌ=& ¨Q&§h&ÐÍy&0¯Ž&@¤&€dÂ&eç&P#ú&F'`"?'àbX'°j{'pK•'^­'ÀIÁ'€kß'Xþ' ’(@!4(`lM(kn(€iŽ(ða­(PcÎ(Àdï(àf)À#/)0éI)àHb) >})Hž)°Kº) M×)4ï)À3* 2*`59*Ð1P*P3`*ÐJy*ÀIŽ*p¬*à!¬*ðǺ*€ÉÊ*pGç*À3ÿ*03+;)+€:?+@4O+ 1i+08z+:+ 2¤+€9·+ 2Å+À4Ô+p5å+6ô+¿, a, [',0`A,°a],@ss,à~‹,à£,»,ðXÐ,ÐKã,@Lø,É-@±-ð™)- iC-2Q-°8i-pæ„-°l¢-@0Â-@?×-°>î-0Ú.pÙ).ÐØL.Øp.Ù‘.°Ù­.ðÙÎ.°Hò.pK/ K&/ ¹7/œJ/P¨Z/0âi/P$y/&‹/0*¤/Ð<¼/@øÖ/-ò/- 0€'.0€/P00q0ð*0°+¬0p)É0 %ã0`(11&1ð˜11€$Q1€·m1ð(}1$1#¤1Ð]º1 ˆ¼È1À%Î1p6_startswithextractstring_startswithextractnum_simple_error_handler_cleanupstr_xfrm_to_sig8_print_die_data_print_debug_fission_header_read_cu_list_char_to_uns4bit_format_sig8_string_get_die_and_siblings_resetsrcfiles_print_die_data_i_printnamestrings_print_subprog_print_comp_dir_print_name_strings_attr_print_single_string_get_number_get_addr_getBaseName_getSeparator_macho_get_section_info_macho_get_byte_order_macho_get_length_size_macho_get_pointer_size_macho_get_section_count_macho_load_section_simple_compare_function_string_is_in_debug_section_simple_value_hashfunc_freecontextlist_rela_free_tdestroy_free_node_reloc_incomplete__dwarf_find_CU_Context__dwarf_make_CU_Context__dwarf_may_have_base_fields_find_context_base_fields_dwarf_ptr_CU_offset__dwarf_next_die_info_ptr_is_cu_tag__dwarf_find_offdie_CU_Context_section_name_ends_with_dwo__dwarf_read_cu_length_plus_is_unknown_UT_value_read_a_name_index_free_inhdr_list_get_inhdr_cur__dwarf_internal_abbrev_by_code_free_inhdr_content_read_uword_val_fill_in_abbrevs_table_freedabs_get_dsc_leb_entries_get_attr_dbg__dwarf_formsig8_internal_dwarf_init_reg_rules_ru_dwarf_initialize_fde_table__dwarf_get_fde_info_for_a_pc_row_dwarf_free_fde_table_dwarf_init_reg_rules_dw_dwarf_init_reg_rules_dw3_init_reg_rules_alloc_dealloc_fde_cie_list_internal_dwarf_find_existing_cie_ptr_chain_up_cie_get_cieptr_given_offset_dwarf_create_cie_from_start_chain_up_fde_qsort_compare_get_gcc_eh_augmentation_gnu_aug_encodings_validate_length_read_encoded_ptr_grp_data_hashfunc_grp_make_entry_grp_compare_function_grp_walk_map_map_sort_compar_grp_walk_for_name__dwarf_grp_destroy_free_node_safe_strncpy__dwarf_setup_load_debugfission_tables_do_decompress_zlib_determine_target_group_this_section_dwarf_relevant_is_a_rela_section_is_a_special_section_semi_dwarf_is_section_name_known_already_enter_section_in_de_debug_sections_array_get_basic_section_data_add_rela_data_to_secdata_insert_sht_list_in_group_map_startswith_set_up_section_add_debug_section_info_is_path_separator__dwarf_read_line_table_header_create_fullest_file_path_read_line_table_program_dwarf_filename_delete_line_context_itself_operandmismatch_special_cat_construct_at_path_from_parts__dwarf_internal_macro_context_dealloc_macro_srcfiles_construct_from_dir_and_name_specialcat_translate_srcfiles_to_srcfiles2__dwarf_internal_macro_context_by_offset_read_operands_table__dwarf_get_macro_ops_count_internal_valid_macro_form_validate_opcode_is_std_moperator__dwarf_skim_forms__dwarf_get_value_ptr__dwarf_get_address_base_attr_value__dwarf_look_in_local_and_tied_by_index__dwarf_die_attr_unsigned_constant__dwarf_get_ranges_base_attr_value_dw_get_special_offset_tied_data_hashfunc_tied_compare_function__dwarf_loop_reading_debug_info_for_cu_tied_make_entry_calculate_allowed_fill_dumptree_inner_tsearch_inner_dwarf_twalk_inner_dwarf_tdestroy_inner_print_entry_resize_table_allocate_ts_entry_copy_abbrev_table_to_new_table_bufferdoublesize_inthissection__dwarf_get_xuhdr__dwarf_search_fission_for_offset_transform_xu_to_dfp__dwarf_search_fission_for_key_dwarf_udata_string_form_dwarf_udata_udata_form_dwarf_udata_strp_form_dwarf_secoffset_form_dwarf_udata_strp_sup_form_dwarf_udata_strx_form_macho_methods_SectionNames_alloc_instance_basics_dwarf_default_macro_opslist_g_is_info_unittype_fissionfordie_stdrun_dwo_secnames__dwarf_apply_relocs_set_up_section.dprefix_set_up_section.zprefix__dwarf_line_table_regs_default_values_dwarf_standard_opcode_operand_count_dwarf_arm_standard_opcode_operand_count__dwarf_read_line_table_header.expbytes_primes_allowed_fill_percent_dwp_secnames_namesoptionon_dumpallnamespath_dumpallnames_checkoptionon_tuhash_cuhash_tufissionhash_cufissionhash_passnullerror_dupstrused_dupstrarray_dienumber_temp_map_data_map_reccount_found_name_in_group_target_group__dwarf_assume_string_in_bounds_zerohashkey__dwarf_add_to_files_list__dwarf_allow_formudata__dwarf_calculate_abbrev_section_end_ptr__dwarf_calculate_info_section_end_ptr__dwarf_calculate_info_section_start_ptr__dwarf_check_string_valid__dwarf_cie_section_offset__dwarf_debugnames_destructor__dwarf_decode_line_string_form__dwarf_decode_line_udata_form__dwarf_decode_s_leb128_chk__dwarf_decode_u_leb128_chk__dwarf_destroy_group_map__dwarf_dsc_destructor__dwarf_dumpsig__dwarf_dwo_groupnumber_given_name__dwarf_errmsgs__dwarf_error__dwarf_error_mv_s_to_t__dwarf_exec_frame_instr__dwarf_extract_address_from_debug_addr__dwarf_extract_local_debug_str_string_given_offset__dwarf_extract_string_offset_via_str_offsets__dwarf_failsafe_error__dwarf_fde_destructor__dwarf_fde_section_offset__dwarf_file_has_debug_fission_cu_index__dwarf_file_has_debug_fission_index__dwarf_file_has_debug_fission_tu_index__dwarf_file_name_is_full_path__dwarf_formudata_internal__dwarf_frame_constructor__dwarf_frame_destructor__dwarf_free_abbrev_hash_table_contents__dwarf_free_all_of_one_debug__dwarf_free_chain_entries__dwarf_get_abbrev_for_code__dwarf_get_addr_from_tied__dwarf_get_addr_index_itself__dwarf_get_address_size__dwarf_get_alloc__dwarf_get_augmentation_type__dwarf_get_debug__dwarf_get_debugfission_for_offset__dwarf_get_dwp_extra_offset__dwarf_get_elf_flags_func_ptr__dwarf_get_fde_list_internal__dwarf_get_fission_addition_die__dwarf_get_ranges_base_attr_from_tied__dwarf_get_return_address_reg__dwarf_get_size_of_val__dwarf_get_string_base_attr_value__dwarf_get_string_from_tied__dwarf_initialize_search_hash__dwarf_insert_in_group_map__dwarf_internal_get_die_comp_dir__dwarf_internal_get_pubnames_like_data__dwarf_internal_globals_dealloc__dwarf_internal_srclines__dwarf_length_of_cu_header__dwarf_length_of_cu_header_simple__dwarf_line_context_constructor__dwarf_line_context_destructor__dwarf_load_debug_info__dwarf_load_debug_types__dwarf_load_section__dwarf_look_in_local_and_tied__dwarf_macro_constructor__dwarf_macro_destructor__dwarf_memcpy_swap_bytes__dwarf_next_cu_header_internal__dwarf_print_header_issue__dwarf_pro_encode_leb128_nm__dwarf_pro_encode_signed_leb128_nm__dwarf_reference_outside_section__dwarf_search_for_signature__dwarf_section_get_target_group_from_map__dwarf_section_in_group_by_name__dwarf_set_line_table_regs_default_values__dwarf_special_no_dbg_error_malloc__dwarf_tdelete__dwarf_tdestroy__dwarf_tdump__dwarf_tfind__dwarf_tied_destroy_free_node__dwarf_tsearch__dwarf_twalk__dwarf_update_chain_list__dwarf_valid_form_we_know__dwarf_what_section_are_we__mh_execute_header_close_a_file_cu_offset_size_cu_version_stamp_dumpallnamesfile_dw5formsarray_dwarf_CU_dieoffset_given_die_dwarf_arrayorder_dwarf_attr_dwarf_attr_offset_dwarf_attrlist_dwarf_bitoffset_dwarf_bitsize_dwarf_bytesize_dwarf_child_dwarf_cie_section_offset_dwarf_cmdline_options_dwarf_convert_to_global_offset_dwarf_create_cie_from_after_start_dwarf_create_fde_from_after_start_dwarf_dealloc_dwarf_dealloc_macro_context_dwarf_dealloc_uncompressed_block_dwarf_debug_addr_index_to_addr_dwarf_debugnames_abbrev_by_code_dwarf_debugnames_abbrev_by_index_dwarf_debugnames_abbrev_form_by_index_dwarf_debugnames_bucket_dwarf_debugnames_cu_entry_dwarf_debugnames_entrypool_dwarf_debugnames_entrypool_values_dwarf_debugnames_foreign_tu_entry_dwarf_debugnames_header_dwarf_debugnames_local_tu_entry_dwarf_debugnames_name_dwarf_debugnames_sizes_dwarf_die_CU_offset_dwarf_die_CU_offset_range_dwarf_die_abbrev_children_flag_dwarf_die_abbrev_code_dwarf_die_abbrev_global_offset_dwarf_die_from_hash_signature_dwarf_die_offsets_dwarf_die_text_dwarf_diename_dwarf_dieoffset_dwarf_dietype_offset_dwarf_discr_entry_s_dwarf_discr_entry_u_dwarf_discr_list_dwarf_encode_leb128_dwarf_encode_signed_leb128_dwarf_errmsg_dwarf_errno_dwarf_expand_frame_instructions_dwarf_fde_cie_list_dealloc_dwarf_fde_section_offset_dwarf_formaddr_dwarf_formblock_dwarf_formexprloc_dwarf_formflag_dwarf_formref_dwarf_formsdata_dwarf_formsig8_dwarf_formsig8_const_dwarf_formstring_dwarf_formudata_dwarf_get_ACCESS_name_dwarf_get_ADDR_name_dwarf_get_ATCF_name_dwarf_get_ATE_name_dwarf_get_AT_name_dwarf_get_CC_name_dwarf_get_CFA_name_dwarf_get_CHILDREN_name_dwarf_get_DEFAULTED_name_dwarf_get_DSC_name_dwarf_get_DS_name_dwarf_get_EH_name_dwarf_get_END_name_dwarf_get_FORM_name_dwarf_get_FRAME_name_dwarf_get_IDX_name_dwarf_get_ID_name_dwarf_get_INL_name_dwarf_get_ISA_name_dwarf_get_LANG_name_dwarf_get_LLEX_name_dwarf_get_LLE_name_dwarf_get_LNCT_name_dwarf_get_LNE_name_dwarf_get_LNS_name_dwarf_get_MACINFO_name_dwarf_get_MACRO_name_dwarf_get_OP_name_dwarf_get_ORD_name_dwarf_get_RLE_name_dwarf_get_SECT_name_dwarf_get_TAG_name_dwarf_get_UT_name_dwarf_get_VIRTUALITY_name_dwarf_get_VIS_name_dwarf_get_address_size_dwarf_get_aranges_section_name_dwarf_get_children_name_dwarf_get_cie_augmentation_data_dwarf_get_cie_index_dwarf_get_cie_info_dwarf_get_cie_info_b_dwarf_get_cie_of_fde_dwarf_get_cu_die_offset_given_cu_header_offset_dwarf_get_cu_die_offset_given_cu_header_offset_b_dwarf_get_debug_addr_index_dwarf_get_debug_str_index_dwarf_get_debugfission_for_die_dwarf_get_debugfission_for_key_dwarf_get_die_address_size_dwarf_get_die_infotypes_flag_dwarf_get_die_section_name_dwarf_get_die_section_name_b_dwarf_get_fde_at_pc_dwarf_get_fde_augmentation_data_dwarf_get_fde_exception_info_dwarf_get_fde_for_die_dwarf_get_fde_info_for_all_regs_dwarf_get_fde_info_for_all_regs3_dwarf_get_fde_info_for_cfa_reg3_dwarf_get_fde_info_for_cfa_reg3_b_dwarf_get_fde_info_for_reg_dwarf_get_fde_info_for_reg3_dwarf_get_fde_info_for_reg3_b_dwarf_get_fde_instr_bytes_dwarf_get_fde_list_dwarf_get_fde_list_eh_dwarf_get_fde_n_dwarf_get_fde_range_dwarf_get_form_class_dwarf_get_frame_section_name_dwarf_get_frame_section_name_eh_gnu_dwarf_get_globals_dwarf_get_harmless_error_list_dwarf_get_line_section_name_from_die_dwarf_get_macro_context_dwarf_get_macro_context_by_offset_dwarf_get_macro_defundef_dwarf_get_macro_import_dwarf_get_macro_op_dwarf_get_macro_section_name_dwarf_get_macro_startend_file_dwarf_get_offset_size_dwarf_get_ranges_section_name_dwarf_get_section_count_dwarf_get_section_info_by_index_dwarf_get_section_info_by_name_dwarf_get_section_max_offsets_dwarf_get_section_max_offsets_b_dwarf_get_section_max_offsets_c_dwarf_get_section_max_offsets_d_dwarf_get_string_section_name_dwarf_get_version_of_die_dwarf_get_xu_hash_entry_dwarf_get_xu_index_header_dwarf_get_xu_index_section_type_dwarf_get_xu_section_names_dwarf_get_xu_section_offset_dwarf_global_cu_offset_dwarf_global_die_offset_dwarf_global_formref_dwarf_global_name_offsets_dwarf_globals_dealloc_dwarf_globname_dwarf_harmless_cleanout_dwarf_harmless_init_dwarf_hasattr_dwarf_hasform_dwarf_highpc_dwarf_highpc_b_dwarf_insert_harmless_error_dwarf_line_is_addr_set_dwarf_line_srcfileno_dwarf_line_subprog_dwarf_line_subprogno_dwarf_lineaddr_dwarf_linebeginstatement_dwarf_lineblock_dwarf_linecontext_dwarf_lineendsequence_dwarf_linelogical_dwarf_lineno_dwarf_lineoff_dwarf_lineoff_b_dwarf_linesrc_dwarf_lowpc_dwarf_macho_finish_dwarf_macho_init_dwarf_macro_context_head_dwarf_macro_operands_table_dwarf_next_cu_header_dwarf_next_cu_header_b_dwarf_next_cu_header_c_dwarf_next_cu_header_d_dwarf_object_finish_dwarf_object_init_dwarf_object_init_b_dwarf_offdie_dwarf_offdie_b_dwarf_offset_list_dwarf_print_memory_stats_dwarf_printf_dwarf_prologue_end_etc_dwarf_read_cie_fde_prefix_dwarf_record_cmdline_options_dwarf_register_printf_callback_dwarf_sec_group_map_dwarf_sec_group_sizes_dwarf_set_default_address_size_dwarf_set_frame_cfa_value_dwarf_set_frame_rule_inital_value_dwarf_set_frame_rule_initial_value_dwarf_set_frame_rule_table_size_dwarf_set_frame_same_value_dwarf_set_frame_undefined_value_dwarf_set_harmless_error_list_size_dwarf_set_reloc_application_dwarf_set_stringcheck_dwarf_siblingof_dwarf_siblingof_b_dwarf_srcfiles_dwarf_srclang_dwarf_srclines_dwarf_srclines_b_dwarf_srclines_comp_dir_dwarf_srclines_dealloc_dwarf_srclines_dealloc_b_dwarf_srclines_files_count_dwarf_srclines_files_data_dwarf_srclines_from_linecontext_dwarf_srclines_include_dir_count_dwarf_srclines_include_dir_data_dwarf_srclines_subprog_count_dwarf_srclines_subprog_data_dwarf_srclines_table_offset_dwarf_srclines_two_level_dwarf_srclines_two_level_from_linecontext_dwarf_srclines_version_dwarf_tag_dwarf_uncompress_integer_block_dwarf_validate_die_sibling_dwarf_whatattr_dwarf_whatform_dwarf_whatform_direct_dwarf_xu_header_free_lookfor_name_main_open_a_fileÜû /usr/include/usr/include/i386/usr/include/sys/tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/tmp/c/tmp/dwarf-20170709/libdwarfstdio.h_types.h_types.hsimplereader.clibdwarf.hÀ%ä ? ŸŸ g Ÿ  Ÿ  t »Ÿ YŸžff< .gf*t<g ó/f.h ó#Xf1t<g ó4f/f. h4f/f. h4f/f. i4f/f. i#Xf9t<g ó#Xf9t<g Ÿ1f,f. h1f,f. h1f,f. iC>f O#_X ä"Xf gÈg*ºfä$c&$ fº»t"e vYf ‚ htg Yt6! f"ÈgŸ­ htgh½%f-f:f f t jt !ƒó#È’ó fu.= f-'hd Èi tØóŸŸ= f f$f f ‘Xt ! ƒ®$Èf‚ 4iYÈ’ó fu.= f-'hd Èi tØóŸŸ= f f$f f ‘Xt ! ƒ®#Èf‚ 4jYÈZ ó* ºÉ7= f.'hd Èi t!× ×Xt ! ƒ®#Èf‚ 4iYÈZ ó* ºÉ7= f.'hd Èi t!× ×Xt ! ƒ®#Èf‚ 4i YÈg f…"f f º jt !ØÈg ºØfƒÉà4„ ×!u<º=<<<. g¼ <<=<‚ < /<.uå tåÉ"u Ð5ò u!u< =u<<<. g¼ <<? <‚=< </up6ê Ø t <. ><°6Ø å  <)ä<ã õe  P7¨ = óž<"g< žƒ<!Ô\ÉÐ7Å" 3< =uw "< <D! = ;L"< <g)<<= Jg"<Y)Ž \ Yt<<*g <f<!I% `tJ,g+< <J,=+< <J>&º =-ã X- < <*9Ý ƒžJ/å<f= J*âÚ× : A t„ $º fgŸŸ Èg Ÿ­2¼geòht"evt"ev"f+f1f f‘Ÿ" KZf#f)ff=,<« )= wJ fh؃< . žå/"< ô<e,<<,% /žJgu-×< Yufó#„< º= Jå¼< ¬h=f d,s?‚ ?° #××gggh×%×Kf >uju uvuu × $Èg uƒ&9*•‹ nB Jg*ž<‚4:= <v J ¼ØJ»J!h%<,<=; t> Jg*ž<‚4A= <v J "ɼ"<)< <"< <» < Qº 0Cÿ »<ƒPC² 0 J<J <gJ <=YJ<fJ<gJ< <=YJ<fJ<gJ< <=0×2J JK ®<@D˜ óu <= J!Éæ/‘»J Y)6/;\`Eø -u<=uuvt‘uƒ><<(<<iu*<< ò= J9å <" J"g&<,<4<<<?< <u< <!½%<-<><< t= Jg*ž<‚%>< ;L" J h [< <g< <’<=<$<-< <d<X°G” /×f<fK)<< <. <, [<<.‘<u<g<×Îf *uug uuuuug vt‘uƒh(< < ò =J7å < "Jå= #< < ò =J3å <L J º =J<å <"žg< <>1< < ž = Jhƒ,<< ò= J<å <Ê#=J º= Jå>< <“žfž gJ <gžEåK<<0<(<.<1< <vž!f%J<< gJ(< gJ :j< <AKG< <ó <)</< <h0×6<:JB< < uJ(!1J < ®®Jg< <’ ðLÐ »uu× ×v < < = Jg ZÖff'K <f!?%<)< <î ^<<’NÚ 0uu××Ø× ×uvt»uƒ’2< < < =J g ZÖff&Ê<0f< ò= JgJ<g$Ø<fåX["f&.*<;fDff-Ÿ6< $< .< >YJ<$‘<f¼J<"‘<f¼J<"“<f ¼Y#<< f e  XÈ »uuŸ====‘¥+<<" ?C<<È>)<<¬'g <¼ Jw ¹  ¬J ! ƒM Jht<"¹  ­t"! º»(ºJ"½¸'h¹ &XJ ! ƒO t# ¹  ¬t ! ƒõÛÈf"‚%f0"<*f3¬*<?4 e?Èff Ø$< e$Èff Ø$< e$<<‘ Vé &uuØvt‘uƒ“2< < < =J g&Z+<=<XJ< >Öff&v<0f< ò= JgJ<‘0u(<9f<ò=Jæ<; 1YJ< h YY#<< f p X<<‘"t 'ugguv < . =J åÉw < ò =J åÉ# »J ò ? JgZ<<=`Y¡ ,u uv < ž = Jå)f <ó< <¼ Z½ uv××vtguƒh&< < ò =Jg X< K„&< < ò =Jg X< KZY[¨ uv×vtguƒi%< < ò =Jg X< KZY«Íû /tmp/c/tmp/dwarf-20170709/libdwarf/usr/include/i386/usr/include/sys/_types/tmp/c/dwarf/usr/include/_types/usr/include/mach-o/usr/include/mach/i386/usr/include/mach/usr/include/usr/include/syslibdwarf.hdwarf_opaque.hdwarf_base_types.hdwarf_error.hdwarf_util.hdwarf_xu_index.h_types.h_size_t.hdwarf_macho.c_uint32_t.hloader.hvm_types.hmachine.hstdio.h _types.h _uint64_t.h [ ¡ 0#v<º*<@<< ‚ =J¯q < ä =J-2 <"#t,8tAfPtYft0õ(=J+\<)</*<?<"É<Ö/='<‚%<gž h< g'<1f9<<>¯,<=,<×,<u(<#Ù2t;ºtRhY<4f$>+tJ\åx<{<@t:ò%=JTgW<0ž7<%<E<XK]<0X7<%<E<Xg^<c<\<0.7<%<E<%K3<"_xX7 º1t<.<=,<K,<KL[S<1f$>+tJVår<u<=t7ò%=JTgW<0ž7<%<E<XKG<0<7<%<E<X»^<c<\<0.7<%<E<%K3<"_xX7 º1t<.<=,<K,<N$<f7»E<N<V<_<#<!t>J#g*<f#ƒ<„Z<ƒ YY <Ø < „< à` -, »<‚ = Jg < „<= a ƒ) !.<!.==D<.$=)<< º =<f ƒ< ƒ<€a  ¼ u<? ¬ . =J<fJ#<&f(J <g<> å<ða ø= %< > J f.K< Ê:ž f< Y:ž J< =< Ø#< ×¼u Àb Ü= »< =<<àb ã= »< =< c ê= »< =<  c ñ »=f@c Š= '< > J.f.J5<f .K!t<4X << /¼u £&dumpallnamesfilescu_version_stamp…cu_offset_size—namesoptionon¨dupstrusedÀdupstrarrayÝdumpallnamespathîdumpallnamesÿcheckoptionontuhash!cuhash2tufissionhashCcufissionhashTpassnullerroreg_is_infounittype’fissionfordie£stdrun´dienumberdmainòstartswithextractstringUstartswithextractnumÀopen_a_file÷simple_error_handler8cleanupstrYxfrm_to_sig8$print_die_dataÌprint_debug_fission_headere read_cu_listÞ close_a_file char_to_uns4bit5 format_sig8_string” get_die_and_siblingsp resetsrcfiles± print_die_data_i˜ printnamestrings.print_subprogprint_comp_dirãprint_name_strings_attroprint_single_stringÝget_numberZget_addr£G&macho_methodsµSectionNamesÖdwarf_macho_init0getBaseNamecdwarf_macho_finishÇgetSeparatormacho_get_section_infosmacho_get_byte_order¦macho_get_length_sizeÙmacho_get_pointer_size macho_get_section_count?macho_load_section£=FILEH__sFILEnunsigned charuint|shortƒ__sbufÚcharüfpos_t__darwin_off_t__int64_tlong long int`sizetype¹unsigned intvDwarf_BoolÅDwarf_Form_ClassGDwarf_PtrRDwarf_Unsigned]long long unsigned intÍDwarf_DebugäDwarf_ErrorûDwarf_HandlerDwarf_Sig8$Dwarf_Sig8_sLDwarf_Diecsrcfilesdata–Dwarf_Signed¡Dwarf_Debug_Fission_Per_CU­Dwarf_Debug_Fission_Per_CU_s_Dwarf_Halfjunsigned shortqDwarf_AttributeDwarf_Addr˜£G<Dwarf_Obj_Access_MethodsHDwarf_Obj_Access_Methods_sÛintãDwarf_Halfîunsigned shortúDwarf_Obj_Access_SectionDwarf_Obj_Access_Section_syDwarf_Addr„long long unsigned int‹Dwarf_Unsigned char½Dwarf_EndiannessìDwarf_Small÷unsigned charYDwarf_DebugjDwarf_Debug_s|Dwarf_Obj_Access_Interface_s©Dwarf_HandlerÇDwarf_ErrorØDwarf_Error_sýDwarf_Swordlong intDwarf_PtrDwarf_Debug_InfoTypes_sœDwarf_CU_Context¬Dwarf_CU_Context_sS Dwarf_Sig8^ Dwarf_Sig8_s sizetypeˆ Dwarf_Debug_Fission_Per_CU_s Dwarf_Bool Dwarf_Byte_Ptr Dwarf_Hash_Table/ Dwarf_Hash_Table_sf long unsigned intr Dwarf_Hash_Table_Entry_s‹ Dwarf_Abbrev_List¡ Dwarf_Die² Dwarf_Die_s unsigned int Dwarf_Group_Data_sS Dwarf_Ciej Dwarf_Signedu long long int Dwarf_Fde˜ Dwarf_Section_sì Dwarf_Wordü Dwarf_Xu_Index_Header Dwarf_Xu_Index_Header_sù size_t__darwin_size_tDwarf_dbg_sect_sDwarf_Harmless_süDwarf_Printf_Callback_Info_s`dwarf_printf_callback_function_type~Dwarf_Tied_Data_sýmach_header_64vuint32_tcpu_type_tŒinteger_t—cpu_subtype_t¬mach_headermacho_access_object_t¾Dwarf_Obj_Access_Interface«FILE¶__sFILE×shortÞ__sbufJfpos_tU__darwin_off_t`__int64_t³section_64}uint64_t’section¼À%à4èÐ5‘p66°6šP7uÐ74:q<Š ?0CPCâ@D`EM°G=ðL NVO`Y¹ ZÙ[”d£ [9à`= a[€amðaÇÀbàbc c@c‘Ÿ -oÀ%”[„8„|¼=H•™šXz¢i{#¥u|#¨u}#«|~# ²|#¸ƒ€#¼u#Ũ„#Í©…# Ôº†#$Úá‡#(à$ˆ#,烋#0ëIŒ#8òu#<öT#@üg‘#Cƒ”#Du—#Lü˜#Pn%)/X6iY#<uZ#® u ¨¿ u ¨ Õ uÚBæ ü ¨ ü uGMNG].g) u ¨ ? uD ÚN u n`~ n`‡u‘€¼˜u’„¼§u˜¼µ¹¥¼¼ÀÍѤÀ¼ ?`dÙ?…œ¼êuƒ ¼÷u‚¤¼?œ¨¼ ?›¬¼?ž°¼!?´¼/u˜¸¼=vX´uG^RuŽ\´[u—`´iuŒd´pu–P¾z–‹¡·Ëâø !:O j ‚ — ® ÅÛñ !;¨Wv]a`pÀ%Ö4U‡du‘|Œdu‘Œ|‘dÈ‘ˆ|–fÍ‘„|šgu‘€|h?‘ü{¦iu‘ø{ªjä‘ô{°kû‘ð{¸lG‘h¿m‘ì{ÅnG‘è{Êoum&Q+‘ä{Øtu,p.‘à{ÚÄL5-Ù-‘Ð{ÞÍc†.u0‘Ì{ÚÜL:/Þ/‘¸{Þåc˜0>2‘€~áõ¡a24‘˜|á ¡à4È5Uéu‘t?‘p?‘l .‘h?‘d¹Ð5a6U òu‘xò?‘tò?‘p5ò3‘lô?‘hõ¹‘d<öup6¦6U>ju‘|Jj?‘xOmu°6J7UQX‘tªXä‘p¸XG‘hfZRP7Å7Um¨‘|ت¹Ð7:UxÅ‘\…Å?‘XÅ8‘`˜Ç=‘T¢ȹ‘P­ɹ‘L¸ʹ‘HØ˹œ8Ó8‘DÂÔ¹9f9‘CÌãn‘BÓän¢9Á9‘AÚën:<UÜ@‘„~–@Í‘€~ë@L‘ü}ôAu‘ø}ÞBIq:<‘ˆ~úF¡­:ÿ;‘ô}¦Iu‘ð}ªJä‘ì}ÅKG<?U+‘L+N‘H-?‘DØ.¹‘R*/S >è>‘@2A?‘¸:BR‘°>CR‘¬¦Du ?'CUC0‘d–0Í‘XP2R‘Pa3R‘No4_‘L|5_‘JŠ6_‘H–7_‘h¥8‘@¯9R‘¸º:R‘¶É;_‘°Ø<v‘¬ª=䑨à>u‘¤Å?GÇ?C‘ êCL‘œñDL‘˜¦Eu‘ˆÞFc A…A‘„øXÕÿAwB‘€øfÕ0COCUû‘|OuPC2DU²¹‘{Ú²n‘t<´¹@DQEU‘p+8‘l*Õ‘h0¹‘dع‘`9Õ`E­GU<v‘p–vÍ‘lQvL‘hØwu‘dXwu‘`ÞxI‘\¦zu‘Xa{L‘Ti|L‘Pª}ä‘LÅ~GôE G‘HoˆLÕF?G‘Dø•Õ°G€HUw”‘x–”Í‘tÞ”I‘h…––€HíLU‰é‘p–éÍ‘lëéL‘hôêu‘dÞëI‘`JíÕ‘\ªîä‘Zšï_‘Tžð?‘P¦ñu‘L¦òu‘HÅóG‘D°ôq‘Bµõ_‘¼½ö?ðLùMUÆÐ‘t–ÐÍ‘pÚÐL‘lªÒä‘h×Óˆ‘`ÞÔ–‘XØÕ–‘T¦Öu–M»M‘P°ÝqNVUæ×‘p–×Í‘lÚ×L‘hôØu‘dÞÙI‘`JÚ?‘\¦Üu‘XªÝä‘TôÞˆ‘Hüß‘@à‘¸ á–‘°Øâ–‘¨ãR‘ äR‘œ#åÕ‘˜ÅæG!O~P‘–,ò_WOäO‘ˆ2ö–®P'T‘„<u‘€Au‘ü~Gu‘ð~L‘è~T‘à~_‘Ø~h‘Ö~p_‘Ð~yÅVXUƒh‘t–hÍ‘pÚhL‘lôiu‘hÞiI‘d¦ku‘`ªlä‘\ômˆ‘P n–‘HØo–‘DÅpGWÒW‘B,_>W•W‘¼JƒÕX_YU’±‘p–±Í‘lÚ±L‘h°²q‘d¦´u‘bªµ_‘`²¶_‘\¼·Å‘Xª¸ä`YZU¿¡‘p–¡Í‘lÚ¡L‘jª¡_‘d¦£u‘`ª¤ä‘\Ó¥Õ ZùZUݽ‘|°½q‘x轘‘tª¿ä‘p¦Àu‘hìÁ–‘`ñÂR‘\ÅÃG[”[Uö¨‘|°¨q‘x訑tªªä‘p¦«u‘hñ¬‘dÅ­GÕÙÿ8Þ ð @õ % 3 ]  ä G$A L Œ¥;# Ú`äXY 9] c o k| Èl#… –m#“ un# Ÿ c­¬ C Ç ä, !ä ?0 #!í R6 #!÷ 7 # ! "> #! "? #t! R@ #Ô! RA #Ü R` ?u Ú`c­ Ú`j$ a/ }> A‚ N q]` dRC k "o [Ñc† 7 –İ <H” x ­ ·!È »Ê#!Ù ¬×#!è Ûå#!ø Ûï# ! þù#!  #!( 9#À Û â ã õ §%î$ a/ ú; y T 4„!o yˆ#!t ‹‹#!>‹Ž#!J–’#!y ‹–#!~ ‹š#$!ƒ ‹ #,„` dp„a`›  BÛ± ½ âÉ ¨"¥ž ¬ à ì â÷º b ‹ â Û â ã / §4ì> Û â ã Y §eÿ8j# X+!Æ w0#!Ò ©2#!Ý 3#!ç 5# !÷ 6#0!  <#T!  ?#X!' ìE#h!6 ìI#i!F ìN#j!a âR#l!o N W#p!{ j Y#t!ˆ N [#|!— j \#€!§ | ^#ˆ!³ ‹`#Œ!À | b#”!Ï ‹c#˜!ß ˜ e# !í ˜ f#!ü ˜ g#€! ˜ h#ð! ˜ i#à!, ˜ j#Ð!9 ˜ k#À!J ˜ l#°![ ˜ m# !j ˜ n# !y ˜ o#€ !‹ ˜ p#ð !˜ ˜ q#à !¥ ˜ r#Ð !· ˜ s#À !É ˜ t#°!Ø ˜ w# !î ˜ y#!˜ #€!˜ €#ð!&˜ #à!8˜ ‚#Ð!K˜ „#À![˜ †#°!p˜ ‡# !~˜ ‹#!˜ “#€!¢˜ ”#ð!´˜ ˜#à!˜ ™#Ð!Ðü  #À!åü ¡#Ä!úØ £#È!÷¤#Ì!÷¥#Í!(ãª#Î!Dã­#Ð!cã¯#Ò!{ã°#Ô!–ã±#Ö!¶÷³#Ø!˶#Ü!Ý ·#œ(!ý¹# (!ü»#´(!#~½#Ì(| 03!Mâ7#!T¤8#7µ3 ]º Ç Ó @Ø% $\ý%#fÛ3#v‚‚âWv ‹$u!£œy#!±œ|#!Äœ#!Ûœ‚# !ðœƒ#! ‹‰#! Ž#!'¡ # §3™¬$Dh‚WYƒ#^‹‰#hì# wì—# ‰ã›#š‹ #«ì¤#»ì¥#Ô‹¯#äS ½#$ö‹Ã#,ˆ Ï#4 æ#˜3 è#œH é# _ ê#¤{ î#¨… ò#¬ž‹õ#°«‹÷#¸º‹ù#À΋ý#Èê ÿ#Ð!ý #Ô! #Ø!(œ#Ü!0 #à!;ã #ä^ A L Œ¥u #   ~ Ç ä, !ä –0 #!í ‹6 #!÷ S 7 # ! ý > #! ý ? #t! ‹@ #Ô! ‹A #Ü ‹ ÛG^4H‡* Wš/ h †!{f ‡#!f ˆ#!¦m Š#±r Ñ!Ü‹ ’#– ä—› ö­ Y 9² c N  O#‹ P#&œQ#4ÛR# C U#À N!a  #!u ##!‹ %#!žâ(# S _ ¥Dd ¯u Ÿ cg  »C’ Å Ñp!á4#!ê‹#!ó‹# !ì "#! y'#!ì(# !(ì+#!!6ì 2#$!Gì?#(!_ì F#,!hãI#0!x4J#4!‡‹K#8!–‹L#@!ªyM#H!¹yP#P!Êì T#X!Ù÷ W#\!ä–Z#`!í ]#d!øì c#h!ì d#lf ˜  H 1X'IY(#P4)#`‹*#r‹,#}‹-#–‹.# ¨‹/#(¹‹0#0΋1#8ä‹2#@þ‹3#HÌ 6#P–9#T   Ý â â ó ù ø %.f 5\  2 E ™!V–œ#!^ ž#!h÷ ¡#!s £# !‚Û¤#!ŒÛ¥#!˜Û¦#!¦Û§# µj!Æ k#!Ò l#!á m#!ê n# !øòo#÷   !â #!/` #!7÷ #!A  # !OÛ #!gâ #ls q â – — !©Y#!¸  #!Êâ#ÙÆ :à° Ò  ×& 7æ– 8#í– 9#ýô Hv I#  J#— K#v L# %v M#+v N#6v O#<v P# E ŒN EÛY ^Œc F÷¬q 6v 7#  8#— 9#v :# %v ;#+v <#6v =#'} Y&ü L“¾ N#™½ O#£ì P# «ì Q# ³‹ R#»Ê W#& S>‹ T#J– U#+4 V# ¿â X#ø|Èw  ' [Ù`Uã ¡Û‘pô ¡–‘l° ¡©‘h¸ ¡‘dú ¡œ‘`ª ¡¡‘\¦ £Û‘XJ ¥÷ \Ë`‘TO ¨¦¦\À`‘P ®  ]¯`‘L ³C]ª`‘H ¶f J^5_‘D  Íø‘@Ø ÎÛp^ý^‘¼» Щ5_`‘¸  Þ§‘´Ø ßÛ[_ì_‘°» áˆà`aU -–‘x -–‘t& /– a{aU1 Û‘|– Y‘xª ¡‘t“ A‘p ‘l¦ Û€aíaUD –‘| –‘xQ –‘tS –‘sÚ " ða·bUU xÛ‘pl xâ‘np xã‘h~ xõ‘dª x§‘` zÀbÝbU \½‘|l \â‘x ^àbþbU¢ cì‘|l câ‘x eccU¸ jì‘|l jâ‘x l c} ®#(!"v ¯#0!)v °#4!/v ±#8!6v ²#v  #$!"v ¡#(!)v ¢#,!/v £#0!6v ¤#4!6v ¥#8!=v ¦#  I' I &I < I!I7 $ > 4I: ;   : ;( .@ : ;' I?  : ;I4 : ;I .@ : ;' I.@ : ; ' I : ; I4 : ; I.@ : ;' .@ : ; ' .@ : ;' ? I: ;'  : ;! I: ;8 " : ;# : ;$ : ; %&& : ; '.@ : ; ' I? Apple LLVM version 8.0.0 (clang-800.0.42.1)/tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c/tmp/c/dwarf/gcc_m32dumpallnamesfileFILE__sFILE_p_r_w_flags_file_bf_lbfsize_cookie_close_read_seek_write_ub_extra_ur_ubuf_nbuf_lb_blksize_offsetunsigned charintshort__sbuf_base_sizecharfpos_t__darwin_off_t__int64_tlong long int__sFILEXsizetypecu_version_stampcu_offset_sizenamesoptionondupstrusedunsigned intdupstrarraydumpallnamespathdumpallnamescheckoptionontuhashcuhashtufissionhashcufissionhashpassnullerrorg_is_infoDwarf_BoolunittypefissionfordiestdrundienumberDwarf_Form_ClassDW_FORM_CLASS_UNKNOWNDW_FORM_CLASS_ADDRESSDW_FORM_CLASS_BLOCKDW_FORM_CLASS_CONSTANTDW_FORM_CLASS_EXPRLOCDW_FORM_CLASS_FLAGDW_FORM_CLASS_LINEPTRDW_FORM_CLASS_LOCLISTPTRDW_FORM_CLASS_MACPTRDW_FORM_CLASS_RANGELISTPTRDW_FORM_CLASS_REFERENCEDW_FORM_CLASS_STRINGDW_FORM_CLASS_FRAMEPTRDW_FORM_CLASS_MACROPTRDW_FORM_CLASS_ADDRPTRDW_FORM_CLASS_LOCLISTDW_FORM_CLASS_LOCLISTSPTRDW_FORM_CLASS_RNGLISTDW_FORM_CLASS_RNGLISTSPTRDW_FORM_CLASS_STROFFSETSPTRDwarf_PtrDwarf_Unsignedlong long unsigned intmainargcargvdbgfdfilepathreserrorerrhanderrarghash8errpsimpleerrhandidiesffisdatastartswithextractstringarglookforptroutsprefixlenstartswithextractnumnumoutvopen_a_filenamefsimple_error_handlerunusedcleanupstrxfrm_to_sig8cuhash_inhash_outlocalhashhashin_lenfixed_sizeinit_byteadd_zeroshicharlocharcprint_die_dataprint_melevelpercuprint_debug_fission_headerfsdfissionsecstr_bufnstringoffsizeread_cu_listcu_header_lengthabbrev_offsetaddress_sizeversion_stampoffset_sizeextension_sizesignaturetypeoffsetnext_cu_headerheader_cu_typeis_infocu_numberno_diecu_dieemclose_a_filechar_to_uns4bitformat_sig8_stringdatabuf_sizecpget_die_and_siblingsin_diein_levelcur_diechildsib_dieresetsrcfilessriprint_die_data_itagtagnamelocalnameattrformnumformnameprintnamestringsatlistatcountprint_subprogattrbuflowpchighpcattrcountfilenumlinenumfilenameaformfilenum_shreshresblresalthipchipcoffsetalthipcbaltlopchighformhighclassprint_comp_dirprint_name_strings_attrattrnumfinalformclprint_single_stringstringvalget_numbervalsvaluvalget_addrDwarf_DebugDwarf_Debug_sDwarf_ErrorDwarf_Error_sDwarf_HandlerDwarf_Sig8Dwarf_Sig8_sDwarf_DieDwarf_Die_ssrcfilesdatasrcfilessrcfilescountsrcfilesresDwarf_SignedDwarf_Debug_Fission_Per_CUDwarf_Debug_Fission_Per_CU_spcu_typepcu_indexpcu_hashpcu_offsetpcu_sizeunused1unused2Dwarf_Halfunsigned shortDwarf_AttributeDwarf_Attribute_sDwarf_Addr/tmp/c/dwarf/dwarf_macho.cmacho_methodsDwarf_Obj_Access_MethodsDwarf_Obj_Access_Methods_sget_section_infoget_byte_orderget_length_sizeget_pointer_sizeget_section_countload_sectionrelocate_a_sectionDwarf_Obj_Access_SectionDwarf_Obj_Access_Section_saddrtypelinkinfoentrysizeDwarf_EndiannessDW_OBJECT_MSBDW_OBJECT_LSBDwarf_Smallde_obj_filede_errhandde_errargde_info_readingde_types_readingde_groupnumberde_groupnumbersde_length_sizede_pointer_sizede_assume_string_in_boundsde_alloc_treede_cie_datade_cie_countde_cie_data_ehde_cie_count_ehde_fde_datade_fde_countde_fde_data_ehde_fde_count_ehde_debug_infode_debug_typesde_debug_abbrevde_debug_linede_debug_line_strde_debug_locde_debug_arangesde_debug_macinfode_debug_macrode_debug_namesde_debug_pubnamesde_debug_strde_debug_supde_debug_loclistsde_debug_rnglistsde_debug_framede_debug_frame_eh_gnude_debug_pubtypesde_debug_funcnamesde_debug_typenamesde_debug_varnamesde_debug_weaknamesde_debug_rangesde_debug_str_offsetsde_debug_addrde_debug_gdbindexde_debug_cu_indexde_debug_tu_indexde_elf_symtabde_elf_strtabde_cu_hashindex_datade_tu_hashindex_datade_copy_wordde_same_endiande_elf_must_closede_frame_rule_initial_valuede_frame_reg_rules_entry_countde_frame_cfa_col_numberde_frame_same_value_numberde_frame_undefined_value_numberde_big_endian_objectde_debug_sectionsde_debug_sections_total_entriesde_harmless_errorsde_printf_callbackde_tied_dataDwarf_Obj_Access_Interface_sobjectmethodser_errvaler_static_allocDwarf_Swordlong intDwarf_Debug_InfoTypes_sde_cu_contextde_cu_context_listde_cu_context_list_endde_offdie_cu_contextde_offdie_cu_context_endde_last_offsetde_last_di_ptrde_last_dieDwarf_CU_ContextDwarf_CU_Context_scc_dbgcc_lengthcc_length_sizecc_extension_sizecc_version_stampcc_abbrev_offsetcc_address_sizecc_segment_selector_sizecc_debug_offsetcc_type_signaturecc_type_signature_offsetcc_dwp_offsetscc_signature_presentcc_addr_base_presentcc_ranges_base_presentcc_str_offsets_base_presentcc_is_dwocc_cu_die_offset_presentcc_addr_basecc_ranges_basecc_str_offsets_basecc_cu_die_global_sec_offsetcc_last_abbrev_ptrcc_last_abbrev_endptrcc_abbrev_hash_tablecc_nextcc_is_infocc_unit_typeDwarf_Byte_PtrDwarf_Hash_TableDwarf_Hash_Table_stb_table_entry_counttb_total_abbrev_counttb_entrieslong unsigned intDwarf_Hash_Table_Entry_sat_headDwarf_Abbrev_ListDwarf_Abbrev_List_sdi_debug_ptrdi_abbrev_listdi_cu_contextdi_abbrev_codedi_is_infoDwarf_Group_Data_sgd_number_of_groupsgd_number_of_sectionsgd_map_entry_countgd_mapDwarf_CieDwarf_Cie_sDwarf_FdeDwarf_Fde_sDwarf_Section_sdss_datadss_sizedss_entrysizedss_indexdss_addrdss_data_was_mallocdss_is_in_usedss_group_numberdss_requires_decompressdss_linkdss_reloc_indexdss_reloc_datadss_reloc_sizedss_reloc_entrysizedss_reloc_addrdss_reloc_symtabdss_reloc_linkdss_symtabdss_namedss_numberdss_flagsdss_addralignDwarf_WordDwarf_Xu_Index_HeaderDwarf_Xu_Index_Header_sgx_dbggx_section_datagx_section_lengthgx_versiongx_column_count_sectionsgx_units_in_indexgx_slots_in_hashgx_hash_table_offsetgx_index_table_offsetgx_section_offsets_offsetgx_section_sizes_offsetgx_typegx_section_namesize_t__darwin_size_tDwarf_dbg_sect_sds_nameds_numberds_secdatads_groupnumberds_duperrds_emptyerrds_have_dwarfds_have_zdebugDwarf_Harmless_sdh_maxcountdh_next_to_usedh_firstdh_errs_countdh_errorsDwarf_Printf_Callback_Info_sdp_user_pointerdp_fptrdp_bufferdp_buffer_lendp_buffer_user_provideddp_reserveddwarf_printf_callback_function_typeDwarf_Tied_Data_std_tied_objecttd_is_tied_objecttd_tied_searchSectionNamesmonamedwnamemach_header_64magiccputypecpusubtypefiletypencmdssizeofcmdsflagsreserveduint32_tcpu_type_tinteger_tcpu_subtype_tmach_headermacho_access_object_tintfcbyteorderlensizeptrsizesec_cntsecdsym_bufDwarf_Obj_Access_Interfacedwarf_macho_initfnameret_dbgmacholenmhgetBaseNameszFilenamepSeparatordwarf_macho_finishgetSeparatorpqmacho_get_section_infoobjsection_indexreturn_sectionmacho_get_byte_ordermacho_get_length_sizemacho_get_pointer_sizemacho_get_section_countmacho_load_sectionreturn_datasection_64sectnamesegnameoffsetalignreloffnrelocreserved1reserved2reserved3uint64_tsectionHSAH6 ÿÿÿÿ #ÿÿÿÿ$%&'().12ÀÆAm¯g«ÓÕü•E\.„i{Ç!²†³,FT¶¯¯v`¼ÃäˆTqüS¤<ñn S–ÒƒÙÕ1†¸)Tæõ‡qg#&” gCÀ‘~KA¡M÷zøþòãßæµ¢¬OËÚü”€DÊbNýe±I›¶õçªúOòSõ2ºr"@ÁÿPnþÌ^˜ kMöÑr(Òæèg£LAÙçÞ‚À4ímáÁ=œðU×ðå)Œ¾ËÈ…Xäæjš|&ñÅ]7•¡¢l»õn׿<L\l|Œœ¬¼ÌÜìü ,<L\l|Œœ¬¼ÌÜìü ,<L\l|Œœ¬¼ÌÜìü ,<L\l|Œ1( ˜…!CÙX$RCe >À† ÉêîÜ$‰± Ó'æ.[’m8¸|)¢I)U¹(çâ) !)wp <” §—éòûÞ Æ˜ ¿oQ÷Ì=ep´öZµ¨xYÝÝ„&ϯ)Dj(÷ÿ5 U/T’ãi£ƒÍÀ‡d‡s2ãy&ÙÝHSAH ÿÿÿÿHSAH'N  ÿÿÿÿ #ÿÿÿÿ(,/1235689;ÿÿÿÿÿÿÿÿ>@BEÿÿÿÿGHôŽŒ/Ñÿî¢çcÚ çœ´2b[Úöò¨[«zDtõÏ ó„/ >rñ4Ù¨ýÕðZÃSBŠ/b‹ãSN€/D…òT v´K«Ù¡h‹^Öá~zTí²^H$Þ“òÐ,÷—™PÁöýá×l'6I×>Í“<²:niUÐ2%;ã @=K=ïIs™·ÑpÚÒ‹UÞv]ÇÆ&|¤ó¦ÁÏqÞŠe›ß5ÿp÷0€ˆ SðpìDzìñtE ìsÿ¸ÚÑ«Ô nßìñ­{Õûã·b7fÀ‘Ͳ_b4Ÿ#×µà&ï]èS†îÖm” ×—)™éÅ/$;·´ÕŸÞÀÊ}£Pa?Íc •|êªìñ”ÈÞ–U¤ /¥²„|©¦ìñ §Ëù½|5û8Of}”¶Íï3Jaƒš¼Þ9Pg‰ ÂÙð)Km„›½Ôë0G^uŒ£ºÜþ 7Ne|“ªÌî  > U l ƒ š ± È ß   : Q h Š ¬ Ã Ú ü  5 W !謥 ‹½E*fv [@µ}¿%[š¶[ äÖ7´jÖ7´1°!j Í]ª÷Ž,ª÷ŽaRéùm.éùm$ _ç6 †ç6 µ@#ý¯ÈŸ#(¬Àø)|$I†z+$I†c Uöÿ³A G`£ öG`£ ~`$Vœt\$$Vœt\` l™ l™ Ÿ!¸‚ô}g$„Õ[K $„Õ[Kc:%¿ÊpN$%•†¤ÏšHJ¤÷SY*J¤÷SÈa&HsˆÇ ­ü<Ù+ü<Ù.œ"‡6A‡> q íGüDgií+DgizÅÕœ©þ3 ûª½ÕLª½ÕÀ¹$ÁþΤ$ÁþÎo c.|F#—!$ݸ¥ÏŸ –&ýV &ýVWÂ×Ñ|;  ÄÝÝô $ãA ” ß«{-d5-N•{dhÒI°ø&s$Ñ?¶°DON&Ú:,²E¾"ù5bä.ÙþãN)÷kø+)÷k%u$¤(: ~$¤(: /ƒG4áW+G4áW»$ ;⟠3?hÇV‚«$,}˜  …ØXªÑ; s¯ º EˆµWGâ  ²â  p]$¡'E'$¡'EV,×Õ{¨qO%ÚœÎa/ j$¦W¨‘$¦W¨0úq;Ò5§")פÖE%QùäY/%úJ¡,¬ ¡Êóo½ `œUn­ ë{L $¹šüV¹šüVH·u¯SIÿÍ»ý³ü»ý³T ©¾_ÌN«D3ÁfBÚ$W×{“C$W×{“Y L^ÚŸ D^ÚŸ % {’Ä[ -ö¦æGv˜(š ¬˜(š •=™ik“N*™ik“¥öÖŸ n$q±š$q±± $1à ºHSAH ÿÿÿÿlibdwarf-20210528/dwarfdump/CODINGSTYLE0000664000175000017500000000300713644370703014203 00000000000000This document is a brief description of the main coding style conventions in dwarfdump. Many of them will be obvious from the code, but over time some accidental diffences crept in. Code should be indented in multiples of 4 spaces, and tabs should not be used to indent the source code. Use the dicheck program to check indenting. The struct naming convention is 'struct my_struct_s' for the struct defined here (meaning the name should end with _s). It is better to not do struct typedefs of local structs. Coders should type 'struct mystruct_s'. Readability is much more important than brevity. Any data or function not referenced outside the defining source file should be declared 'static'. Any duplicated code is a candidate for refactoring into a subprogram. Function names should be all lower case with underbars with the goal that statements and comments 'read well'. Variables should be lower-case with underbars for readability. It's ok for a small loop with counters to use single letter names like i or k or m. Structure members should have a struct-specific 2-character prefix to the name (followed by an underbar). That makes it much easier to grep for uses of members. Try to keep lines under 80 characters in length. Ensure every if() has {} to enclose the actions. Use libdwarf.h types for all the data objects you define, though sometimes an 'unsigned' or 'int' or 'size_t' is ok in restricted circumstances. Dwarf_Unsigned and Dwarf_Signed are the preferred integer types for general use. ------------ libdwarf-20210528/dwarfdump/print_reloc.c0000664000175000017500000007423414003121667015163 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #include "print_reloc.h" #include "print_reloc_decls.h" #include "section_bitmaps.h" #include "esb.h" #include "globals.h" #include "sanitized.h" static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link); static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link); static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size); static int print_relocinfo_64(Elf * elf ); static int print_relocinfo_32(Elf * elf); /* Set the relocation names based on the machine type */ static void set_relocation_table_names(Dwarf_Small machine_type) { reloc_type_names = 0; number_of_reloc_type_names = 0; switch (machine_type) { case EM_MIPS: #ifdef DWARF_RELOC_MIPS reloc_type_names = reloc_type_names_MIPS; number_of_reloc_type_names = sizeof(reloc_type_names_MIPS) / sizeof(char *); #endif /* DWARF_RELOC_MIPS */ break; case EM_PPC: #ifdef DWARF_RELOC_PPC reloc_type_names = reloc_type_names_PPC; number_of_reloc_type_names = sizeof(reloc_type_names_PPC) / sizeof(char *); #endif /* DWARF_RELOC_PPC */ break; case EM_PPC64: #ifdef DWARF_RELOC_PPC64 reloc_type_names = reloc_type_names_PPC64; number_of_reloc_type_names = sizeof(reloc_type_names_PPC64) / sizeof(char *); #endif /* DWARF_RELOC_PPC64 */ break; case EM_ARM: #ifdef DWARF_RELOC_ARM reloc_type_names = reloc_type_names_ARM; number_of_reloc_type_names = sizeof(reloc_type_names_ARM) / sizeof(char *); #endif /* DWARF_RELOC_ARM */ break; case EM_386: #ifdef DWARF_RELOC_386 reloc_type_names = reloc_type_names_386; number_of_reloc_type_names = sizeof(reloc_type_names_386) / sizeof(char *); #endif /* DWARF_RELOC_386 */ break; case EM_X86_64: #ifdef DWARF_RELOC_X86_64 reloc_type_names = reloc_type_names_X86_64; number_of_reloc_type_names = sizeof(reloc_type_names_X86_64) / sizeof(char *); #endif /* DWARF_RELOC_X86_64 */ break; default: /* We don't have others covered. */ reloc_type_names = 0; number_of_reloc_type_names = 0; break; } } static void get_reloc_type_names(int index,struct esb_s* outbuf) { if (index < 0 || index >= number_of_reloc_type_names) { if (number_of_reloc_type_names == 0) { /* No table provided. */ esb_append_printf_i(outbuf, "reloc type %d", (int) index); } else { /* Table incomplete? */ esb_append_printf_i(outbuf, "reloc type %d unknown", (int) index); } return; } esb_append(outbuf, reloc_type_names[index]); } static int get_reloc_section(Elf_Scn *scn, char *scn_name, Elf64_Word sh_type, struct sect_data_s * printable_sect, unsigned sectnum) { Elf_Data *data; int index; /* Check for reloc records we are interested in. */ for (index = 1; index < DW_SECTION_REL_ARRAY_SIZE; ++index) { const char *n = rel_info[index].name_rel; const char *na = rel_info[index].name_rela; if (strcmp(scn_name, n) == 0) { SECT_DATA_SET(rel_info[index].index,sh_type,n, printable_sect,sectnum) return DW_DLV_OK; } if (strcmp(scn_name, na) == 0) { SECT_DATA_SET(rel_info[index].index,sh_type,na, printable_sect,sectnum) return DW_DLV_OK; } } return DW_DLV_OK; } int print_relocinfo(UNUSEDARG Dwarf_Debug dbg, Dwarf_Error *err) { Elf *elf = 0; char *endr_ident = 0; int is_64bit = 0; int res = 0; int i = 0; for (i = 1; i < DW_SECTION_REL_ARRAY_SIZE; i++) { sect_data[i].display = reloc_map_enabled(i); sect_data[i].buf = 0; sect_data[i].size = 0; sect_data[i].type = SHT_NULL; } res = dwarf_get_elf(dbg, &elf, err); if (res == DW_DLV_NO_ENTRY) { printf("No Elf, so no elf relocations to print.\n"); return res; } else if (res == DW_DLV_ERROR) { return res; } endr_ident = elf_getident(elf, NULL); if (!endr_ident) { glflags.gf_count_major_errors++; printf("ERROR: elf_getident() failed\n"); return DW_DLV_NO_ENTRY; } is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64); if (is_64bit) { res = print_relocinfo_64(elf); } else { res = print_relocinfo_32(elf); } return res; } static int print_relocinfo_64(Elf * elf) { #ifdef HAVE_ELF64_GETEHDR Elf_Scn *scn = NULL; unsigned sect_number = 0; Elf64_Ehdr *ehdr64 = 0; Elf64_Shdr *shdr64 = 0; char *scn_name = 0; int i = 0; Elf64_Sym *sym_64 = 0; char **scn_names = 0; struct sect_data_s *printable_sects = 0; int scn_names_cnt = 0; ehdr64 = elf64_getehdr(elf); if (ehdr64 == NULL) { glflags.gf_count_major_errors++; printf("ERROR: elf64_getehdr() failed\n"); return DW_DLV_NO_ENTRY; } /* Make the section name array big enough that we don't need to check for overrun in the loop. */ scn_names_cnt = ehdr64->e_shnum + 1; scn_names = (char **)calloc(scn_names_cnt, sizeof(char *)); if (!scn_names) { unsigned long space = scn_names_cnt* sizeof(char *); glflags.gf_count_major_errors++; printf("ERROR: out of malloc space for section names" " allocating %lu bytes" " for relocations Elf64\n", space); return DW_DLV_NO_ENTRY; } printable_sects = (struct sect_data_s *)calloc(scn_names_cnt, sizeof(struct sect_data_s)); if (!printable_sects) { unsigned long space = scn_names_cnt* sizeof(struct sect_data_s); glflags.gf_count_major_errors++; printf("ERROR: out of malloc space allocating %lu bytes" " for sections Elf6\n", space); free(scn_names); return DW_DLV_NO_ENTRY; } /* First nextscn returns section 1 */ while ((scn = elf_nextscn(elf, scn)) != NULL) { ++sect_number; shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { free(scn_names); free(printable_sects); glflags.gf_count_major_errors++; printf("ERROR: elf64_getshsr() failed\n"); return DW_DLV_NO_ENTRY; } scn_name = elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name); if (scn_name == NULL) { glflags.gf_count_major_errors++; free(scn_name); free(printable_sects); printf("ERROR: elf_strptr (elf64) failed\n"); return DW_DLV_NO_ENTRY; } /* elf_nextscn() skips section with index '0' */ scn_names[sect_number] = scn_name; if (shdr64->sh_type == SHT_SYMTAB) { size_t sym_size = 0; size_t count = 0; sym_64 = (Elf64_Sym *) get_scndata(scn, &sym_size); if (sym_64 == NULL) { free(scn_names); free(printable_sects); glflags.gf_count_major_errors++; printf("ERROR: elf_getdata() (Elf64) " "failed to get symbol table " "elf_getdata returned NULL.\n"); return DW_DLV_NO_ENTRY; } count = sym_size / sizeof(Elf64_Sym); if (sym_size%sizeof(Elf64_Sym)) { glflags.gf_count_major_errors++; free(scn_names); free(printable_sects); printf("ERROR: symbols size %lu " "not a proper multiple of size of Elf64_sym\n", (unsigned long)sym_size* (unsigned long)(sizeof(Elf64_Sym))); return DW_DLV_NO_ENTRY; } sym_64++; count--; free(sym_data_64); sym_data_64 = 0; sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link); sym_data_64_entry_count = count; if (sym_data_64 == NULL) { free(scn_names); free(printable_sects); glflags.gf_count_major_errors++; printf("ERROR: malloc of %lu Elf64 symbols " "failed\n",(unsigned long)count); return DW_DLV_NO_ENTRY; } } else { int res = 0; res = get_reloc_section(scn,scn_name,shdr64->sh_type, printable_sects,sect_number); if (res != DW_DLV_OK) { free(scn_names); free(printable_sects); return res; } } } /* Set the relocation names based on the machine type */ set_relocation_table_names(ehdr64->e_machine); for (i = 1; i < ehdr64->e_shnum + 1; i++) { if (printable_sects[i].display && printable_sects[i].buf != NULL && printable_sects[i].size > 0) { print_reloc_information_64(i, printable_sects[i].buf, printable_sects[i].size, printable_sects[i].type, scn_names,scn_names_cnt); } } free(printable_sects); free(scn_names); #endif return DW_DLV_OK; } static int print_relocinfo_32(Elf * elf) { Elf_Scn *scn = NULL; Elf32_Ehdr *ehdr32 = 0; Elf32_Shdr *shdr32 = 0; unsigned sect_number = 0; char *scn_name = 0; int i = 0; Elf32_Sym *sym = 0; char **scn_names = 0; int scn_names_cnt = 0; struct sect_data_s *printable_sects = 0; ehdr32 = elf32_getehdr(elf); if (ehdr32 == NULL) { glflags.gf_count_major_errors++; printf("ERROR: elf32_getehdr() failed\n"); return DW_DLV_NO_ENTRY; } /* Make the section name array big enough that we don't need to check for overrun in the loop. */ scn_names_cnt = ehdr32->e_shnum + 1; scn_names = (char **)calloc(scn_names_cnt, sizeof(char *)); if (!scn_names) { unsigned long space = scn_names_cnt* sizeof(char *); glflags.gf_count_major_errors++; printf("ERROR Out of malloc space " "in relocation section names names " "elf 32 requesting %lu bytes", space); return DW_DLV_NO_ENTRY; } printable_sects = (struct sect_data_s *)calloc(scn_names_cnt, sizeof(struct sect_data_s)); if (!printable_sects) { unsigned long space = scn_names_cnt* sizeof(struct sect_data_s); free(scn_names); glflags.gf_count_major_errors++; printf("ERROR Out of malloc space in " "in relocation sects elf 32 requesting %lu bytes", space); } while ((scn = elf_nextscn(elf, scn)) != NULL) { ++sect_number; shdr32 = elf32_getshdr(scn); if (shdr32 == NULL) { free(printable_sects); free(scn_names); glflags.gf_count_major_errors++; printf("ERROR: elf_nextscn returns null \n"); return DW_DLV_NO_ENTRY; } scn_name = elf_strptr(elf, ehdr32->e_shstrndx,shdr32->sh_name); if (scn_name == NULL) { free(printable_sects); free(scn_names); glflags.gf_count_major_errors++; printf("ERROR: elf_stgrptr returns null \n"); return DW_DLV_NO_ENTRY; } scn_names[sect_number] = scn_name; if (shdr32->sh_type == SHT_SYMTAB) { size_t sym_size = 0; size_t count = 0; sym = (Elf32_Sym *) get_scndata(scn, &sym_size); if (sym == NULL) { free(printable_sects); free(scn_names); glflags.gf_count_major_errors++; printf("ERROR: elf_getdata() (Elf32) " "failed to get symbol table" " elf_getdata returned null\n"); return DW_DLV_NO_ENTRY; } count = sym_size / sizeof(Elf32_Sym); if (sym_size%sizeof(Elf32_Sym)) { glflags.gf_count_major_errors++; free(printable_sects); free(scn_names); printf("ERROR: size of Elf32 %lu sym not" " a multiple of symbols size %lu.\n", (unsigned long)sym_size, (unsigned long)sizeof(Elf32_Sym)); return DW_DLV_NO_ENTRY; } sym++; count--; free(sym_data); sym_data = 0; sym_data = readsyms(sym, count, elf, shdr32->sh_link); sym_data_entry_count = count; if (sym_data == NULL) { free(printable_sects); free(scn_names); glflags.gf_count_major_errors++; printf("ERROR: Cannot read symbo table\n"); return DW_DLV_NO_ENTRY; } } else { int res = 0; res = get_reloc_section(scn,scn_name,shdr32->sh_type, printable_sects,sect_number); if (res != DW_DLV_OK) { free(printable_sects); free(scn_names); return res; } } } /* End while. */ /* Set the relocation names based on the machine type */ set_relocation_table_names(ehdr32->e_machine); for (i = 1; i < ehdr32->e_shnum + 1; i++) { if (printable_sects[i].display && printable_sects[i].buf != NULL && printable_sects[i].size > 0) { print_reloc_information_32(i, printable_sects[i].buf, printable_sects[i].size, printable_sects[i].type, scn_names,scn_names_cnt); } } free(printable_sects); free(scn_names); return DW_DLV_OK; } #if HAVE_ELF64_R_INFO #ifndef ELF64_R_TYPE #define ELF64_R_TYPE(x) 0 /* FIXME */ #endif #ifndef ELF64_R_SYM #define ELF64_R_SYM(x) 0 /* FIXME */ #endif #ifndef ELF64_ST_TYPE #define ELF64_ST_TYPE(x) 0 /* FIXME */ #endif #ifndef ELF64_ST_BIND #define ELF64_ST_BIND(x) 0 /* FIXME */ #endif #endif /* HAVE_ELF64_R_INFO */ static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names,int scn_names_count) { /* Include support for Elf64_Rel and Elf64_Rela */ Dwarf_Unsigned add = 0; Dwarf_Half rel_size = SHT_RELA == type ? sizeof(Elf64_Rela) : sizeof(Elf64_Rel); Dwarf_Unsigned off = 0; struct esb_s tempesb; struct esb_s tempesc; printf("\n[%3d] %s:\n",section_no, sanitized(scn_names[section_no])); /* Print some headers and change the order for better reading */ printf("Offset Addend %-26s Index Symbol Name\n", "Reloc Type"); #if HAVE_ELF64_GETEHDR for (off = 0; off < size; off += rel_size) { #if HAVE_ELF64_R_INFO /* This works for the Elf64_Rel in linux */ Elf64_Rel *p = (Elf64_Rel *) (buf + off); char *name = 0; if (sym_data_64) { size_t index = ELF64_R_SYM(p->r_info) - 1; if (index < sym_data_64_entry_count) { name = sym_data_64[index].name; if (!name || !name[0]){ SYM64 *sym_64 = &sym_data_64[index]; if (sym_64->type == STT_SECTION && sym_64->shndx < scn_names_count) { name = scn_names[sym_64->shndx]; } } } } if (!name || !name[0]) { name = ""; } if (SHT_RELA == type) { Elf64_Rela *pa = (Elf64_Rela *)p; add = pa->r_addend; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(ELF64_R_TYPE(p->r_info),&tempesc); esb_append(&tempesb,sanitized(esb_get_string(&tempesc))); /* sanitized uses a static buffer, call just once here */ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n", (unsigned long int) (p->r_offset), (unsigned long int) (add), esb_get_string(&tempesb), (long)ELF64_R_SYM(p->r_info), sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); #else /* ! R_INFO */ /* sgi/mips -64 does not have r_info in the 64bit relocations, but seperate fields, with 3 types, actually. Only one of which prints here, as only one really used with dwarf */ Elf64_Rel *p = (Elf64_Rel *) (buf + off); char *name = 0; /* We subtract 1 from sym indexes since we left symtab entry 0 out of the sym_data[_64] array */ if (sym_data_64) { size_t index = p->r_sym - 1; if (index < sym_data_64_entry_count) { name = sym_data_64[index].name; } } if (!name || !name[0]) { name = ""; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(p->r_type,&tempesc)); esb_append(&tempesb,sanitized(esb_get_string(&tempesc))); printf("%5" DW_PR_DUu " %-26s <%3ld> %s\n", (Dwarf_Unsigned) (p->r_offset), esb_get_string(&tempesb), (long)p->r_sym, sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); #endif } #endif /* HAVE_ELF64_GETEHDR */ } static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count) { /* Include support for Elf32_Rel and Elf32_Rela */ Dwarf_Unsigned add = 0; Dwarf_Half rel_size = SHT_RELA == type ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel); Dwarf_Unsigned off = 0; struct esb_s tempesb; struct esb_s tempesc; printf("\n[%3d] %s:\n",section_no, sanitized(scn_names[section_no])); /* Print some headers and change the order for better reading. */ printf("Offset Addend %-26s Index Symbol Name\n", "Reloc Type"); for (off = 0; off < size; off += rel_size) { Elf32_Rel *p = (Elf32_Rel *) (buf + off); char *name = 0; /* We subtract 1 from sym indexes since we left symtab entry 0 out of the sym_data[_64] array */ if (sym_data) { size_t index = ELF32_R_SYM(p->r_info) - 1; if (index < sym_data_entry_count) { name = sym_data[index].name; if ((!name || !name[0]) && sym_data) { SYM *sym = &sym_data[index]; if (sym->type == STT_SECTION&& sym->shndx < scn_names_count) { name = scn_names[sym->shndx]; } } } } if (!name || !name[0]) { name = ""; } if (SHT_RELA == type) { Elf32_Rela *pa = (Elf32_Rela *)p; add = pa->r_addend; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(ELF32_R_TYPE(p->r_info),&tempesc); esb_append(&tempesb,esb_get_string(&tempesc)); /* sanitized uses a static buffer, call just once here */ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n", (unsigned long int) (p->r_offset), (unsigned long int) (add), esb_get_string(&tempesb), (long)ELF32_R_SYM(p->r_info), sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); } } /* We are only reading and saving syms 1...num-1. */ static SYM * readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link) { SYM *s = 0; SYM *buf = 0; indx_type i = 0; buf = (SYM *) calloc(num, sizeof(SYM)); if (buf == NULL) { return NULL; } s = buf; /* save pointer to head of array */ for (i = 0; i < num; i++, data++, buf++) { buf->indx = i; buf->name = (char *) elf_strptr(elf, link, data->st_name); buf->value = data->st_value; buf->size = data->st_size; buf->type = ELF32_ST_TYPE(data->st_info); buf->bind = ELF32_ST_BIND(data->st_info); buf->other = data->st_other; buf->shndx = data->st_shndx; } /* end for loop */ return (s); } /* We are only reading and saving syms 1...num-1. */ static SYM64 * read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link) { #ifdef HAVE_ELF64_GETEHDR SYM64 *s = 0; SYM64 *buf = 0; indx_type i = 0; buf = (SYM64 *) calloc(num, sizeof(SYM64)); if (buf == NULL) { return NULL; } s = buf; /* save pointer to head of array */ for (i = 0; i < num; i++, data++, buf++) { buf->indx = i; buf->name = (char *) elf_strptr(elf, link, data->st_name); buf->value = data->st_value; buf->size = data->st_size; buf->type = ELF64_ST_TYPE(data->st_info); buf->bind = ELF64_ST_BIND(data->st_info); buf->other = data->st_other; buf->shndx = data->st_shndx; } /* end for loop */ return (s); #else return 0; #endif /* HAVE_ELF64_GETEHDR */ } static void * get_scndata(Elf_Scn * fd_scn, size_t * scn_size) { Elf_Data *p_data; p_data = 0; if ((p_data = elf_getdata(fd_scn, p_data)) == 0 || p_data->d_size == 0) { return NULL; } *scn_size = p_data->d_size; return (p_data->d_buf); } /* Cleanup of malloc space (some of the pointers will be 0 here) so dwarfdump looks 'clean' to a malloc checker. */ void clean_up_syms_malloc_data() { free(sym_data); sym_data = 0; free(sym_data_64); sym_data_64 = 0; sym_data_64_entry_count = 0; sym_data_entry_count = 0; } int print_object_header(Dwarf_Debug dbg,Dwarf_Error *err) { Elf *elf = 0; int res = 0; /* Check if header information is required */ res = dwarf_get_elf(dbg, &elf, err); if (res == DW_DLV_NO_ENTRY) { printf(" No Elf, so no elf headers to print.\n"); return res; } else if (res == DW_DLV_ERROR) { return res; } if (section_map_enabled(DW_HDR_HEADER)) { #ifdef _WIN32 #ifdef HAVE_ELF32_GETEHDR /* Standard libelf has no function generating the names of the encodings, but this libelf apparently does. */ Elf_Ehdr_Literal eh_literals; Elf32_Ehdr *eh32 = 0; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *eh64 = 0; #endif /* HAVE_ELF64_GETEHDR */ eh32 = elf32_getehdr(elf); if (eh32) { /* Get literal strings for header fields */ elf32_gethdr_literals(eh32,&eh_literals); /* Print 32-bit obj header */ printf("\nObject Header:\ne_ident:\n"); printf(" File ID = %s\n",eh_literals.e_ident_file_id); printf(" File class = %02x (%s)\n", eh32->e_ident[EI_CLASS],eh_literals.e_ident_file_class); printf(" Data encoding = %02x (%s)\n", eh32->e_ident[EI_DATA],eh_literals.e_ident_data_encoding); printf(" File version = %02x (%s)\n", eh32->e_ident[EI_VERSION], eh_literals.e_ident_file_version); printf(" OS ABI = %02x (%s) (%s)\n", eh32->e_ident[EI_OSABI], eh_literals.e_ident_os_abi_s, eh_literals.e_ident_os_abi_l); printf(" ABI version = %02x (%s)\n", eh32->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version); printf("e_type : 0x%x (%s)\n", eh32->e_type,eh_literals.e_type); printf("e_machine : 0x%x (%s) (%s)\n",eh32->e_machine, eh_literals.e_machine_s,eh_literals.e_machine_l); printf("e_version : 0x%x\n", eh32->e_version); printf("e_entry : 0x%08x\n",eh32->e_entry); printf("e_phoff : 0x%08x\n",eh32->e_phoff); printf("e_shoff : 0x%08x\n",eh32->e_shoff); printf("e_flags : 0x%x\n",eh32->e_flags); printf("e_ehsize : 0x%x\n",eh32->e_ehsize); printf("e_phentsize: 0x%x\n",eh32->e_phentsize); printf("e_phnum : 0x%x\n",eh32->e_phnum); printf("e_shentsize: 0x%x\n",eh32->e_shentsize); printf("e_shnum : 0x%x\n",eh32->e_shnum); printf("e_shstrndx : 0x%x\n",eh32->e_shstrndx); } else { #ifdef HAVE_ELF64_GETEHDR /* not a 32-bit obj */ eh64 = elf64_getehdr(elf); if (eh64) { /* Get literal strings for header fields */ elf64_gethdr_literals(eh64,&eh_literals); /* Print 64-bit obj header */ printf("\nObject Header:\ne_ident:\n"); printf(" File ID = %s\n", eh_literals.e_ident_file_id); printf(" File class = %02x (%s)\n", eh64->e_ident[EI_CLASS], eh_literals.e_ident_file_class); printf(" Data encoding = %02x (%s)\n", eh64->e_ident[EI_DATA], eh_literals.e_ident_data_encoding); printf(" File version = %02x (%s)\n", eh64->e_ident[EI_VERSION], eh_literals.e_ident_file_version); printf(" OS ABI = %02x (%s) (%s)\n", eh64->e_ident[EI_OSABI], eh_literals.e_ident_os_abi_s, eh_literals.e_ident_os_abi_l); printf(" ABI version = %02x (%s)\n", eh64->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version); printf("e_type : 0x%x (%s)\n", eh64->e_type,eh_literals.e_type); printf("e_machine : 0x%x (%s) (%s)\n",eh64->e_machine, eh_literals.e_machine_s,eh_literals.e_machine_l); printf("e_version : 0x%x\n", eh64->e_version); printf("e_entry : 0x%" DW_PR_XZEROS DW_PR_DUx "\n", eh64->e_entry); printf("e_phoff : 0x%" DW_PR_XZEROS DW_PR_DUx "\n", eh64->e_phoff); printf("e_shoff : 0x%" DW_PR_XZEROS DW_PR_DUx "\n", eh64->e_shoff); printf("e_flags : 0x%x\n",eh64->e_flags); printf("e_ehsize : 0x%x\n",eh64->e_ehsize); printf("e_phentsize: 0x%x\n",eh64->e_phentsize); printf("e_phnum : 0x%x\n",eh64->e_phnum); printf("e_shentsize: 0x%x\n",eh64->e_shentsize); printf("e_shnum : 0x%x\n",eh64->e_shnum); printf("e_shstrndx : 0x%x\n",eh64->e_shstrndx); } #endif /* HAVE_ELF64_GETEHDR */ } #endif /* HAVE_ELF32_GETEHDR */ #endif /* _WIN32 */ } /* Print basic section information is required */ /* Mask only known sections (debug and text) bits */ if (any_section_header_to_print()) { int nCount = 0; int section_index = 0; const char *section_name = NULL; Dwarf_Addr section_addr = 0; Dwarf_Unsigned section_size = 0; Dwarf_Error error = 0; Dwarf_Unsigned total_bytes = 0; int printed_sections = 0; /* Print section information (name, size, address). */ nCount = dwarf_get_section_count(dbg); printf("\nInfo for %d sections:\n" " Nro Index Address Size(h) Size(d) Name\n", nCount); /* Ignore section with index=0 */ for (section_index = 1; section_index < nCount; ++section_index) { res = dwarf_get_section_info_by_index(dbg,section_index, §ion_name, §ion_addr, §ion_size, &error); if (res == DW_DLV_OK) { Dwarf_Bool print_it = FALSE; /* Use original mapping */ /* Check if the section name is a debug section */ print_it = section_name_is_debug_and_wanted( section_name); if (print_it) { ++printed_sections; printf(" %3d " "0x%03x " "0x%" DW_PR_XZEROS DW_PR_DUx " " "0x%" DW_PR_XZEROS DW_PR_DUx " " "%" DW_PR_XZEROS DW_PR_DUu " " "%s\n", printed_sections, section_index, section_addr, section_size, section_size, section_name); total_bytes += section_size; } } } printf("*** Summary: %" DW_PR_DUu " bytes " "for %d section(s) ***\n", total_bytes, printed_sections); } return DW_DLV_OK; } #endif /* DWARF_WITH_LIBELF */ libdwarf-20210528/dwarfdump/ChangeLog20170000664000175000017500000002631713644370703014571 000000000000002017-12-01 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-11-20 David Anderson * configure.in: Just do TRY_COMPILE instead of TRY_RUN to avoid issues in a cross-compile. * configure: Regenerated. 2017-10-20 David Anderson * print_die.c: Now handles DW_FORM_data16. 2017-10-16 David Anderson * dwarfdump.c,globals.h,print_ranges.c,print_section_groups.c: a large group of per-object totals/values were not free()d or zeroed for each member of an archive. Some of the zero/free() was moved from the end of main() to be done per-object and some were simply never completely reset before. These problems were only visible when running dwarfdump on an archive. 2017-10-15 David Anderson * dwarfdump.c: Added a call to destruct_abbrev_array() per object so the archive case can work properly with -ka. * dwgetopt.c: Unused local variable 'found' deleted. * print_abbrevs.c: Now -ka can handle bogus large abbreviation number without crashing when checking abbreviations.. 2017-10-15 David Anderson * dwgetopt.c,dwgetopt.h: Now handles simple long argument names cases. * getopttest.c: Added tests of long (--) argument names. 2017-10-13 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-10-12 David Anderson * dwarfdump.c: Now more careful with archive names presented by libelf and Elf_Arhdr. 2017-10-12 David Anderson * print_section_groups.c: Added a cast on a free() call to avoid a compiler warning. * dwarfdump.c: On an archive (.a) dwarfdump would print a useless warning on encountering a special / or // member. Now just skips those, and if some other member is not an object dwarfdump prints a more useful message to identify the particular member. * print_die.c: The attributes_encoding_table was not getting reset properly in the case of reading an archive, and that is now fixed. 2017-10-05 David Anderson * tag_attr.list: Changed the spelling from DW_AT_ranges_base to the final DWARF5 spelling, DW_AT_rnglists_base. 2017-10-05 David Anderson * dwconf.c: Open the config file "r", not "rw". 2017-09-26 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-08-22 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-08-21 David Anderson * CMakeLists.txt: Fix the TAG_TREE_SOURCES and TAG_ATTR_SOURCES entries. * Makefile.in: Fix a misuse of LD_LIBRARY_PATH and use LIBDWARF_PATH as the path to libdwarf.so. * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. * common.c: #include changes help for builds on Windows. Rename a parameter to avoid accidental name-shadowing. * configure.cmake: Fix ac_check_lib() uses. * dwarfdump.c,dwconf.c,esb.c: Modify #ifdefs to ease building on Windows. * getopttest.c: Cast/printf changes avoid warnings on 32 and 64 bit builds. * macrocheck.c: An extra newline makes the 'make test' output easier to understand. * testesb.c: The check() function is local, so call it 'static' to avoid a compiler warning. 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Renamed LOCATION_OF_LIBELFHEADER to HAVE_LOCATION_OF_LIBELFHEADER for consistency with config.h.in generally. * configure: Regenerated 2017-07-24 David Anderson * configure.in, configure.cmake: Consistent use of LOCATION_OF_LIBELFHEADER so Windows can build libdwarf with configure or cmake. * configure: Regenerated 2017-07-09 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-05-28 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-05-28 David Anderson * macrocheck.c: Trivial revision of main() declaration to our standard format. * print_reloc.c: We were reading one-past the end of symtab entries(now fixed). Now relocation sections show the Elf section index and we print them in order as in the object file (earlier it printed in a fixed order not related to the object file). Deleted the rel/rela section name arrays, we already have the section name at hand. 2017-05-27 David Anderson * esb.c: For selftest now indents report lines to make it easier to see the overview pass/fail. * Makefile.in,macrocheck.c,print_reloc.c: Makes macrocheck self test results clearer (pass/fail) and adds a check on the array of relocation section data in print_reloc.c. 2017-05-26 David Anderson * section_bitmaps.h,section_bitmaps.c: Added comments. 2017-05-25 David Anderson * common.c,tag_attr.c,tag_tree.c: Update version string. * dwarfdump.c: Update version string. Instead of using bitmaps for printing sections and relocations use char arrays instead. Faster, easier to read, and much easier to expand to the longer lists of sections. By using fixed size arrays for this the compiler can check for simple errors. * print_reloc.c: Moved #defines over to section_bitmap.h Arrays are now fixed size to give compiler the ability to notice simple coding errors. Added the new DWARF5 sections to lists of what is to print. We do not use zero as a section number so we add an unused zero element to each array. * print_reloc.h: Made idempotent with ifndef. * section_bitmaps.c: Now uses the char array id and indexes starting at 1 (per the #defines in section_bitmaps.h). Revised the code in 'make selftest' to do more complete checking. * section_bitmaps.h: Now all the REL and RELA #defines are here so it's easy to see them all at once. Now using indexes starting at 1, not bitfields. Faster,simpler, and for a given dwarfdump run the switch from bitmaps will expand static data by well under 20 bytes total. 2017-05-18 David Anderson * dwarfdump.c: Fixed a small memory leak in special_program_name(). Deleted four lines of test code that never got removed. 2017-05-17 David Anderson * CMakeLists.txt: Add section_bitmaps.h,.c. * Makefile.in: Add section_bitmaps.o, section_bitmaps.h. Add section_bitmaps 'make selftest' rules. * section_bitmaps.h, section_bitmaps.c: The bit field code used to control the -E option set was out of date and difficult to get right. Now 'make selftest' ensures that the bits match up with the strings. * glflags.h, glflags.c: Fixed the misnamed gf_type_flag to be gf_types_flag. * globals.h: Move defines to section_bitmaps.h * common.c: Use sanitized() on incoming strings we print. * print_aranges.c,print_debugfission.c: Names from elf now get sanitized() for printing. * print_section_groups.c: Improved one interface. * print_die.c: Critical fixes so we get the section names on output when we want them, and sanitized(). * common.c, print_aranges.c, print_debugfission.c,print_ranges.c, print_strings.c: Calling sanitized() to ensure printf safety. * print_section_groups.c: Revised function interface. Do not use May 13 interface. * print_die.c: Crucial revision so DWARF4 debug_types prints. * dwarfdump.c: Revised flags so the gf_section_groups_flag works. Revised the section bitmaps code. * print_section_groups.c: Delete a printf left in for debugging. 2017-05-13 David Anderson * CMakeLists.txt, Makefile.in: Mention new print_section_groups.c or .o. * dwarfdump.c: Add needed section names in print_object_header() data. Implement glflags.gf_section_groups_flag. * print_section_groups.c: New, implementing handling of section groups (aka COMDAT). 2017-04-20 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-17 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-16 David Anderson * CMakeLists.txt: Added in new files glflangs.c, .h 2017-04-12 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-06 David Anderson * Makefile.in: Add glflags.o. Instead of dozens of boolean variables, a struct with the booleans makes understanding them much easier. * glflags.h, glflags.c: define and initialize all these flags and settings. * dwarfdump.c: Use the new glflags.h setting fields. Add one new one for debug_names (nothing useful implemented yet). * globals.h: Remove the flag global extern lines. * naming.c,print_abbrevs.c, print_aranges.c, print_die.c, print_frames.c, print_gdbindex.c, print_lines.c, print locs.c, print_macro.c, print_macros.c, print_pubnames.c, print_ranges.c, print_static_funcs.c, print_static_vars.c, print_strings.c, print_types.c, print_weaknames.c: Using the new flag globals as glflags.gf_ * print_dnames.c: New for .debug_names printing. 2017-04-06 David Anderson * dwarfdump.c, Makefile.in, globals.h: This is a small start on dealing with DWARF5 .debug_names. 2017-04-02 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-02 David Anderson * dwarfdump.c: If printing group 2 (DWARF5 dwo sections) ensure that printing of those sections only possible in group 1 is turned off. 2017-03-30 David Anderson 2017-03-30 David Anderson * dwarfdump.1: Documenting the new -x groupnumber= option. * dwarfdump.c: Adding groupnumber option support. * sanitized.c: Removed trailing whitespace 2017-03-24 David Anderson * dwarfdump.c: Now argv[0] is checked before setting the program_name global variable. If it contains /dwarfdump.O that part of the string is shortened to /dwarfdump. Doing this removes a need for the regressiontests to use sed and shortens the regressiontests runtime on a one machine from 77 minutes to 23 minutes. 2017-03-23 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-03-21 David Anderson * sanitized.c: Now all non-ascii bytes are changed to %xx and a % input character is changed to %xx too iso-8859 and for html are now sanitized using URI %xx notation so the printf output looks sensible. These usually represent a corrupted string in an object file. 2017-03-21 David Anderson * print_die.c: Added casts to call args match with the function declaration. So a fussy compiler will be less likely to complain. * sanitized.c: Added explicit initializers to global variables. Moved a static var to the function that uses it. 2017-01-31 David Anderson * esb.c(esb_force_allocation): Code was wrong all this time. Fixed and corrected commentary. Updated copyright. 2017-01-30 David Anderson * esb.c(esb_force_allocation): Add commentary about to clarify the purpose of the function. 2017-01-23 David Anderson * dwarf_tsearchbal.c(dwarf_tsearch): In memory exhausted situation the function could leak a little bit of memory. libdwarf-20210528/dwarfdump/print_pubnames.c0000664000175000017500000004721714003121746015670 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "sanitized.h" /* This unifies the code for some error checks to avoid code duplication. */ static void check_info_offset_sanity( const char *sec, const char *field, char *global, Dwarf_Unsigned offset, Dwarf_Unsigned maxoff) { if (maxoff == 0) { /* Lets make a heuristic check. */ if (offset > 0xffffffff) { printf("Warning: section %s %s %s offset 0x%" DW_PR_XZEROS DW_PR_DUx " " "exceptionally large \n", sec, field, global, offset); } return; } if (offset >= maxoff) { printf("Warning: section %s %s %s offset 0x%" DW_PR_XZEROS DW_PR_DUx " " "larger than max of 0x%" DW_PR_DUx "\n", sec, field, global, offset, maxoff); } } /* Unified pubnames style output. The error checking here against maxoff may be useless (in that libdwarf may return an error if the offset is bad and we will not get called here). But we leave it in nonetheless as it looks sensible. In at least one gigantic executable such offsets turned out wrong. */ static int print_pubname_style_entry(Dwarf_Debug dbg, const char *line_title, char *name, Dwarf_Unsigned die_off, Dwarf_Unsigned cu_die_off, Dwarf_Unsigned global_cu_offset, Dwarf_Unsigned maxoff,Dwarf_Error *err) { Dwarf_Die die = NULL; Dwarf_Off die_CU_off = 0; int dres = 0; int ddres = 0; int cudres = 0; /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, err); /* Some llvm version puts the global die offset into pubnames with the result that we will get an error here but we just let that create an error, papering it over here by subtracting out the applicable debug_info CU header offset is problematic. */ if (dres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie : " "die offset does not reference valid DIE "); esb_append_printf_u(&details,"at offset 0x%" DW_PR_DUx, die_off); esb_append(&details,"."); print_error_and_continue(dbg, esb_get_string(&details), dres, *err); esb_destructor(&details); return dres; } /* get offset of die from its cu-header */ ddres = dwarf_die_CU_offset(die, &die_CU_off, err); if (ddres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," cannot get CU die offset"); print_error_and_continue(dbg, esb_get_string(&details), dres, *err); esb_destructor(&details); die_CU_off = 0; dwarf_dealloc(dbg, die, DW_DLA_DIE); return ddres; } /* Get die at offset cu_die_off to check its existence. */ { Dwarf_Die cu_die = NULL; cudres = dwarf_offdie(dbg, cu_die_off, &cu_die, err); if (cudres != DW_DLV_OK) { struct esb_s details; dwarf_dealloc(dbg, die, DW_DLA_DIE); esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie: " "cu die offset does not reference valid CU DIE. "); esb_append_printf_u(&details,"0x%" DW_PR_DUx, cu_die_off); esb_append(&details,"."); /* does not return */ print_error_and_continue(dbg, esb_get_string(&details), cudres, *err); esb_destructor(&details); return cudres; } else { /* It exists, all is well. */ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); } } /* Display offsets */ if (glflags.gf_display_offsets) { /* Print 'name' at the end for better layout */ printf("%s die-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx "," " die-in-cu 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-header-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx , line_title, die_off, cu_die_off, (Dwarf_Unsigned) die_CU_off, /* Following is absolute offset of the beginning of the cu */ (Dwarf_Signed) (die_off - die_CU_off)); } if ((die_off - die_CU_off) != global_cu_offset) { struct esb_s details; dwarf_dealloc(dbg, die, DW_DLA_DIE); esb_constructor(&details); esb_append(&details,"\nERROR: "); esb_append(&details,line_title); esb_append(&details,"has improper die offset:"); esb_append_printf_u(&details," global cu offset 0x%x ", global_cu_offset); esb_append_printf_u(&details," does not match die_off 0x%x ", die_off); esb_append_printf_u(&details," minus die_CU_off 0x%x ", die_CU_off); esb_append(&details,"\n."); simple_err_return_msg_either_action(DW_DLV_ERROR, esb_get_string(&details)); return DW_DLV_NO_ENTRY; } /* Display offsets */ if (glflags.gf_display_offsets && glflags.verbose) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx , global_cu_offset); } /* Print 'name' at the end for better layout */ printf(" '%s'\n",name); dwarf_dealloc(dbg, die, DW_DLA_DIE); check_info_offset_sanity(line_title, "die offset", name, die_off, maxoff); check_info_offset_sanity(line_title, "die cu offset", name, die_CU_off, maxoff); check_info_offset_sanity(line_title, "cu offset", name, (die_off - die_CU_off), maxoff); return DW_DLV_OK; } static void print_globals_header( Dwarf_Off pub_section_hdr_offset, Dwarf_Unsigned length_size, /* from pubnames header */ Dwarf_Unsigned length, /* from pubnames header */ Dwarf_Unsigned version, Dwarf_Off info_header_offset, Dwarf_Unsigned info_length) { printf("Pub section offset 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", pub_section_hdr_offset,pub_section_hdr_offset); printf(" offset size 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", length_size, length_size); printf(" length 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", length, length); printf(" version 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", version, version); printf(" info hdr offset 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", info_header_offset, info_header_offset); printf(" info hdr length 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", info_length, info_length); } /* Get all the data in .debug_pubnames */ int print_pubnames(Dwarf_Debug dbg,Dwarf_Error *err) { Dwarf_Global *globbuf = NULL; Dwarf_Signed count = 0; /* Offset to previous CU */ int res = 0; Dwarf_Addr elf_max_address = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s truename; char sanbuf[ESB_FIXED_ALLOC_SIZE]; struct esb_s sanitname; glflags.current_section_id = DEBUG_PUBNAMES; res = get_address_size_and_max(dbg,0,&elf_max_address,err); if (res != DW_DLV_OK) { simple_err_return_msg_either_action(res, "print_pubnames call to get address size and max address" " fails."); return res; } if (glflags.verbose) { /* For best testing! */ res = dwarf_return_empty_pubnames(dbg,1,err); if (res != DW_DLV_OK) { simple_err_return_msg_either_action(res, "ERROR: Erroneous " "libdwarf call " "of dwarf_return_empty_pubnames: " "dwarfdump internal error"); return res; } } res = dwarf_get_globals(dbg, &globbuf, &count, err); /* Do get_true_section_name() after loading section so it reports on compressed data */ esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_pubnames", &truename,TRUE); esb_constructor_fixed(&sanitname,sanbuf,sizeof(sanbuf)); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); esb_destructor(&truename); if (glflags.gf_do_print_dwarf && count > 0) { printf("\n%s\n",esb_get_string(&sanitname)); } if (res == DW_DLV_ERROR) { simple_err_return_msg_either_action(res,"ERROR: " "dwarf_get_globals failed in print_pubnames()."); esb_destructor(&sanitname); return res; /* fall through to end*/ } if (res == DW_DLV_NO_ENTRY) { esb_destructor(&sanitname); return res; } res = print_all_pubnames_style_records(dbg, "global", esb_get_string(&sanitname), globbuf,count,err); esb_destructor(&sanitname); dwarf_globals_dealloc(dbg,globbuf,count); dwarf_return_empty_pubnames(dbg,0,err); return res; } int print_all_pubnames_style_records(Dwarf_Debug dbg, const char *linetitle, const char * section_true_name, Dwarf_Global *globbuf, Dwarf_Signed count, Dwarf_Error *err) { Dwarf_Unsigned maxoff = get_info_max_offset(dbg); Dwarf_Unsigned lastcudieoff = 0; Dwarf_Addr elf_max_address = 0; Dwarf_Signed i = 0; int ares = 0; ares = get_address_size_and_max(dbg,0,&elf_max_address,err); if (ares != DW_DLV_OK) { simple_err_return_msg_either_action(ares, "ERROR: print_pubnames style call to get " "address size and max address" " fails."); return ares; } for (i = 0; i < count; i++) { int nres = 0; int cures3 = 0; Dwarf_Off die_off = 0; Dwarf_Off cu_die_off = 0; Dwarf_Off prev_cu_off = elf_max_address; Dwarf_Off global_cu_off = 0; char *name = 0; /* Turns the cu-local die_off in globbuf entry into a global die_off. The cu_off returned is the offset of the CU DIE, not the CU header. */ nres = dwarf_global_name_offsets(globbuf[i], &name, &die_off, &cu_die_off, err); if (nres != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "ERROR: dwarf_global_name_offsets for globals index " " %d ", i); esb_append_printf_i(&m," with globals count %d.", count); simple_err_return_msg_either_action(nres, esb_get_string(&m)); esb_destructor(&m); return nres; } if (glflags.verbose) { /* We know no die_off can be zero (except for the fake global created when the debug_pubnames for a CU has no actual entries) we do not need to check for i==0 to detect this is the initial global record and we want to print this pubnames section CU header. */ if (lastcudieoff != cu_die_off) { Dwarf_Off pub_section_hdr_offset = 0; Dwarf_Unsigned pub_offset_size = 0; Dwarf_Unsigned pub_length = 0; Dwarf_Unsigned pub_version = 0; Dwarf_Off info_header_offset = 0; Dwarf_Unsigned info_length = 0; nres = dwarf_get_globals_header(globbuf[i], &pub_section_hdr_offset, &pub_offset_size, &pub_length,&pub_version, &info_header_offset,&info_length,err); if (nres != DW_DLV_OK) { struct esb_s msge; esb_constructor(&msge); esb_append(&msge, "ERROR Access dwarf_get_globals_header "); esb_append_printf_i(&msge, " for index %d in ",i); esb_append(&msge,section_true_name); esb_append(&msge,"."); simple_err_return_msg_either_action(nres, esb_get_string(&msge)); esb_destructor(&msge); return nres; } if (glflags.gf_do_print_dwarf) { print_globals_header(pub_section_hdr_offset, pub_offset_size, pub_length, pub_version, info_header_offset, info_length); } } } lastcudieoff = cu_die_off; if (glflags.verbose) { /* If verbose we can see a zero die_off. */ if (!die_off && !strlen(name)) { /* A different and impossible cu die offset in case of an empty pubnames CU. */ continue; } } /* This gets the CU header offset, which is the offset that die_off needs to be added to to calculate the DIE offset. Note that dwarf_global_name_offsets already did that addition properly so this call is just so we can print the CU header offset. */ cures3 = dwarf_global_cu_offset(globbuf[i], &global_cu_off, err); if (cures3 != DW_DLV_OK) { struct esb_s msge; esb_constructor(&msge); esb_append(&msge,"ERROR Access dwarf_global_cu_offset "); esb_append_printf_i(&msge," for index %d in ",i); esb_append(&msge,section_true_name); esb_append(&msge,"."); simple_err_return_msg_either_action(cures3, esb_get_string(&msge)); esb_destructor(&msge); return cures3; } if (glflags.gf_check_pubname_attr) { Dwarf_Bool has_attr = 0; int dres = 0; Dwarf_Die die = 0; /* We are processing a new set of pubnames for a different CU; get the producer ID, at 'cu_off' to see if we need to skip these pubnames */ if (cu_die_off != prev_cu_off) { char proname[100]; struct esb_s producername; Dwarf_Die lcudie = 0; /* Record offset for previous CU */ prev_cu_off = cu_die_off; dres = dwarf_offdie(dbg, cu_die_off, &lcudie, err); if (dres != DW_DLV_OK) { struct esb_s msge; esb_constructor(&msge); esb_append(&msge, "ERROR Accessing dwarf_offdie "); esb_append_printf_i(&msge, " for index %d in ",i); esb_append(&msge,section_true_name); esb_append(&msge,"."); simple_err_return_msg_either_action(dres, esb_get_string(&msge)); esb_destructor(&msge); return dres; } /* Get producer name for this CU and update compiler list */ esb_constructor_fixed(&producername,proname, sizeof(proname)); dres = get_producer_name(dbg,lcudie,cu_die_off, &producername,err); dwarf_dealloc(dbg,lcudie,DW_DLA_DIE); if (dres == DW_DLV_ERROR) { esb_destructor(&producername); return dres; } update_compiler_target( esb_get_string(&producername)); glflags.DIE_CU_overall_offset = cu_die_off; esb_destructor(&producername); } /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, err); if (dres != DW_DLV_OK) { struct esb_s msge; esb_constructor(&msge); esb_append(&msge,"ERROR Accessing dwarf_offdie "); esb_append_printf_i(&msge," for index %d in ",i); esb_append(&msge,section_true_name); esb_append_printf_u(&msge," with die offset 0x%x ", die_off); esb_append(&msge,"."); simple_err_return_msg_either_action(dres, esb_get_string(&msge)); esb_destructor(&msge); return dres; } ares = dwarf_hasattr(die, DW_AT_external, &has_attr, err); if (ares == DW_DLV_ERROR) { struct esb_s msgd; esb_constructor(&msgd); esb_append(&msgd,"ERROR: hasattr on DW_AT_external" " from "); esb_append(&msgd,section_true_name); esb_append(&msgd," fails."); dwarf_dealloc(dbg, die, DW_DLA_DIE); /* print_error does not return */ simple_err_return_msg_either_action(ares, esb_get_string(&msgd)); esb_destructor(&msgd); return ares; } /* DW_DLV_NO_ENTRY is odd. Check that if checking. */ /* Check for specific compiler */ if (checking_this_compiler()) { DWARF_CHECK_COUNT(pubname_attr_result,1); if (ares == DW_DLV_OK && has_attr) { /* Should the value of flag be examined? */ } else { DWARF_CHECK_ERROR2(pubname_attr_result,name, "pubname does not have DW_AT_external"); } } dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* Now print name, after the test */ if (glflags.gf_do_print_dwarf || (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode)) { int res = 0; res = print_pubname_style_entry(dbg, linetitle, name, die_off, cu_die_off, global_cu_off, maxoff,err); if (res != DW_DLV_OK) { return res; } glflags.gf_record_dwarf_error = FALSE; } } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/section_bitmaps.h0000644000175000017500000001774013767716017016047 00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef SECTION_BITMAPS_H_INCLUDED #define SECTION_BITMAPS_H_INCLUDED /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in dwarfdump.c */ /* Value is one of the DW_HDR_DEBUG_* names. */ struct section_map_s { const char *name; unsigned value; }; extern struct section_map_s map_sectnames[] ; #define DW_HDR_DEBUG_INFO 1 #define DW_HDR_DEBUG_INFO_DWO 2 #define DW_HDR_DEBUG_LINE 3 #define DW_HDR_DEBUG_LINE_DWO 4 #define DW_HDR_DEBUG_PUBNAMES 5 #define DW_HDR_DEBUG_ABBREV 6 #define DW_HDR_DEBUG_ABBREV_DWO 7 #define DW_HDR_DEBUG_ARANGES 8 #define DW_HDR_DEBUG_FRAME 9 #define DW_HDR_DEBUG_LOC 10 #define DW_HDR_DEBUG_LOCLISTS 11 #define DW_HDR_DEBUG_LOCLISTS_DWO 12 #define DW_HDR_DEBUG_RANGES 13 #define DW_HDR_DEBUG_RNGLISTS 14 #define DW_HDR_DEBUG_RNGLISTS_DWO 15 #define DW_HDR_DEBUG_STR 16 #define DW_HDR_DEBUG_STR_DWO 17 #define DW_HDR_DEBUG_STR_OFFSETS 18 #define DW_HDR_DEBUG_STR_OFFSETS_DWO 19 #define DW_HDR_DEBUG_PUBTYPES 20 #define DW_HDR_DEBUG_TYPES 21 #define DW_HDR_TEXT 22 #define DW_HDR_GDB_INDEX 23 #define DW_HDR_EH_FRAME 24 #define DW_HDR_DEBUG_MACINFO 25 #define DW_HDR_DEBUG_MACRO 26 #define DW_HDR_DEBUG_MACRO_DWO 27 #define DW_HDR_DEBUG_NAMES 28 #define DW_HDR_DEBUG_CU_INDEX 29 #define DW_HDR_DEBUG_TU_INDEX 30 #define DW_HDR_HEADER 31 #define DW_HDR_ARRAY_SIZE 32 /* Debug section names to be included in printing */ #define DW_SECTNAME_DEBUG_INFO ".debug_info" #define DW_SECTNAME_DEBUG_INFO_DWO ".debug_info.dwo" #define DW_SECTNAME_DEBUG_LINE ".debug_line" #define DW_SECTNAME_DEBUG_LINE_DWO ".debug_line.dwo" #define DW_SECTNAME_DEBUG_PUBNAMES ".debug_pubnames" #define DW_SECTNAME_DEBUG_ABBREV ".debug_abbrev" #define DW_SECTNAME_DEBUG_ABBREV_DWO ".debug_abbrev.dwo" #define DW_SECTNAME_DEBUG_ARANGES ".debug_aranges" #define DW_SECTNAME_DEBUG_FRAME ".debug_frame" #define DW_SECTNAME_DEBUG_LOC ".debug_loc" #define DW_SECTNAME_DEBUG_LOCLISTS ".debug_loclists" #define DW_SECTNAME_DEBUG_LOCLISTS_DWO ".debug_loclists.dwo" #define DW_SECTNAME_DEBUG_RANGES ".debug_ranges" #define DW_SECTNAME_DEBUG_RNGLISTS ".debug_rnglists" #define DW_SECTNAME_DEBUG_RNGLISTS_DWO ".debug_rnglists.dwo" #define DW_SECTNAME_DEBUG_STR ".debug_str" #define DW_SECTNAME_DEBUG_STR_DWO ".debug_str.dwo" #define DW_SECTNAME_DEBUG_STR_OFFSETS ".debug_str_offsets" #define DW_SECTNAME_DEBUG_STR_OFFSETS_DWO ".debug_str_offsets.dwo" /* obsolete SGI-only section was .debug_typenames */ #define DW_SECTNAME_DEBUG_PUBTYPES ".debug_pubtypes" #define DW_SECTNAME_DEBUG_TYPES ".debug_types" #define DW_SECTNAME_TEXT ".text" #define DW_SECTNAME_GDB_INDEX ".gdb_index" #define DW_SECTNAME_EH_FRAME ".eh_frame" #define DW_SECTNAME_DEBUG_SUP ".debug_sup" #define DW_SECTNAME_DEBUG_MACINFO ".debug_macinfo" #define DW_SECTNAME_DEBUG_MACRO ".debug_macro" #define DW_SECTNAME_DEBUG_MACRO_DWO ".debug_macro.dwo" #define DW_SECTNAME_DEBUG_NAMES ".debug_names" #define DW_SECTNAME_DEBUG_CU_INDEX ".debug_cu_index" #define DW_SECTNAME_DEBUG_TU_INDEX ".debug_tu_index" /* Definitions for printing relocations. */ #define DW_SECTION_REL_DEBUG_INFO 1 #define DW_SECTION_REL_DEBUG_LINE 2 #define DW_SECTION_REL_DEBUG_PUBNAMES 3 #define DW_SECTION_REL_DEBUG_ABBREV 4 #define DW_SECTION_REL_DEBUG_ARANGES 5 #define DW_SECTION_REL_DEBUG_FRAME 6 #define DW_SECTION_REL_DEBUG_LOC 7 #define DW_SECTION_REL_DEBUG_LOCLISTS 8 #define DW_SECTION_REL_DEBUG_RANGES 9 #define DW_SECTION_REL_DEBUG_RNGLISTS 10 #define DW_SECTION_REL_DEBUG_TYPES 11 #define DW_SECTION_REL_DEBUG_STR_OFFSETS 12 #define DW_SECTION_REL_DEBUG_PUBTYPES 13 #define DW_SECTION_REL_GDB_INDEX 14 #define DW_SECTION_REL_EH_FRAME 15 #define DW_SECTION_REL_DEBUG_SUP 16 #define DW_SECTION_REL_DEBUG_MACINFO 17 #define DW_SECTION_REL_DEBUG_MACRO 18 #define DW_SECTION_REL_DEBUG_NAMES 19 #define DW_SECTION_REL_ARRAY_SIZE 20 #define DW_SECTNAME_RELA_DEBUG_INFO ".rela.debug_info" #define DW_SECTNAME_RELA_DEBUG_LINE ".rela.debug_line" #define DW_SECTNAME_RELA_DEBUG_PUBNAMES ".rela.debug_pubnames" #define DW_SECTNAME_RELA_DEBUG_ABBREV ".rela.debug_abbrev" #define DW_SECTNAME_RELA_DEBUG_ARANGES ".rela.debug_aranges" #define DW_SECTNAME_RELA_DEBUG_FRAME ".rela.debug_frame" #define DW_SECTNAME_RELA_DEBUG_LOC ".rela.debug_loc" #define DW_SECTNAME_RELA_DEBUG_LOCLISTS ".rela.debug_loclists" #define DW_SECTNAME_RELA_DEBUG_RANGES ".rela.debug_ranges" #define DW_SECTNAME_RELA_DEBUG_RNGLISTS ".rela.debug_rnglists" #define DW_SECTNAME_RELA_DEBUG_TYPES ".rela.debug_types" #define DW_SECTNAME_RELA_DEBUG_STR_OFFSETS ".rela.debug_str_offsets" #define DW_SECTNAME_RELA_DEBUG_PUBTYPES ".rela.debug_pubtypes" #define DW_SECTNAME_RELA_GDB_INDEX ".rela.debug_gdb_index" #define DW_SECTNAME_RELA_EH_FRAME ".rela.eh_frame" #define DW_SECTNAME_RELA_DEBUG_SUP ".rela.debug_sup" #define DW_SECTNAME_RELA_DEBUG_MACINFO ".rela.debug_macinfo" #define DW_SECTNAME_RELA_DEBUG_MACRO ".rela.debug_macro" #define DW_SECTNAME_RELA_DEBUG_NAMES ".rela.debug_names" #define DW_SECTNAME_REL_DEBUG_INFO ".rel.debug_info" #define DW_SECTNAME_REL_DEBUG_LINE ".rel.debug_line" #define DW_SECTNAME_REL_DEBUG_PUBNAMES ".rel.debug_pubnames" #define DW_SECTNAME_REL_DEBUG_ABBREV ".rel.debug_abbrev" #define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges" #define DW_SECTNAME_REL_DEBUG_FRAME ".rel.debug_frame" #define DW_SECTNAME_REL_DEBUG_LOC ".rel.debug_loc" #define DW_SECTNAME_REL_DEBUG_LOCLISTS ".rel.debug_loclists" #define DW_SECTNAME_REL_DEBUG_RANGES ".rel.debug_ranges" #define DW_SECTNAME_REL_DEBUG_RNGLISTS ".rel.debug_rnglists" #define DW_SECTNAME_REL_DEBUG_TYPES ".rel.debug_types" #define DW_SECTNAME_REL_DEBUG_STR_OFFSETS ".rel.debug_str_offsets" #define DW_SECTNAME_REL_DEBUG_PUBTYPES ".rel.debug_pubtypes" #define DW_SECTNAME_REL_GDB_INDEX ".rel.debug_gdb_index" #define DW_SECTNAME_REL_EH_FRAME ".rel.eh_frame" #define DW_SECTNAME_REL_DEBUG_SUP ".rel.debug_sup" #define DW_SECTNAME_REL_DEBUG_MACINFO ".rel.debug_macinfo" #define DW_SECTNAME_REL_DEBUG_MACRO ".rel.debug_macro" #define DW_SECTNAME_REL_DEBUG_NAMES ".rel.debug_names" Dwarf_Bool section_name_is_debug_and_wanted(const char *section_name); unsigned section_bitmap_array_size(void); void set_all_section_defaults(void); Dwarf_Bool any_section_header_to_print(void); void enable_section_map_entry(unsigned index); Dwarf_Bool section_map_enabled(unsigned index); void set_all_sections_on(void); void enable_reloc_map_entry(unsigned index); Dwarf_Bool reloc_map_enabled(unsigned index); void set_all_reloc_sections_on(void); #endif /* SECTION_BITMAPS_H_INCLUDED*/ libdwarf-20210528/dwarfdump/common.c0000664000175000017500000000631614003122476014126 00000000000000/* Copyright (C) 2008-2010 SN Systems. All Rights Reserved. Portions Copyright (C) 2008-2017 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. . All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* These do little except on Windows */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "common.h" #include "defined_types.h" #include "sanitized.h" #include "warningcontrol.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ #include #ifndef BUILD_STANDARD_SOURCE /* Must match libdwarf.h.in declaration. */ const char * dwarf_package_version(void); #endif /* BUILD_STANDARD_SOURCE */ /*#define RELEASE_DATE "20180416" */ /* PACKAGE_VERSION is from config.h */ /* The Linux/Unix version does not want a version string to print unless -V is on the command line. */ void print_version_details(UNUSEDARG const char * name, #ifdef _WIN32 UNUSEDARG /* we don't use this arg with Windows */ #endif int alwaysprint) { #ifdef _WIN32 #ifdef _DEBUG char *acType = "Debug"; #else char *acType = "Release"; #endif /* _DEBUG */ #ifdef _WIN64 char *bits = "64"; #else char *bits = "32"; #endif /* _WIN64 */ printf("%s [%s %s %s Win%s (%s)]\n", sanitized(name),__DATE__,__TIME__,acType,bits, PACKAGE_VERSION); #else /* !_WIN32 */ if (alwaysprint) { #ifdef BUILD_STANDARD_SOURCE /* Used by scripts/buildstandardsource.sh */ printf("%s\n",DW_VERSION_DATE_STR); #else const char *pv = dwarf_package_version(); printf("%s Package Version \"%s\"\n",DW_VERSION_DATE_STR, pv); #endif } #endif /* _WIN32 */ } void print_args(UNUSEDARG int argc, UNUSEDARG char *argv[]) { #ifdef _WIN32 int index = 1; printf("Arguments: "); for (index = 1; index < argc; ++index) { printf("%s ",sanitized(argv[index])); } printf("\n"); #endif /* _WIN32 */ } /* Going to stdout as of April 2018. dwarfdump only calls if requested by user. */ void print_usage_message( UNUSEDARG const char *program_name_in, const char **text) { unsigned i = 0; for (i = 0; *text[i]; ++i) { printf("%s\n", text[i]); } } libdwarf-20210528/dwarfdump/print_debug_sup.c0000664000175000017500000000773613764006205016042 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* To print .debug_sup */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #define TRUE 1 #define FALSE 0 int print_debug_sup(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; const char *stdname = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s truename; Dwarf_Half version = 0; Dwarf_Small is_supplementary = 0; char * filename = 0; Dwarf_Unsigned checksum_len = 0; Dwarf_Unsigned i =0; Dwarf_Small *checksum_ptr = 0; Dwarf_Small *curptr = 0; esb_constructor_fixed(&truename,buf, DWARF_SECNAME_BUFFER_SIZE); glflags.current_section_id = DEBUG_SUP; stdname = ".debug_sup"; get_true_section_name(dbg,stdname, &truename,TRUE); res = dwarf_get_debug_sup(dbg, &version,&is_supplementary, &filename,&checksum_len, &checksum_ptr,error); if (res == DW_DLV_ERROR) { glflags.gf_count_major_errors++; printf("ERROR: problem reading %s. %s\n", sanitized(esb_get_string(&truename)), dwarf_errmsg(*error)); dwarf_dealloc_error(dbg,*error); *error = 0; esb_destructor(&truename); return DW_DLV_OK; } else if (res == DW_DLV_NO_ENTRY) { esb_destructor(&truename); return res; } printf("\n%s\n",sanitized(esb_get_string(&truename))); printf(" Version : %u\n",version); if (version != 2) { glflags.gf_count_major_errors++; printf("ERROR: the %s version is %u but " "only 2 is currently valid\n", sanitized(esb_get_string(&truename)), version); } printf(" Supplementary file : %u (%s}\n",is_supplementary, is_supplementary?"yes":"no"); if (is_supplementary > 1) { glflags.gf_count_major_errors++; printf("ERROR: the %s is_supplementary field is %u but " "only 0 or 1 is currently valid\n", sanitized(esb_get_string(&truename)), is_supplementary); } printf(" Filename : %s\n",sanitized(filename)); printf(" Checksum Length : %" DW_PR_DUu "\n",checksum_len); printf(" Checksum bytes in hex:\n"); curptr = checksum_ptr; if (checksum_len > 0) { printf(" "); } for (i = 0 ; i < checksum_len; ++i,++curptr) { if (i > 0 && (i%16) == 0) { printf("\n "); } printf("%02x",*curptr); } printf("\n"); esb_destructor(&truename); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/tag_attr_ext.list0000664000175000017500000001070214015312551016044 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-attr relation. See tag_attr.list for details. Notes: If new top level TAGs are added/removed, update EXT_ATTR_TABLE_ROWS If new child TAGs are added/removed, update EXT_ATTR_TABLE_COLS EXT_ATTR_TABLE_ROWS is defined in tag_tree.c and specifies the maximum number of top level TAGs. Current value is 10. EXT_ATTR_TABLE_COLS is defined in tag_tree.c and specifies the maximum number of entries for the top level TAGs. Current value is 10. */ /* Common DWARF extensions */ 0xffffffff DW_TAG_structure_type DW_AT_containing_type DW_AT_MIPS_linkage_name 0xffffffff DW_TAG_compile_unit DW_AT_APPLE_optimized /* Used by LLVM */ DW_AT_GNU_dwo_id DW_AT_GNU_pubnames DW_AT_GNU_pubtypes DW_AT_GNU_dwo_name DW_AT_GNU_ranges_base DW_AT_GNU_addr_base DW_AT_GNU_macros 0xffffffff DW_TAG_skeleton_unit DW_AT_GNU_dwo_id DW_AT_GNU_pubnames DW_AT_GNU_pubtypes DW_AT_GNU_dwo_name DW_AT_GNU_ranges_base DW_AT_GNU_addr_base DW_AT_GNU_macros 0xffffffff DW_TAG_partial_unit DW_AT_dwo_id /* DWARF4 GNU */ 0xffffffff DW_TAG_member DW_AT_GNU_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_pt_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_pt_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_MIPS_linkage_name 0xffffffff DW_TAG_enumeration_type DW_AT_encoding 0xffffffff DW_TAG_array_type DW_AT_GNU_vector 0xffffffff DW_TAG_subprogram DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */ DW_AT_MIPS_fde /* SGI-IRIX uses this */ DW_AT_GNU_locks_excluded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_exclusive_locks_required DW_AT_GNU_shared_locks_required DW_AT_APPLE_omit_frame_ptr /* Used by LLVM */ DW_AT_APPLE_optimized /* Used by LLVM */ DW_AT_GNU_all_tail_call_sites DW_AT_GNU_all_call_sites DW_AT_ghs_rsm DW_AT_ghs_frsm DW_AT_ghs_rso DW_AT_ghs_frames DW_AT_ghs_subcpu 0xffffffff DW_TAG_type_unit DW_AT_GNU_addr_base DW_AT_GNU_dwo_name DW_AT_GNU_odr_signature DW_AT_GNU_pubnames 0xffffffff DW_TAG_variable DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */ DW_AT_GNU_guarded_by DW_AT_GNU_pt_guarded_by DW_AT_GNU_guarded DW_AT_GNU_pt_guarded 0xffffffff DW_TAG_GNU_template_template_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_GNU_template_name DW_AT_GNU_guarded_by /* GNU changed the name of 0x2108! */ 0xffffffff DW_TAG_GNU_template_parameter_pack DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_GNU_formal_parameter_pack DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_GNU_call_site DW_AT_abstract_origin DW_AT_GNU_call_site_target DW_AT_low_pc DW_AT_sibling DW_AT_GNU_tail_call 0xffffffff DW_TAG_GNU_call_site_parameter DW_AT_GNU_call_site_value DW_AT_GNU_call_site_data_value DW_AT_abstract_origin DW_AT_location 0xffffffff DW_TAG_constant DW_AT_GNU_numerator DW_AT_GNU_denominator 0xffffffff DW_TAG_subrange_type DW_AT_GNU_bias 0xffffffff DW_TAG_inlined_subroutine DW_AT_GNU_discriminator /* Used by LLVM */ 0xffffffff DW_TAG_lexical_block 0xffffffff libdwarf-20210528/dwarfdump/Makefile.am0000664000175000017500000000613514046761606014540 00000000000000###Copyright (C) 2018 Vincent Torri #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "makename.h" #include "globals.h" #if defined(__WIN32) && (!defined(__GNUC__) && !defined(__clang__)) #pragma warning(disable:4996) /* Warning when migrated to VS2010 */ #endif /* _WIN32 */ #define TRUE 1 #define FALSE 0 #define VALTYPE char * #define DW_TSHASHTYPE uintptr_t char *samples[] = { "abcd", "efgh", "a", "abcd", 0 }; int main() { char *e1 = 0; char *e2= 0; char *e3= 0; char *e4= 0; int errct = 0; e1 = makename(samples[0]); e2 = makename(samples[1]); e3 = makename(samples[2]); e4 = makename(samples[3]); if (e1 != e4) { printf(" FAIL. mismatch pointers\n"); ++errct; } if (e1 == e2 ) { printf(" FAIL. match pointers\n"); ++errct; } if ( e1 == e3) { printf(" FAIL. match pointers\n"); ++errct; } if (errct) { exit(1); } printf("PASS makename test\n"); return 0; } libdwarf-20210528/dwarfdump/dwgetopt.h0000664000175000017500000000630413771427301014503 00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * 3. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwopterr; extern int dwoptind; extern int dwoptopt; extern int dwoptreset; extern char *dwoptarg; int dwgetopt(int nargc, char * const nargv[], const char *ostr); /* As of October 2017 it seems advisable to allow long option names. So based on a reading of 'man 3 getopt' we reimplement a portion of GNU getopt_long(). It's a wonderfully sensible design and all the credit should go to the original designers. We are not implementing all the features of GNU/Linux getopt_long(), just the features we wish to use. Specifically, we require val be 0 and flag be NULL and ignore those fields. We do not implement GNU digit_optind at all. Within these restrictions the interface behaves the same as GNU getopt_long() (or so it appears from the getopt documentation: release 4.04 of the Linux man-pages project, GETOPT(3), http://www.kernel.org/doc/man-pages/). */ struct dwoption { const char *name; int has_arg; int *flag; int val; }; #define dwno_argument 0 #define dwrequired_argument 1 #define dwoptional_argument 2 int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex); #ifdef __cplusplus } #endif /* __cplusplus */ libdwarf-20210528/dwarfdump/dwarfdump-ta-table.h0000664000175000017500000015601114054205620016320 00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #ifndef HAVE_USAGE_TAG_ATTR #define HAVE_USAGE_TAG_ATTR 1 #endif /* HAVE_USAGE_TAG_ATTR */ #ifdef HAVE_USAGE_TAG_ATTR #include "dwarf.h" #include "libdwarf.h" typedef struct { unsigned int count; /* Attribute count */ Dwarf_Half attr; /* Attribute value */ } Usage_Tag_Attr; /* 0x23 - DW_TAG_access_declaration */ static Usage_Tag_Attr tag_attr_23[9] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x01 - DW_TAG_array_type */ static Usage_Tag_Attr tag_attr_01[24] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x09 */ 0, DW_AT_ordering}, {/* 0x71 */ 0, DW_AT_rank}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x47 - DW_TAG_atomic_type */ static Usage_Tag_Attr tag_attr_47[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x24 - DW_TAG_base_type */ static Usage_Tag_Attr tag_attr_24[25] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x5b */ 0, DW_AT_binary_scale}, {/* 0x0c */ 0, DW_AT_bit_offset}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x6b */ 0, DW_AT_data_bit_offset}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5c */ 0, DW_AT_decimal_scale}, {/* 0x5e */ 0, DW_AT_decimal_sign}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x5f */ 0, DW_AT_digit_count}, {/* 0x3e */ 0, DW_AT_encoding}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x60 */ 0, DW_AT_picture_string}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x5d */ 0, DW_AT_small}, {/* */ 0, 0} }; /* 0x48 - DW_TAG_call_site */ static Usage_Tag_Attr tag_attr_48[13] = { {/* 0x57 */ 0, DW_AT_call_column}, {/* 0x58 */ 0, DW_AT_call_file}, {/* 0x59 */ 0, DW_AT_call_line}, {/* 0x7f */ 0, DW_AT_call_origin}, {/* 0x81 */ 0, DW_AT_call_pc}, {/* 0x7d */ 0, DW_AT_call_return_pc}, {/* 0x82 */ 0, DW_AT_call_tail_call}, {/* 0x83 */ 0, DW_AT_call_target}, {/* 0x84 */ 0, DW_AT_call_target_clobbered}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x49 - DW_TAG_call_site_parameter */ static Usage_Tag_Attr tag_attr_49[10] = { {/* 0x85 */ 0, DW_AT_call_data_location}, {/* 0x86 */ 0, DW_AT_call_data_value}, {/* 0x80 */ 0, DW_AT_call_parameter}, {/* 0x7e */ 0, DW_AT_call_value}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x25 - DW_TAG_catch_block */ static Usage_Tag_Attr tag_attr_25[12] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x02 - DW_TAG_class_type */ static Usage_Tag_Attr tag_attr_02[23] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x36 */ 0, DW_AT_calling_convention}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x44 - DW_TAG_coarray_type */ static Usage_Tag_Attr tag_attr_44[10] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x1a - DW_TAG_common_block */ static Usage_Tag_Attr tag_attr_1a[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x1b - DW_TAG_common_inclusion */ static Usage_Tag_Attr tag_attr_1b[9] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1a */ 0, DW_AT_common_reference}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x11 - DW_TAG_compile_unit */ static Usage_Tag_Attr tag_attr_11[24] = { {/* 0x73 */ 0, DW_AT_addr_base}, {/* 0x35 */ 0, DW_AT_base_types}, {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x75 */ 0, DW_AT_dwo_id}, {/* 0x76 */ 0, DW_AT_dwo_name}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x42 */ 0, DW_AT_identifier_case}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x13 */ 0, DW_AT_language}, {/* 0x8c */ 0, DW_AT_loclists_base}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x43 */ 0, DW_AT_macro_info}, {/* 0x79 */ 0, DW_AT_macros}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x25 */ 0, DW_AT_producer}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x74 */ 0, DW_AT_rnglists_base}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x3f - DW_TAG_condition */ static Usage_Tag_Attr tag_attr_3f[7] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x26 - DW_TAG_const_type */ static Usage_Tag_Attr tag_attr_26[9] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x27 - DW_TAG_constant */ static Usage_Tag_Attr tag_attr_27[17] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x36 - DW_TAG_dwarf_procedure */ static Usage_Tag_Attr tag_attr_36[3] = { {/* 0x02 */ 0, DW_AT_location}, {/* */ 0, 0} }; /* 0x46 - DW_TAG_dynamic_type */ static Usage_Tag_Attr tag_attr_46[14] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x03 - DW_TAG_entry_point */ static Usage_Tag_Attr tag_attr_03[16] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x40 */ 0, DW_AT_frame_base}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x48 */ 0, DW_AT_static_link}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x04 - DW_TAG_enumeration_type */ static Usage_Tag_Attr tag_attr_04[26] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x6d */ 0, DW_AT_enum_class}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x28 - DW_TAG_enumerator */ static Usage_Tag_Attr tag_attr_28[9] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x29 - DW_TAG_file_type */ static Usage_Tag_Attr tag_attr_29[18] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x05 - DW_TAG_formal_parameter */ static Usage_Tag_Attr tag_attr_05[18] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x21 */ 0, DW_AT_is_optional}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4b */ 0, DW_AT_variable_parameter}, {/* */ 0, 0} }; /* 0x2a - DW_TAG_friend */ static Usage_Tag_Attr tag_attr_2a[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x41 */ 0, DW_AT_friend}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x45 - DW_TAG_generic_subrange */ static Usage_Tag_Attr tag_attr_45[23] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x22 */ 0, DW_AT_lower_bound}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x62 */ 0, DW_AT_threads_scaled}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x2f */ 0, DW_AT_upper_bound}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x08 - DW_TAG_imported_declaration */ static Usage_Tag_Attr tag_attr_08[11] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x18 */ 0, DW_AT_import}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x4b - DW_TAG_immutable_type */ static Usage_Tag_Attr tag_attr_4b[6] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x3a - DW_TAG_imported_module */ static Usage_Tag_Attr tag_attr_3a[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x18 */ 0, DW_AT_import}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x3d - DW_TAG_imported_unit */ static Usage_Tag_Attr tag_attr_3d[3] = { {/* 0x18 */ 0, DW_AT_import}, {/* */ 0, 0} }; /* 0x1c - DW_TAG_inheritance */ static Usage_Tag_Attr tag_attr_1c[10] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x38 */ 0, DW_AT_data_member_location}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4c */ 0, DW_AT_virtuality}, {/* */ 0, 0} }; /* 0x1d - DW_TAG_inlined_subroutine */ static Usage_Tag_Attr tag_attr_1d[16] = { {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x57 */ 0, DW_AT_call_column}, {/* 0x58 */ 0, DW_AT_call_file}, {/* 0x59 */ 0, DW_AT_call_line}, {/* 0x6c */ 0, DW_AT_const_expr}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x56 */ 0, DW_AT_trampoline}, {/* */ 0, 0} }; /* 0x38 - DW_TAG_interface_type */ static Usage_Tag_Attr tag_attr_38[12] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x0a - DW_TAG_label */ static Usage_Tag_Attr tag_attr_0a[12] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x0b - DW_TAG_lexical_block */ static Usage_Tag_Attr tag_attr_0b[14] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x0d - DW_TAG_member */ static Usage_Tag_Attr tag_attr_0d[23] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x0c */ 0, DW_AT_bit_offset}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x6b */ 0, DW_AT_data_bit_offset}, {/* 0x38 */ 0, DW_AT_data_member_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x61 */ 0, DW_AT_mutable}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x1e - DW_TAG_module */ static Usage_Tag_Attr tag_attr_1e[18] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x45 */ 0, DW_AT_priority}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2b - DW_TAG_namelist */ static Usage_Tag_Attr tag_attr_2b[11] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2c - DW_TAG_namelist_item */ static Usage_Tag_Attr tag_attr_2c[7] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x44 */ 0, DW_AT_namelist_item}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x39 - DW_TAG_namespace */ static Usage_Tag_Attr tag_attr_39[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x54 */ 0, DW_AT_extension}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x2d - DW_TAG_packed_type */ static Usage_Tag_Attr tag_attr_2d[9] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x3c - DW_TAG_partial_unit */ static Usage_Tag_Attr tag_attr_3c[24] = { {/* 0x73 */ 0, DW_AT_addr_base}, {/* 0x35 */ 0, DW_AT_base_types}, {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x76 */ 0, DW_AT_dwo_name}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x42 */ 0, DW_AT_identifier_case}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x13 */ 0, DW_AT_language}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x43 */ 0, DW_AT_macro_info}, {/* 0x79 */ 0, DW_AT_macros}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x87 */ 0, DW_AT_noreturn}, {/* 0x25 */ 0, DW_AT_producer}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x74 */ 0, DW_AT_rnglists_base}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x0f - DW_TAG_pointer_type */ static Usage_Tag_Attr tag_attr_0f[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x1f - DW_TAG_ptr_to_member_type */ static Usage_Tag_Attr tag_attr_1f[20] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4a */ 0, DW_AT_use_location}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x10 - DW_TAG_reference_type */ static Usage_Tag_Attr tag_attr_10[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x37 - DW_TAG_restrict_type */ static Usage_Tag_Attr tag_attr_37[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x42 - DW_TAG_rvalue_reference_type */ static Usage_Tag_Attr tag_attr_42[10] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x20 - DW_TAG_set_type */ static Usage_Tag_Attr tag_attr_20[20] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x40 - DW_TAG_shared_type */ static Usage_Tag_Attr tag_attr_40[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x4a - DW_TAG_skeleton_unit */ static Usage_Tag_Attr tag_attr_4a[13] = { {/* 0x73 */ 0, DW_AT_addr_base}, {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x76 */ 0, DW_AT_dwo_name}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x74 */ 0, DW_AT_rnglists_base}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x12 - DW_TAG_string_type */ static Usage_Tag_Attr tag_attr_12[22] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x19 */ 0, DW_AT_string_length}, {/* 0x6f */ 0, DW_AT_string_length_bit_size}, {/* 0x70 */ 0, DW_AT_string_length_byte_size}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x13 - DW_TAG_structure_type */ static Usage_Tag_Attr tag_attr_13[24] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x36 */ 0, DW_AT_calling_convention}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2e - DW_TAG_subprogram */ static Usage_Tag_Attr tag_attr_2e[49] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x7a */ 0, DW_AT_call_all_calls}, {/* 0x7c */ 0, DW_AT_call_all_tail_calls}, {/* 0x7b */ 0, DW_AT_call_all_source_calls}, {/* 0x36 */ 0, DW_AT_calling_convention}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x8b */ 0, DW_AT_defaulted}, {/* 0x8a */ 0, DW_AT_deleted}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x66 */ 0, DW_AT_elemental}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x63 */ 0, DW_AT_explicit}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x40 */ 0, DW_AT_frame_base}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x20 */ 0, DW_AT_inline}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x87 */ 0, DW_AT_noreturn}, {/* 0x64 */ 0, DW_AT_object_pointer}, {/* 0x27 */ 0, DW_AT_prototyped}, {/* 0x67 */ 0, DW_AT_pure}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x68 */ 0, DW_AT_recursive}, {/* 0x77 */ 0, DW_AT_reference}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x78 */ 0, DW_AT_rvalue_reference}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x48 */ 0, DW_AT_static_link}, {/* 0x56 */ 0, DW_AT_trampoline}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* 0x4c */ 0, DW_AT_virtuality}, {/* 0x4d */ 0, DW_AT_vtable_elem_location}, {/* */ 0, 0} }; /* 0x21 - DW_TAG_subrange_type */ static Usage_Tag_Attr tag_attr_21[24] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x22 */ 0, DW_AT_lower_bound}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x62 */ 0, DW_AT_threads_scaled}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x2f */ 0, DW_AT_upper_bound}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x15 - DW_TAG_subroutine_type */ static Usage_Tag_Attr tag_attr_15[22] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x64 */ 0, DW_AT_object_pointer}, {/* 0x27 */ 0, DW_AT_prototyped}, {/* 0x78 */ 0, DW_AT_rvalue_reference}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x43 - DW_TAG_template_alias */ static Usage_Tag_Attr tag_attr_43[18] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2f - DW_TAG_template_type_parameter */ static Usage_Tag_Attr tag_attr_2f[10] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x30 - DW_TAG_template_value_parameter */ static Usage_Tag_Attr tag_attr_30[13] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x31 - DW_TAG_thrown_type */ static Usage_Tag_Attr tag_attr_31[12] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x32 - DW_TAG_try_block */ static Usage_Tag_Attr tag_attr_32[12] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x16 - DW_TAG_typedef */ static Usage_Tag_Attr tag_attr_16[18] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x41 - DW_TAG_type_unit */ static Usage_Tag_Attr tag_attr_41[7] = { {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x13 */ 0, DW_AT_language}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x17 - DW_TAG_union_type */ static Usage_Tag_Attr tag_attr_17[24] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x36 */ 0, DW_AT_calling_convention}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x18 - DW_TAG_unspecified_parameters */ static Usage_Tag_Attr tag_attr_18[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x3b - DW_TAG_unspecified_type */ static Usage_Tag_Attr tag_attr_3b[7] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* */ 0, 0} }; /* 0x34 - DW_TAG_variable */ static Usage_Tag_Attr tag_attr_34[26] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x6c */ 0, DW_AT_const_expr}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x19 - DW_TAG_variant */ static Usage_Tag_Attr tag_attr_19[11] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x3d */ 0, DW_AT_discr_list}, {/* 0x16 */ 0, DW_AT_discr_value}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x33 - DW_TAG_variant_part */ static Usage_Tag_Attr tag_attr_33[11] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x15 */ 0, DW_AT_discr}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x35 - DW_TAG_volatile_type */ static Usage_Tag_Attr tag_attr_35[8] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x22 - DW_TAG_with_stmt */ static Usage_Tag_Attr tag_attr_22[14] = { {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; static Usage_Tag_Attr *usage_tag_attr[77] = { 0, tag_attr_01, /* 0x01 - DW_TAG_array_type */ tag_attr_02, /* 0x02 - DW_TAG_class_type */ tag_attr_03, /* 0x03 - DW_TAG_entry_point */ tag_attr_04, /* 0x04 - DW_TAG_enumeration_type */ tag_attr_05, /* 0x05 - DW_TAG_formal_parameter */ 0, 0, tag_attr_08, /* 0x08 - DW_TAG_imported_declaration */ 0, tag_attr_0a, /* 0x0a - DW_TAG_label */ tag_attr_0b, /* 0x0b - DW_TAG_lexical_block */ 0, tag_attr_0d, /* 0x0d - DW_TAG_member */ 0, tag_attr_0f, /* 0x0f - DW_TAG_pointer_type */ tag_attr_10, /* 0x10 - DW_TAG_reference_type */ tag_attr_11, /* 0x11 - DW_TAG_compile_unit */ tag_attr_12, /* 0x12 - DW_TAG_string_type */ tag_attr_13, /* 0x13 - DW_TAG_structure_type */ 0, tag_attr_15, /* 0x15 - DW_TAG_subroutine_type */ tag_attr_16, /* 0x16 - DW_TAG_typedef */ tag_attr_17, /* 0x17 - DW_TAG_union_type */ tag_attr_18, /* 0x18 - DW_TAG_unspecified_parameters */ tag_attr_19, /* 0x19 - DW_TAG_variant */ tag_attr_1a, /* 0x1a - DW_TAG_common_block */ tag_attr_1b, /* 0x1b - DW_TAG_common_inclusion */ tag_attr_1c, /* 0x1c - DW_TAG_inheritance */ tag_attr_1d, /* 0x1d - DW_TAG_inlined_subroutine */ tag_attr_1e, /* 0x1e - DW_TAG_module */ tag_attr_1f, /* 0x1f - DW_TAG_ptr_to_member_type */ tag_attr_20, /* 0x20 - DW_TAG_set_type */ tag_attr_21, /* 0x21 - DW_TAG_subrange_type */ tag_attr_22, /* 0x22 - DW_TAG_with_stmt */ tag_attr_23, /* 0x23 - DW_TAG_access_declaration */ tag_attr_24, /* 0x24 - DW_TAG_base_type */ tag_attr_25, /* 0x25 - DW_TAG_catch_block */ tag_attr_26, /* 0x26 - DW_TAG_const_type */ tag_attr_27, /* 0x27 - DW_TAG_constant */ tag_attr_28, /* 0x28 - DW_TAG_enumerator */ tag_attr_29, /* 0x29 - DW_TAG_file_type */ tag_attr_2a, /* 0x2a - DW_TAG_friend */ tag_attr_2b, /* 0x2b - DW_TAG_namelist */ tag_attr_2c, /* 0x2c - DW_TAG_namelist_item */ tag_attr_2d, /* 0x2d - DW_TAG_packed_type */ tag_attr_2e, /* 0x2e - DW_TAG_subprogram */ tag_attr_2f, /* 0x2f - DW_TAG_template_type_parameter */ tag_attr_30, /* 0x30 - DW_TAG_template_value_parameter */ tag_attr_31, /* 0x31 - DW_TAG_thrown_type */ tag_attr_32, /* 0x32 - DW_TAG_try_block */ tag_attr_33, /* 0x33 - DW_TAG_variant_part */ tag_attr_34, /* 0x34 - DW_TAG_variable */ tag_attr_35, /* 0x35 - DW_TAG_volatile_type */ tag_attr_36, /* 0x36 - DW_TAG_dwarf_procedure */ tag_attr_37, /* 0x37 - DW_TAG_restrict_type */ tag_attr_38, /* 0x38 - DW_TAG_interface_type */ tag_attr_39, /* 0x39 - DW_TAG_namespace */ tag_attr_3a, /* 0x3a - DW_TAG_imported_module */ tag_attr_3b, /* 0x3b - DW_TAG_unspecified_type */ tag_attr_3c, /* 0x3c - DW_TAG_partial_unit */ tag_attr_3d, /* 0x3d - DW_TAG_imported_unit */ 0, tag_attr_3f, /* 0x3f - DW_TAG_condition */ tag_attr_40, /* 0x40 - DW_TAG_shared_type */ tag_attr_41, /* 0x41 - DW_TAG_type_unit */ tag_attr_42, /* 0x42 - DW_TAG_rvalue_reference_type */ tag_attr_43, /* 0x43 - DW_TAG_template_alias */ tag_attr_44, /* 0x44 - DW_TAG_coarray_type */ tag_attr_45, /* 0x45 - DW_TAG_generic_subrange */ tag_attr_46, /* 0x46 - DW_TAG_dynamic_type */ tag_attr_47, /* 0x47 - DW_TAG_atomic_type */ tag_attr_48, /* 0x48 - DW_TAG_call_site */ tag_attr_49, /* 0x49 - DW_TAG_call_site_parameter */ tag_attr_4a, /* 0x4a - DW_TAG_skeleton_unit */ tag_attr_4b, /* 0x4b - DW_TAG_immutable_type */ 0 }; typedef struct { Dwarf_Small legal; /* Legal attributes */ Dwarf_Small found; /* Found attributes */ } Rate_Tag_Attr; static Rate_Tag_Attr rate_tag_attr[77] = { {0, 0}, {22, 0, /* 0x01 - DW_TAG_array_type */}, {21, 0, /* 0x02 - DW_TAG_class_type */}, {14, 0, /* 0x03 - DW_TAG_entry_point */}, {24, 0, /* 0x04 - DW_TAG_enumeration_type */}, {16, 0, /* 0x05 - DW_TAG_formal_parameter */}, {0, 0}, {0, 0}, { 9, 0, /* 0x08 - DW_TAG_imported_declaration */}, {0, 0}, {10, 0, /* 0x0a - DW_TAG_label */}, {12, 0, /* 0x0b - DW_TAG_lexical_block */}, {0, 0}, {21, 0, /* 0x0d - DW_TAG_member */}, {0, 0}, {11, 0, /* 0x0f - DW_TAG_pointer_type */}, {11, 0, /* 0x10 - DW_TAG_reference_type */}, {22, 0, /* 0x11 - DW_TAG_compile_unit */}, {20, 0, /* 0x12 - DW_TAG_string_type */}, {22, 0, /* 0x13 - DW_TAG_structure_type */}, {0, 0}, {20, 0, /* 0x15 - DW_TAG_subroutine_type */}, {16, 0, /* 0x16 - DW_TAG_typedef */}, {22, 0, /* 0x17 - DW_TAG_union_type */}, { 6, 0, /* 0x18 - DW_TAG_unspecified_parameters */}, { 9, 0, /* 0x19 - DW_TAG_variant */}, {11, 0, /* 0x1a - DW_TAG_common_block */}, { 7, 0, /* 0x1b - DW_TAG_common_inclusion */}, { 8, 0, /* 0x1c - DW_TAG_inheritance */}, {14, 0, /* 0x1d - DW_TAG_inlined_subroutine */}, {16, 0, /* 0x1e - DW_TAG_module */}, {18, 0, /* 0x1f - DW_TAG_ptr_to_member_type */}, {18, 0, /* 0x20 - DW_TAG_set_type */}, {22, 0, /* 0x21 - DW_TAG_subrange_type */}, {12, 0, /* 0x22 - DW_TAG_with_stmt */}, { 7, 0, /* 0x23 - DW_TAG_access_declaration */}, {23, 0, /* 0x24 - DW_TAG_base_type */}, {10, 0, /* 0x25 - DW_TAG_catch_block */}, { 7, 0, /* 0x26 - DW_TAG_const_type */}, {15, 0, /* 0x27 - DW_TAG_constant */}, { 7, 0, /* 0x28 - DW_TAG_enumerator */}, {16, 0, /* 0x29 - DW_TAG_file_type */}, { 6, 0, /* 0x2a - DW_TAG_friend */}, { 9, 0, /* 0x2b - DW_TAG_namelist */}, { 5, 0, /* 0x2c - DW_TAG_namelist_item */}, { 7, 0, /* 0x2d - DW_TAG_packed_type */}, {47, 0, /* 0x2e - DW_TAG_subprogram */}, { 8, 0, /* 0x2f - DW_TAG_template_type_parameter */}, {11, 0, /* 0x30 - DW_TAG_template_value_parameter */}, {10, 0, /* 0x31 - DW_TAG_thrown_type */}, {10, 0, /* 0x32 - DW_TAG_try_block */}, { 9, 0, /* 0x33 - DW_TAG_variant_part */}, {24, 0, /* 0x34 - DW_TAG_variable */}, { 6, 0, /* 0x35 - DW_TAG_volatile_type */}, { 1, 0, /* 0x36 - DW_TAG_dwarf_procedure */}, { 6, 0, /* 0x37 - DW_TAG_restrict_type */}, {10, 0, /* 0x38 - DW_TAG_interface_type */}, {11, 0, /* 0x39 - DW_TAG_namespace */}, { 6, 0, /* 0x3a - DW_TAG_imported_module */}, { 5, 0, /* 0x3b - DW_TAG_unspecified_type */}, {22, 0, /* 0x3c - DW_TAG_partial_unit */}, { 1, 0, /* 0x3d - DW_TAG_imported_unit */}, {0, 0}, { 5, 0, /* 0x3f - DW_TAG_condition */}, {11, 0, /* 0x40 - DW_TAG_shared_type */}, { 5, 0, /* 0x41 - DW_TAG_type_unit */}, { 8, 0, /* 0x42 - DW_TAG_rvalue_reference_type */}, {16, 0, /* 0x43 - DW_TAG_template_alias */}, { 8, 0, /* 0x44 - DW_TAG_coarray_type */}, {21, 0, /* 0x45 - DW_TAG_generic_subrange */}, {12, 0, /* 0x46 - DW_TAG_dynamic_type */}, { 6, 0, /* 0x47 - DW_TAG_atomic_type */}, {11, 0, /* 0x48 - DW_TAG_call_site */}, { 8, 0, /* 0x49 - DW_TAG_call_site_parameter */}, {11, 0, /* 0x4a - DW_TAG_skeleton_unit */}, { 4, 0, /* 0x4b - DW_TAG_immutable_type */}, {0, 0} }; #endif /* HAVE_USAGE_TAG_ATTR */ #define ATTR_TREE_ROW_COUNT 76 #define ATTR_TREE_COLUMN_COUNT 5 static unsigned int tag_attr_combination_table [ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = { /* 0x00 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00802a0a,0x1e065000,0x0401c280,0x00020000,0x00000100,}, /* 0x02 - DW_TAG_class_type */ { 0x2080280a,0x1e461000,0x0401c080,0x00000200,0x00000100,}, /* 0x03 - DW_TAG_entry_point */ { 0x0002000a,0x0e080400,0x04000341,0x00004000,0x00000000,}, /* 0x04 - DW_TAG_enumeration_type */ { 0x0080280a,0x1e065000,0x0403c280,0x00006200,0x00000100,}, /* 0x05 - DW_TAG_formal_parameter */ { 0x5000000e,0x0e120002,0x04000a40,0x00000020,0x00000000,}, /* 0x06 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x07 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x08 - DW_TAG_imported_declaration */ { 0x0100000a,0x0e041000,0x04000000,0x00000000,0x00000000,}, /* 0x09 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0a - DW_TAG_label */ { 0x0002000a,0x0e021000,0x04000040,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0006000a,0x0e020000,0x04240040,0x00000000,0x00000000,}, /* 0x0c - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x1080380a,0x9f140000,0x04000200,0x00000802,0x00000100,}, /* 0x0e - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0f - DW_TAG_pointer_type */ { 0x0000280a,0x0e080000,0x00000200,0x00000000,0x00000100,}, /* 0x10 - DW_TAG_reference_type */ { 0x0000280a,0x0e080000,0x00000200,0x00000000,0x00000100,}, /* 0x11 - DW_TAG_compile_unit */ { 0x080f0008,0x00200020,0x002c004c,0x027c0400,0x00001000,}, /* 0x12 - DW_TAG_string_type */ { 0x0280280a,0x1e061000,0x0401c040,0x00018000,0x00000000,}, /* 0x13 - DW_TAG_structure_type */ { 0x0080280a,0x1e461000,0x0401c080,0x00004200,0x00000300,}, /* 0x14 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x15 - DW_TAG_subroutine_type */ { 0x0080000a,0x1e0e1080,0x0401c200,0x01000010,0x00000100,}, /* 0x16 - DW_TAG_typedef */ { 0x0080000a,0x1e061000,0x0401c200,0x00000000,0x00000100,}, /* 0x17 - DW_TAG_union_type */ { 0x0080280a,0x1e461000,0x0401c080,0x00004200,0x00000300,}, /* 0x18 - DW_TAG_unspecified_parameters */ { 0x00000002,0x0e120000,0x00000000,0x00000000,0x00000000,}, /* 0x19 - DW_TAG_variant */ { 0x00400002,0x3e060000,0x00000000,0x00000000,0x00000000,}, /* 0x1a - DW_TAG_common_block */ { 0x0080000e,0x1e000000,0x04000040,0x00004000,0x00000000,}, /* 0x1b - DW_TAG_common_inclusion */ { 0x04800002,0x1e000000,0x00000000,0x00000000,0x00000000,}, /* 0x1c - DW_TAG_inheritance */ { 0x00000002,0x0f040000,0x00001200,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x00060002,0x00021400,0x03e40040,0x00001000,0x00000000,}, /* 0x1e - DW_TAG_module */ { 0x0086000a,0x1e040000,0x042400e0,0x00000000,0x00000000,}, /* 0x1f - DW_TAG_ptr_to_member_type */ { 0x2080000a,0x1e0a0000,0x0401c600,0x00000000,0x00000100,}, /* 0x20 - DW_TAG_set_type */ { 0x0080280a,0x1e061000,0x0401c200,0x00000000,0x00000100,}, /* 0x21 - DW_TAG_subrange_type */ { 0x0080280a,0x1e86c004,0x0403c200,0x00000004,0x00000000,}, /* 0x22 - DW_TAG_with_stmt */ { 0x00860006,0x100c0000,0x00240240,0x00000000,0x00000000,}, /* 0x23 - DW_TAG_access_declaration */ { 0x0000000a,0x0e040000,0x04000000,0x00000000,0x00000000,}, /* 0x24 - DW_TAG_base_type */ { 0x0000380a,0x4e000000,0xfc01c000,0x00000821,0x00000100,}, /* 0x25 - DW_TAG_catch_block */ { 0x00060002,0x0e020000,0x00240040,0x00000000,0x00000000,}, /* 0x26 - DW_TAG_const_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x27 - DW_TAG_constant */ { 0x1080000a,0x9e041000,0x04000200,0x00004020,0x00000000,}, /* 0x28 - DW_TAG_enumerator */ { 0x1000000a,0x0e000000,0x04000000,0x00000000,0x00000000,}, /* 0x29 - DW_TAG_file_type */ { 0x0080280a,0x0e021000,0x0401c200,0x00000000,0x00000100,}, /* 0x2a - DW_TAG_friend */ { 0x00000002,0x0e020000,0x00000002,0x00000000,0x00000000,}, /* 0x2b - DW_TAG_namelist */ { 0x0080000a,0x1e060000,0x00000000,0x00000000,0x00000000,}, /* 0x2c - DW_TAG_namelist_item */ { 0x00000002,0x0e000000,0x00000010,0x00000000,0x00000000,}, /* 0x2d - DW_TAG_packed_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x2e - DW_TAG_subprogram */ { 0x2086000a,0x9e5e1481,0x046433c1,0x1d8045d8,0x00000d80,}, /* 0x2f - DW_TAG_template_type_parameter */ { 0x4000000a,0x0e000000,0x04000200,0x00000000,0x00000000,}, /* 0x30 - DW_TAG_template_value_parameter */ { 0x5000000e,0x0e000000,0x04000200,0x00000000,0x00000100,}, /* 0x31 - DW_TAG_thrown_type */ { 0x0000000a,0x0e000000,0x0001c200,0x00000000,0x00000100,}, /* 0x32 - DW_TAG_try_block */ { 0x00060002,0x0e020000,0x00240040,0x00000000,0x00000000,}, /* 0x33 - DW_TAG_variant_part */ { 0x00200002,0x1e060000,0x00000200,0x00000000,0x00000000,}, /* 0x34 - DW_TAG_variable */ { 0x1080280e,0x9e161000,0x040002c0,0x00005020,0x00000100,}, /* 0x35 - DW_TAG_volatile_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000000,}, /* 0x36 - DW_TAG_dwarf_procedure */ { 0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x37 - DW_TAG_restrict_type */ { 0x00000002,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x38 - DW_TAG_interface_type */ { 0x0000000a,0x0e041000,0x04000000,0x00000200,0x00000100,}, /* 0x39 - DW_TAG_namespace */ { 0x0000000a,0x1e001000,0x04100000,0x00000000,0x00000200,}, /* 0x3a - DW_TAG_imported_module */ { 0x01000002,0x0e001000,0x00000000,0x00000000,0x00000000,}, /* 0x3b - DW_TAG_unspecified_type */ { 0x00000008,0x0e000000,0x04000000,0x00000000,0x00000000,}, /* 0x3c - DW_TAG_partial_unit */ { 0x080f0008,0x00200020,0x042c004c,0x025c0400,0x00000080,}, /* 0x3d - DW_TAG_imported_unit */ { 0x01000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x3e - DW_TAG_mutable_type */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x3f - DW_TAG_condition */ { 0x0000000a,0x0e000000,0x00000000,0x00000000,0x00000000,}, /* 0x40 - DW_TAG_shared_type */ { 0x0000000a,0x0e800000,0x0000c200,0x00000000,0x00000100,}, /* 0x41 - DW_TAG_type_unit */ { 0x08090000,0x00000000,0x00080000,0x00040000,0x00000000,}, /* 0x42 - DW_TAG_rvalue_reference_type */ { 0x00000808,0x0e080000,0x00000200,0x00000000,0x00000100,}, /* 0x43 - DW_TAG_template_alias */ { 0x0080000a,0x1e061000,0x0401c200,0x00000200,0x00000000,}, /* 0x44 - DW_TAG_coarray_type */ { 0x00002802,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x45 - DW_TAG_generic_subrange */ { 0x0080280a,0x1e82c004,0x0403c200,0x00000004,0x00000000,}, /* 0x46 - DW_TAG_dynamic_type */ { 0x0000000a,0x0e020000,0x0401c200,0x00000000,0x00000100,}, /* 0x47 - DW_TAG_atomic_type */ { 0x00000002,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x48 - DW_TAG_call_site */ { 0x00000002,0x00000000,0x03800200,0xa0000000,0x0000001e,}, /* 0x49 - DW_TAG_call_site_parameter */ { 0x0000000e,0x00000000,0x00000200,0x40000000,0x00000061,}, /* 0x4a - DW_TAG_skeleton_unit */ { 0x08070000,0x00000000,0x00280000,0x005c0000,0x00000000,}, /* 0x4b - DW_TAG_immutable_type */ { 0x00000000,0x0e000000,0x00000200,0x00000000,0x00000000,}, }; /* END FILE */ libdwarf-20210528/dwarfdump/print_aranges.c0000664000175000017500000003761713767716336015526 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" static int do_checking(Dwarf_Debug dbg, Dwarf_Arange *arange_buf,Dwarf_Signed i, Dwarf_Off cu_die_offset,Dwarf_Bool first_cu, Dwarf_Off cu_die_offset_prev, Dwarf_Die cu_die, Dwarf_Error *err ) { int dres = 0; Dwarf_Off cuhdroff = 0; Dwarf_Off cudieoff3 = 0; /* .debug_types has no address ranges, only .debug_info[.dwo] has them.*/ int is_info = 1; dres = dwarf_get_arange_cu_header_offset( arange_buf[i],&cuhdroff,err); if (dres == DW_DLV_OK) { Dwarf_Off cudieoff2 = 0; /* Get the CU offset for easy error reporting */ if (first_cu || cu_die_offset != cu_die_offset_prev) { dres = dwarf_die_offsets(cu_die,&glflags. DIE_overall_offset, &glflags.DIE_offset,err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; if (dres != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: reading dwarf_die_offsets", dres, *err); return dres; } } dres = dwarf_get_cu_die_offset_given_cu_header_offset_b( dbg,cuhdroff,is_info,&cudieoff2,err); if (dres == DW_DLV_OK) { /* Get the CU offset for easy error reporting */ dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; DWARF_CHECK_COUNT(aranges_result,1); if (cu_die_offset != cudieoff2) { printf("Error, cu_die offsets mismatch, 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff2); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset_given_cu..." " gets wrong offset"); } } else { print_error_and_continue(dbg, "ERROR from arange checking " "dwarf_get_cu_die_offset_given... fails", dres, *err); return dres; } } else { print_error_and_continue(dbg, "ERROR: from arange checking " "dwarf_get_arange_cu_header_offset fails", dres, *err); return dres; } dres = dwarf_get_cu_die_offset(arange_buf[i],&cudieoff3, err); if (dres == DW_DLV_OK) { DWARF_CHECK_COUNT(aranges_result,1); if (cudieoff3 != cu_die_offset) { printf( "Error, cu_die offsets (b) mismatch , 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff3); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset " " gets wrong offset"); } } else { print_error_and_continue(dbg, "ERROR: from arange checking " "dwarf_get_cu_die_offset fails", dres,*err); return dres; } return DW_DLV_OK; } static void aranges_dealloc_now(Dwarf_Debug dbg, Dwarf_Signed count, Dwarf_Arange *arange_buf) { Dwarf_Signed i = 0; for ( ; i < count; ++i) { dwarf_dealloc(dbg,arange_buf[i],DW_DLA_ARANGE); } dwarf_dealloc(dbg,arange_buf,DW_DLA_LIST); } /* get all the data in .debug_aranges */ int print_aranges(Dwarf_Debug dbg,Dwarf_Error *ga_err) { Dwarf_Signed count = 0; Dwarf_Signed i = 0; Dwarf_Arange *arange_buf = NULL; int ares = 0; int aires = 0; Dwarf_Off prev_off = 0; /* Holds previous CU offset */ Dwarf_Bool first_cu = TRUE; Dwarf_Off cu_die_offset_prev = 0; /* Reset the global state, so we can traverse the debug_info */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; glflags.need_CU_base_address = TRUE; glflags.need_CU_high_address = TRUE; glflags.current_section_id = DEBUG_ARANGES; ares = dwarf_get_aranges(dbg, &arange_buf, &count, ga_err); if (glflags.gf_do_print_dwarf) { /* Now we know the section is loaded (if any) so lets get the true name with any compression info. */ struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_aranges", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } if (ares == DW_DLV_ERROR) { print_error_and_continue(dbg, "Unable to load the .debug_aranges section.", ares,*ga_err); return ares; } else if (ares == DW_DLV_NO_ENTRY) { return ares; } else { for (i = 0; i < count; i++) { Dwarf_Unsigned segment = 0; Dwarf_Unsigned segment_entry_size = 0; Dwarf_Addr start = 0; Dwarf_Unsigned length = 0; Dwarf_Off cu_die_offset = 0; Dwarf_Die cu_die = NULL; aires = dwarf_get_arange_info_b(arange_buf[i], &segment, &segment_entry_size, &start, &length, &cu_die_offset, ga_err); if (aires != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_i(&m, "\nERROR: attempt to read arange %d", i); esb_append_printf_i(&m, " of %d aranges failed.", count); simple_err_return_msg_either_action(aires, esb_get_string(&m)); esb_destructor(&m); aranges_dealloc_now(dbg,count,arange_buf); return aires; } else { int dres; /* Get basic locations for error reporting */ dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, ga_err); if (dres != DW_DLV_OK) { struct esb_s m; const char *failtype = "no-entry"; if (dres == DW_DLV_ERROR) { failtype = "error"; } esb_constructor(&m); esb_append_printf_s(&m, "\nERROR: dwarf_offdie() gets a " "return of %s ", failtype); esb_append_printf_i(&m," finding the " "compilation-unit DIE for " "arange number %d and that " "should never happen.", i); simple_err_return_msg_either_action(dres, esb_get_string(&m)); esb_destructor(&m); aranges_dealloc_now(dbg,count,arange_buf); arange_buf = 0; return dres; } if (glflags.gf_cu_name_flag) { Dwarf_Bool should_skip = FALSE; /* Always sets should_skip */ should_skip_this_cu(dbg, &should_skip,cu_die); if (should_skip) { dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); } } /* Get producer name for this CU and update compiler list */ { struct esb_s producer_name; int pres = 0; esb_constructor(&producer_name); pres = get_producer_name(dbg,cu_die,cu_die_offset, &producer_name,ga_err); if (pres == DW_DLV_ERROR) { dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); aranges_dealloc_now(dbg,count,arange_buf); return pres; } update_compiler_target( esb_get_string(&producer_name)); esb_destructor(&producer_name); } if (!checking_this_compiler()) { dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); cu_die = 0; continue; } if (glflags.gf_check_aranges) { int cres = 0; cres = do_checking(dbg,arange_buf,i, cu_die_offset,first_cu, cu_die_offset_prev,cu_die,ga_err); if (cres == DW_DLV_ERROR) { aranges_dealloc_now(dbg,count,arange_buf); return cres; } } /* Get the offset of the cu header itself in the section, but not for end-entries. */ if (start || length) { Dwarf_Off off = 0; int cures3 = dwarf_get_arange_cu_header_offset( arange_buf[i], &off, ga_err); if (cures3 != DW_DLV_OK) { struct esb_s m; const char *failtype = "no-entry"; if (dres == DW_DLV_ERROR) { failtype = "error"; } esb_constructor(&m); esb_append_printf_s(&m, "\nERROR: dwarf_get_arange_cu_" "header_offset() " "gets a return of %s ", failtype); esb_append_printf_i(&m,"finding the " "compilation-unit DIE offset for " "arange number %d and that should " "never happen.", i); simple_err_return_msg_either_action(cures3, esb_get_string(&m)); esb_destructor(&m); dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); aranges_dealloc_now(dbg,count,arange_buf); return cures3; } /* Print the CU information if different. */ if (prev_off != off || first_cu) { first_cu = FALSE; prev_off = off; /* We are faking the indent level. We do not know what level it is, really. If do_check_dwarf we do not want to do the die print call as it will do check/print we may not have asked for. And if we did ask for debug_info checks this will do the checks a second time! So only call print_one_die if printing. */ if (glflags.gf_do_print_dwarf){ /* There is no die if its a set-end entry */ int pres = 0; Dwarf_Bool attr_duplicated = FALSE; pres = print_one_die(dbg, cu_die, cu_die_offset, /* print_information= */ (Dwarf_Bool) TRUE, /* indent_level = */0, /* srcfiles= */ 0, /* cnt= */ 0, &attr_duplicated, /* ignore_die_stack= */TRUE, ga_err); if (pres == DW_DLV_ERROR) { dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); aranges_dealloc_now(dbg, count,arange_buf); return pres; } } /* Reset the state, so we can traverse the debug_info */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; if (glflags.gf_do_print_dwarf) { printf("\n"); } } if (glflags.gf_do_print_dwarf) { /* Print current aranges record */ if (segment_entry_size) { printf( "\narange starts at seg,off 0x%" DW_PR_XZEROS DW_PR_DUx ",0x%" DW_PR_XZEROS DW_PR_DUx ", ", segment, (Dwarf_Unsigned)start); } else { printf("\narange starts at 0x%" DW_PR_XZEROS DW_PR_DUx ", ", (Dwarf_Unsigned)start); } printf("length of 0x%" DW_PR_XZEROS DW_PR_DUx ", cu_die_offset = 0x%" DW_PR_XZEROS DW_PR_DUx, length, (Dwarf_Unsigned)cu_die_offset); } if (glflags.verbose && glflags.gf_do_print_dwarf) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned)off); } } else { /* Must be a range end. We really do want to print this as there is a real record here, an 'arange end' record. */ if (glflags.gf_do_print_dwarf) { printf("\narange end\n"); } }/* end start||length test */ } /* end aires DW_DLV_OK test */ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; /* print associated die too? */ } /* end loop on arange_buf */ aranges_dealloc_now(dbg,count,arange_buf); arange_buf = 0; } /* end DW_DLV_OK */ return DW_DLV_OK; } libdwarf-20210528/dwarfdump/print_ranges.c0000664000175000017500000003313314003121717015323 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" static struct esb_s esb_string; void ranges_esb_string_destructor(void) { esb_destructor(&esb_string); } /* Because we do not know what DIE is involved, if the object being printed has different address sizes in different compilation units this will not work properly: anything could happen. */ extern int print_ranges(Dwarf_Debug dbg, UNUSEDARG Dwarf_Error *err) { Dwarf_Unsigned off = 0; int group_number = 0; int wasdense = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; unsigned loopct = 0; glflags.current_section_id = DEBUG_RANGES; if (!glflags.gf_do_print_dwarf) { return DW_DLV_OK; } esb_constructor_fixed(&truename,buf,sizeof(buf)); /* Turn off dense, we do not want print_ranges_list_to_extra to use dense form here. */ wasdense = glflags.dense; glflags.dense = 0; for (;;++loopct) { Dwarf_Ranges *rangeset = 0; Dwarf_Signed rangecount = 0; Dwarf_Unsigned bytecount = 0; Dwarf_Error pr_err; /* We do not know what DIE is involved, we use the older call here. */ int rres = dwarf_get_ranges(dbg,off,&rangeset, &rangecount,&bytecount,&pr_err); if (!loopct) { get_true_section_name(dbg,".debug_ranges", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); } if (rres == DW_DLV_OK) { char *val = 0; printf(" Ranges group %d:\n",group_number); esb_empty_string(&esb_string); print_ranges_list_to_extra(dbg,off,off, rangeset,rangecount,bytecount, &esb_string); dwarf_ranges_dealloc(dbg,rangeset,rangecount); val = esb_get_string(&esb_string); printf("%s",sanitized(val)); ++group_number; } else if (rres == DW_DLV_NO_ENTRY) { printf("End of %s.\n", sanitized(esb_get_string(&truename))); break; } else { /* ERROR, which does not quite mean a real error, as we might just be misaligned reading things without a DW_AT_ranges offset.*/ struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m,"ERROR: at offset 0x%lx in ",off); esb_append_printf_s(&m,"section %s. Stopping ranges" " output.",sanitized(esb_get_string(&truename))); print_error_and_continue(dbg,esb_get_string(&m), rres,pr_err); dwarf_dealloc(dbg,pr_err,DW_DLA_ERROR); pr_err = 0; esb_destructor(&m); break; } off += bytecount; } glflags.dense = wasdense; esb_destructor(&truename); return DW_DLV_OK; } /* Extracted this from print_range_attribute() to isolate the check of the range list. */ static int check_ranges_list(Dwarf_Debug dbg, UNUSEDARG Dwarf_Off die_off, Dwarf_Die cu_die, Dwarf_Unsigned original_off, Dwarf_Unsigned finaloff, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount, Dwarf_Error *err) { Dwarf_Unsigned off = original_off; Dwarf_Signed index = 0; Dwarf_Addr base_address = glflags.CU_base_address; Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Bool bError = FALSE; Dwarf_Half elf_address_size = 0; Dwarf_Addr elf_max_address = 0; static Dwarf_Bool do_print = TRUE; const char *sec_name = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_ranges", &truename,FALSE); sec_name = esb_get_string(&truename); get_address_size_and_max(dbg,&elf_address_size, &elf_max_address,err); /* Ignore last entry, is the end-of-list */ for (index = 0; index < rangecount - 1; index++) { Dwarf_Ranges *r = rangeset + index; if (r->dwr_addr1 == elf_max_address) { /* (0xffffffff,addr), use specific address (current PU address) */ base_address = r->dwr_addr2; } else { /* (offset,offset), update using CU address */ lopc = r->dwr_addr1 + base_address; hipc = r->dwr_addr2 + base_address; DWARF_CHECK_COUNT(ranges_result,1); /* Check the low_pc and high_pc are within a valid range in the .text section */ if (IsValidInBucketGroup(glflags.pRangesInfo,lopc) && IsValidInBucketGroup(glflags.pRangesInfo,hipc)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol */ if (IsValidInLinkonce(glflags.pLinkonceInfo, glflags.PU_name,lopc,hipc)) { /* Valid values; do nothing */ } else { struct esb_s errbuf; bError = TRUE; esb_constructor(&errbuf); esb_append_printf_s(&errbuf, "%s: Address outside a " "valid .text range",sanitized(sec_name)); DWARF_CHECK_ERROR(ranges_result, esb_get_string(&errbuf)); esb_destructor(&errbuf); if (glflags.gf_check_verbose_mode && do_print) { /* Update DIEs offset just for printing */ int dioff_res = dwarf_die_offsets(cu_die, &glflags.DIE_overall_offset, &glflags.DIE_offset,err); if (dioff_res != DW_DLV_OK) { simple_err_return_msg_either_action( dioff_res, "Call to dwarf_die_offsets failed " "for the CU DIE." "in printing ranges"); return dioff_res; } printf( "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx ", " "Low = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx "), High = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", off,base_address,lopc, r->dwr_addr1,hipc, r->dwr_addr2); } } } } /* Each entry holds 2 addresses (offsets) */ off += elf_address_size * 2; } /* In the case of errors, we have to print the range records that caused the error. */ if (bError && glflags.gf_check_verbose_mode && do_print) { struct esb_s rangesstr; esb_constructor(&rangesstr); printf("\n"); print_ranges_list_to_extra(dbg,original_off, finaloff, rangeset,rangecount,bytecount, &rangesstr); printf("%s\n", sanitized(esb_get_string(&rangesstr))); esb_destructor(&rangesstr); } /* In the case of printing unique errors, stop the printing of any subsequent errors, which have the same text. */ if (bError && glflags.gf_check_verbose_mode && glflags.gf_print_unique_errors) { do_print = FALSE; } esb_destructor(&truename); return DW_DLV_OK; } /* Records information about compilers (producers) found in the debug information, including the check results for several categories (see -k option). */ typedef struct { Dwarf_Off die_off; Dwarf_Off range_off; } Range_Array_Entry; /* Array to record the DW_AT_range attribute DIE, to be used at the end of the CU, to check the range values; DWARF4 allows an offset relative to the low_pc as the high_pc value. Also, LLVM generates for the CU the pair (low_pc, at_ranges) instead of the traditional (low_pc, high_pc). */ static Range_Array_Entry *range_array = NULL; static Dwarf_Unsigned range_array_size = 0; static Dwarf_Unsigned range_array_count = 0; #define RANGE_ARRAY_INITIAL_SIZE 64 /* Allocate space to store information about the ranges; the values are extracted from the DW_AT_ranges attribute. The space is reused by all CUs. */ void allocate_range_array_info() { if (range_array == NULL) { /* Allocate initial range array info */ range_array = (Range_Array_Entry *) calloc(RANGE_ARRAY_INITIAL_SIZE, sizeof(Range_Array_Entry)); range_array_size = RANGE_ARRAY_INITIAL_SIZE; } } void release_range_array_info() { if (range_array) { free(range_array); range_array = 0; range_array_size = 0; range_array_count = 0; } } /* Clear out values from previous CU */ static void reset_range_array_info() { if (range_array) { memset((void *)range_array,0, (range_array_count) * sizeof(Range_Array_Entry)); range_array_count = 0; } } void record_range_array_info_entry(Dwarf_Off die_off,Dwarf_Off range_off) { /* Record a new detected range info. */ if (range_array_count == range_array_size) { /* Resize range array */ range_array_size *= 2; range_array = (Range_Array_Entry *) realloc(range_array, (range_array_size) * sizeof(Range_Array_Entry)); } /* The 'die_off' is the Global Die Offset */ range_array[range_array_count].die_off = die_off; range_array[range_array_count].range_off = range_off; ++range_array_count; } /* Now that we are at the end of the CU, check the range lists */ int check_range_array_info(Dwarf_Debug dbg,Dwarf_Error * err) { if (range_array && range_array_count) { /* Traverse the range array and for each entry: Load the ranges Check for any outside conditions */ Dwarf_Off original_off = 0; Dwarf_Off finaloffset = 0; Dwarf_Off die_off = 0; Dwarf_Unsigned index = 0; Dwarf_Die cu_die = 0; int res = 0; /* In case of errors, the correct DIE offset should be displayed. At this point we are at the end of the PU */ Dwarf_Off DIE_overall_offset_bak = glflags.DIE_overall_offset; for (index = 0; index < range_array_count; ++index) { Dwarf_Ranges *rangeset = 0; Dwarf_Signed rangecount = 0; Dwarf_Unsigned bytecount = 0; /* Get a range info record */ die_off = range_array[index].die_off; original_off = range_array[index].range_off; res = dwarf_offdie(dbg,die_off,&cu_die,err); if (res != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "Call to dwarf_offdie failed " "getting the CU die from offset " " 0x%" DW_PR_XZEROS DW_PR_DUx "in checking ranges",die_off); simple_err_return_msg_either_action( res, esb_get_string(&m)); esb_destructor(&m); return res; } res = dwarf_get_ranges_b(dbg,original_off, cu_die, &finaloffset, &rangeset,&rangecount,&bytecount,err); if (res == DW_DLV_OK) { res = check_ranges_list(dbg,die_off, cu_die,original_off,finaloffset, rangeset,rangecount,bytecount,err); if (res != DW_DLV_OK) { dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); reset_range_array_info(); return res; } dwarf_dealloc(dbg,rangeset,DW_DLA_RANGES); } dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); }; reset_range_array_info(); /* Point back to the end of the PU */ glflags.DIE_overall_offset = DIE_overall_offset_bak; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/dwarfdump.c0000664000175000017500000025275614053210210014627 00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" /* for 'open' */ #ifdef SYS_TYPES_H #include #endif /* SYS_TYPES_H */ #ifdef SYS_STAT_H #include #endif /* SYS_STAT_H */ #include #include #ifdef HAVE_UNISTD_H #include /* for dup2() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include "makename.h" #include "macrocheck.h" #include "dwconf.h" #include "dwconf_using_functions.h" #include "common.h" #include "helpertree.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "tag_common.h" #include "addrmap.h" #include "attr_form.h" #include "print_debug_gnu.h" #include "naming.h" /* for get_FORM_name() */ #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ #include "command_options.h" #include "compiler_info.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ #ifdef HAVE_ELF_OPEN extern int elf_open(const char *name,int mode); #endif /* HAVE_ELF_OPEN */ #ifdef HAVE_CUSTOM_LIBELF extern int elf_is_custom_format(void *header, size_t headerlen, size_t *size, unsigned *endian, unsigned *offsetsize, int *errcode); #endif /* HAVE_CUSTOM_LIBELF */ #define BYTES_PER_INSTRUCTION 4 /* The type of Bucket. */ #define KIND_RANGES_INFO 1 #define KIND_SECTIONS_INFO 2 #define KIND_VISITED_INFO 3 /* Build section information */ void build_linkonce_info(Dwarf_Debug dbg); struct glflags_s glflags; /* Functions used to manage the unique errors table */ static void allocate_unique_errors_table(void); static void release_unique_errors_table(void); #ifdef TESTING static void dump_unique_errors_table(void); #endif static Dwarf_Bool add_to_unique_errors_table(char * error_text); static struct esb_s esb_short_cu_name; static struct esb_s esb_long_cu_name; static struct esb_s dwarf_error_line; static int global_basefd = -1; static int global_tiedfd = -1; static struct esb_s global_file_name; static struct esb_s global_tied_file_name; static int process_one_file(int fd, int tiedfd, Elf *efp, Elf * tiedfp, const char * file_name, const char * tied_file_name, char * tempbuf, unsigned int tempbuflen, #ifdef DWARF_WITH_LIBELF int archive, #endif struct dwconf_s *conf); static int print_gnu_debuglink(Dwarf_Debug dbg,Dwarf_Error *err); static int open_a_file(const char * name) { /* Set to a file number that cannot be legal. */ int fd = -1; #if HAVE_ELF_OPEN /* It is not possible to share file handles between applications or DLLs. Each application has its own file-handle table. For two applications to use the same file using a DLL, they must both open the file individually. Let the 'libelf' dll open and close the file. */ fd = elf_open(name, O_RDONLY | O_BINARY); #else fd = open(name, O_RDONLY | O_BINARY); #endif return fd; } static void close_a_file(int f) { if (f != -1) { close(f); } } static void global_destructors(void) { makename_destructor(); uri_data_destructor(); esb_destructor(&esb_long_cu_name); esb_destructor(&esb_short_cu_name); esb_destructor(&dwarf_error_line); esb_destructor(glflags.newprogname); esb_destructor(&global_file_name); esb_destructor(&global_tied_file_name); free_all_dwconf(glflags.config_file_data); sanitized_string_destructor(); ranges_esb_string_destructor(); /* Global flags initialization and esb-buffers destruction. */ reset_global_flags(); close_a_file(global_basefd); close_a_file(global_tiedfd); #ifdef _WIN32 /* Close the null device used during formatting printing */ esb_close_null_device(); #endif /* _WIN32 */ if (glflags.gf_global_debuglink_paths) { unsigned int i = 0; for ( ; i < glflags.gf_global_debuglink_count ; ++i ) { free(glflags.gf_global_debuglink_paths[i]); glflags.gf_global_debuglink_paths[i] = 0; } free(glflags.gf_global_debuglink_paths); glflags.gf_global_debuglink_paths = 0; } glflags.gf_global_debuglink_count = 0; } #ifdef DWARF_WITH_LIBELF static int is_it_known_elf_header(Elf *elf) { Elf32_Ehdr *eh32; eh32 = elf32_getehdr(elf); if (eh32) { return 1; } #ifdef HAVE_ELF64_GETEHDR { Elf64_Ehdr *eh64; /* not a 32-bit obj */ eh64 = elf64_getehdr(elf); if (eh64) { return 1; } } #endif /* HAVE_ELF64_GETEHDR */ /* Not something we can handle. */ return 0; } #endif /* DWARF_WITH_LIBELF */ static void check_for_notes(void) { long int ect = glflags.gf_count_macronotes; const char *w = "was"; const char *e = "MACRONOTE"; if (!ect) { return; } if (ect > 1) { w = "were"; e = "MACRONOTEs"; } printf("There %s %ld DWARF %s reported: " "see MACRONOTE above.\n", w, ect,e); } static void check_for_major_errors(void) { long int ect = glflags.gf_count_major_errors; const char *w = "was"; const char *e = "error"; if (!ect) { return; } if (ect > 1) { w = "were"; e = "errors"; } printf("There %s %ld DWARF %s reported: " "see ERROR above.\n", w, ect,e); } static void flag_data_pre_allocation(void) { memset(glflags.section_high_offsets_global,0, sizeof(*glflags.section_high_offsets_global)); /* If we are checking .debug_line, .debug_ranges, .debug_aranges, or .debug_loc build the tables containing the pairs LowPC and HighPC. It is safer (and not expensive) to build all of these at once so mistakes in options do not lead to coredumps (like -ka -p did once). */ if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations || glflags.gf_do_check_dwarf || glflags.gf_check_self_references) { glflags.pRangesInfo = AllocateBucketGroup(KIND_RANGES_INFO); glflags.pLinkonceInfo = AllocateBucketGroup(KIND_SECTIONS_INFO); glflags.pVisitedInfo = AllocateBucketGroup(KIND_VISITED_INFO); } /* Create the unique error table */ if (glflags.gf_print_unique_errors) { allocate_unique_errors_table(); } /* Allocate range array to be used by all CUs */ if (glflags.gf_check_ranges) { allocate_range_array_info(); } } static void flag_data_post_cleanup(void) { #ifdef DWARF_WITH_LIBELF clean_up_syms_malloc_data(); #endif /* DWARF_WITH_LIBELF */ if (glflags.pRangesInfo) { ReleaseBucketGroup(glflags.pRangesInfo); glflags.pRangesInfo = 0; } if (glflags.pLinkonceInfo) { ReleaseBucketGroup(glflags.pLinkonceInfo); glflags.pLinkonceInfo = 0; } if (glflags.pVisitedInfo) { ReleaseBucketGroup(glflags.pVisitedInfo); glflags.pVisitedInfo = 0; } /* Release range array to be used by all CUs */ if (glflags.gf_check_ranges) { release_range_array_info(); } /* Delete the unique error set */ if (glflags.gf_print_unique_errors) { release_unique_errors_table(); } clean_up_compilers_detected(); destruct_abbrev_array(); } #ifdef DWARF_WITH_LIBELF static int process_using_libelf(int fd, int tiedfd, const char *file_name, const char *tied_file_name, int archive) { Elf_Cmd cmd = 0; Elf *arf = 0; Elf *elf = 0; Elf *elftied = 0; int archmemnum = 0; (void) elf_version(EV_NONE); if (elf_version(EV_CURRENT) == EV_NONE) { (void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n"); exit(FAILED); } /* We will use libelf to process an archive so long as is convienient. we don't intend to ever write our own archive reader. Archive support was never tested and may disappear. */ cmd = ELF_C_READ; arf = elf_begin(fd, cmd, (Elf *) 0); if (!arf) { fprintf(stderr, "%s ERROR: " "Unable to obtain ELF descriptor for %s\n", glflags.program_name, file_name); return (FAILED); } if (esb_string_len(glflags.config_file_tiedpath) > 0) { int isknown = 0; if (tiedfd == -1) { fprintf(stderr, "%s ERROR: " "can't open tied file.... %s\n", glflags.program_name, tied_file_name); return (FAILED); } elftied = elf_begin(tiedfd, cmd, (Elf *) 0); if (elf_kind(elftied) == ELF_K_AR) { fprintf(stderr, "%s ERROR: tied file %s is " "an archive. Not allowed. Giving up.\n", glflags.program_name, tied_file_name); return (FAILED); } isknown = is_it_known_elf_header(elftied); if (!isknown) { fprintf(stderr, "Cannot process tied file %s: unknown format\n", tied_file_name); return FAILED; } } while ((elf = elf_begin(fd, cmd, arf)) != 0) { int isknown = is_it_known_elf_header(elf); if (!isknown) { /* not a 64-bit obj either! */ /* dwarfdump is almost-quiet when not an object */ if (archive) { Elf_Arhdr *mem_header = elf_getarhdr(elf); const char *memname = (mem_header && mem_header->ar_name)? mem_header->ar_name:""; /* / and // archive entries are not archive objects, but are not errors. For the ATT/USL type of archive. */ if (strcmp(memname,"/") && strcmp(memname,"//")) { fprintf(stderr, "Can't process archive member " "%d %s of %s: unknown format\n", archmemnum, sanitized(memname), file_name); } } else { fprintf(stderr, "Can't process %s: unknown format\n", file_name); } glflags.check_error = 1; cmd = elf_next(elf); elf_end(elf); continue; } flag_data_pre_allocation(); process_one_file(fd,tiedfd, elf,elftied, file_name, tied_file_name, 0,0, archive, glflags.config_file_data); reset_usage_rate_tag_trees(); flag_data_post_cleanup(); cmd = elf_next(elf); elf_end(elf); archmemnum += 1; } elf_end(arf); if (elftied) { elf_end(elftied); elftied = 0; } return 0; /* normal return. */ } #endif /* DWARF_WITH_LIBELF */ void _dwarf_alloc_tree_counts(Dwarf_Unsigned *allocount, Dwarf_Unsigned *allosum, Dwarf_Unsigned *treecount, Dwarf_Unsigned *treesum, Dwarf_Unsigned *earlydealloccount, Dwarf_Unsigned *earlydeallocsize, Dwarf_Unsigned *unused1, Dwarf_Unsigned *unused2, Dwarf_Unsigned *unused3); /* This intended for dwarfdump testing only by the developers. It's quite odd, really. See regressiontests/scripts/analyzedwalloc.py But handy for some performance analysis. */ static void print_libdwarf_alloc_values(const char *file_name, int argc,char **argv) { Dwarf_Unsigned alloct = 0; Dwarf_Unsigned allosum = 0; Dwarf_Unsigned treect = 0; Dwarf_Unsigned treesum = 0; Dwarf_Unsigned earlydelct = 0; Dwarf_Unsigned earlydelsum = 0; FILE *out = 0; int i = 1; _dwarf_alloc_tree_counts(&alloct, &allosum,&treect,&treesum, &earlydelct,&earlydelsum, 0,0,0); out = fopen("libdwallocs","a"); if (!out) { return; } fprintf(out,"==== %s ",file_name); for ( ; i < argc; ++i) { fprintf(out," %s",argv[i]); } fprintf(out,"\n"); fprintf(out,"%" DW_PR_DSd " ", alloct); fprintf(out,"%" DW_PR_DSd " ", allosum); fprintf(out,"%" DW_PR_DSd " ", treect); fprintf(out,"%" DW_PR_DSd " ", treesum); fprintf(out,"%" DW_PR_DSd " ", earlydelct); fprintf(out,"%" DW_PR_DSd " ", earlydelsum); fprintf(out,"\n"); fclose(out); } /* Iterate through dwarf and print all info. */ int main(int argc, char *argv[]) { const char * file_name = 0; unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int errcode = 0; char *temp_path_buf = 0; unsigned temp_path_buf_len = 0; int res = 0; /* path_source will be DW_PATHSOURCE_basic */ unsigned char path_source = DW_PATHSOURCE_unspecified; #ifdef _WIN32 /* Open the null device used during formatting printing */ if (!esb_open_null_device()) { fprintf(stderr,"dwarfdump: Unable to open null device.\n"); exit(FAILED); } #endif /* _WIN32 */ /* Global flags initialization and esb-buffers construction. */ init_global_flags(); set_checks_off(); uri_data_constructor(); esb_constructor(&esb_short_cu_name); esb_constructor(&esb_long_cu_name); esb_constructor(&dwarf_error_line); #ifdef _WIN32 /* Often we redirect the output to a file, but we have found issues due to the buffering associated with stdout. Some issues were fixed just by the use of 'fflush', but the main issued remained. The stdout stream is buffered, so will only display what's in the buffer after it reaches a newline (or when it's told to). We have a few options to print immediately: - Print to stderr instead using fprintf. - Print to stdout and flush stdout whenever we need it to using fflush. - We can also disable buffering on stdout by using setbuf: setbuf(stdout,NULL); Make stdout unbuffered; this seems to work for all cases. The problem is no longer present. Now, for practical purposes, there is no stderr output, all is stdout. September 2018. */ /* Calling setbuf() with NULL argument, it turns off all buffering for the specified stream. Then writing to and/or reading from the stream will be exactly as directed by the program. But if dwarfdump is used over a network drive, it shows a dramatic slowdown when sending the output to a file. An operation that takes couple of seconds, it was taking few hours. */ /* setbuf(stdout,NULL); */ /* Redirect stderr to stdout. */ dup2(fileno(stdout),fileno(stderr)); #endif /* _WIN32 */ print_version_details(argv[0],FALSE); file_name = process_args(argc, argv); print_args(argc,argv); /* Redirect stdout and stderr to an specific file */ if (glflags.output_file) { if (NULL == freopen(glflags.output_file,"w",stdout)) { fprintf(stderr, "dwarfdump: Unable to redirect output to '%s'\n", glflags.output_file); global_destructors(); exit(FAILED); } dup2(fileno(stdout),fileno(stderr)); /* Record version and arguments in the output file */ print_version_details(argv[0],FALSE); print_args(argc,argv); } /* Allow the user to hide some warnings by using command line options */ { Dwarf_Cmdline_Options wcmd; /* The struct has just one field!. */ wcmd.check_verbose_mode = glflags.gf_check_verbose_mode; dwarf_record_cmdline_options(wcmd); } /* ======= BEGIN FINDING NAMES AND OPENING FDs ===== */ /* The 200+2 etc is more than suffices for the expansion that a MacOS dsym or a GNU debuglink might need, we hope. */ temp_path_buf_len = strlen(file_name)*3 + 200 + 2; temp_path_buf = malloc(temp_path_buf_len); if (!temp_path_buf) { fprintf(stderr, "%s ERROR: Unable to malloc %lu bytes " "for possible path string %s.\n", glflags.program_name,(unsigned long)temp_path_buf_len, file_name); return (FAILED); } temp_path_buf[0] = 0; /* This data scan is to find Elf objects and unknown objects early. If the user asks for libelf with certain options that will rule out handling GNU_debuglink on that object. This does not concern itself with dSYM or debuglink at all. */ res = dwarf_object_detector_path_b(file_name, 0,0, 0,0, &ftype,&endian,&offsetsize,&filesize, &path_source,&errcode); if (res != DW_DLV_OK) { fprintf(stderr, "%s ERROR: Can't open %s\n", glflags.program_name, sanitized(file_name)); global_destructors(); free(temp_path_buf); return (FAILED); } esb_append(&global_file_name,file_name); temp_path_buf[0] = 0; global_basefd = open_a_file(esb_get_string( &global_file_name)); if (global_basefd == -1) { fprintf(stderr, "%s ERROR: can't open.. %s\n", glflags.program_name, esb_get_string(&global_file_name)); global_destructors(); free(temp_path_buf); return (FAILED); } if (esb_string_len(glflags.config_file_tiedpath) > 0) { unsigned tftype = 0; unsigned tendian = 0; unsigned toffsetsize = 0; Dwarf_Unsigned tfilesize = 0; const char * tied_file_name = 0; /* path_source will be DW_PATHSOURCE_basic */ unsigned char tpath_source = 0; temp_path_buf[0] = 0; tied_file_name = esb_get_string(glflags.config_file_tiedpath); /* A genuine tiedpath cannot be dsym or debuglink. */ res = dwarf_object_detector_path_b (tied_file_name, 0,0, 0,0, &tftype,&tendian,&toffsetsize,&tfilesize, &tpath_source,&errcode); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { char *errmsg = dwarf_errmsg_by_number(errcode); fprintf(stderr, "%s ERROR: can't open tied file" ".. %s: %s\n", glflags.program_name, sanitized(tied_file_name), errmsg); } else { fprintf(stderr, "%s ERROR: tied file not an object file '%s'.\n", glflags.program_name, sanitized(tied_file_name)); } global_destructors(); free(temp_path_buf); return (FAILED); } if (ftype != tftype || endian != tendian || offsetsize != toffsetsize) { fprintf(stderr, "%s ERROR: tied file \'%s\' and " "main file \'%s\' not " "the same kind of object!\n", glflags.program_name, sanitized(tied_file_name), esb_get_string(&global_file_name)); free(temp_path_buf); global_destructors(); return (FAILED); } esb_append(&global_tied_file_name,tied_file_name); global_tiedfd = open_a_file(esb_get_string( &global_tied_file_name)); if (global_tiedfd == -1) { fprintf(stderr, "%s ERROR: can't open tied file" "... %s\n", glflags.program_name, sanitized(esb_get_string(&global_tied_file_name))); global_destructors(); free(temp_path_buf); return (FAILED); } } /* ======= end FINDING NAMES AND OPENING FDs ===== */ temp_path_buf[0] = 0; /* ======= BEGIN PROCESSING OBJECT FILES BY TYPE ===== */ if ((ftype == DW_FTYPE_ELF && (glflags.gf_reloc_flag || glflags.gf_header_flag)) || #ifdef HAVE_CUSTOM_LIBELF ftype == DW_FTYPE_CUSTOM_ELF || #endif /* HAVE_CUSTOM_LIBELF */ ftype == DW_FTYPE_ARCHIVE) { #ifdef DWARF_WITH_LIBELF int excode = 0; excode = process_using_libelf(global_basefd, global_tiedfd, esb_get_string(&global_file_name), esb_get_string(&global_tied_file_name), (ftype == DW_FTYPE_ARCHIVE)? TRUE:FALSE); if (excode) { free(temp_path_buf); global_destructors(); flag_data_post_cleanup(); return(excode); } #else /* !DWARF_WITH_LIBELF */ fprintf(stderr, "Can't process %s: archives and " "printing elf headers not supported in this dwarfdump " "--disable-libelf build.\n", file_name); #endif /* DWARF_WITH_LIBELF */ } else if (ftype == DW_FTYPE_ELF || ftype == DW_FTYPE_MACH_O || ftype == DW_FTYPE_PE ) { flag_data_pre_allocation(); close_a_file(global_basefd); global_basefd = -1; close_a_file(global_tiedfd); global_tiedfd = -1; process_one_file(-1,-1, 0,0, esb_get_string(&global_file_name), esb_get_string(&global_tied_file_name), temp_path_buf, temp_path_buf_len, #ifdef DWARF_WITH_LIBELF 0 /* elf_archive */, #endif glflags.config_file_data); flag_data_post_cleanup(); } else { fprintf(stderr, "Can't process %s: unhandled format\n", file_name); } free(temp_path_buf); temp_path_buf = 0; temp_path_buf_len = 0; if (glflags.gf_print_alloc_sums) { print_libdwarf_alloc_values(file_name,argc,argv); } /* ======= END PROCESSING OBJECT FILES BY TYPE ===== */ /* These cleanups only necessary once all objects processed. */ #ifdef HAVE_REGEX if (glflags.search_regex_text) { regfree(glflags.search_re); } #endif /* In case of a serious DWARF error we try to get here, we try not to exit(1) by using print_error() */ check_for_major_errors(); check_for_notes(); flag_data_post_cleanup(); global_destructors(); free(temp_path_buf); /* As the tool have reached this point, it means there are no internal errors and we should return an OKAY condition, regardless if the file being processed has minor errors. */ return OKAY; } void print_any_harmless_errors(Dwarf_Debug dbg) { #define LOCAL_PTR_ARY_COUNT 50 /* We do not need to initialize the local array, libdwarf does it. */ const char *buf[LOCAL_PTR_ARY_COUNT]; unsigned totalcount = 0; unsigned i = 0; unsigned printcount = 0; int res = dwarf_get_harmless_error_list(dbg, LOCAL_PTR_ARY_COUNT,buf, &totalcount); if (res == DW_DLV_NO_ENTRY) { return; } if (totalcount > 0) { printf("\n*** HARMLESS ERROR COUNT: %u ***\n",totalcount); } for (i = 0 ; buf[i]; ++i) { ++printcount; DWARF_CHECK_COUNT(harmless_result,1); DWARF_CHECK_ERROR(harmless_result,buf[i]); } if (totalcount > printcount) { /*harmless_result.checks += (totalcount - printcount); */ DWARF_CHECK_COUNT(harmless_result,(totalcount - printcount)); /*harmless_result.errors += (totalcount - printcount); */ DWARF_ERROR_COUNT(harmless_result,(totalcount - printcount)); } } /* Print a summary of search results */ static void print_search_results(void) { const char *search_type = 0; const char *search_text = 0; if (glflags.search_any_text) { search_type = "any"; search_text = glflags.search_any_text; } else { if (glflags.search_match_text) { search_type = "match"; search_text = glflags.search_match_text; } else { search_type = "regex"; search_text = glflags.search_regex_text; } } fflush(stdout); fflush(stderr); printf("\nSearch type : '%s'\n",search_type); printf("Pattern searched : '%s'\n",search_text); printf("Occurrences Found: %d\n",glflags.search_occurrences); fflush(stdout); } /* This is for dwarf_print_lines() */ static void printf_callback_for_libdwarf(UNUSEDARG void *userdata, const char *data) { printf("%s",sanitized(data)); } int get_address_size_and_max(Dwarf_Debug dbg, Dwarf_Half * size, Dwarf_Addr * max, Dwarf_Error *aerr) { int dres = 0; Dwarf_Half lsize = 4; /* Get address size and largest representable address */ dres = dwarf_get_address_size(dbg,&lsize,aerr); if (dres != DW_DLV_OK) { return dres; } if (max) { *max = (lsize == 8 ) ? 0xffffffffffffffffULL : 0xffffffff; } if (size) { *size = lsize; } return DW_DLV_OK; } /* dbg is often null when dbgtied was passed in. */ static void dbgsetup(Dwarf_Debug dbg,struct dwconf_s *setup_config_file_data) { if (!dbg) { return; } dwarf_set_frame_rule_initial_value(dbg, setup_config_file_data->cf_initial_rule_value); dwarf_set_frame_rule_table_size(dbg, setup_config_file_data->cf_table_entry_count); dwarf_set_frame_cfa_value(dbg, setup_config_file_data->cf_cfa_reg); dwarf_set_frame_same_value(dbg, setup_config_file_data->cf_same_val); dwarf_set_frame_undefined_value(dbg, setup_config_file_data->cf_undefined_val); if (setup_config_file_data->cf_address_size) { dwarf_set_default_address_size(dbg, setup_config_file_data->cf_address_size); } dwarf_set_harmless_error_list_size(dbg,50); } /* Callable at any time, Sets section sizes with the sizes known as of the call. Repeat whenever about to reference a size that might not have been set as of the last call. */ static void set_global_section_sizes(Dwarf_Debug dbg) { dwarf_get_section_max_offsets_c(dbg, &glflags.section_high_offsets_global->debug_info_size, &glflags.section_high_offsets_global->debug_abbrev_size, &glflags.section_high_offsets_global->debug_line_size, &glflags.section_high_offsets_global->debug_loc_size, &glflags.section_high_offsets_global->debug_aranges_size, &glflags.section_high_offsets_global->debug_macinfo_size, &glflags.section_high_offsets_global->debug_pubnames_size, &glflags.section_high_offsets_global->debug_str_size, &glflags.section_high_offsets_global->debug_frame_size, &glflags.section_high_offsets_global->debug_ranges_size, &glflags.section_high_offsets_global->debug_pubtypes_size, &glflags.section_high_offsets_global->debug_types_size, &glflags.section_high_offsets_global->debug_macro_size, &glflags.section_high_offsets_global->debug_str_offsets_size, &glflags.section_high_offsets_global->debug_sup_size, &glflags.section_high_offsets_global->debug_cu_index_size, &glflags.section_high_offsets_global->debug_tu_index_size); } /* Set limits for Ranges Information. The linker may put parts of the text(code) in additional sections such as .init .fini __libc_freeres_fn .rodata __libc_subfreeres __libc_atexit too. */ #define LIKELYNAMESMAX 3 static const char *likely_ns[LIKELYNAMESMAX] = { /* .text is first as it is often the only thing.See below. */ ".init", ".text", ".fini" }; #define ORIGLKLYTEXTINDEX 1 struct likely_names_s { const char * name; int origindex; Dwarf_Unsigned low; Dwarf_Unsigned size; Dwarf_Unsigned end; }; static struct likely_names_s likely_names[LIKELYNAMESMAX]; #if 0 /* FOR DEBUG ONLY */ static void printlnrec(const char *msg,struct likely_names_s * ln, int line,char * fn) { printf("%s: name %s origindx %d " "low 0x%lx " "size 0x%lx " "end 0x%lx " " line %d %s\n",msg, ln->name,ln->origindex, (unsigned long)ln->low, (unsigned long)ln->size, (unsigned long)ln->end,line,fn); } #endif /* 0 */ static int likelycmp(const void *l_in, const void *r_in) { struct likely_names_s *l = (struct likely_names_s *)l_in; struct likely_names_s *r = (struct likely_names_s *)r_in; if (l->low < r->low) { return -1; } if (l->low > r->low ) { return 1; } if (l->end < r->end) { return -1; } if (l->end > r->end) { return 1; } return 0; } /* This is a bit slow, but happens only once for a dbg. It is not as much help as I expected in avoiding line table content CHECK warnings because, so far, those come from .init csu code and the DWARF has no subprogram information nor any high/low pc information at all. */ static int calculate_likely_limits_of_code(Dwarf_Debug dbg, Dwarf_Unsigned *lower, Dwarf_Unsigned *size) { struct likely_names_s * ln = 0; int ct = 0; Dwarf_Unsigned baselow = 0; Dwarf_Unsigned basesize = 0; Dwarf_Unsigned baseend = 0; int lnindex = 0; int lncount = 0; memset(likely_names,0,sizeof(likely_names)); for (ct = 0 ; ct < LIKELYNAMESMAX; ct++) { Dwarf_Unsigned clow = 0; Dwarf_Unsigned csize = 0; int res = 0; Dwarf_Error err = 0; const char *name = likely_ns[ct]; ln = likely_names + lnindex; res = dwarf_get_section_info_by_name(dbg,name, &clow,&csize,&err); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,err); if (ct == ORIGLKLYTEXTINDEX) { return DW_DLV_NO_ENTRY; } continue; } if (res == DW_DLV_NO_ENTRY) { if (ct == ORIGLKLYTEXTINDEX) { return DW_DLV_NO_ENTRY; } continue; } ln->name = name; ln->low = clow; ln->size = csize; ln->end = csize +clow; ln->origindex = ct; if (ct == ORIGLKLYTEXTINDEX) { basesize = csize; baselow = clow; baseend = csize+clow; } ++lnindex; } if (lnindex == 0) { return DW_DLV_NO_ENTRY; } if (lnindex == 1) { *lower = baselow; *size = basesize; return DW_DLV_OK; } lncount = lnindex; qsort(likely_names,lncount,sizeof(struct likely_names_s), likelycmp); ln = likely_names; baselow =ln->low; basesize =ln->size; baseend = ln->end; for (lnindex = 1; lnindexend > baseend) { baseend = ln->end; basesize = (baseend - baselow); } } *lower = baselow; *size = basesize; return DW_DLV_OK; } /* Given a file which is an object type we think we can read, process the dwarf data. */ static int process_one_file( UNUSEDARG int fd, UNUSEDARG int tiedfd, Elf *elf, Elf *tiedelf, const char * file_name, const char * tied_file_name, char * temp_path_buf, unsigned int temp_path_buf_len, #ifdef DWARF_WITH_LIBELF int archive, #endif struct dwconf_s *l_config_file_data) { Dwarf_Debug dbg = 0; Dwarf_Debug dbgtied = 0; int dres = 0; struct Dwarf_Printf_Callback_Info_s printfcallbackdata; Dwarf_Half elf_address_size = 0; /* Target pointer size */ Dwarf_Error onef_err = 0; const char *title = 0; unsigned char path_source = 0; int localerrno = 0; /* If using a tied file group number should be 2 DW_GROUPNUMBER_DWO but in a dwp or separate-split-dwarf object then 0 will find the .dwo data automatically. */ if (elf) { title = "dwarf_elf_init_b fails exit dwarfdump"; dres = dwarf_elf_init_b(elf, DW_DLC_READ, glflags.group_number, NULL, NULL, &dbg, &onef_err); if (dres == DW_DLV_OK) { int pres = 0; pres = dwarf_add_file_path(dbg,file_name,&onef_err); if (pres != DW_DLV_OK) { print_error(dbg,"Unable to add file path " "to object file data", pres, onef_err); } } } else { /* This will go for the real main file, whether an underlying dSYM or via debuglink or if those find nothing then the original. */ char *tb = temp_path_buf; unsigned tblen = temp_path_buf_len; title = "dwarf_init_path_dl fails exit dwarfdump"; if (glflags.gf_no_follow_debuglink) { tb = 0; tblen = 0; } dres = dwarf_init_path_dl(file_name, tb,tblen, DW_DLC_READ, glflags.group_number, NULL, NULL, &dbg, glflags.gf_global_debuglink_paths, glflags.gf_global_debuglink_count, &path_source, 0,0,0, &onef_err); } if (dres == DW_DLV_NO_ENTRY) { if (glflags.group_number > 0) { printf("No DWARF information present in %s " "for section group %d \n", file_name,glflags.group_number); } else { printf("No DWARF information present in %s\n",file_name); } return dres; } if (dres == DW_DLV_ERROR) { /* Prints error, cleans up Dwarf_Error data. Never returns*/ print_error_and_continue(dbg, title,dres,onef_err); DROP_ERROR_INSTANCE(dbg,dres,onef_err); return DW_DLV_ERROR; } if (path_source == DW_PATHSOURCE_dsym) { printf("Filename by dSYM is %s\n", sanitized(temp_path_buf)); } else if (path_source == DW_PATHSOURCE_debuglink) { printf("Filename by debuglink is %s\n", sanitized(temp_path_buf)); glflags.gf_gnu_debuglink_flag = TRUE; } if (tied_file_name && strlen(tied_file_name)) { if (tiedelf) { dres = dwarf_elf_init_b(tiedelf, DW_DLC_READ, DW_GROUPNUMBER_BASE, NULL, NULL, &dbgtied, &onef_err); if (dres == DW_DLV_OK) { int pres = 0; pres = dwarf_add_file_path(dbgtied, tied_file_name,&onef_err); if (pres != DW_DLV_ERROR) { /* Prints error, cleans up Dwarf_Error data if any. Never returns */ print_error(dbg, "Unable to add tied file name " "to tied file", pres, onef_err); } } } else { /* The tied file we define as group 1, BASE. Cannot follow debuglink or dSYM, is a tied file */ dres = dwarf_init_path(tied_file_name, 0,0, /* ignore dSYM & debuglink */ DW_DLC_READ, DW_GROUPNUMBER_BASE, 0,0, &dbgtied, 0,0,0, &onef_err); /* path_source = DW_PATHSOURCE_basic; */ } if (dres == DW_DLV_NO_ENTRY) { printf("No DWARF information present in tied file: %s\n", tied_file_name); return dres; } if (dres == DW_DLV_ERROR) { /* Prints error, cleans up Dwarf_Error data. Never returns*/ print_error(dbg, "dwarf_elf_init on tied_file", dres, onef_err); } } memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); printfcallbackdata.dp_fptr = printf_callback_for_libdwarf; dwarf_register_printf_callback(dbg,&printfcallbackdata); if (dbgtied) { dwarf_register_printf_callback(dbgtied,&printfcallbackdata); } memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); dbgsetup(dbg,l_config_file_data); dbgsetup(dbgtied,l_config_file_data); dres = get_address_size_and_max(dbg,&elf_address_size,0, &onef_err); if (dres != DW_DLV_OK) { print_error(dbg,"Unable to read address" " size so unable to continue", dres,onef_err); } if (glflags.gf_check_tag_attr || glflags.gf_print_usage_tag_attr) { dres = build_attr_form_base_tree(&localerrno); if (dres != DW_DLV_OK) { simple_err_return_msg_either_action(dres, "ERROR: Failed to initialize attribute/form" " tables properly"); } } #ifdef DWARF_WITH_LIBELF if (archive) { Elf_Arhdr *mem_header = elf_getarhdr(elf); const char *memname = (mem_header && mem_header->ar_name)? mem_header->ar_name:""; printf("\narchive member %s\n",sanitized(memname)); } #endif /* DWARF_WITH_LIBELF */ /* Ok for dbgtied to be NULL. */ dres = dwarf_set_tied_dbg(dbg,dbgtied,&onef_err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_set_tied_dbg() failed", dres, onef_err); } /* Get .text and .debug_ranges info if in check mode */ if (glflags.gf_do_check_dwarf) { Dwarf_Addr lower = 0; Dwarf_Addr upper = 0; Dwarf_Unsigned size = 0; Dwarf_Debug dbg_with_code = dbg; int res = 0; if (dbgtied) { /* Assuming tied is exectuable main is dwo/dwp */ dbg_with_code = dbgtied; } res = calculate_likely_limits_of_code(dbg_with_code, &lower,&size); upper = lower + size; /* Set limits for Ranges Information. Some objects have CUs for startup code and the expanded range here turns out not to actually help. */ if (res == DW_DLV_OK && glflags.pRangesInfo) { SetLimitsBucketGroup(glflags.pRangesInfo,lower,upper); AddEntryIntoBucketGroup(glflags.pRangesInfo, 1, lower,lower, upper, ".text", TRUE); } /* Build section information linkonce is an SNR thing, we*/ build_linkonce_info(dbg); } if (glflags.gf_header_flag && elf) { #ifdef DWARF_WITH_LIBELF int res = 0; Dwarf_Error err = 0; res = print_object_header(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing Elf object Header had a problem.", res,err); DROP_ERROR_INSTANCE(dbg,res,err); } #endif /* DWARF_WITH_LIBELF */ } if (glflags.gf_section_groups_flag) { int res = 0; Dwarf_Error err = 0; res = print_section_groups_data(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing section groups had a problem.", res,err); DROP_ERROR_INSTANCE(dbg,res,err); } /* If groupnum > 2 this turns off some of the gf_flags here so we don't print section names of things we do not want to print. */ update_section_flags_per_groups(dbg); } reset_overall_CU_error_data(); if (glflags.gf_info_flag || glflags.gf_line_flag || glflags.gf_types_flag || glflags.gf_check_macros || glflags.gf_macinfo_flag || glflags.gf_macro_flag || glflags.gf_cu_name_flag || glflags.gf_search_is_on || glflags.gf_producer_children_flag) { Dwarf_Error err = 0; int res = 0; reset_overall_CU_error_data(); res = print_infos(dbg,TRUE,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing .debug_info had a problem.", res,err); DROP_ERROR_INSTANCE(dbg,res,err); } reset_overall_CU_error_data(); res = print_infos(dbg,FALSE,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing .debug_types had a problem.", res,err); DROP_ERROR_INSTANCE(dbg,res,err); } { set_global_section_sizes(dbg); /* The statistics are for ALL of the DWARF5 (and DWARF4 with .debug_macro) across all CUs. */ if (macro_check_tree) { /* debug_macro_size is to check the section end */ print_macrocheck_statistics("DWARF5 .debug_macro", ¯o_check_tree, /* DWARF5 */ TRUE, glflags.section_high_offsets_global-> debug_macro_size, &err); } } if (glflags.gf_check_macros) { if (macinfo_check_tree) { /* debug_macinfo_size is to check the section end */ print_macrocheck_statistics("DWARF2 .debug_macinfo", &macinfo_check_tree, /* DWARF5 */ FALSE, glflags.section_high_offsets_global-> debug_macinfo_size, &err); } } clear_macrocheck_statistics(¯o_check_tree); clear_macrocheck_statistics(&macinfo_check_tree); } if (glflags.gf_gdbindex_flag) { int res = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); /* By definition if gdb_index is present then "cu" and "tu" will not be. And vice versa. */ res = print_gdb_index(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the gdb index section had a problem " ,res,err); } res = print_debugfission_index(dbg,"cu",&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the debugfission cu section " "had a problem " ,res,err); } res = print_debugfission_index(dbg,"tu",&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the debugfission tu section " "had a problem " ,res,err); } } if (glflags.gf_pubnames_flag) { int res = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); res = print_pubnames(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing pubnames data had a problem ",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_loc_flag) { int locres = 0; Dwarf_Error locerr = 0; reset_overall_CU_error_data(); locres = print_locs(dbg,&locerr); if (locres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing location data had a problem ", locres,locerr); } } if (glflags.gf_abbrev_flag) { Dwarf_Error err = 0; int res = 0; reset_overall_CU_error_data(); res = print_abbrevs(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the .debug_abbrev section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_string_flag) { Dwarf_Error err = 0; int res = 0; reset_overall_CU_error_data(); res = print_strings(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the .debug_str section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_aranges_flag) { Dwarf_Error err = 0; int res = 0; reset_overall_CU_error_data(); res = print_aranges(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the aranges section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_ranges_flag) { int res = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); res = print_ranges(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the ranges section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_print_raw_loclists) { int res = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); res = print_raw_all_loclists(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the raw .debug_loclists section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_print_raw_rnglists) { int res = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); res = print_raw_all_rnglists(dbg,&err); if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing the raw .debug_rnglists section" " had a problem.",res,err); DROP_ERROR_INSTANCE(dbg,res,err); } } if (glflags.gf_frame_flag || glflags.gf_eh_frame_flag) { int sres = 0; Dwarf_Error err = 0; int want_eh = 0; /* These three shared .eh_frame and .debug_frame as they are about the DIEs, not about frames. */ Dwarf_Die cu_die_for_print_frames = 0; void *map_lowpc_to_name = 0; void *lowpcSet = 0; reset_overall_CU_error_data(); if (glflags.gf_frame_flag) { want_eh = 0; sres = print_frames(dbg,want_eh, l_config_file_data, &cu_die_for_print_frames, &map_lowpc_to_name, &lowpcSet, &err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing standard frame data had a problem.", sres,err); DROP_ERROR_INSTANCE(dbg,sres,err); } } if (glflags.gf_eh_frame_flag) { want_eh = 1; sres = print_frames(dbg, want_eh, l_config_file_data, &cu_die_for_print_frames, &map_lowpc_to_name, &lowpcSet, &err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing eh frame data had a problem.",sres, err); DROP_ERROR_INSTANCE(dbg,sres,err); } } addr_map_destroy(lowpcSet); addr_map_destroy(map_lowpc_to_name); if (cu_die_for_print_frames) { dwarf_dealloc_die(cu_die_for_print_frames); } } if (glflags.gf_static_func_flag) { int sres = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); sres = print_static_funcs(dbg,&err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing SGI static funcs had a problem.",sres,err); DROP_ERROR_INSTANCE(dbg,sres,err); } } if (glflags.gf_static_var_flag) { int sres = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); sres = print_static_vars(dbg,&err); if (sres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing SGI static vars had a problem.",sres,err); DROP_ERROR_INSTANCE(dbg,sres,err); } } /* DWARF_PUBTYPES is the standard typenames dwarf section. SGI_TYPENAME is the same concept but is SGI specific ( it was defined 10 years before dwarf pubtypes). */ if (glflags.gf_pubtypes_flag) { Dwarf_Error err = 0; int tres = 0; reset_overall_CU_error_data(); tres = print_types(dbg, DWARF_PUBTYPES,&err); if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing pubtypes had a problem.",tres,err); DROP_ERROR_INSTANCE(dbg,tres,err); } reset_overall_CU_error_data(); tres = print_types(dbg, SGI_TYPENAME,&err); if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing SGI typenames had a problem.",tres,err); DROP_ERROR_INSTANCE(dbg,tres,err); } } if (glflags.gf_weakname_flag) { Dwarf_Error err = 0; int res3 = 0; reset_overall_CU_error_data(); res3 = print_weaknames(dbg, &err); if (res3 == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing weaknames had a problem.",res3,err); DROP_ERROR_INSTANCE(dbg,res3,err); } } if (glflags.gf_reloc_flag && elf) { #ifdef DWARF_WITH_LIBELF int leres = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); leres = print_relocinfo(dbg,&err); if (leres == DW_DLV_ERROR) { print_error_and_continue(dbg, "printing relocinfo had a problem.",leres,err); DROP_ERROR_INSTANCE(dbg,leres,err); } #else reset_overall_CU_error_data(); #endif /* DWARF_WITH_LIBELF */ } if (glflags.gf_debug_names_flag) { int nres = 0; Dwarf_Error err = 0; reset_overall_CU_error_data(); nres = print_debug_names(dbg,&err); if (nres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print .debug_names section failed", nres, err); DROP_ERROR_INSTANCE(dbg,nres,err); } } /* Print search results */ if (glflags.gf_search_print_results && glflags.gf_search_is_on) { /* No dwarf errors possible in this function. */ print_search_results(); } /* The right time to do this is unclear. But we need to do it. */ if (glflags.gf_check_harmless) { /* No dwarf errors possible in this function. */ print_any_harmless_errors(dbg); } /* Print error report only if errors have been detected Print error report if the -kd option. No errors possible in this function. */ print_checks_results(); /* Print the detailed attribute usage space and free the attributes_encoding data allocated. Option -kE Also prints the attr/formclass/form reports from attr_form.c See build_attr_form_base() call above and record_attr_form_use() in print_die.c */ if (glflags.gf_check_attr_encoding ) { int ares = 0; Dwarf_Error aerr = 0; ares = print_attributes_encoding(dbg,&aerr); if (ares == DW_DLV_ERROR) { print_error_and_continue(dbg, "print attributes encoding failed", ares, aerr); DROP_ERROR_INSTANCE(dbg,ares,aerr); } } /* Print the tags and attribute usage -ku or -kuf */ if (glflags.gf_print_usage_tag_attr) { int tres = 0; Dwarf_Error err = 0; tres = print_tag_attributes_usage(); if (tres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print tag attributes usage failed", tres, err); DROP_ERROR_INSTANCE(dbg,tres,err); } } if (glflags.gf_print_str_offsets) { /* print the .debug_str_offsets section, if any. */ int lres = 0; Dwarf_Error err = 0; lres = print_str_offsets_section(dbg,&err); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print .debug_str_offsets failed", lres, err); DROP_ERROR_INSTANCE(dbg,lres,err); } } /* prints nothing unless section .gnu_debuglink is present. Lets print for a few critical sections. */ if (glflags.gf_gnu_debuglink_flag) { int lres = 0; Dwarf_Error err = 0; lres = print_gnu_debuglink(dbg,&err); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print gnu_debuglink data failed", lres, err); DROP_ERROR_INSTANCE(dbg,lres,err); } } if (glflags.gf_debug_gnu_flag) { int lres = 0; Dwarf_Error err = 0; lres = print_debug_gnu(dbg,&err); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print .debug_gnu* section failed", lres, err); DROP_ERROR_INSTANCE(dbg,lres,err); } } if (glflags.gf_debug_sup_flag) { int lres = 0; Dwarf_Error err = 0; lres = print_debug_sup(dbg,&err); if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "print .debug_sup* section failed", lres, err); DROP_ERROR_INSTANCE(dbg,lres,err); } } if (glflags.gf_debug_addr_missing) { printf("\nERROR: At some point " "the .debug_addr section was needed but missing, " "meaning some frame information was missing " "relevant function names. See the dwarfdump " " option --file-tied=."); glflags.gf_count_major_errors++; } if (glflags.gf_error_code_search_by_address) { printf("\nERROR: At some point " "There was some data corruption in frame data " "so at least the following error occurred: " "%s .\n", dwarf_errmsg_by_number( glflags.gf_error_code_search_by_address)); glflags.gf_count_major_errors++; } /* Could finish dbg first. Either order ok. */ if (dbgtied) { dres = dwarf_finish(dbgtied,&onef_err); if (dres != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_finish failed on tied dbg", dres, onef_err); DROP_ERROR_INSTANCE(dbg,dres,onef_err); } dbgtied = 0; } groups_restore_subsidiary_flags(); dres = dwarf_finish(dbg, &onef_err); if (dres != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_finish failed", dres, onef_err); DROP_ERROR_INSTANCE(dbg,dres,onef_err); dbg = 0; } printf("\n"); #ifdef DWARF_WITH_LIBELF clean_up_syms_malloc_data(); #endif /* DWARF_WITH_LIBELF */ destroy_attr_form_trees(); destruct_abbrev_array(); esb_close_null_device(); release_range_array_info(); helpertree_clear_statistics(&helpertree_offsets_base_info); helpertree_clear_statistics(&helpertree_offsets_base_types); return 0; } /* Generic constants for debugging */ #define DUMP_RANGES_INFO 1 /* Dump RangesInfo Table. */ /* Dump Location (.debug_loc) Info. */ #define DUMP_LOCATION_SECTION_INFO 2 /* Dump Ranges (.debug_ranges) Info. */ #define DUMP_RANGES_SECTION_INFO 3 #define DUMP_LINKONCE_INFO 4 /* Dump Linkonce Table. */ #define DUMP_VISITED_INFO 5 /* Dump Visited Info. */ /* ==============START of dwarfdump error print functions. */ int simple_err_return_msg_either_action(int res,const char *msg) { const char *etype = "No-entry"; if (res == DW_DLV_ERROR) { etype="Major error"; } glflags.gf_count_major_errors++; printf("%s fails. %s\n",msg,etype); return res; } int simple_err_return_action(int res,const char *msg) { if (res == DW_DLV_ERROR) { const char *etype = "Major error"; glflags.gf_count_major_errors++; printf("%s %s\n",msg, etype); } return res; } int simple_err_only_return_action(int res,const char *msg) { const char *etype="Major error"; /*const char *msg = "\nERROR: dwarf_get_address_size() fails."; */ glflags.gf_count_major_errors++; printf("%s %s\n",msg,etype); return res; } /* ARGSUSED */ static void print_error_maybe_continue(UNUSEDARG Dwarf_Debug dbg, const char * msg, int dwarf_ret_val, Dwarf_Error lerr, Dwarf_Bool do_continue) { unsigned long realmajorerr = glflags.gf_count_major_errors; printf("\n"); if (dwarf_ret_val == DW_DLV_ERROR) { /* We do not dwarf_dealloc the error here. */ char * errmsg = dwarf_errmsg(lerr); /* We now (April 2016) guarantee the error number is in the error string so we do not need to print the dwarf_errno() value to show the number. */ if (do_continue) { printf( "%s ERROR: %s: %s. " "Attempting to continue.\n", glflags.program_name, msg, errmsg); } else { printf( "%s ERROR: %s: %s\n", glflags.program_name, msg, errmsg); } } else if (dwarf_ret_val == DW_DLV_NO_ENTRY) { printf("%s NO ENTRY: %s: \n", glflags.program_name, msg); } else if (dwarf_ret_val == DW_DLV_OK) { printf("%s: %s \n", glflags.program_name, msg); } else { printf("%s InternalError: %s: code %d\n", glflags.program_name, msg, dwarf_ret_val); } /* Display compile unit name */ PRINT_CU_INFO(); glflags.gf_count_major_errors = realmajorerr; } void print_error(Dwarf_Debug dbg, const char * msg, int dwarf_ret_val, Dwarf_Error lerr) { print_error_maybe_continue(dbg,msg,dwarf_ret_val,lerr,FALSE); glflags.gf_count_major_errors++; if (dwarf_ret_val == DW_DLV_ERROR) { Dwarf_Error ignored_err = 0; /* If dbg was never initialized this still cleans up the Error data. */ DROP_ERROR_INSTANCE(dbg,dwarf_ret_val,lerr); dwarf_finish(dbg, &ignored_err); check_for_major_errors(); check_for_notes(); } global_destructors(); flag_data_post_cleanup(); destroy_attr_form_trees(); exit(FAILED); } /* ARGSUSED */ void print_error_and_continue(Dwarf_Debug dbg, const char * msg, int dwarf_ret_val, Dwarf_Error lerr) { glflags.gf_count_major_errors++; print_error_maybe_continue(dbg, msg,dwarf_ret_val,lerr,TRUE); } /* ==============END of dwarfdump error print functions. */ static Dwarf_Bool is_a_string_form(int sf) { switch(sf){ case DW_FORM_string: case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: case DW_FORM_GNU_str_index: case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: case DW_FORM_strp: case DW_FORM_line_strp: /* There is some hope we can actually get the string itself, depending on other factors */ return TRUE; } /* Nope. No string is possible */ return FALSE; } /* Always sets the return argument *should_skip, whether it returns DW_DLV_NO_ENTRY or DW_DLV_ERROR or DW_DLV_OK. determines if the CU should be skipped as the DW_AT_name of the CU does not match the command-line-supplied cu name. The two callers ignore the return value. This suppresses any errors it finds, no Dwarf_Error is lost and none is returned. */ int should_skip_this_cu(Dwarf_Debug dbg, Dwarf_Bool*should_skip, Dwarf_Die cu_die) { Dwarf_Half tag = 0; Dwarf_Attribute attrib = 0; Dwarf_Half theform = 0; Dwarf_Error skperr; int dares = 0; int tres = 0; int fres = 0; tres = dwarf_tag(cu_die, &tag, &skperr); if (tres != DW_DLV_OK) { print_error_and_continue(dbg, "ERROR: " "Cannot get the TAG of the cu_die to check " " if we should skip this CU or not.", tres, skperr); *should_skip = FALSE; DROP_ERROR_INSTANCE(dbg,tres,skperr); return tres; } dares = dwarf_attr(cu_die, DW_AT_name, &attrib, &skperr); if (dares != DW_DLV_OK) { print_error_and_continue(dbg, "should skip this cu? " " cu die has no DW_AT_name attribute!", dares, skperr); *should_skip = FALSE; DROP_ERROR_INSTANCE(dbg,dares,skperr); return dares; } fres = dwarf_whatform(attrib, &theform, &skperr); if (fres == DW_DLV_OK) { if (is_a_string_form(theform)) { char * temps = 0; int sres = dwarf_formstring(attrib, &temps, &skperr); if (sres == DW_DLV_OK) { char *lcun = esb_get_string(glflags.cu_name); char *p = temps; if (lcun[0] != '/') { p = strrchr(temps, '/'); if (p == NULL) { p = temps; } else { p++; } } /* Ignore case if Windows */ #if _WIN32 if (stricmp(lcun, p)) { /* skip this cu. */ dwarf_dealloc_attribute(attrib); *should_skip = TRUE; return DW_DLV_OK; } #else if (strcmp(lcun, p)) { /* skip this cu. */ dwarf_dealloc_attribute(attrib); *should_skip = TRUE; return DW_DLV_OK; } #endif /* _WIN32 */ } else if (sres == DW_DLV_ERROR) { struct esb_s m; int dwarf_names_print_on_error = 1; dwarf_dealloc_attribute(attrib); esb_constructor(&m); esb_append(&m,"In determining if we should " "skip this CU dwarf_formstring " "gets an error on form "); esb_append(&m,get_FORM_name(theform, dwarf_names_print_on_error)); esb_append(&m,"."); print_error_and_continue(dbg, esb_get_string(&m), sres, skperr); *should_skip = FALSE; esb_destructor(&m); return sres; } else { /* DW_DLV_NO_ENTRY on the string itself */ dwarf_dealloc_attribute(attrib); *should_skip = FALSE; return sres; } } } else if (fres == DW_DLV_ERROR) { /* DW_DLV_ERROR */ print_error_and_continue(dbg, "dwarf_whatform failed on a CU_die when" " attempting to determine if this CU should" " be skipped.", fres, skperr); } /* else DW_DLV_NO_ENTRY */ dwarf_dealloc_attribute(attrib); *should_skip = FALSE; return fres; } /* Returns the cu of the CUn the name fields when it can, else a no-entry else DW_DLV_ERROR. */ int get_cu_name(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, char * *short_name, char * *long_name, Dwarf_Error *lerr) { Dwarf_Attribute name_attr = 0; int ares = 0; ares = dwarf_attr(cu_die, DW_AT_name, &name_attr, lerr); if (ares == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_attr fails on DW_AT_name on the CU die", ares, *lerr); return ares; } else if (ares == DW_DLV_NO_ENTRY) { *short_name = ""; *long_name = ""; } else { /* DW_DLV_OK */ /* The string return is valid until the next call to this function; so if the caller needs to keep the returned string, the string must be copied (makename()). */ char *filename = 0; esb_empty_string(&esb_long_cu_name); ares = get_attr_value(dbg, DW_TAG_compile_unit, cu_die, /* die_indent */ 0, dieprint_cu_offset, name_attr, NULL, 0, &esb_long_cu_name, 0 /*show_form_used*/,0 /* verbose */,lerr); if (ares != DW_DLV_OK) { *short_name = ""; *long_name = ""; return ares; } *long_name = esb_get_string(&esb_long_cu_name); /* Generate the short name (filename) */ filename = strrchr(*long_name,'/'); if (!filename) { filename = strrchr(*long_name,'\\'); } if (filename) { ++filename; } else { filename = *long_name; } esb_empty_string(&esb_short_cu_name); esb_append(&esb_short_cu_name,filename); *short_name = esb_get_string(&esb_short_cu_name); dwarf_dealloc_attribute(name_attr); } return ares; } /* Returns the producer of the CU Caller must ensure producernameout is a valid, constructed, empty esb_s instance before calling. */ int get_producer_name(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, struct esb_s *producernameout, Dwarf_Error *err) { Dwarf_Attribute producer_attr = 0; int ares = 0; /* See also glflags.c for "" as default producer string */ if (!cu_die) { glflags.gf_count_major_errors++; esb_append(producernameout, "\"\""); return DW_DLV_NO_ENTRY; } ares = dwarf_attr(cu_die, DW_AT_producer, &producer_attr, err); if (ares == DW_DLV_ERROR) { glflags.gf_count_major_errors++; esb_append(producernameout, "\"\""); return ares; } if (ares == DW_DLV_NO_ENTRY) { /* We add extra quotes so it looks more like the names for real producers that get_attr_value produces. */ /* Same string is in glflags.c */ esb_append(producernameout, "\"\""); dwarf_dealloc_attribute(producer_attr); return ares; } /* DW_DLV_OK */ ares = get_attr_value(dbg, DW_TAG_compile_unit, cu_die,/* die_indent*/ 0, dieprint_cu_offset, producer_attr, NULL, 0, producernameout, 0 /*show_form_used*/,0 /* verbose */,err); dwarf_dealloc_attribute(producer_attr); return ares; } void print_secname(Dwarf_Debug dbg,const char *secname) { if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,secname, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } } /* We'll check for errors when checking. print only if printing (as opposed to checking). */ static int print_gnu_debuglink(Dwarf_Debug dbg, Dwarf_Error *err) { int res = 0; char * name = 0; unsigned char *crcbytes = 0; char * link_path = 0; unsigned link_path_len = 0; unsigned buildidtype = 0; char *buildidowner = 0; unsigned char *buildidbyteptr = 0; unsigned buildidlength = 0; char **paths_array = 0; unsigned paths_array_length = 0; res = dwarf_gnu_debuglink(dbg, &name, &crcbytes, &link_path, /* free this */ &link_path_len, &buildidtype, &buildidowner, &buildidbyteptr, &buildidlength, &paths_array, /* free this */ &paths_array_length, err); if (res == DW_DLV_NO_ENTRY) { return res; } else if (res == DW_DLV_ERROR) { print_secname(dbg,".gnu_debuglink"); return res; } if (crcbytes) { print_secname(dbg,".gnu_debuglink"); /* Done with error checking, so print if we are printing. */ if (glflags.gf_do_print_dwarf) { printf(" Debuglink name : %s",sanitized(name)); { unsigned char *crc = 0; unsigned char *end = 0; crc = crcbytes; end = crcbytes +4; printf(" crc 0X: "); for (; crc < end; crc++) { printf("%02x ", *crc); } } printf("\n"); if (link_path_len) { printf(" Debuglink target: %s\n", sanitized(link_path)); } } } if (buildidlength) { print_secname(dbg,".note.gnu.build-id"); if (glflags.gf_do_print_dwarf) { printf(" Build-id type : %u\n", buildidtype); printf(" Build-id ownername: %s\n", sanitized(buildidowner)); printf(" Build-id length : %u\n",buildidlength); printf(" Build-id : "); { const unsigned char *cur = 0; const unsigned char *end = 0; cur = buildidbyteptr; end = cur + buildidlength; for (; cur < end; cur++) { printf("%02x", (unsigned char)*cur); } } printf("\n"); } } if (paths_array_length) { unsigned i = 0; printf(" Possible " ".gnu_debuglink/.note.gnu.build-id pathnames for\n"); printf(" an alternate object file with more detailed " "DWARF\n"); for ( ; i < paths_array_length; ++i) { char *path = paths_array[i]; char outpath[2000]; unsigned long outpathlen = sizeof(outpath); unsigned int ftype = 0; unsigned int endian = 0; unsigned int offsetsize = 0; Dwarf_Unsigned filesize = 0; int errcode = 0; printf(" [%u] %s\n",i,sanitized(path)); res = dwarf_object_detector_path(path, outpath,outpathlen,&ftype,&endian,&offsetsize, &filesize, &errcode); if (res == DW_DLV_NO_ENTRY) { if (glflags.verbose) { printf(" file above does not exist\n"); } continue; } if (res == DW_DLV_ERROR) { printf(" access attempt of the above leads" " to error %s\n", dwarf_errmsg_by_number(errcode)); continue; } switch(ftype) { case DW_FTYPE_ELF: printf(" file above is an Elf object\n"); break; case DW_FTYPE_MACH_O: printf(" file above is a Mach-O object\n"); break; case DW_FTYPE_PE: printf(" file above is a PE object"); break; case DW_FTYPE_CUSTOM_ELF: printf(" file above is a custom elf object"); break; case DW_FTYPE_ARCHIVE: if (glflags.verbose) { printf(" file above is an archive " "so ignore it.\n"); } continue; default: if (glflags.verbose) { printf(" file above is not" " any object type we recognize\n"); } continue; } } printf("\n"); } free(link_path); free(paths_array); return DW_DLV_OK; } /* GCC linkonce names */ char *lo_text = ".text."; /*".gnu.linkonce.t.";*/ char *lo_debug_abbr = ".gnu.linkonce.wa."; char *lo_debug_aranges = ".gnu.linkonce.wr."; char *lo_debug_frame_1 = ".gnu.linkonce.wf."; char *lo_debug_frame_2 = ".gnu.linkonce.wF."; char *lo_debug_info = ".gnu.linkonce.wi."; char *lo_debug_line = ".gnu.linkonce.wl."; char *lo_debug_macinfo = ".gnu.linkonce.wm."; char *lo_debug_loc = ".gnu.linkonce.wo."; char *lo_debug_pubnames = ".gnu.linkonce.wp."; char *lo_debug_ranges = ".gnu.linkonce.wR."; char *lo_debug_str = ".gnu.linkonce.ws."; /* SNC compiler/linker linkonce names */ char *nlo_text = ".text."; char *nlo_debug_abbr = ".debug.wa."; char *nlo_debug_aranges = ".debug.wr."; char *nlo_debug_frame_1 = ".debug.wf."; char *nlo_debug_frame_2 = ".debug.wF."; char *nlo_debug_info = ".debug.wi."; char *nlo_debug_line = ".debug.wl."; char *nlo_debug_macinfo = ".debug.wm."; char *nlo_debug_loc = ".debug.wo."; char *nlo_debug_pubnames = ".debug.wp."; char *nlo_debug_ranges = ".debug.wR."; char *nlo_debug_str = ".debug.ws."; /* Build linkonce section information */ void build_linkonce_info(Dwarf_Debug dbg) { int nCount = 0; int section_index = 0; int res = 0; static char **linkonce_names[] = { &lo_text, /* .text */ &nlo_text, /* .text */ &lo_debug_abbr, /* .debug_abbr */ &nlo_debug_abbr, /* .debug_abbr */ &lo_debug_aranges, /* .debug_aranges */ &nlo_debug_aranges, /* .debug_aranges */ &lo_debug_frame_1, /* .debug_frame */ &nlo_debug_frame_1, /* .debug_frame */ &lo_debug_frame_2, /* .debug_frame */ &nlo_debug_frame_2, /* .debug_frame */ &lo_debug_info, /* .debug_info */ &nlo_debug_info, /* .debug_info */ &lo_debug_line, /* .debug_line */ &nlo_debug_line, /* .debug_line */ &lo_debug_macinfo, /* .debug_macinfo */ &nlo_debug_macinfo, /* .debug_macinfo */ &lo_debug_loc, /* .debug_loc */ &nlo_debug_loc, /* .debug_loc */ &lo_debug_pubnames, /* .debug_pubnames */ &nlo_debug_pubnames, /* .debug_pubnames */ &lo_debug_ranges, /* .debug_ranges */ &nlo_debug_ranges, /* .debug_ranges */ &lo_debug_str, /* .debug_str */ &nlo_debug_str, /* .debug_str */ NULL }; const char *section_name = NULL; Dwarf_Addr section_addr = 0; Dwarf_Unsigned section_size = 0; Dwarf_Error error = 0; int nIndex = 0; nCount = dwarf_get_section_count(dbg); /* Ignore section with index=0 */ for (section_index = 1; section_index < nCount; ++section_index) { res = dwarf_get_section_info_by_index(dbg,section_index, §ion_name, §ion_addr, §ion_size, &error); if (res == DW_DLV_OK) { for (nIndex = 0; linkonce_names[nIndex]; ++nIndex) { if (section_name == strstr(section_name, *linkonce_names[nIndex])) { /* Insert only linkonce sections */ AddEntryIntoBucketGroup(glflags.pLinkonceInfo, section_index, section_addr,section_addr, section_addr + section_size, section_name, TRUE); break; } } } } if (dump_linkonce_info) { PrintBucketGroup(glflags.pLinkonceInfo,TRUE); } } /* Check for specific TAGs and initialize some information used by '-k' options */ void tag_specific_globals_setup(Dwarf_Debug dbg, Dwarf_Half val,int die_indent_level) { switch (val) { /* DW_TAG_type unit will not have addresses */ /* DW_TAG_skeleton unit will have addresses, but likely no children. But they are useful as marking glflags.seen_CU TRUE is useful */ case DW_TAG_partial_unit: case DW_TAG_compile_unit: case DW_TAG_type_unit: case DW_TAG_skeleton_unit: /* To help getting the compile unit name */ glflags.seen_CU = TRUE; /* If we are checking line information, build the table containing the pairs LowPC and HighPC */ if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations) { Dwarf_Debug td = 0; if (!dbg) { ResetBucketGroup(glflags.pRangesInfo); } else { /* Only returns DW_DLV_OK */ dwarf_get_tied_dbg(dbg,&td,0); /* With a tied-dbg we do not have detailed address ranges, so do not reset the single .text-size bucket group */ if (!td) { ResetBucketGroup(glflags.pRangesInfo); } } } /* The following flag indicate that only low_pc and high_pc values found in DW_TAG_subprograms are going to be considered when building the address table used to check ranges, lines, etc */ glflags.need_PU_valid_code = TRUE; break; case DW_TAG_subprogram: /* Keep track of a PU */ if (die_indent_level == 1) { /* A DW_TAG_subprogram can be nested, when is used to declare a member function for a local class; process the DIE only if we are at level zero in the DIEs tree */ glflags.seen_PU = TRUE; glflags.seen_PU_base_address = FALSE; glflags.seen_PU_high_address = FALSE; glflags.PU_name[0] = 0; glflags.need_PU_valid_code = TRUE; } break; } } /* Print CU basic information but use the local DIE for the offsets. */ void PRINT_CU_INFO(void) { Dwarf_Unsigned loff = glflags.DIE_offset; Dwarf_Unsigned goff = glflags.DIE_overall_offset; char lbuf[50]; char hbuf[50]; if (glflags.current_section_id == DEBUG_LINE || glflags.current_section_id == DEBUG_FRAME || glflags.current_section_id == DEBUG_FRAME_EH_GNU || glflags.current_section_id == DEBUG_ARANGES || glflags.current_section_id == DEBUG_MACRO || glflags.current_section_id == DEBUG_PUBNAMES || glflags.current_section_id == DEBUG_MACINFO ) { /* These sections involve the CU die, so use the CU offsets. The DEBUG_MAC* cases are logical but not yet useful (Dec 2015). In other cases the local DIE offset makes more sense. */ loff = glflags.DIE_CU_offset; goff = glflags.DIE_CU_overall_offset; } if (!cu_data_is_set()) { return; } printf("\n"); printf("CU Name = %s\n",sanitized(glflags.CU_name)); printf("CU Producer = %s\n",sanitized(glflags.CU_producer)); printf("DIE OFF = 0x%" DW_PR_XZEROS DW_PR_DUx " GOFF = 0x%" DW_PR_XZEROS DW_PR_DUx, loff,goff); /* We used to print leftover and incorrect values at times. */ if (glflags.need_CU_high_address) { safe_strcpy(hbuf,sizeof(hbuf),"unknown ",10); } else { /* safe, hbuf is large enough. */ sprintf(hbuf, "0x%" DW_PR_XZEROS DW_PR_DUx,glflags.CU_high_address); } if (glflags.need_CU_base_address) { safe_strcpy(lbuf,sizeof(lbuf),"unknown ",10); } else { /* safe, lbuf is large enough. */ sprintf(lbuf, "0x%" DW_PR_XZEROS DW_PR_DUx,glflags.CU_low_address); } printf(", Low PC = %s, High PC = %s", lbuf,hbuf); printf("\n"); } void DWARF_CHECK_ERROR_PRINT_CU() { if (glflags.gf_check_verbose_mode) { if (glflags.gf_print_unique_errors) { if (!glflags.gf_found_error_message) { PRINT_CU_INFO(); } } else { PRINT_CU_INFO(); } } glflags.check_error++; glflags.gf_record_dwarf_error = TRUE; } /* Sometimes is useful, just to know the kind of errors in an object file; not much interest in the number of errors; the specific case is just to have a general idea about the DWARF quality in the file */ char ** set_unique_errors = NULL; unsigned int set_unique_errors_entries = 0; unsigned int set_unique_errors_size = 0; #define SET_UNIQUE_ERRORS_DELTA 64 /* Create the space to store the unique error messages */ void allocate_unique_errors_table(void) { if (!set_unique_errors) { set_unique_errors = (char **) malloc(SET_UNIQUE_ERRORS_DELTA * sizeof(char*)); set_unique_errors_size = SET_UNIQUE_ERRORS_DELTA; set_unique_errors_entries = 0; } } #ifdef TESTING /* Just for debugging purposes, dump the unique errors table */ void dump_unique_errors_table(void) { unsigned int index; printf("*** Unique Errors Table ***\n"); printf("Delta : %d\n",SET_UNIQUE_ERRORS_DELTA); printf("Size : %d\n",set_unique_errors_size); printf("Entries: %d\n",set_unique_errors_entries); for (index = 0; index < set_unique_errors_entries; ++index) { printf("%3d: '%s'\n",index,set_unique_errors[index]); } } #endif /* Release the space used to store the unique error messages */ void release_unique_errors_table(void) { unsigned int index; for (index = 0; index < set_unique_errors_entries; ++index) { free(set_unique_errors[index]); } free(set_unique_errors); set_unique_errors = 0; set_unique_errors_entries = 0; set_unique_errors_size = 0; } /* Returns TRUE if the text is already in the set; otherwise FALSE */ Dwarf_Bool add_to_unique_errors_table(char * error_text) { unsigned int index; size_t len; char * stored_text; char * filtered_text; char * start = NULL; char * end = NULL; char * pattern = "0x"; char * white = " "; char * question = "?"; /* Create a copy of the incoming text */ filtered_text = makename(error_text); len = strlen(filtered_text); /* Remove from the error_text, any hexadecimal numbers (start with 0x), because for some errors, an additional information is given in the form of addresses; we are interested just in the general error. */ start = strstr(filtered_text,pattern); while (start) { /* We have found the start of the pattern; look for a space */ end = strstr(start,white); if (!end) { /* Preserve any line terminator */ end = filtered_text + len -1; } memset(start,*question,end - start); start = strstr(filtered_text,pattern); } /* Check if the error text is already in the table */ for (index = 0; index < set_unique_errors_entries; ++index) { stored_text = set_unique_errors[index]; if (!strcmp(stored_text,filtered_text)) { return TRUE; } } /* Store the new text; check if we have space to store the error text */ if (set_unique_errors_entries + 1 == set_unique_errors_size) { set_unique_errors_size += SET_UNIQUE_ERRORS_DELTA; set_unique_errors = (char **)realloc(set_unique_errors, set_unique_errors_size * sizeof(char*)); } set_unique_errors[set_unique_errors_entries] = filtered_text; ++set_unique_errors_entries; return FALSE; } /* Print a DWARF error message and if in "reduced" output only print one error of each kind; this feature is useful, when we are interested only in the kind of errors and not on the number of errors. PRECONDITION: if s3 non-null so are s1,s2. If s2 is non-null so is s1. s1 is always non-null. */ static void print_dwarf_check_error(const char *s1, const char *s2, const char *s3) { static Dwarf_Bool do_init = TRUE; Dwarf_Bool found = FALSE; char * error_text = NULL; static char *leader = "\n*** DWARF CHECK: "; static char *trailer = " ***\n"; if (do_init) { esb_constructor(&dwarf_error_line); do_init = FALSE; } esb_empty_string(&dwarf_error_line); esb_append(&dwarf_error_line,leader); if (s3) { esb_append(&dwarf_error_line,s1); esb_append(&dwarf_error_line," -> "); esb_append(&dwarf_error_line,s2); esb_append(&dwarf_error_line,": "); esb_append(&dwarf_error_line,s3); } else if (s2) { esb_append(&dwarf_error_line,s1); esb_append(&dwarf_error_line,": "); esb_append(&dwarf_error_line,s2); } else { esb_append(&dwarf_error_line,s1); } esb_append(&dwarf_error_line,trailer); error_text = esb_get_string(&dwarf_error_line); if (glflags.gf_print_unique_errors) { found = add_to_unique_errors_table(error_text); if (!found) { printf("%s",error_text); } } else { printf("%s",error_text); } /* To indicate if the current error message has been found or not */ glflags.gf_found_error_message = found; } void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category, const char *str1, const char *str2, const char *strexpl) { if (checking_this_compiler()) { DWARF_ERROR_COUNT(category,1); if (glflags.gf_check_verbose_mode) { print_dwarf_check_error(str1, str2,strexpl); } DWARF_CHECK_ERROR_PRINT_CU(); } } /* This is too much to put in the DROP_ERROR_INSTANCE macro, so we put it here rather arbitrarily. */ void report_caller_error_drop_error(int dwdlv, int line, char *fname) { printf("\nERROR in dwarfdump:" " The value passed to the macro DROP_ERROR_INSTANCE " "is not one of the three allowed values, but is " "%d. dwarfdump has a bug. " " See line %d file %s\n",dwdlv,line,fname); glflags.gf_count_major_errors++; } libdwarf-20210528/dwarfdump/print_loclists_codes.c0000664000175000017500000002165113764006205017066 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "helpertree.h" #include "tag_common.h" /* Prints locentry descriptsions for DWARF5 DW_LKIND_loclists */ int print_debug_loclists_linecodes(Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char *attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * esbp, Dwarf_Bool * bError) { if (debug_addr_unavailable) { *bError = TRUE; } switch(lle_value) { case DW_LLE_base_address: /* debug_addr_unavailable is not applicable here. */ esb_append_printf_u(esbp, "", lopc); /* ASSERT: *lopc = rawlopc */ break; case DW_LLE_base_addressx: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawlopc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "", lopc); } break; case DW_LLE_end_of_list: /* Nothing to do. */ esb_append(esbp,""); break; case DW_LLE_start_length: if (glflags.verbose) { esb_append_printf_u(esbp, "",hipc); if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLE_startx_length: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLE_offset_pair: /* debug_addr_unavailable does apply becase that might cause base address to be invalid. */ if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLE_start_end: /* debug_addr_unavailable does not apply here */ esb_append_printf_u(esbp, "",hipc); if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; case DW_LLE_startx_endx: if (debug_addr_unavailable) { esb_append_printf_u(esbp, "",rawhipc); } else { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "",hipc); } if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; default: { struct esb_s unexp; esb_constructor(&unexp); esb_append_printf_u(&unexp, "ERROR: Unexpected LLE code 0x%x", lle_value); print_error_and_continue(dbg, esb_get_string(&unexp), DW_DLV_OK, 0); esb_destructor(&unexp); } break; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/dwarf_tsearch.h0000664000175000017500000001020714012575576015466 00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ /* The hashfunc return is now easily changed with cc "-DDW_TSHASHTYPE=unsigned long" The quotes required here as the example type has a space character. */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, /* Before visit children */ dwarf_postorder,/* After first children visit, before last */ dwarf_endorder, /* After visit of children, last visit */ dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. Hence the void ** and rootp name. */ void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* Here the argument is really void *, theroot*/ void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ libdwarf-20210528/dwarfdump/macrocheck.c0000664000175000017500000005040313767710523014745 00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* macrocheck.c, .h create a map of macro import operators to establish that they are resolved and that their offsets refer to actual macro groups. This is across all CUs in the object file, not per-cu.. DEFECTS: There are some things done here that are not correct and need fixing at some point. See macfile_stack, macro_import_stack, macro_check_tree and macinfo_check_tree here and in print_macro.c and in print_die.c print_macro.c, print_die.c, and macrocheck.c work together in checking DWARF macro data. A) macro_import_stack and macfile_stack are global to dwarfdump and therefore these can only be safely used with DWARF5-style .debug_macro data. Not with .debug_macinfo. B) To support .debug_macro_sup in a separate object will likely require moving all the macro data out of global and into something per-open-dbg. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "macrocheck.h" #include "esb.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ Dwarf_Unsigned macro_import_stack[MACRO_IMPORT_STACK_DEPTH +1]; unsigned macro_import_stack_next_to_use; unsigned macro_import_stack_max_seen; unsigned macfile_stack_next_to_use = 0; unsigned macfile_stack[MACFILE_STACK_DEPTH_MAX+1]; unsigned macfile_stack_max_seen; void * macro_check_tree; /* DWARF5 macros */ void * macinfo_check_tree; /* DWARF 2,3,4 macros */ void * macdefundeftree; /* DWARF5 macros */ static struct Macrocheck_Map_Entry_s * macrocheck_map_insert( Dwarf_Unsigned off, unsigned prim,unsigned sec, Dwarf_Unsigned linenum, unsigned src_file_num, void **map); static void macrocheck_map_destroy(void *map); static Dwarf_Unsigned macro_count_recs(void **base); #ifdef SELFTEST int failcount = 0; struct glflags_s glflags; #endif /* SELFTEST */ static struct Macrocheck_Map_Entry_s * macrocheck_map_create_entry(Dwarf_Unsigned offset, unsigned add_primary, unsigned add_secondary) { struct Macrocheck_Map_Entry_s *mp = (struct Macrocheck_Map_Entry_s *) calloc(1,sizeof(struct Macrocheck_Map_Entry_s)); if (!mp) { return 0; } mp->mp_key = offset; mp->mp_len = 0; mp->mp_printed = 0; mp->mp_refcount_primary = add_primary; mp->mp_refcount_secondary = add_secondary; return mp; } static void macrocheck_map_free_func(void *mx) { struct Macrocheck_Map_Entry_s *m = mx; free(m); } static int macrocheck_map_compare_func(const void *l, const void *r) { const struct Macrocheck_Map_Entry_s *ml = l; const struct Macrocheck_Map_Entry_s *mr = r; if (ml->mp_key < mr->mp_key) { return -1; } if (ml->mp_key > mr->mp_key) { return 1; } return 0; } static struct Macrocheck_Map_Entry_s * macrocheck_map_insert(Dwarf_Unsigned offset, unsigned add_prim,unsigned add_sec, Dwarf_Unsigned line_num, unsigned src_file_num, void **tree1) { void *retval = 0; struct Macrocheck_Map_Entry_s *re = 0; struct Macrocheck_Map_Entry_s *e; e = macrocheck_map_create_entry(offset,add_prim,add_sec); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, macrocheck_map_compare_func); if (retval) { re = *(struct Macrocheck_Map_Entry_s **)retval; if (re != e) { /* We returned an existing record, e not needed. Increment refcounts. Lets update line, filenum to latest. So later reports show latest...? */ re->mp_import_linenum = line_num; re->mp_import_from_filenum = src_file_num; re->mp_refcount_primary += add_prim; re->mp_refcount_secondary += add_sec; macrocheck_map_free_func(e); } else { /* New record */ e->mp_import_linenum = line_num; e->mp_import_from_filenum = src_file_num; /* Record e got added to tree1, do not free record e. */ } } return NULL; } struct Macrocheck_Map_Entry_s * macrocheck_map_find(Dwarf_Unsigned offset,void **tree1) { void *retval = 0; struct Macrocheck_Map_Entry_s *re = 0; struct Macrocheck_Map_Entry_s *e = 0; e = macrocheck_map_create_entry(offset,0,0); retval = dwarf_tfind(e,tree1, macrocheck_map_compare_func); if (retval) { re = *(struct Macrocheck_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ macrocheck_map_free_func(e); return re; } static void macrocheck_map_destroy(void *map) { /* tdestroy is not part of Posix. */ dwarf_tdestroy(map,macrocheck_map_free_func); } void add_macro_import_sup(UNUSEDARG void **base, UNUSEDARG Dwarf_Unsigned offset) { /* FIXME */ return; } void add_macro_import(void **base, Dwarf_Bool is_primary, Dwarf_Unsigned offset, Dwarf_Unsigned line_num, unsigned src_filenum) { Dwarf_Unsigned prim_count = 0; Dwarf_Unsigned sec_count = 0; if (is_primary) { prim_count = 1; } else { sec_count = 1; } macrocheck_map_insert(offset,prim_count,sec_count, line_num,src_filenum,base); } void add_macro_area_len(void **base, Dwarf_Unsigned offset, Dwarf_Unsigned len) { struct Macrocheck_Map_Entry_s *re = 0; re = macrocheck_map_find(offset,base); if (re) { re->mp_len = len; } } static Dwarf_Unsigned reccount = 0; static void macro_walk_count_recs(UNUSEDARG const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { if (which == dwarf_postorder || which == dwarf_endorder) { return; } reccount += 1; } static Dwarf_Unsigned macro_count_recs(void **base) { reccount = 0; dwarf_twalk(*base,macro_walk_count_recs); return reccount; } static Dwarf_Unsigned lowestoff = 0xffffff; static Dwarf_Bool lowestfound = FALSE; static void macro_walk_find_lowest(const void *nodep,const DW_VISIT which, UNUSEDARG const int depth) { struct Macrocheck_Map_Entry_s * re = *(struct Macrocheck_Map_Entry_s**)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } if (!re->mp_printed) { if (!lowestfound) { lowestoff = re->mp_key; lowestfound = TRUE; } else if (re->mp_key <= lowestoff) { lowestoff = re->mp_key; } } } /* Never returns DW_DLV_ERROR */ int get_next_unprinted_macro_offset(void **tree, Dwarf_Unsigned * off) { lowestfound = FALSE; lowestoff = 0xffffffff; /* This walks the tree to find one entry. Which could get slow if the tree has lots of entries. */ dwarf_twalk(*tree,macro_walk_find_lowest); if (!lowestfound) { return DW_DLV_NO_ENTRY; } *off = lowestoff; return DW_DLV_OK; } void mark_macro_offset_printed(void **base, Dwarf_Unsigned offset) { struct Macrocheck_Map_Entry_s *re = 0; re = macrocheck_map_find(offset,base); if (re) { re->mp_printed = TRUE; } } static struct Macrocheck_Map_Entry_s **mac_as_array = 0; static unsigned mac_as_array_next = 0; static void macro_walk_to_array(const void *nodep,const DW_VISIT which, UNUSEDARG const int depth) { struct Macrocheck_Map_Entry_s * re = *(struct Macrocheck_Map_Entry_s**)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } mac_as_array[mac_as_array_next] = re; mac_as_array_next++; } static int qsort_compare(const void *lin, const void *rin) { const struct Macrocheck_Map_Entry_s *l = *(const struct Macrocheck_Map_Entry_s **)lin; const struct Macrocheck_Map_Entry_s *r = *(const struct Macrocheck_Map_Entry_s **)rin; if (l->mp_key < r->mp_key) { return -1; } if (l->mp_key > r->mp_key) { return 1; } if (l->mp_len < r->mp_len) { return -1; } if (l->mp_len > r->mp_len) { return 1; } return 0; } static void warnprimeandsecond(struct Macrocheck_Map_Entry_s *r) { #ifdef SELFTEST ++failcount; #endif glflags.gf_count_major_errors++; printf("\nERROR: For offset " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a nonzero primary count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " with a secondary count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, r->mp_refcount_primary, r->mp_refcount_primary, r->mp_refcount_secondary, r->mp_refcount_secondary); } int print_macrocheck_statistics(const char *name,void **tsbase, int isdwarf5, Dwarf_Unsigned section_size, UNUSEDARG Dwarf_Error * err) { Dwarf_Unsigned count = 0; Dwarf_Unsigned lowest = -1ll; Dwarf_Unsigned highest = 0; Dwarf_Unsigned lastend = 0; Dwarf_Unsigned laststart = 0; Dwarf_Unsigned internalgap = 0; Dwarf_Unsigned wholegap = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned end = 0; if (! *tsbase) { return DW_DLV_NO_ENTRY; } count = macro_count_recs(tsbase); if (count < 1) { return DW_DLV_NO_ENTRY; } free(mac_as_array); mac_as_array = 0; mac_as_array_next = 0; mac_as_array = (struct Macrocheck_Map_Entry_s **)calloc(count, sizeof(struct Macrocheck_Map_Entry_s *)); if (!mac_as_array) { #ifdef SELFTEST ++failcount; #endif glflags.gf_count_major_errors++; printf("\nERROR: Macro checking %s: " "unable to allocate %" DW_PR_DUu "pointers\n", name, count); /* Return OK so dwarfdump.c won't look for Dwarf_Error */ return DW_DLV_OK; } dwarf_twalk(*tsbase,macro_walk_to_array); printf(" Macro unit count %s: %" DW_PR_DUu "\n",name,count); qsort(mac_as_array, count,sizeof(struct Macrocheck_Map_Entry_s *), qsort_compare); for (i = 0; i < count ; ++i) { struct Macrocheck_Map_Entry_s *r = mac_as_array[i]; #if 0 printf("debugging: i %u off 0x%x len 0x%x printed? %u " " ref prim: %u sec: %u\n", (unsigned)i, (unsigned)r->mp_key, (unsigned)r->mp_len, (unsigned)r->mp_printed, (unsigned)r->mp_refcount_primary, (unsigned)r->mp_refcount_secondary); #endif if (r->mp_key < lowest) { lowest = r->mp_key; } end = r->mp_key + r->mp_len; if (end > highest) { highest = end; } if (r->mp_refcount_primary > 1) { #ifdef SELFTEST ++failcount; #endif glflags.gf_count_major_errors++; printf("\nERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a primary reference count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, r->mp_refcount_primary, r->mp_refcount_primary); } /* For DWARF5 style macros (in .debug_macro) having both counts is normal. Not so for DWARF2 .debug_macinfo. */ if (!isdwarf5 && r->mp_refcount_primary && r->mp_refcount_secondary) { warnprimeandsecond(r); } } lastend = mac_as_array[0]->mp_key + mac_as_array[0]->mp_len; laststart = mac_as_array[0]->mp_key; printf(" Macro Offsets start at 0x%" DW_PR_XZEROS DW_PR_DUx " and end at 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lowest, highest); for (i = 1; i < count ; ++i) { struct Macrocheck_Map_Entry_s *r = mac_as_array[i]; #if 0 printf("debugging i %u off 0x%x len 0x%x\n", (unsigned)i, (unsigned)r->mp_key, (unsigned)r->mp_len); #endif if (r->mp_key > lastend) { internalgap += (r->mp_key - lastend); } else if (r->mp_key < lastend) { /* crazy overlap */ #ifdef SELFTEST ++failcount; #endif glflags.gf_count_major_errors++; printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a crazy overlap with the previous " "end offset of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " (previous start offset " "of 0x%" DW_PR_XZEROS DW_PR_DUx ")" " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, lastend, lastend, laststart, laststart); } laststart = r->mp_key; lastend = laststart + r->mp_len; } /* wholegap is a) starting offset > 0 and b) space after used area before end of section. */ wholegap = mac_as_array[0]->mp_key + internalgap; if (lastend > section_size) { /* Something seriously wrong */ #ifdef SELFTEST ++failcount; #endif printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is an overlap with the end of section " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n",laststart,laststart, lastend, lastend); } else { wholegap += (section_size - lastend); } if (wholegap) { printf(" Macro Offsets internal unused space: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", internalgap); printf(" Macro Offsets total unused space: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", wholegap); } if (macfile_stack_max_seen) { printf("Maximum nest depth of DW_MACRO_start_file: %u\n", macfile_stack_max_seen-1); } if (macro_import_stack_max_seen) { printf("Maximum nest depth of DW_MACRO_import : %u\n", macro_import_stack_max_seen-1); } free (mac_as_array); mac_as_array = 0; mac_as_array_next = 0; return DW_DLV_OK; } void clear_macrocheck_statistics(void **tsbase) { if (!*tsbase) { return; } macrocheck_map_destroy(*tsbase); *tsbase = 0; } void print_macro_import_stack(void) { unsigned i = 0; printf("Macro Stack Depth: %u\n", macro_import_stack_next_to_use); for ( ; i < macro_import_stack_next_to_use; ++i) { printf("Macro Stack[%u] " "MOFF=0x%" DW_PR_XZEROS DW_PR_DUx "\n", i,macro_import_stack[i]); } } /* Returns DW_DLV_ERROR if the push could not done, which would be because full. Else returns DW_DLV_OK. */ int macro_import_stack_push(Dwarf_Unsigned offset) { if (macro_import_stack_next_to_use >= MACRO_IMPORT_STACK_DEPTH) { printf("ERROR: The macro_import_stack has exceeded " "its maximum of %d\n",MACRO_IMPORT_STACK_DEPTH); print_macro_import_stack(); glflags.gf_count_major_errors++; return DW_DLV_ERROR; } macro_import_stack[macro_import_stack_next_to_use] = offset; ++macro_import_stack_next_to_use; if (macro_import_stack_max_seen < macro_import_stack_next_to_use) { macro_import_stack_max_seen = macro_import_stack_next_to_use; } return DW_DLV_OK; } /* Returns DW_DLV_ERROR if the pop could not done, else returns DW_DLV_OK. */ int macro_import_stack_pop(void) { if (!macro_import_stack_next_to_use) { printf("ERROR: The macro_import_stack is" " empty and the attempted pop() is " "impossible. A dwarfdump bug.\n"); glflags.gf_count_major_errors++; return DW_DLV_ERROR; } --macro_import_stack_next_to_use; return DW_DLV_OK; } /* Returns DW_DLV_OK if offset present else DW_DLV_NO_ENTRY. */ int macro_import_stack_present(Dwarf_Unsigned offset) { unsigned i = 0; for ( ; i < macro_import_stack_next_to_use;++i) { if (macro_import_stack[i] == offset) { return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } void macro_import_stack_cleanout(void) { macro_import_stack_next_to_use = 0; } #ifdef SELFTEST int main() { void * base = 0; Dwarf_Unsigned count = 0; int basefailcount = 0; Dwarf_Error err = 0; int isdwarf5=FALSE; /* Test 1 */ add_macro_import(&base,TRUE,200,0,0); count = macro_count_recs(&base); if (count != 1) { printf("FAIL: expect count 1, got %" DW_PR_DUu "\n",count); ++failcount; } print_macrocheck_statistics("test1",&base,isdwarf5,2000,&err); /* Test two */ add_macro_area_len(&base,200,100); add_macro_import(&base,FALSE,350,0,0); add_macro_area_len(&base,350,100); count = macro_count_recs(&base); if (count != 2) { printf("FAIL: expect count 2, got %" DW_PR_DUu "\n",count); ++failcount; } print_macrocheck_statistics("test 2",&base,isdwarf5,2000,&err); clear_macrocheck_statistics(&base); /* Test three */ basefailcount = failcount; add_macro_import(&base,TRUE,0,0,0); add_macro_area_len(&base,0,1000); add_macro_import(&base,FALSE,2000,0,0); add_macro_area_len(&base,2000,100); mark_macro_offset_printed(&base,2000); add_macro_import(&base,FALSE,1000,0,0); add_macro_area_len(&base,1000,900); add_macro_import(&base,FALSE,1000,0,0); add_macro_area_len(&base,1000,900); count = macro_count_recs(&base); if (count != 3) { printf("FAIL: expect count 3, got %" DW_PR_DUu "\n",count); ++failcount; } printf("\n Expect an ERROR about overlap with " "the end of section\n"); print_macrocheck_statistics("test 3",&base,isdwarf5,2000,&err); clear_macrocheck_statistics(&base); if ((basefailcount+1) != failcount) { printf("FAIL: Found no error in test 3 checking!\n"); ++failcount; } else { failcount = basefailcount; } /* Test Four */ basefailcount = failcount; add_macro_import(&base,TRUE,50,0,0); add_macro_import(&base,TRUE,50,0,0); add_macro_area_len(&base,50,50); add_macro_import(&base,FALSE,200,0,0); add_macro_import(&base,FALSE,50,0,0); add_macro_import(&base,FALSE,60,0,0); add_macro_area_len(&base,60,10); printf( "\n Expect an ERROR about offset 50 having " "2 primaries\n"); printf( " and Expect an ERROR about offset 50 having 2\n" " primaries" " and a secondary\n"); printf( " and Expect an ERROR about crazy overlap 60\n\n"); print_macrocheck_statistics("test 4",&base,isdwarf5,2000,&err); clear_macrocheck_statistics(&base); if ((basefailcount + 3) != failcount) { printf("FAIL: Found wrong errors in test 4 checking!\n"); } else { failcount = basefailcount; } if (failcount > 0) { printf("FAIL macrocheck selftest\n"); exit(1); } printf("PASS macrocheck selftest\n"); return 0; } #endif /* SELFTEST */ libdwarf-20210528/dwarfdump/test-mach-o-32.base0000664000175000017500000012501514012575576015704 00000000000000 .debug_info COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit DW_AT_producer Apple LLVM version 8.0.0 (clang-800.0.42.1) DW_AT_language DW_LANG_C99 DW_AT_name /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_stmt_list 0x00000000 DW_AT_comp_dir /tmp/c/dwarf/gcc_m32 DW_AT_low_pc 0x000025c0 DW_AT_high_pc 0x00005b94 LOCAL_SYMBOLS: < 1><0x00000026> DW_TAG_variable DW_AT_name dumpallnamesfile DW_AT_type <0x00000038> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000084 DW_AT_location len 0x0005: 0x037cbc0500: DW_OP_addr 0x0005bc7c < 1><0x00000038> DW_TAG_pointer_type DW_AT_type <0x0000003d> < 1><0x0000003d> DW_TAG_typedef DW_AT_type <0x00000048> DW_AT_name FILE DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000099 < 1><0x00000048> DW_TAG_structure_type DW_AT_name __sFILE DW_AT_byte_size 0x00000058 DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007a < 2><0x00000050> DW_TAG_member DW_AT_name _p DW_AT_type <0x00000169> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007b DW_AT_data_member_location len 0x0002: 0x2300: DW_OP_plus_uconst 0 < 2><0x0000005e> DW_TAG_member DW_AT_name _r DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007c DW_AT_data_member_location len 0x0002: 0x2304: DW_OP_plus_uconst 4 < 2><0x0000006c> DW_TAG_member DW_AT_name _w DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007d DW_AT_data_member_location len 0x0002: 0x2308: DW_OP_plus_uconst 8 < 2><0x0000007a> DW_TAG_member DW_AT_name _flags DW_AT_type <0x0000017c> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007e DW_AT_data_member_location len 0x0002: 0x230c: DW_OP_plus_uconst 12 < 2><0x00000088> DW_TAG_member DW_AT_name _file DW_AT_type <0x0000017c> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007f DW_AT_data_member_location len 0x0002: 0x230e: DW_OP_plus_uconst 14 < 2><0x00000096> DW_TAG_member DW_AT_name _bf DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000080 DW_AT_data_member_location len 0x0002: 0x2310: DW_OP_plus_uconst 16 < 2><0x000000a4> DW_TAG_member DW_AT_name _lbfsize DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000081 DW_AT_data_member_location len 0x0002: 0x2318: DW_OP_plus_uconst 24 < 2><0x000000b2> DW_TAG_member DW_AT_name _cookie DW_AT_type <0x000001a8> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000084 DW_AT_data_member_location len 0x0002: 0x231c: DW_OP_plus_uconst 28 < 2><0x000000c0> DW_TAG_member DW_AT_name _close DW_AT_type <0x000001a9> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000085 DW_AT_data_member_location len 0x0002: 0x2320: DW_OP_plus_uconst 32 < 2><0x000000ce> DW_TAG_member DW_AT_name _read DW_AT_type <0x000001ba> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000086 DW_AT_data_member_location len 0x0002: 0x2324: DW_OP_plus_uconst 36 < 2><0x000000dc> DW_TAG_member DW_AT_name _seek DW_AT_type <0x000001e1> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000087 DW_AT_data_member_location len 0x0002: 0x2328: DW_OP_plus_uconst 40 < 2><0x000000ea> DW_TAG_member DW_AT_name _write DW_AT_type <0x00000224> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000088 DW_AT_data_member_location len 0x0002: 0x232c: DW_OP_plus_uconst 44 < 2><0x000000f8> DW_TAG_member DW_AT_name _ub DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008b DW_AT_data_member_location len 0x0002: 0x2330: DW_OP_plus_uconst 48 < 2><0x00000106> DW_TAG_member DW_AT_name _extra DW_AT_type <0x00000249> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008c DW_AT_data_member_location len 0x0002: 0x2338: DW_OP_plus_uconst 56 < 2><0x00000114> DW_TAG_member DW_AT_name _ur DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008d DW_AT_data_member_location len 0x0002: 0x233c: DW_OP_plus_uconst 60 < 2><0x00000122> DW_TAG_member DW_AT_name _ubuf DW_AT_type <0x00000254> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000090 DW_AT_data_member_location len 0x0002: 0x2340: DW_OP_plus_uconst 64 < 2><0x00000130> DW_TAG_member DW_AT_name _nbuf DW_AT_type <0x00000267> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000091 DW_AT_data_member_location len 0x0002: 0x2343: DW_OP_plus_uconst 67 < 2><0x0000013e> DW_TAG_member DW_AT_name _lb DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000094 DW_AT_data_member_location len 0x0002: 0x2344: DW_OP_plus_uconst 68 < 2><0x0000014c> DW_TAG_member DW_AT_name _blksize DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000097 DW_AT_data_member_location len 0x0002: 0x234c: DW_OP_plus_uconst 76 < 2><0x0000015a> DW_TAG_member DW_AT_name _offset DW_AT_type <0x000001fc> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000098 DW_AT_data_member_location len 0x0002: 0x2350: DW_OP_plus_uconst 80 < 1><0x00000169> DW_TAG_pointer_type DW_AT_type <0x0000016e> < 1><0x0000016e> DW_TAG_base_type DW_AT_name unsigned char DW_AT_encoding DW_ATE_unsigned_char DW_AT_byte_size 0x00000001 < 1><0x00000175> DW_TAG_base_type DW_AT_name int DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000004 < 1><0x0000017c> DW_TAG_base_type DW_AT_name short DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000002 < 1><0x00000183> DW_TAG_structure_type DW_AT_name __sbuf DW_AT_byte_size 0x00000008 DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000058 < 2><0x0000018b> DW_TAG_member DW_AT_name _base DW_AT_type <0x00000169> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000059 DW_AT_data_member_location len 0x0002: 0x2300: DW_OP_plus_uconst 0 < 2><0x00000199> DW_TAG_member DW_AT_name _size DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000005a DW_AT_data_member_location len 0x0002: 0x2304: DW_OP_plus_uconst 4 < 1><0x000001a8> DW_TAG_pointer_type < 1><0x000001a9> DW_TAG_pointer_type DW_AT_type <0x000001ae> < 1><0x000001ae> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x000001b4> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 1><0x000001ba> DW_TAG_pointer_type DW_AT_type <0x000001bf> < 1><0x000001bf> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x000001c5> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x000001ca> DW_TAG_formal_parameter DW_AT_type <0x000001d5> < 2><0x000001cf> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x000001d5> DW_TAG_pointer_type DW_AT_type <0x000001da> < 1><0x000001da> DW_TAG_base_type DW_AT_name char DW_AT_encoding DW_ATE_signed_char DW_AT_byte_size 0x00000001 < 1><0x000001e1> DW_TAG_pointer_type DW_AT_type <0x000001e6> < 1><0x000001e6> DW_TAG_subroutine_type DW_AT_type <0x000001fc> DW_AT_prototyped yes(1) < 2><0x000001ec> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x000001f1> DW_TAG_formal_parameter DW_AT_type <0x000001fc> < 2><0x000001f6> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x000001fc> DW_TAG_typedef DW_AT_type <0x00000207> DW_AT_name fpos_t DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000004d < 1><0x00000207> DW_TAG_typedef DW_AT_type <0x00000212> DW_AT_name __darwin_off_t DW_AT_decl_file 0x00000003 /usr/include/sys/_types.h DW_AT_decl_line 0x00000047 < 1><0x00000212> DW_TAG_typedef DW_AT_type <0x0000021d> DW_AT_name __int64_t DW_AT_decl_file 0x00000002 /usr/include/i386/_types.h DW_AT_decl_line 0x0000002e < 1><0x0000021d> DW_TAG_base_type DW_AT_name long long int DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000008 < 1><0x00000224> DW_TAG_pointer_type DW_AT_type <0x00000229> < 1><0x00000229> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x0000022f> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x00000234> DW_TAG_formal_parameter DW_AT_type <0x0000023f> < 2><0x00000239> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x0000023f> DW_TAG_pointer_type DW_AT_type <0x00000244> < 1><0x00000244> DW_TAG_const_type DW_AT_type <0x000001da> < 1><0x00000249> DW_TAG_pointer_type DW_AT_type <0x0000024e> < 1><0x0000024e> DW_TAG_structure_type DW_AT_name __sFILEX DW_AT_declaration yes(1) < 1><0x00000254> DW_TAG_array_type DW_AT_type <0x0000016e> < 2><0x00000259> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000003 < 1><0x00000260> DW_TAG_base_type DW_AT_name sizetype DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned < 1><0x00000267> DW_TAG_array_type DW_AT_type <0x0000016e> < 2><0x0000026c> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000001 < 1><0x00000273> DW_TAG_variable DW_AT_name cu_version_stamp DW_AT_type <0x00000175> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000091 DW_AT_location len 0x0005: 0x0380bc0500: DW_OP_addr 0x0005bc80 < 1><0x00000285> DW_TAG_variable DW_AT_name cu_offset_size DW_AT_type <0x00000175> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000092 DW_AT_location len 0x0005: 0x0384bc0500: DW_OP_addr 0x0005bc84 < 1><0x00000297> DW_TAG_variable DW_AT_name namesoptionon DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000081 DW_AT_location len 0x0005: 0x0398bc0500: DW_OP_addr 0x0005bc98 < 1><0x000002a8> DW_TAG_variable DW_AT_name dupstrused DW_AT_type <0x000002b9> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000000a5 DW_AT_location len 0x0005: 0x03bcbc0500: DW_OP_addr 0x0005bcbc < 1><0x000002b9> DW_TAG_base_type DW_AT_name unsigned int DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 0x00000004 < 1><0x000002c0> DW_TAG_variable DW_AT_name dupstrarray DW_AT_type <0x000002d1> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000000a4 DW_AT_location len 0x0005: 0x03c0bc0500: DW_OP_addr 0x0005bcc0 < 1><0x000002d1> DW_TAG_array_type DW_AT_type <0x0000023f> < 2><0x000002d6> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000064 < 1><0x000002dd> DW_TAG_variable DW_AT_name dumpallnamespath DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000085 DW_AT_location len 0x0005: 0x039cbc0500: DW_OP_addr 0x0005bc9c < 1><0x000002ee> DW_TAG_variable DW_AT_name dumpallnames DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000083 DW_AT_location len 0x0005: 0x03a0bc0500: DW_OP_addr 0x0005bca0 < 1><0x000002ff> DW_TAG_variable DW_AT_name checkoptionon DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000082 DW_AT_location len 0x0005: 0x03a4bc0500: DW_OP_addr 0x0005bca4 < 1><0x00000310> DW_TAG_variable DW_AT_name tuhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009c DW_AT_location len 0x0005: 0x03a8bc0500: DW_OP_addr 0x0005bca8 < 1><0x00000321> DW_TAG_variable DW_AT_name cuhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009b DW_AT_location len 0x0005: 0x03acbc0500: DW_OP_addr 0x0005bcac < 1><0x00000332> DW_TAG_variable DW_AT_name tufissionhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009e DW_AT_location len 0x0005: 0x03b0bc0500: DW_OP_addr 0x0005bcb0 < 1><0x00000343> DW_TAG_variable DW_AT_name cufissionhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009d DW_AT_location len 0x0005: 0x03b4bc0500: DW_OP_addr 0x0005bcb4 < 1><0x00000354> DW_TAG_variable DW_AT_name passnullerror DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000098 DW_AT_location len 0x0005: 0x03b8bc0500: DW_OP_addr 0x0005bcb8 < 1><0x00000365> DW_TAG_variable DW_AT_name g_is_info DW_AT_type <0x00000376> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008f DW_AT_location len 0x0005: 0x0358b40500: DW_OP_addr 0x0005b458 < 1><0x00000376> DW_TAG_typedef DW_AT_type <0x00000175> DW_AT_name Dwarf_Bool DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x0000005e < 1><0x00000381> DW_TAG_variable DW_AT_name unittype DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008e DW_AT_location len 0x0005: 0x035cb40500: DW_OP_addr 0x0005b45c < 1><0x00000392> DW_TAG_variable DW_AT_name fissionfordie DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000097 DW_AT_location len 0x0005: 0x0360b40500: DW_OP_addr 0x0005b460 < 1><0x000003a3> DW_TAG_variable DW_AT_name stdrun DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008c DW_AT_location len 0x0005: 0x0364b40500: DW_OP_addr 0x0005b464 < 1><0x000003b4> DW_TAG_variable DW_AT_name dienumber DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000096 DW_AT_location len 0x0005: 0x0350be0500: DW_OP_addr 0x0005be50 < 1><0x000003c5> DW_TAG_enumeration_type DW_AT_name Dwarf_Form_Class DW_AT_byte_size 0x00000004 DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000596 < 2><0x000003ce> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_UNKNOWN DW_AT_const_value 0 < 2><0x000003d4> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_ADDRESS DW_AT_const_value 1 < 2><0x000003da> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_BLOCK DW_AT_const_value 2 < 2><0x000003e0> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_CONSTANT DW_AT_const_value 3 < 2><0x000003e6> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_EXPRLOC DW_AT_const_value 4 < 2><0x000003ec> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_FLAG DW_AT_const_value 5 < 2><0x000003f2> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LINEPTR DW_AT_const_value 6 < 2><0x000003f8> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLISTPTR DW_AT_const_value 7 < 2><0x000003fe> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_MACPTR DW_AT_const_value 8 < 2><0x00000404> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RANGELISTPTR DW_AT_const_value 9 < 2><0x0000040a> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_REFERENCE DW_AT_const_value 10 < 2><0x00000410> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_STRING DW_AT_const_value 11 < 2><0x00000416> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_FRAMEPTR DW_AT_const_value 12 < 2><0x0000041c> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_MACROPTR DW_AT_const_value 13 < 2><0x00000422> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_ADDRPTR DW_AT_const_value 14 < 2><0x00000428> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLIST DW_AT_const_value 15 < 2><0x0000042e> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLISTSPTR DW_AT_const_value 16 < 2><0x00000434> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RNGLIST DW_AT_const_value 17 < 2><0x0000043a> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RNGLISTSPTR DW_AT_const_value 18 < 2><0x00000440> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_STROFFSETSPTR DW_AT_const_value 19 < 1><0x00000447> DW_TAG_typedef DW_AT_type <0x000001a8> DW_AT_name Dwarf_Ptr DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000076 < 1><0x00000452> DW_TAG_typedef DW_AT_type <0x0000045d> DW_AT_name Dwarf_Unsigned DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000060 < 1><0x0000045d> DW_TAG_base_type DW_AT_name long long unsigned int DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 0x00000008 < 1><0x00000464> DW_TAG_subprogram DW_AT_low_pc 0x000025c0 DW_AT_high_pc 0x000034d6 DW_AT_frame_base len 0x0001: 0x55: DW_OP_reg5 DW_AT_name main DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_prototyped yes(1) DW_AT_type <0x00000175> DW_AT_external yes(1) < 2><0x0000047c> DW_TAG_formal_parameter DW_AT_location len 0x0003: 0x91907c: DW_OP_fbreg -496 DW_AT_name argc DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_type <0x00000175> < 2><0x0000048c> DW_TAG_formal_parameter DW_AT_location len 0x0003: 0x918c7c: DW_OP_fbreg -500 DW_AT_name argv DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_type <0x000012c8> < 2><0x0000049c> DW_TAG_variable DW_AT_location len 0x0003: 0x91887c: DW_OP_fbreg -504 DW_AT_name dbg DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000166 DW_AT_type <0x000012cd> < 2><0x000004ac> DW_TAG_variable DW_AT_location len 0x0003: 0x91847c: DW_OP_fbreg -508 DW_AT_name fd DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000167 DW_AT_type <0x00000175> < 2><0x000004bc> DW_TAG_variable DW_AT_location len 0x0003: 0x91807c: DW_OP_fbreg -512 DW_AT_name filepath DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000168 DW_AT_type <0x0000023f> < 2><0x000004cc> DW_TAG_variable DW_AT_location len 0x0003: 0x91fc7b: DW_OP_fbreg -516 DW_AT_name res DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000169 DW_AT_type <0x00000175> < 2><0x000004dc> DW_TAG_variable DW_AT_location len 0x0003: 0x91f87b: DW_OP_fbreg -520 DW_AT_name error DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016a DW_AT_type <0x000012e4> < 2><0x000004ec> DW_TAG_variable DW_AT_location len 0x0003: 0x91f47b: DW_OP_fbreg -524 DW_AT_name errhand DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016b DW_AT_type <0x000012fb> < 2><0x000004fc> DW_TAG_variable DW_AT_location len 0x0003: 0x91f07b: DW_OP_fbreg -528 DW_AT_name errarg DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016c DW_AT_type <0x00000447> < 2><0x0000050c> DW_TAG_variable DW_AT_location len 0x0002: 0x9168: DW_OP_fbreg -24 DW_AT_name hash8 DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016d DW_AT_type <0x00001319> < 2><0x0000051b> DW_TAG_variable DW_AT_location len 0x0003: 0x91ec7b: DW_OP_fbreg -532 DW_AT_name errp DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016e DW_AT_type <0x00001347> < 2><0x0000052b> DW_TAG_variable DW_AT_location len 0x0003: 0x91e87b: DW_OP_fbreg -536 DW_AT_name simpleerrhand DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000016f DW_AT_type <0x00000175> < 2><0x0000053b> DW_TAG_lexical_block DW_AT_low_pc 0x0000266d DW_AT_high_pc 0x00002b51 < 3><0x00000544> DW_TAG_variable DW_AT_location len 0x0003: 0x91e47b: DW_OP_fbreg -540 DW_AT_name i DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000174 DW_AT_type <0x00000175> < 2><0x00000555> DW_TAG_lexical_block DW_AT_low_pc 0x00002c81 DW_AT_high_pc 0x00002e70 < 3><0x0000055e> DW_TAG_variable DW_AT_location len 0x0003: 0x91e07b: DW_OP_fbreg -544 DW_AT_name die DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000001c4 DW_AT_type <0x0000134c> < 3><0x0000056e> DW_TAG_lexical_block DW_AT_low_pc 0x00002d35 DW_AT_high_pc 0x00002dd9 < 4><0x00000577> DW_TAG_variable DW_AT_location len 0x0003: 0x91d07b: DW_OP_fbreg -560 DW_AT_name sf DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000001cd DW_AT_type <0x00001363> < 2><0x00000589> DW_TAG_lexical_block DW_AT_low_pc 0x00002e86 DW_AT_high_pc 0x00003075 < 3><0x00000592> DW_TAG_variable DW_AT_location len 0x0003: 0x91cc7b: DW_OP_fbreg -564 DW_AT_name die DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000001dc DW_AT_type <0x0000134c> < 3><0x000005a2> DW_TAG_lexical_block DW_AT_low_pc 0x00002f3a DW_AT_high_pc 0x00002fde < 4><0x000005ab> DW_TAG_variable DW_AT_location len 0x0003: 0x91b87b: DW_OP_fbreg -584 DW_AT_name sf DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000001e5 DW_AT_type <0x00001363> < 2><0x000005bd> DW_TAG_lexical_block DW_AT_low_pc 0x00003098 DW_AT_high_pc 0x0000323e < 3><0x000005c6> DW_TAG_variable DW_AT_location len 0x0003: 0x91807e: DW_OP_fbreg -256 DW_AT_name fisdata DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000001f5 DW_AT_type <0x000013a1> < 2><0x000005d7> DW_TAG_lexical_block DW_AT_low_pc 0x00003261 DW_AT_high_pc 0x00003407 < 3><0x000005e0> DW_TAG_variable DW_AT_location len 0x0003: 0x91987c: DW_OP_fbreg -488 DW_AT_name fisdata DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000209 DW_AT_type <0x000013a1> < 1><0x000005f2> DW_TAG_subprogram DW_AT_low_pc 0x000034e0 DW_AT_high_pc 0x000035c8 DW_AT_frame_base len 0x0001: 0x55: DW_OP_reg5 DW_AT_name startswithextractstring DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000103 DW_AT_prototyped yes(1) DW_AT_type <0x00000175> < 2><0x00000609> DW_TAG_formal_parameter DW_AT_location len 0x0002: 0x9174: DW_OP_fbreg -12 DW_AT_name arg DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000103 DW_AT_type <0x0000023f> < 2><0x00000618> DW_TAG_formal_parameter libdwarf-20210528/dwarfdump/dwconf.h0000664000175000017500000001102613762510743014126 00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWCONFIG_H #define DWCONFIG_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define FOUND_ABI_START 1 #define FOUND_OPTION 2 #define FOUND_ERROR 3 #define FOUND_DONE 4 /* Declarations helping configure the frame reader. We are not allowing negative register numbers. Which could be allowed if necessary with a little work. */ struct dwconf_s { char *cf_config_file_path; char *cf_abi_name; /* 2 for old, 3 for frame interface 3. 2 means use the old mips-abi-oriented frame interface. 3 means use the new DWARF3-capable and configureable-abi interface. Now, anyone who revises dwarf.h and libdwarf.h to match their abi-of-interest will still be able to use cf_interface_number 2 as before. But most folks don't update those header files and instead of making *them* configurable we make dwarfdump (and libdwarf) configurable sufficiently to print frame information sensibly. */ int cf_interface_number; /* The number of table rules , aka columns. For MIPS/IRIX is 66. */ unsigned long cf_table_entry_count; /* Array of cf_table_entry_count reg names. Names not filled in from dwarfdump.conf have NULL (0) pointer value. cf_named_regs_table_size must match size of cf_regs array. Set cf_regs_malloced 1 if table was malloced. Set 0 if static. */ char **cf_regs; unsigned long cf_named_regs_table_size; unsigned cf_regs_malloced; /* The 'default initial value' when intializing a table. for MIPS is DW_FRAME_SAME_VAL(1035). For other ISA/ABIs may be DW_FRAME_UNDEFINED_VAL(1034). */ unsigned cf_initial_rule_value; unsigned cf_same_val; unsigned cf_undefined_val; /* The number of the cfa 'register'. For cf_interface_number 2 of MIPS this is 0. For other architectures (and anytime using cf_interface_number 3) this should be outside the table, a special value such as 1436, not a table column at all). */ unsigned cf_cfa_reg; /* If non-zero it is the number of bytes in an address for the frame data. Normally it will be zero because there are usually other sources for the correct address size. However, with DWARF2 frame data there is no explicit address size in the frame data and the object file might not have other .debug_ sections to work with. If zero, no address size was supplied, and that is normal and the already-set (or defaulted) address size is to be used. Only an exceptional frame configure will specify address size here. This won't work at all if the object needing this setting has different address size in different CUs. */ unsigned cf_address_size; }; /* Returns DW_DLV_OK if works. Returns DW_DLV_ERROR if cannot do what is asked. */ int find_conf_file_and_read_config(const char *named_file, const char *named_abi, char **defaults, struct dwconf_s *conf_out); void init_conf_file_data(struct dwconf_s *config_file_data); void init_mips_conf_file_data(struct dwconf_s *config_file_data); void print_reg_from_config_data(Dwarf_Unsigned reg, struct dwconf_s *config_data); void free_all_dwconf(struct dwconf_s *config_data); void init_generic_config_1200_regs(struct dwconf_s *conf); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWCONFIG_H */ libdwarf-20210528/dwarfdump/checkutil.c0000664000175000017500000004374714003122441014612 00000000000000/* Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* These simple list-processing functions are in support of checking DWARF for compiler-errors of various sorts. */ #include "globals.h" /* It includes config.h */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "esb.h" /* Private function */ static void DumpFullBucketGroup(Bucket_Group *pBucketGroup); static int FindDataIndexInBucket(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData); static void PrintBucketData(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData); static void ProcessBucketGroup(Bucket_Group *pBucketGroup, void (*pFunction)(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData)); Bucket_Group * AllocateBucketGroup(int kind) { Bucket_Group *pBucketGroup = (Bucket_Group *)calloc(1, sizeof(Bucket_Group)); pBucketGroup->kind = kind; return pBucketGroup; } void ReleaseBucketGroup(Bucket_Group *pBucketGroup) { Bucket *pBucket = 0; Bucket *pNext = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; ) { pNext = pBucket->pNext; free(pBucket); pBucket = pNext; } pBucketGroup->pHead = NULL; pBucketGroup->pTail = NULL; free(pBucketGroup); } void ResetBucketGroup(Bucket_Group *pBucketGroup) { Bucket *pBucket = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { pBucket->nEntries = 0; } ResetSentinelBucketGroup(pBucketGroup); } /* Reset sentinels in a Bucket Group. */ void ResetSentinelBucketGroup(Bucket_Group *pBucketGroup) { /* Sanity checks */ assert(pBucketGroup); pBucketGroup->pFirst = NULL; pBucketGroup->pLast = NULL; } void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull) { if (pBucketGroup) { if (bFull) { DumpFullBucketGroup(pBucketGroup); } else { if (pBucketGroup->pFirst && pBucketGroup->pLast) { printf("\nBegin Traversing, First = 0x%08" DW_PR_DUx ", Last = 0x%08" DW_PR_DUx "\n", pBucketGroup->pFirst->key,pBucketGroup->pLast->key); ProcessBucketGroup(pBucketGroup,PrintBucketData); } } } } static void PrintBucketData(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData) { int nCount = 0; assert(pBucketGroup); assert(pBucketData); nCount = FindDataIndexInBucket(pBucketGroup,pBucketData); printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx ", Flag = %d, Name = '%s'\n", ++nCount, pBucketData->key, pBucketData->base, pBucketData->low, pBucketData->high, pBucketData->bFlag, pBucketData->name); } static void DumpFullBucketGroup(Bucket_Group *pBucketGroup) { int nBucketNo = 1; int nIndex = 0; int nCount = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); printf("\nBucket Group at 0x%" DW_PR_DUx " [lower 0x%" DW_PR_DUx " upper 0x%" DW_PR_DUx "]\n", (Dwarf_Unsigned)(uintptr_t)pBucketGroup, (Dwarf_Unsigned)pBucketGroup->lower, (Dwarf_Unsigned)pBucketGroup->upper); for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { printf("LowPC & HighPC records for bucket %d, at 0x%08" DW_PR_DUx "\n", nBucketNo++, (Dwarf_Unsigned)(uintptr_t)pBucket); for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx ", Flag = %d, Name = '%s'\n", ++nCount, pBucketData->key, pBucketData->base, pBucketData->low, pBucketData->high, pBucketData->bFlag, pBucketData->name); } } } /* Insert entry into Bucket Group. We make no check for duplicate information. */ void AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key,Dwarf_Addr base, Dwarf_Addr low,Dwarf_Addr high, const char *name, Dwarf_Bool bFlag) { Bucket *pBucket = 0; Bucket_Data data; data.bFlag = bFlag; data.name = name; data.key = key; data.base = base; data.low = low; data.high = high; assert(pBucketGroup); if (!pBucketGroup->pHead) { /* Allocate first bucket */ pBucket = (Bucket *)calloc(1,sizeof(Bucket)); pBucketGroup->pHead = pBucket; pBucketGroup->pTail = pBucket; pBucket->nEntries = 1; pBucket->Entries[0] = data; return; } pBucket = pBucketGroup->pTail; /* Check if we have a previous allocated set of buckets (have been cleared */ if (pBucket->nEntries) { if (pBucket->nEntries < BUCKET_SIZE) { pBucket->Entries[pBucket->nEntries++] = data; } else { /* Allocate new bucket */ pBucket = (Bucket *)calloc(1,sizeof(Bucket)); pBucketGroup->pTail->pNext = pBucket; pBucketGroup->pTail = pBucket; pBucket->nEntries = 1; pBucket->Entries[0] = data; } } else { /* We have an allocated bucket with zero entries; search for the first available bucket to be used as the current insertion point */ for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { if (pBucket->nEntries < BUCKET_SIZE) { pBucket->Entries[pBucket->nEntries++] = data; break; } } } } /* For Groups where entries are individually deleted, this does that work. */ Dwarf_Bool DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; /* Sanity checks */ assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData->key == key) { Bucket_Data data = {FALSE,NULL,0,0,0,0}; int nStart; for (nStart = nIndex + 1; nStart < pBucket->nEntries; ++nStart) { pBucket->Entries[nIndex] = pBucket->Entries[nStart]; ++nIndex; } pBucket->Entries[nIndex] = data; --pBucket->nEntries; return TRUE; } } } return FALSE; } /* Search to see if the address is in the range between low and high addresses in some Bucked Data record. This matches == if high is exact match (which usually means one-past-true-high). */ Dwarf_Bool FindAddressInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr address) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (address >= pBucketData->low && address <= pBucketData->high) { return TRUE; } } } return FALSE; } /* Search an entry (Bucket Data) in the Bucket Set */ Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key) { int mid = 0; int low = 0; int high = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { /* Get lower and upper references */ if (pBucket->nEntries) { low = 0; high = pBucket->nEntries; while (low < high) { mid = low + (high - low) / 2; if (pBucket->Entries[mid].key < key) { low = mid + 1; } else { high = mid; } } if ((low < pBucket->nEntries) && (pBucket->Entries[low].key == key)) { pBucketData = &pBucket->Entries[low]; /* Update sentinels to allow traversing the table */ if (!pBucketGroup->pFirst) { pBucketGroup->pFirst = pBucketData; } pBucketGroup->pLast = pBucketData; return pBucketData; } } } return (Bucket_Data *)NULL; } /* Find the Bucket that contains a given Bucket Data and return its local index. Else return -1. */ static int FindDataIndexInBucket(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData) { Bucket *pBucket = 0; Bucket_Data *pLower = 0; Bucket_Data *pUpper = 0; /* Sanity checks */ assert(pBucketGroup); assert(pBucketData); /* Use sentinels if any. */ if (pBucketGroup->pFirst && pBucketGroup->pLast && pBucketData >= pBucketGroup->pFirst && pBucketData <= pBucketGroup->pLast) { /* Find bucket that contains the first sentinel */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket. */ if (pBucketGroup->pFirst >= pLower && pBucketGroup->pFirst <= pUpper) { /* We have found the bucket, return the index. */ return pBucketData - pBucketGroup->pFirst; } } } else { /* Find bucket that contains the entry */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket */ if (pBucketData >= pLower && pBucketData <= pUpper) { /* We have found the bucket, return the index */ return pBucketData - pLower; } } } /* Invalid data; just return index indicating not-found */ return -1; } /* Search an entry (Bucket Data) in the Bucket Group. The key is an offset, a DIE offset within Visited info. */ Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; /* Sanity checks */ assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData->key == key) { return pBucketData; } } } return (Bucket_Data *)NULL; } /* Search an entry (Bucket Data) in the Bucket Set by name. Used to find link-once section names. */ Bucket_Data * FindNameInBucketGroup(Bucket_Group *pBucketGroup,char *name) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); /* For now do a linear search. */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (!strcmp(pBucketData->name,name)) { return pBucketData; } } } return (Bucket_Data *)NULL; } /* Check if an address valid or not. That is, check if it is in the lower -> upper range of a bucket. It checks <= and >= so the lower end and one-past on the upper end matches. */ Dwarf_Bool IsValidInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address) { Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; int nIndex = 0; assert(pBucketGroup); /* Check the address is within the allowed limits */ if (address >= pBucketGroup->lower && address <= pBucketGroup->upper) { pBucket = pBucketGroup->pHead; for ( ; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (address >= pBucketData->low && address <= pBucketData->high) { return TRUE; } } } } return FALSE; } /* Reset limits for values in the Bucket Set */ void ResetLimitsBucketSet(Bucket_Group *pBucketGroup) { assert(pBucketGroup); pBucketGroup->lower = 0; pBucketGroup->upper = 0; } /* Limits are set only for ranges, so only in pRangesInfo. But is used for ranges and location lists. The default is set from object data (virt addr, size in object file) but that does not work sensibly in PE object files. */ void SetLimitsBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr lower,Dwarf_Addr upper) { assert(pBucketGroup); if (lower < upper) { pBucketGroup->lower = lower; pBucketGroup->upper = upper; } } /* Traverse Bucket Set and execute a supplied function */ static void ProcessBucketGroup(Bucket_Group *pBucketGroup, void (*pFunction)(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData)) { int nIndex = 0; int nStart = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; Bucket_Data *pLower = 0; Bucket_Data *pUpper = 0; Dwarf_Bool bFound = FALSE; /* Sanity checks */ assert(pBucketGroup); /* No sentinels present; do nothing */ if (!pBucketGroup->pFirst || !pBucketGroup->pLast) { return; } /* Find bucket that contains the first sentinel */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket */ if (pBucketGroup->pFirst >= pLower && pBucketGroup->pFirst <= pUpper) { /* Low sentinel is in this bucket */ bFound = TRUE; break; } } /* Invalid sentinel; do nothing */ if (!bFound) { return; } /* Calculate index for first sentinel */ nStart = pBucketGroup->pFirst - pLower; /* Start traversing from found bucket */ for (; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = nStart; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData > pBucketGroup->pLast) { return; } /* Call the user supplied function */ if (pFunction) { pFunction(pBucketGroup,pBucketData); } } /* For next bucket start with first entry */ nStart = 0; } } /* Check if a given (lopc,hipc) are valid for a linkonce. We pass in the linkonce (instead of referencing the global pLinkonceInfo) as that means searches for pLinkonceInfo find all the uses, making understanding of the code a tiny bit easier. The section name created is supposed to be the appropriate linkonce section name. */ Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo, const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc) { #define SECTION_NAME_LEN 2048 /* Guessing a sensible length */ static char section_name[SECTION_NAME_LEN]; Bucket_Data *pBucketData = 0; /* Since text is quite uniformly just this name, no need to get it from elsewhere, though it will not work for non-elf. */ const char *lo_text = ".text."; /* Build the name that represents the linkonce section (.text). This is not defined in DWARF so not correct for all compilers. */ struct esb_s sn; esb_constructor_fixed(&sn,section_name,sizeof(section_name)); esb_append(&sn,lo_text); esb_append(&sn,name); pBucketData = FindNameInBucketGroup(pLo,esb_get_string(&sn)); esb_destructor(&sn); if (pBucketData) { if (lopc >= pBucketData->low && lopc <= pBucketData->high) { if (hipc >= pBucketData->low && hipc <= pBucketData->high) { return TRUE; } } } return FALSE; } libdwarf-20210528/dwarfdump/attr_formclass_ext.list0000664000175000017500000001622314015312236017266 00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* Most of these are not formally documented. */ /* badly named GNU extensions. */ 0xffffffff DW_AT_sf_names 0xffffffff DW_AT_body_begin 0xffffffff DW_AT_body_end 0xffffffff DW_AT_src_info 0xffffffff DW_AT_src_coords 0xffffffff DW_AT_mac_info /* DW_AT_UPC_theads_scaled would be better, but... */ 0xffffffff DW_AT_upc_threads_scaled 0xffffffff DW_AT_ALTIUM_loclist 0xffffffff DW_AT_APPLE_block 0xffffffff DW_AT_APPLE_flags 0xffffffff DW_AT_APPLE_isa 0xffffffff DW_AT_APPLE_major_runtime_vers 0xffffffff DW_AT_APPLE_omit_frame_ptr 0xffffffff DW_AT_APPLE_optimized 0xffffffff DW_AT_APPLE_runtime_class 0xffffffff DW_AT_GNAT_descriptive_type 0xffffffff DW_AT_GNU_addr_base DW_FORM_CLASS_ADDRPTR 0xffffffff DW_AT_GNU_all_call_sites DW_FORM_CLASS_FLAG 0xffffffff DW_AT_GNU_all_source_call_sites 0xffffffff DW_AT_GNU_all_tail_call_sites DW_FORM_CLASS_FLAG 0xffffffff DW_AT_GNU_bias 0xffffffff DW_AT_GNU_call_site_data_value DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_GNU_call_site_target DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_GNU_call_site_target_clobbered 0xffffffff DW_AT_GNU_call_site_value DW_FORM_CLASS_EXPRLOC 0xffffffff DW_AT_GNU_deleted 0xffffffff DW_AT_GNU_denominator DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_GNU_discriminator DW_FORM_CLASS_CONSTANT /* Expect DW_FORM_ref_sig8 */ 0xffffffff DW_AT_GNU_dwo_id DW_FORM_CLASS_REFERENCE DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_GNU_dwo_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_GNU_entry_view /* The next few are documented on https://gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ 0xffffffff DW_AT_GNU_guarded_by 0xffffffff DW_AT_GNU_pt_guarded_by 0xffffffff DW_AT_GNU_pt_guarded 0xffffffff DW_AT_GNU_locks_excluded 0xffffffff DW_AT_GNU_exclusive_locks_required 0xffffffff DW_AT_GNU_shared_locks_required /* end Thread Safety annotations. */ 0xffffffff DW_AT_GNU_locviews 0xffffffff DW_AT_GNU_macros DW_FORM_CLASS_MACROPTR 0xffffffff DW_AT_GNU_numerator DW_FORM_CLASS_CONSTANT /* Expect DW_FORM_ref_sig8 */ 0xffffffff DW_AT_GNU_odr_signature DW_FORM_CLASS_CONSTANT DW_FORM_CLASS_REFERENCE /* https://binutils.sourceware.narkive.com/zhSf69Vo/gold-patch-handle-dw-at-gnu-pubnames-in-dw-form-flag-present */ 0xffffffff DW_AT_GNU_pubnames DW_FORM_CLASS_REFERENCE DW_FORM_CLASS_FLAG DW_FORM_CLASS_CONSTANT /* Have seen all the above formclasses from gcc */ 0xffffffff DW_AT_GNU_pubtypes DW_FORM_CLASS_REFERENCE DW_FORM_CLASS_FLAG DW_FORM_CLASS_CONSTANT /* Have seen all the above formclasses from gcc */ 0xffffffff DW_AT_GNU_ranges_base /*DW_FORM_CLASS_REFERENCE */ DW_FORM_CLASS_RNGLISTSPTR 0xffffffff DW_AT_GNU_tail_call DW_FORM_CLASS_FLAG 0xffffffff DW_AT_GNU_template_name 0xffffffff DW_AT_GNU_vector 0xffffffff DW_AT_go_kind 0xffffffff DW_AT_go_key 0xffffffff DW_AT_go_elem 0xffffffff DW_AT_go_embedded_field 0xffffffff DW_AT_go_runtime_type /* some DW_AT_HP and all DW_AT_CPQ left off */ 0xffffffff DW_AT_HP_all_variables_modifiable 0xffffffff DW_AT_HP_block_index 0xffffffff DW_AT_HP_cold_region_high_pc 0xffffffff DW_AT_HP_cold_region_low_pc 0xffffffff DW_AT_HP_linkage_name 0xffffffff DW_AT_HP_prof_version_id 0xffffffff DW_AT_INTEL_other_endian 0xffffffff DW_AT_MIPS_abstract_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_MIPS_allocatable_dopetype 0xffffffff DW_AT_MIPS_assumed_shape_dopetype 0xffffffff DW_AT_MIPS_assumed_size 0xffffffff DW_AT_MIPS_clone_origin 0xffffffff DW_AT_MIPS_epilog_begin 0xffffffff DW_AT_MIPS_fde DW_FORM_CLASS_FRAMEPTR 0xffffffff DW_AT_MIPS_has_inlines DW_FORM_CLASS_FLAG 0xffffffff DW_AT_MIPS_linkage_name DW_FORM_CLASS_STRING 0xffffffff DW_AT_MIPS_loop_begin 0xffffffff DW_AT_MIPS_loop_unroll_factor 0xffffffff DW_AT_MIPS_ptr_dopetype 0xffffffff DW_AT_MIPS_software_pipeline_depth 0xffffffff DW_AT_MIPS_stride 0xffffffff DW_AT_MIPS_stride_byte 0xffffffff DW_AT_MIPS_stride_elem 0xffffffff DW_AT_MIPS_tail_loop_begin 0xffffffff DW_AT_PGI_lbase 0xffffffff DW_AT_PGI_lstride 0xffffffff DW_AT_PGI_soffset 0xffffffff DW_AT_SUN_alignment 0xffffffff DW_AT_SUN_amd64_parmdump 0xffffffff DW_AT_SUN_browser_file 0xffffffff DW_AT_SUN_cf_kind 0xffffffff DW_AT_SUN_command_line 0xffffffff DW_AT_SUN_compile_options 0xffffffff DW_AT_SUN_count_guarantee 0xffffffff DW_AT_SUN_c_vla 0xffffffff DW_AT_SUN_dtor_length 0xffffffff DW_AT_SUN_dtor_start 0xffffffff DW_AT_SUN_dtor_state_deltas 0xffffffff DW_AT_SUN_dtor_state_final 0xffffffff DW_AT_SUN_dtor_state_initial 0xffffffff DW_AT_SUN_f90_allocatable 0xffffffff DW_AT_SUN_f90_assumed_shape_array 0xffffffff DW_AT_SUN_f90_pointer 0xffffffff DW_AT_SUN_f90_use_only 0xffffffff DW_AT_SUN_fortran_based 0xffffffff DW_AT_SUN_fortran_main_alias 0xffffffff DW_AT_SUN_func_offset 0xffffffff DW_AT_SUN_func_offsets 0xffffffff DW_AT_SUN_hwcprof_signature 0xffffffff DW_AT_SUN_import_by_lname 0xffffffff DW_AT_SUN_import_by_name 0xffffffff DW_AT_SUN_is_omp_child_func 0xffffffff DW_AT_SUN_language 0xffffffff DW_AT_SUN_link_name DW_FORM_CLASS_STRING /* just guessing about this one */ 0xffffffff DW_AT_SUN_memop_signature 0xffffffff DW_AT_SUN_memop_type_ref 0xffffffff DW_AT_SUN_namelist_spec 0xffffffff DW_AT_SUN_obj_dir 0xffffffff DW_AT_SUN_obj_file 0xffffffff DW_AT_SUN_omp_child_func 0xffffffff DW_AT_SUN_omp_tpriv_addr 0xffffffff DW_AT_SUN_original_name 0xffffffff DW_AT_SUN_part_link_name DW_FORM_CLASS_STRING /* just guessing about this one */ 0xffffffff DW_AT_SUN_pass_by_ref 0xffffffff DW_AT_SUN_pass_with_const 0xffffffff DW_AT_SUN_profile_id 0xffffffff DW_AT_SUN_return_value_ptr 0xffffffff DW_AT_SUN_return_with_const 0xffffffff DW_AT_SUN_template 0xffffffff DW_AT_SUN_vbase 0xffffffff DW_AT_SUN_vtable 0xffffffff DW_AT_SUN_vtable_abi 0xffffffff DW_AT_SUN_vtable_index 0xffffffff DW_AT_use_GNAT_descriptive_type 0xffffffff DW_AT_ghs_rsm DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_ghs_frsm DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_ghs_frames DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_ghs_rso DW_FORM_CLASS_CONSTANT 0xffffffff DW_AT_ghs_subcpu DW_FORM_CLASS_CONSTANT 0xffffffff libdwarf-20210528/dwarfdump/testuriLE64ELf.obj0000664000175000017500000006476013644370703015666 00000000000000ELF>pc@@GÐ< vGŸ<vG¿<wGÉÀóÃfDG©Ã@Hƒì@¾ÏH‹=H¾1Àè1ÀHƒÄÀAUATUSHƒìdH‹%(H‰D$1À¶„Àt_H‰ûH‰õL%Ll$ë"HƒÃL‰îH‰ïˆD$ÆD$è¶„Àt)¶ÈA€< H‰ÊuÔH51ÀHƒÃH‰ïè¶„Àu×H‹D$dH3%(u HƒÄ[]A\A]ÃèAVAUATUSHƒìdH‹%(H‰D$1À¶„À„ŸH‰ûI‰õLt$ëk@D¶cA€ü%„©E„ä„À¶k@„í…ãH‹ H=Hkºs¾èL‰öL‰ïDˆd$ÆD$è¶EH]„Àt'<%t•H‰ÝL‰öL‰ïˆD$ÆD$H]è¶E„ÀuÙH‹D$dH3%(…‹HƒÄ[]A\A]A^Ãf„¸%L‰öL‰ïf‰D$HkèëˆDH‹ H=ºa¾H‰ÝA¼%èéCÿÿÿDA¾üè·ýÿÿA‰Ä@¾ýHkAÁäè£ýÿÿA ÄéÿÿÿèTranslating from uri: A supposed hexadecimal input character is not 0-9 or a-f or A-F, it is (shown as hex here): %x Translating from uri: A supposed hexadecimal input character pair runs off the end of the input after 1 hex digit. Translating from uri: A supposed hexadecimal input character pair runs off the end of the input. %%%02x> jØ8intŒiiŽŽØõ öb ûˆ üˆ ýˆ þˆ ÿˆ( ˆ0 ˆ8 ˆ@ ˆH ˆP ˆX ]`  ch  bp bt px F€ T‚ iƒ yˆ %{ -†˜ .†  /†¨ 0†° 2-¸ 3bÀ 5Äš š ] ¡] ¢c ¦b,š Žy 8% Ž 8?@A•¸¸‡cˆc‰cb ¾ÿôÿ J L M Nb U[ ‘w ’> “` ”w *8 µ@ e~ j~ m8 p8 s xˆ ~~( -0 ‡M8 ’M8 –M8 šM8 žM8 ¡M8 ¤M8? §¥0 &á '> (¸key )3 ,3low -3 .3( /~ :# ;b <# =4ˆ~ á48÷ì >ì8 B¢ Cb D3 E3 F¢ G¢ H¨( I¨0á: JE bM îs2lˆ KÇ L M N O P Q( R0 S8 T@ UH VP WX X` Yh Zp [x \€¸ bb l¹ mÄ o¹ p¹ q¹ r¹ s¹ t¹ u¹ v¹$ w¹( x¹, y¹0 z¹4 {¹8 |¹< }¹@ ~¹D ¹H €¹L ¹P ‚¹T ƒ¹X „¹\ …¹` ‡¹d ˆ¹h йl ‹¹p Œ¹t ¹x ޹| ¹€ ¹„ ‘¹ˆ ’¹Œ “¹ ”¹” •¹˜ –¹œ —¹  ˜¹¤ ™¹¨ 𹬠›¹° œ¹´ ¹¸ ž¹¼ Ÿ¹À  ¹Ä ¢¹È ¦¹Ì §¹Ð ¨¹Ô «¹Ø ¬¹Ü ®¹à ¯¹ä °¹è ±¹ì ²¹ð ´¹ô µ¹ø ·¹ü ¸¹ ¹¹ º¹ »¹  À¹ Á¹ ¹ ù ȹ  ˹$ ̹( Íb, й0 Ó¹4 Õ¹8 Ö¹< ×¹@ عD Ù¹H Û8P Þ¹X ß¹\ à¹` á¹d â¹h ã¹l å¹p æ¹t ç3x è3€ ê(ˆ ë( î(˜ ï(  ðb¨ õ3° ö3¸ ÷3À ù(È ú(Ð ü¸Ø ý¸à ÿ¸è! ¸ð! ¸ø! b! b ! b! ¹! ¹! ¹! b ! h (! !n 0! )n 8! 4n @! :t H! ;t H! <t H! ?… H! B¸x! Cb€! FÞ ˆ! GÞ ! HÞ ˜! IÞ  ! Jé ¨! Mb°„î® Ž… 8ÿ b• 8  ?Þ @ˆ A- D- MŽ NŽ• ä  PÇ[†\†ÅI Ž, 8ÿ"! #vjœš$v¸%outvÞ &cpx¸'yš‘F(Œ&c{Ž(q)}b&c2~Ž*ªˆ8+Æ+»,-Ò-Þ-ê.ôí-õ/!b+80-12U 2T12Qs3_++,4)\56Ý2U|8$8&663k+80-12U 2T12Qa5V2U}2T~12U}2T~12U}2T~6" Žª 87Wb8cpW¸9Wˆ:YŽ:Zb;c[Ž<;c2]Ž7QŽ68c1QŽ8c2QŽ;outSŽ7;Ž^8c;Ž:=Ž#( œ$(¸%out(Þ &cp*¸(=v-š‘F&c.b5í2Uv2T}1+2Uv2T 6">_bE?_K?_Ã@EA6Yœ+G-QB6 +GC DtE K+80-162T12Q 2R óU8$8&FG_HG…GU% : ; I$ > $ >   I&I : ;  : ; I8 : ;I8 : ; I !I/ <4: ;I?<7I4: ; I?<!: ;I : ; : ; : ;I 8  : ;  : ; I8  : ;  : ; I8!I/> I: ; ( (  : ;  : ; I8! : ;I8"4: ; I#.?: ;'@—B$: ;I%: ;I&4: ;I'4: ;I( U)4: ;I*1RUX Y+1, U-41. 1U/1X Y011‰‚12Š‚‘B31RUX Y4415‰‚16‰‚17.: ;'I 8: ;I9: ;I:4: ;I;4: ;I< =4: ;I>.?: ; 'I 4?: ; I@A.1@—BB 1C D41E1X YF.?<n: ; nG.?<n: ; H.?<n4U4jóUŸ4T4Æ]ÆçóTŸçe]ejóTŸ4U4“S“›V›¹S¹¾V¾ÆSç S  V eS4}P~“\Ÿ½PçõP 5P;HP4~0Ÿçe0Ÿ=~\ç1\15s;L\G~ò eòG~sŸ esŸG~0Ÿ 60Ÿ6;%Ÿ;`0ŸG~0Ÿ `0Ÿ`e2ŸG~\ 1\15s;L\ToVo}s;TVT\U]~ Ÿ;TVT\U;L\ 6 Ÿ`•U•óUŸ`•T•àVàóTŸz•U•œSœ°sŸ°ÑSÑÙsŸÙàS•¯RÂØR?U?QRQYóUŸ0ŸP+0Ÿ+,P,Y0Ÿ,?U?QRQRóUŸ,R Ÿ,jŽ˜œ°·ÍÑÙ8“Ÿµ¹¾ðe8“ðeG~eP~@eDLTe+1@CŠû /home/davea/dwarf/code/dwarfdump/usr/include/x86_64-linux-gnu/bits/usr/lib/gcc/x86_64-linux-gnu/7/include/usr/include/x86_64-linux-gnu/bits/types/usr/include../libdwarfuri.cstdio2.hstddef.htypes.hlibio.hFILE.hstdio.hsys_errlist.hlibdwarf.hregex.hcheckutil.hdefined_types.hglflags.hesb.hglobals.h »xxu=‰t‚=xX¥~JîäZºžõBzžPdKYzXv=W=3xRx‚ tÀäºõ°Z\ž‘Kƒ~ªòdYYoX¼tdKjXJiX‚n*Zd[IZÜ}tžó}fþätJ ‚t‚Àgf_check_show_resultsprogram_fullname__streamDIE_offsetDIE_overall_offsetsize_tellipsisdebug_str_sizegf_print_unique_errorsdebug_aranges_sizesection_high_offsets_s__fmt_IO_2_1_stderr_gf_count_major_errorsseen_PU__buffer_IO_save_endgf_check_pubname_attrre_syntax_optionstranslate_to_uriorig__fastmap_accuratefde_offset_for_cu_low_IO_write_basedebug_macro_sizegf_check_self_referencesesb_stringDwarf_Off_lockglflagsnewprognamegf_display_children_treedenseshow_form_usedgf_generic_1200_regs_IO_save_base/home/davea/dwarf/code/dwarfdump/uri.cgf_check_macros_chain_cur_columnsys_nerrdebug_frame_sizekindhexpairtochargf_suppress_nested_name_searchgf_do_print_uri_in_inputdebug_loc_sizelong intgf_display_parent_tree__fprintf_chkorig2lneed_CU_high_address_IO_markerre_nsubpHeadDwarf_Unsignedgf_print_usage_tag_attr_fullgf_header_flaghighgf_reloc_flaggf_check_forward_declesb_fixedsigned char_IO_FILEfilenamebooleancurrent_section_idunsigned char__syntaxincrementgf_macinfo_flagdwarfdump_ctype_tableglflags_sgf_eh_frame_flag_IO_FILE_pluslowerneed_CU_base_addressolengf_check_frames_extendedchargf_search_is_onnTracemyocharBucket_Groupuppergf_check_frames_IO_lock_tdebug_abbrev_sizeseen_PU_high_addressgf_check_abbreviationsgf_check_gcc_compilerreg_syntax_tsearch_regex_text_IO_read_ptrpVisitedInfo__newline_anchorconfig_file_pathBucket_Data_posstdin__can_be_nullgf_pubnames_flagsys_errlistdebug_str_offsets_sizeinputesb_rigid_markersprogram_name__translatetranslate_from_urigf_check_linesgf_check_harmlessre_pattern_buffer_offsetDwarf_Addrgf_check_duplicated_attributesseen_PU_base_address_unused2gf_line_print_pcbreak_after_n_unitssection_high_offsets_globalgf_check_attr_encoding__builtin_fwritegf_loc_flag_IO_2_1_stdin_long unsigned intCU_high_address_flags2gf_static_var_flaggf_do_check_dwarfesb_appendDwarf_Die_s_IO_read_basetohex/tmp/dwbld/dwarfdumpline_flag_type_e__fastmapdwconf_s__not_eolgf_pubtypes_flaggf_check_di_gapsDwarf_Bool_old_offsetmacro_check_treegf_line_flagverboseCU_namePU_high_addresslong long intdebug_pubnames_sizegf_check_debug_namesgf_check_attr_tagCU_base_addressgf_suppress_checking_on_dwpdwarf_cmdline_optionsdebug_sup_size_IO_write_enddebug_types_sizegf_check_verbose_modedebug_macinfo_sizeDIE_CU_overall_offsetconfig_file_data_IO_buf_basegf_cu_name_flagsearch_any_textunsigned intfwrite__not_bolesb_allocated_sizeneed_PU_valid_code__pad1__pad2__pad3__pad4__pad5_sbufcheck_errorgf_check_snc_compilerPU_base_addressgf_line_skeleton_flag_flags_modegroup_numberpLinkonceInfoDwarf_Cmdline_Optionsgf_print_summary_all__stack_chk_faildebug_pubtypes_sizegf_suppress_check_extensions_tablesdebug_cu_index_sizegf_record_dwarf_errorgf_search_print_resultsFILEgf_do_print_dwarfcheck_verbose_modegf_stop_indent_levelgf_gdbindex_flaggf_display_offsetsfde_offset_for_cu_highDIE_CU_offsetregex_tcu_namesearch_regf_frame_flagsearch_occurrencesdebug_tu_index_sizesingledw5long long unsigned intconfig_file_tiedpathpTailEntriesgf_search_wide_format__off_tgf_ranges_flaggf_aranges_flagseen_CUgf_static_func_flaggf_info_flaggf_show_global_offsetsbFlagdebug_line_size_IO_backup_base_shortbuf_IO_2_1_stdout_search_match_textgf_found_error_message__allocated_nextgf_types_flag__off64_tCU_low_addressgf_print_usage_tag_attrgf_line_flag_selectiongf_abbrev_flag__usednEntries_IO_buf_endtempstrCU_producernameesb_used_bytesfprintfgf_producer_children_flagPU_namestderrgf_check_namesshort intpRangesInfogf_check_rangesgf_check_reloc_offset_vtable_offsetoutput_filegf_gnu_debuglink_flagocharbucketgf_macro_flaggf_check_type_offsetgf_string_flaggf_check_locations_IO_read_endgf_check_arangesgf_check_abbrev_codedebug_ranges_size_fileno__regs_allocatedBucketgf_weakname_flaggf_debug_names_flaggf_check_fdesgf_check_dwarf_constants__no_subshort unsigned intstdoutesb_sbasegf_check_decl_file_IO_write_ptrgf_section_groups_flaggf_print_str_offsetspFirstgf_check_tag_treeDwarf_Diegf_file_use_no_libelfpNextgf_check_all_compilersGNU C11 7.4.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strongneed_CU_namepLastgf_uri_options_translationgf_use_old_dwarf_loclistmacinfo_check_treeesb_append_printfhexdigdebug_info_sizecurrent_cu_die_for_print_framesGCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0zRx Ytd84 BBŒA †A(ƒD@Š (A ABBA @pjBŽBB ŒA(†A0ƒD@Ò 0A(A BBBJ ñÿY   $).x3ð8?Uc` t‘¢jµuri.chexdigdwarfdump_ctype_table.LC0.LC1.LC2.LC3stderr_GLOBAL_OFFSET_TABLE___fprintf_chktranslate_to_uriesb_appendesb_append_printf__stack_chk_failtranslate_from_urifwrite;üÿÿÿÿÿÿÿBüÿÿÿÿÿÿÿNüÿÿÿÿÿÿÿŠ üÿÿÿÿÿÿÿ¬üÿÿÿÿÿÿÿÇüÿÿÿÿÿÿÿÕüÿÿÿÿÿÿÿüüÿÿÿÿÿÿÿ`üÿÿÿÿÿÿÿgüÿÿÿÿÿÿÿz üÿÿÿÿÿÿÿüÿÿÿÿÿÿÿºüÿÿÿÿÿÿÿüÿÿÿÿÿÿÿüÿÿÿÿÿÿÿüÿÿÿÿÿÿÿ2 üÿÿÿÿÿÿÿfüÿÿÿÿÿÿÿ i  ©) . N; /B àI ¡P ™ W §^ (l Öq ] | M ‘ ‰› ³§ N ³ N¿ çË •× _ã Ùï ýü l  ´   # Ú 0 ë= óJ OW ,d Qq ~ V‹ d˜ ê ¥ ­² [¿ Ý Ì ä Ù ë æ ò ó ù  U  ¢ , & Ð-  9 9 E  Q – B•  ¡ ô ­ ´É ›Ô ´ß ê b À c   9) £4 c? J ,\ ‰j C x v „ Ø /› ¦ I³ âÀ - Í ¤ Ú îç Ïô   + ¡ 4. 6> ˜N ­ ^ ân h… ´ ™ Ä ¥ Ô ½ ÁÕ tâ Ší ›ü «  ?  L; EN |Z Pf ºr ~ ÁŠ 3– 9 ¯ ­º ÅÅ ¾Ö  â 1è ï —û ' Û Ê  Ç+ „7 2 C qO ^[ kg s ²   ‹ n— Ì£ î¯ ê » ï È 'Õ âá ~ í • ù t  ] 1 Î ) k 5 A   M 6Y «e 8 q } ‰ ¢• ¯¡ e ­ y¹ Œ Å YÑ ÅÝ ìé ? õ L e  ç ð % 1 ø= NI šU a °m Æy ?… (‘ q >© ôµ 7Á Í Ù ýå ‡ñ ý ì õ Æ ! n- ¼9 E ÇQ ®] mi  u   À™ p¥ Ô± f ½ HÉ RÕ  â ï Œ ü 6 l 1 # 0 þ = …J ßW Çd V q G ~ Ž‹  ˜ y ¥ ­ ² | ¿ þÌ ÄÙ Úæ „ ó ´ V   Ê ' 4 íA ( N S[ 0h ;u ¦ ‚ E Íœ ¬© W ¶ Aà IÐ  Ý üê ÷ ‰    < Ü . Ä < CJ àX Uf æt ¼‚ Ð 2ž h ¬ [º  È KÖ È ä žò s [  » ¼ * y8 $ F [ T  – »¢ ˜® · º Ù Æ Ò éå Ùð ³ü % û 7- 9 B I` ãk { 9Š ® À ž P° iµ  ¾ ÷É ëØ #áGé Ðù € À Ð ú [" §+ 8 A]] ag~xx’Dš 0¦ ¯ ô 0ÀIÞ]òú ` æ6!ð9“W r¾j« Ç ¥Ó •ß k £7  R •_  f`} ¼ˆ ˜ K§ —¬ Ë Ð°îÙ è . '9 ®Up Sy Ÿ‚4— œ4¶4Î ]ØRî  ¦   ¦  ~ ~# ¡ ' ¡ , 0 7 ö; ö“ ¦« ¦txùðp — 8`t.symtab.strtab.shstrtab.rela.text.data.bss.rodata.str1.8.rodata.str1.1.rodata.rela.debug_info.debug_abbrev.rela.debug_loc.rela.debug_aranges.debug_ranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.eh_frame @j@¨=°&ª,ª12°R@2O  \ BW@X? "hb¤{‰v@xax ‹#0†@ða0 š¿#­O%G¨@ b¹0–'WÄ0í8,Í9â 9°Ý@8bHÐ9 è<¼€bìlibdwarf-20210528/dwarfdump/print_origloclist_codes.c0000664000175000017500000001077514004410655017565 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2020 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "helpertree.h" #include "tag_common.h" /* Prints locentry descriptsions for DW_LKIND_loclist */ int print_original_loclist_linecodes(Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char * attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * esbp, UNUSEDARG Dwarf_Bool * bError) { switch(lle_value) { case DW_LLE_base_address: esb_append_printf_u(esbp, "", hipc); break; case DW_LLE_end_of_list: /* Nothing to do. */ esb_append(esbp,""); break; case DW_LLE_offset_pair: { if (glflags.verbose) { esb_append_printf_u(esbp, "",rawhipc); esb_append_printf_i(esbp, "\n [%2d]",llent); } esb_append_printf_u(esbp, "", hipc); if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc,rawhipc, locdesc_offset, base_address, bError); } } break; case DW_LLE_start_end: /* debug_addr_unavailable does not apply here */ esb_append_printf_u(esbp, "",hipc); if (checking && !debug_addr_unavailable) { loc_error_check(tagname,attrname, lopc, rawlopc, hipc, rawhipc, locdesc_offset, base_address, bError); } break; default: { struct esb_s unexp; esb_constructor(&unexp); esb_append_printf_u(&unexp, "ERROR: Unexpected LLE code 0x%x" " in original loclist (synthesized code error)", lle_value); print_error_and_continue(dbg, esb_get_string(&unexp), DW_DLV_OK, 0); esb_destructor(&unexp); } break; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/tag_tree.c0000664000175000017500000004147314014247260014434 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2009-2017 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include /* For errno declaration. */ #ifdef HAVE_UNISTD_H #include #endif #include "common.h" #include "tag_common.h" #include "dwgetopt.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ unsigned int tag_tree_combination_table[TAG_TABLE_ROW_MAXIMUM] [TAG_TABLE_COLUMN_MAXIMUM]; #ifdef HAVE_USAGE_TAG_ATTR /* Working array for a specific tag and its valid tags */ static Dwarf_Half tag_tree_vector[DW_TAG_last] = {0}; static Dwarf_Half tag_parents[DW_TAG_last] = {0}; static Dwarf_Half tag_children[DW_TAG_last] = {0}; static Dwarf_Small tag_tree_legal[DW_TAG_last] = {0}; #endif /* HAVE_USAGE_TAG_ATTR */ const char * program_name; Dwarf_Bool ellipsis = FALSE; /* So we can use dwarf_names.c */ /* Expected input format 0xffffffff value of a tag value of a standard tag that may be a child ofthat tag ... 0xffffffff value of a tag value of a standard tag that may be a child ofthat tag ... 0xffffffff ... No commentary allowed, no symbols, just numbers. Blank lines are allowed and are dropped. */ static const char *usage[] = { "Usage: tag_tree_build ", "options:\t-t\tGenerate Tags table", " -i Input-file-path", " -o Output-table-path", " -e (Want Extended table (common extensions))", " -s (Want Standard table)", "" }; static char *input_name = 0; static char *output_name = 0; int extended_flag = FALSE; int standard_flag = FALSE; static void process_args(int argc, char *argv[]) { int c = 0; Dwarf_Bool usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:es")) != EOF) { switch (c) { case 'i': input_name = (char *)strdup(dwoptarg); break; case 'o': output_name = (char *)strdup(dwoptarg); break; case 'e': extended_flag = TRUE; break; case 's': standard_flag = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(argv[0],usage); exit(FAILED); } } /* New naming routine May 2016. Instead of directly calling dwarf_get_*() When bad tag/attr numbers are presented we return a warning string through the pointer. The thought is that eventually someone will notice the error. It might, of course, be better to emit an error message and stop. */ static void ta_get_TAG_name(unsigned int tagnum,const char **nameout) { int res = 0; res = dwarf_get_TAG_name(tagnum,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } /* these are used in assignments. */ static unsigned maxrowused = 0; static unsigned maxcolused = 0; /* The argument sizes are declared in tag_common.h, so the max usable is toprow-1 and topcol-1. */ static void check_unused_combo(unsigned toprow,unsigned topcol) { if ((toprow-1) != maxrowused) { printf("Providing for %u rows but used 0-%u\n", toprow,maxrowused); printf("Giving up\n"); exit(1); } if ((topcol-1) != maxcolused) { printf("Providing for %u cols but used 0-%u\n", topcol,maxcolused); printf("Giving up\n"); exit(1); } } static void validate_row_col(const char *position, unsigned crow, unsigned ccol, unsigned maxrow, unsigned maxcol) { if (crow >= TAG_TABLE_ROW_MAXIMUM) { printf("error generating row in tag-attr array, %s " "current row: %u size of static array decl: %u\n", position,crow, TAG_TABLE_ROW_MAXIMUM); exit(1); } if (crow >= maxrow) { printf("error generating row in tree tag array, %s " "current row: %u max allowed: %u\n", position,crow,maxrow-1); exit(1); } if (ccol >= TAG_TABLE_COLUMN_MAXIMUM) { printf("error generating column in tag-attr array, %s " "current col: %u size of static array decl: %u\n", position,ccol, TAG_TABLE_COLUMN_MAXIMUM); exit(1); } if (ccol >= maxcol) { printf("error generating column in tree tag array, %s " "current row: %u max allowed: %u\n", position,ccol,maxcol-1); exit(1); } if (crow > maxrowused) { maxrowused = crow; } if (ccol > maxcolused) { maxcolused = ccol; } return; } int main(int argc, char **argv) { unsigned u = 0; unsigned int num = 0; int input_eof = 0; unsigned table_rows = 0; unsigned table_columns = 0; unsigned current_row = 0; FILE *fileInp = 0; FILE *fileOut = 0; const char *aname = 0; unsigned int index = 0; print_version_details(argv[0],FALSE); print_args(argc,argv); process_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename," " could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"w"); if (!fileOut) { fprintf(stderr,"Invalid output filename," " could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } if (standard_flag) { table_rows = STD_TAG_TABLE_ROWS; table_columns = STD_TAG_TABLE_COLUMNS; } else { table_rows = EXT_TAG_TABLE_ROWS; table_columns = EXT_TAG_TABLE_COLS; } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } /* Generate main header, regardless of contents */ fprintf(fileOut,"/* Generated code, do not edit. */\n"); fprintf(fileOut,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR ); fprintf(fileOut,"\n/* BEGIN FILE */\n\n"); #ifdef HAVE_USAGE_TAG_ATTR /* Generate the data type to record the usage of the pairs tag-tag */ if (standard_flag) { fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#include \"dwarf.h\"\n"); fprintf(fileOut,"#include \"libdwarf.h\"\n\n"); fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," unsigned int count; /* Tag count */\n"); fprintf(fileOut," Dwarf_Half tag; /* Tag value */\n"); fprintf(fileOut,"} Usage_Tag_Tree;\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ while (!feof(stdin)) { unsigned int tag = 0; unsigned nTagLoc = 0; unsigned int cur_tag = 0; unsigned int child_tag; input_eof = read_value(&tag,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } if (standard_flag) { if (current_row >= table_rows ) { bad_line_input( "tag value exceeds standard table size"); } } else { if (current_row >= table_rows) { bad_line_input("too many extended table rows."); } validate_row_col("Reading tag",current_row,0, table_rows,table_columns); tag_tree_combination_table[current_row][0] = tag; } input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } nTagLoc = 1; cur_tag = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Check if we have duplicated tags */ if (standard_flag) { if (tag_parents[tag]) { bad_line_input("tag 0x%02x already defined",tag); } tag_parents[tag] = tag; /* Clear out the working attribute vector */ memset(tag_tree_vector,0,DW_TAG_last * sizeof(Dwarf_Half)); } #endif /* HAVE_USAGE_TAG_ATTR */ while (num != MAGIC_TOKEN_VALUE) { if (standard_flag) { unsigned idx = num / BITS_PER_WORD; unsigned bit = num % BITS_PER_WORD; if (idx >= table_columns) { fprintf(stderr,"Want column %d, have only %d\n", idx,table_columns); bad_line_input( "too many TAGs: table incomplete."); } validate_row_col("Update columns bit",tag,idx, table_rows,table_columns); tag_tree_combination_table[tag][idx] |= (((unsigned)1) << bit); } else { if (nTagLoc >= table_columns) { printf("Attempting to use column %d, max is %d\n", nTagLoc,table_columns); bad_line_input( "too many subTAGs, table incomplete."); } validate_row_col("Update tagloc",current_row,nTagLoc, table_rows,table_columns); tag_tree_combination_table[current_row][nTagLoc] = num; nTagLoc++; } #ifdef HAVE_USAGE_TAG_ATTR /* Record the usage only for standard tables */ if (standard_flag) { /* Add child tag to current tag */ if (cur_tag >= DW_TAG_last) { bad_line_input( "too many TAGs: table incomplete."); } /* Check for duplicated entries */ if (tag_tree_vector[cur_tag]) { bad_line_input( "duplicated tag: table incomplete."); } tag_tree_vector[cur_tag] = num; cur_tag++; } #endif /* HAVE_USAGE_TAG_ATTR */ input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the tag-tree vector for current tag */ if (standard_flag) { if (tag >= DW_TAG_last) { bad_line_input( "tag value exceeds standard table size"); } if (tag_children[tag]) { bad_line_input("subtag 0x%02x already defined",tag); } tag_children[tag] = tag; /* Generate reference vector */ aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname); fprintf(fileOut, "static Usage_Tag_Tree tag_tree_%02x[%d] = {\n", tag,cur_tag+1); for (index = 1; index < cur_tag; ++index) { child_tag = tag_tree_vector[index]; ta_get_TAG_name(child_tag,&aname); fprintf(fileOut," {/* 0x%02x */ 0, %s},\n", child_tag,aname); } fprintf(fileOut," {/* %4s */ 0, 0}\n};\n\n"," "); /* Record allowed number of attributes */ tag_tree_legal[tag] = cur_tag - 1; } #endif /* HAVE_USAGE_TAG_ATTR */ ++current_row; /* for extended table */ } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the parent of the individual vectors */ if (standard_flag) { unsigned int tag = 0; unsigned int legal = 0; fprintf(fileOut, "static Usage_Tag_Tree *usage_tag_tree[0x%02x] = {\n", DW_TAG_last+1); for (index = 0; index < DW_TAG_last; ++index) { tag = tag_children[index]; if (tag) { aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " tag_tree_%02x, /* 0x%02x - %s */\n", tag,tag,aname); } else { fprintf(fileOut," 0,\n"); } } fprintf(fileOut," 0\n};\n\n"); /* Generate table with allowed number of tags */ fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," Dwarf_Small legal; /* Legal tags */\n"); fprintf(fileOut," Dwarf_Small found; /* Found tags */\n"); fprintf(fileOut,"} Rate_Tag_Tree;\n\n"); fprintf(fileOut, "static Rate_Tag_Tree rate_tag_tree[0x%02x] = {\n", DW_TAG_last+1); for (tag = 0; tag < DW_TAG_last; ++tag) { if (tag_children[tag]) { legal = tag_tree_legal[tag]; aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " {%2d, 0 /* 0x%02x - %s */},\n", legal,tag,aname); } else { fprintf(fileOut," {0, 0},\n"); } } fprintf(fileOut," {0, 0}\n};\n\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ check_unused_combo(table_rows, table_columns); if (standard_flag) { fprintf(fileOut,"#define TAG_TREE_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut,"#define TAG_TREE_ROW_COUNT %d\n\n", table_rows); fprintf(fileOut, "static unsigned int tag_tree_combination_table\n"); fprintf(fileOut, " [TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = {\n"); } else { fprintf(fileOut, "#define TAG_TREE_EXT_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut, "#define TAG_TREE_EXT_ROW_COUNT %d\n\n", table_rows); fprintf(fileOut,"/* Common extensions */\n"); fprintf(fileOut, "static unsigned int tag_tree_combination_ext_table\n"); fprintf(fileOut, " [TAG_TREE_EXT_ROW_COUNT]" "[TAG_TREE_EXT_COLUMN_COUNT]" " = {\n"); } for (u = 0; u < table_rows; u++) { unsigned j = 0; const char *name = 0; if (standard_flag) { ta_get_TAG_name(u,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u, name); } else { unsigned k = tag_tree_combination_table[u][0]; ta_get_TAG_name(k,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n", k, name); } fprintf(fileOut," { "); for (j = 0; j < table_columns; ++j ) { fprintf(fileOut,"0x%08x,", tag_tree_combination_table[u][j]); } fprintf(fileOut,"},\n"); } fprintf(fileOut,"};\n"); fprintf(fileOut,"\n/* END FILE */\n"); fclose(fileInp); fclose(fileOut); return (0); } /* A fake so we can use dwarf_names.c */ void print_error (UNUSEDARG Dwarf_Debug dbg, UNUSEDARG const char *msg, UNUSEDARG int res, UNUSEDARG Dwarf_Error localerr) { } libdwarf-20210528/dwarfdump/uri.c0000664000175000017500000002334513764006205013442 00000000000000/* Copyright 2011-2012 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "esb.h" #include "uri.h" #include #include /* dwarfdump_ctype table. See uritablebuild.c */ static char dwarfdump_ctype_table[256] = { 0, /* NUL 0x00 */ 0, /* control 0x01 */ 0, /* control 0x02 */ 0, /* control 0x03 */ 0, /* control 0x04 */ 0, /* control 0x05 */ 0, /* control 0x06 */ 0, /* control 0x07 */ 0, /* control 0x08 */ 0, /* whitespace 0x09 */ 0, /* whitespace 0x0a */ 0, /* whitespace 0x0b */ 0, /* whitespace 0x0c */ 0, /* whitespace 0x0d */ 0, /* control 0x0e */ 0, /* control 0x0f */ 0, /* control 0x10 */ 0, /* control 0x11 */ 0, /* control 0x12 */ 0, /* control 0x13 */ 0, /* control 0x14 */ 0, /* control 0x15 */ 0, /* control 0x16 */ 0, /* control 0x17 */ 0, /* control 0x18 */ 0, /* control 0x19 */ 0, /* control 0x1a */ 0, /* control 0x1b */ 0, /* control 0x1c */ 0, /* control 0x1d */ 0, /* control 0x1e */ 0, /* control 0x1f */ 1, /* ' ' 0x20 */ 1, /* '!' 0x21 */ 0, /* '"' 0x22 */ 1, /* '#' 0x23 */ 1, /* '$' 0x24 */ 0, /* '%' 0x25 */ 1, /* '&' 0x26 */ 0, /* ''' 0x27 */ 1, /* '(' 0x28 */ 1, /* ')' 0x29 */ 1, /* '*' 0x2a */ 1, /* '+' 0x2b */ 1, /* ',' 0x2c */ 1, /* '-' 0x2d */ 1, /* '.' 0x2e */ 1, /* '/' 0x2f */ 1, /* '0' 0x30 */ 1, /* '1' 0x31 */ 1, /* '2' 0x32 */ 1, /* '3' 0x33 */ 1, /* '4' 0x34 */ 1, /* '5' 0x35 */ 1, /* '6' 0x36 */ 1, /* '7' 0x37 */ 1, /* '8' 0x38 */ 1, /* '9' 0x39 */ 1, /* ':' 0x3a */ 0, /* ';' 0x3b */ 1, /* '<' 0x3c */ 1, /* '=' 0x3d */ 1, /* '>' 0x3e */ 1, /* '?' 0x3f */ 1, /* '@' 0x40 */ 1, /* 'A' 0x41 */ 1, /* 'B' 0x42 */ 1, /* 'C' 0x43 */ 1, /* 'D' 0x44 */ 1, /* 'E' 0x45 */ 1, /* 'F' 0x46 */ 1, /* 'G' 0x47 */ 1, /* 'H' 0x48 */ 1, /* 'I' 0x49 */ 1, /* 'J' 0x4a */ 1, /* 'K' 0x4b */ 1, /* 'L' 0x4c */ 1, /* 'M' 0x4d */ 1, /* 'N' 0x4e */ 1, /* 'O' 0x4f */ 1, /* 'P' 0x50 */ 1, /* 'Q' 0x51 */ 1, /* 'R' 0x52 */ 1, /* 'S' 0x53 */ 1, /* 'T' 0x54 */ 1, /* 'U' 0x55 */ 1, /* 'V' 0x56 */ 1, /* 'W' 0x57 */ 1, /* 'X' 0x58 */ 1, /* 'Y' 0x59 */ 1, /* 'Z' 0x5a */ 1, /* '[' 0x5b */ 1, /* '\' 0x5c */ 1, /* ']' 0x5d */ 1, /* '^' 0x5e */ 1, /* '_' 0x5f */ 0, /* '`' 0x60 */ 1, /* 'a' 0x61 */ 1, /* 'b' 0x62 */ 1, /* 'c' 0x63 */ 1, /* 'd' 0x64 */ 1, /* 'e' 0x65 */ 1, /* 'f' 0x66 */ 1, /* 'g' 0x67 */ 1, /* 'h' 0x68 */ 1, /* 'i' 0x69 */ 1, /* 'j' 0x6a */ 1, /* 'k' 0x6b */ 1, /* 'l' 0x6c */ 1, /* 'm' 0x6d */ 1, /* 'n' 0x6e */ 1, /* 'o' 0x6f */ 1, /* 'p' 0x70 */ 1, /* 'q' 0x71 */ 1, /* 'r' 0x72 */ 1, /* 's' 0x73 */ 1, /* 't' 0x74 */ 1, /* 'u' 0x75 */ 1, /* 'v' 0x76 */ 1, /* 'w' 0x77 */ 1, /* 'x' 0x78 */ 1, /* 'y' 0x79 */ 1, /* 'z' 0x7a */ 1, /* '{' 0x7b */ 1, /* '|' 0x7c */ 1, /* '}' 0x7d */ 1, /* '~' 0x7e */ 0, /* DEL 0x7f */ 1, /* 0x80 */ 1, /* 0x81 */ 1, /* 0x82 */ 1, /* 0x83 */ 1, /* 0x84 */ 1, /* 0x85 */ 1, /* 0x86 */ 1, /* 0x87 */ 1, /* 0x88 */ 1, /* 0x89 */ 1, /* 0x8a */ 1, /* 0x8b */ 1, /* 0x8c */ 1, /* 0x8d */ 1, /* 0x8e */ 1, /* 0x8f */ 1, /* 0x90 */ 1, /* 0x91 */ 1, /* 0x92 */ 1, /* 0x93 */ 1, /* 0x94 */ 1, /* 0x95 */ 1, /* 0x96 */ 1, /* 0x97 */ 1, /* 0x98 */ 1, /* 0x99 */ 1, /* 0x9a */ 1, /* 0x9b */ 1, /* 0x9c */ 1, /* 0x9d */ 1, /* 0x9e */ 1, /* 0x9f */ 0, /* other: 0xa0 */ 1, /* 0xa1 */ 1, /* 0xa2 */ 1, /* 0xa3 */ 1, /* 0xa4 */ 1, /* 0xa5 */ 1, /* 0xa6 */ 1, /* 0xa7 */ 1, /* 0xa8 */ 1, /* 0xa9 */ 1, /* 0xaa */ 1, /* 0xab */ 1, /* 0xac */ 1, /* 0xad */ 1, /* 0xae */ 1, /* 0xaf */ 1, /* 0xb0 */ 1, /* 0xb1 */ 1, /* 0xb2 */ 1, /* 0xb3 */ 1, /* 0xb4 */ 1, /* 0xb5 */ 1, /* 0xb6 */ 1, /* 0xb7 */ 1, /* 0xb8 */ 1, /* 0xb9 */ 1, /* 0xba */ 1, /* 0xbb */ 1, /* 0xbc */ 1, /* 0xbd */ 1, /* 0xbe */ 1, /* 0xbf */ 1, /* 0xc0 */ 1, /* 0xc1 */ 1, /* 0xc2 */ 1, /* 0xc3 */ 1, /* 0xc4 */ 1, /* 0xc5 */ 1, /* 0xc6 */ 1, /* 0xc7 */ 1, /* 0xc8 */ 1, /* 0xc9 */ 1, /* 0xca */ 1, /* 0xcb */ 1, /* 0xcc */ 1, /* 0xcd */ 1, /* 0xce */ 1, /* 0xcf */ 1, /* 0xd0 */ 1, /* 0xd1 */ 1, /* 0xd2 */ 1, /* 0xd3 */ 1, /* 0xd4 */ 1, /* 0xd5 */ 1, /* 0xd6 */ 1, /* 0xd7 */ 1, /* 0xd8 */ 1, /* 0xd9 */ 1, /* 0xda */ 1, /* 0xdb */ 1, /* 0xdc */ 1, /* 0xdd */ 1, /* 0xde */ 1, /* 0xdf */ 1, /* 0xe0 */ 1, /* 0xe1 */ 1, /* 0xe2 */ 1, /* 0xe3 */ 1, /* 0xe4 */ 1, /* 0xe5 */ 1, /* 0xe6 */ 1, /* 0xe7 */ 1, /* 0xe8 */ 1, /* 0xe9 */ 1, /* 0xea */ 1, /* 0xeb */ 1, /* 0xec */ 1, /* 0xed */ 1, /* 0xee */ 1, /* 0xef */ 1, /* 0xf0 */ 1, /* 0xf1 */ 1, /* 0xf2 */ 1, /* 0xf3 */ 1, /* 0xf4 */ 1, /* 0xf5 */ 1, /* 0xf6 */ 1, /* 0xf7 */ 1, /* 0xf8 */ 1, /* 0xf9 */ 1, /* 0xfa */ 1, /* 0xfb */ 1, /* 0xfc */ 1, /* 0xfd */ 1, /* 0xfe */ 0, /* other: 0xff */ }; /* Translate dangerous and some other characters to safe %xx form. */ void translate_to_uri(const char * filename, struct esb_s *out) { const char *cp = 0; for (cp = filename ; *cp; ++cp) { char v[2]; int c = 0xff & (unsigned char)*cp; if (dwarfdump_ctype_table[c]) { v[0] = c; v[1] = 0; esb_append(out,v); } else { esb_append(out,"%"); esb_append_printf_u(out, "%02x",c&0xff); } } } /* This is not very efficient, but it is seldom called. */ static char hexdig(char c) { char ochar = 0; if (c >= '0' && c <= '9') { ochar = (c - '0'); return ochar; } if (c >= 'a' && c <= 'f') { ochar = (c - 'a')+10; return ochar; } if (c >= 'A' && c <= 'F') { ochar = (c - 'A')+10; return ochar; } /* We have an input botch here. */ fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character is " "not 0-9 or a-f or A-F, it is (shown as hex here): %x\n",c); return ochar; } static char tohex(char c1, char c2) { char out = (hexdig(c1) << 4) | hexdig(c2); return out; } static int hexpairtochar(const char *cp, char*myochar) { char ochar = 0; int olen = 0; char c = cp[0]; if (c) { char c2 = cp[1]; if (c2) { ochar = tohex(c,c2); olen = 2; } else { fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character pair " "runs off the end of the input after 1 hex digit.\n"); /* botched input. */ ochar = c; olen = 1; } } else { /* botched input. */ fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character pair " "runs off the end of the input.\n"); ochar = '%'; olen = 0; } *myochar = ochar; return olen; } void translate_from_uri(const char * input, struct esb_s* out) { const char *cp = input; char tempstr[2]; for (; *cp; ++cp) { char c = *cp; if (c == '%') { int increment = 0; char c2 = cp[1]; /* hexpairtochar deals with c2 being NUL. */ if (c2 == '%') { tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); ++cp; continue; } increment = hexpairtochar(cp+1,&c); tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); cp +=increment; continue; } tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); } } #ifdef TEST unsigned int errcnt = 0; static void mytestfrom(const char * in,const char *expected,int testnum) { struct esb_s out; esb_constructor(&out); translate_from_uri(in, &out); if (strcmp(expected, esb_get_string(&out))) { printf(" Fail test %d expected \"%s\" got \"%s\"\n", testnum,expected,esb_get_string(&out)); ++errcnt; } esb_destructor(&out); } static void mytest(char *in,char *expected,int testnum) { struct esb_s out; esb_constructor(&out); translate_to_uri(in, &out); if (strcmp(expected, esb_get_string(&out))) { printf(" Fail test %d expected %s got %s\n", testnum,expected,esb_get_string(&out)); ++errcnt; } esb_destructor(&out); } int main() { /* We no longer translate space to %20, that turns out not to help all that much. */ mytest("aaa","aaa",1); mytest(" bc"," bc",2); mytest(";bc","%3bbc",3); mytest(" bc\n"," bc%0a",4); mytest(";bc\n","%3bbc%0a",5); mytest(" bc\r"," bc%0d",6); mytest(";bc\r","%3bbc%0d",7); mytest(" \x01"," %01",8); mytest(";\x01","%3b%01",9); mytestfrom("abc","abc",10); mytestfrom("a%20bc","a bc",11); mytestfrom("a%%20bc","a%20bc",12); mytestfrom("a%%%20bc","a% bc",13); mytestfrom("a%%%%20bc","a%%20bc",14); mytestfrom("a%20","a ",15); /* The following is mistaken input. */ mytestfrom("a%2","a2",16); mytestfrom("a%","a%",17); mytest("%bc","%25bc",18); if (errcnt) { printf("uri errcount ",errcnt); } return errcnt? 1:0; } #endif libdwarf-20210528/dwarfdump/ChangeLog20160000664000175000017500000006012713644370703014565 000000000000002016-11-24 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version strings. 2016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-22 David Anderson * print_abbrevs.c: Some -k abbrev warnings did not make it clear that they were checking against a heuristic sanity-check value for the maximum number of attributes, not a genuine maximum. 2016-11-22 David Anderson * tag_attr.c: Remove bogus blank line with trailing spaces. 2016-11-11 David Anderson * print_frames.c: Apply fix to local_dwarf_decode_s_leb128_chk so it matches libdwarf dwarf_leb.c. A fix for certain bit pattern provoking undefined behavior in C.. 2016-11-01 David Anderson * tag_attr.c,tag_common.h,tag_attr_ext.list: Adding Ada GNAT gcc attributes DW_AT_GNU_numerator, DW_AT_GNU_denominator, DW_AT_GNU_bias in the extended table for checking. 2016-10-21 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version strings. 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize option. * configure: Regenerated. * print_die.c: Ensure << applied to unsigned to avoid undefined operation. We were getting officially undefined behavior. * tag_attr_ext.list: Removed trailing whitespace from two lines. 2016-09-30 David Anderson * makename.c: The unused static function value_hashfunc() has been removed. * tag_attr.c, tag_tree.c: Changed (1<form with in an error message. * print_frames.c: Now checks for bogus expression block lengths and bogus LEB values. LEB reading functions now here and static functions. * print_sections.c: Moved leb reading functions to print_frames.c 2016-05-07 David Anderson * dwarfdump.c, common.c: Update version string. * print_frames.c: For local variable added initialization-at-definition. 2016-05-06 David Anderson * sanitized.c: Fixed trailing whitespace and added 'static' to local function definition. 2016-05-05 David Anderson * Makefile.in: Added sanitized.o to objects to build. * dwarfdump.1: Document '-x nosanitizestrings'. * dwarfdump.c: Set internal flag based on '-x nosanitizestrings'. * globals.h: add extern for the flag no_sanitize_string_garbage and the sanitized() interface. * print_die.c,print_frames.c,print_lines.c, print_macro.c, print_macros.c : Call sanitized() on some strings. * sanitized.c: Changes control characters int output to %xx uri-style (by default). See '-x nosanitizestrings'. 2016-05-03 David Anderson * dwarfdump.c: revise print_error_maybe_continue() to print additional useful data. * print_die.c: If dwarf_srcfiles() gets DW_DLV_NO_ENTRY do not print a warning. Normal to have no DW_AT_stmt_list. * print_lines.c: Fix column header 'row' changed to 'lno'. Refine a CHECK message to say a DW_LNE_end_sequence does not exactly match function high address. It is not an error, just something about how the code was emitted. 2016-04-30 David Anderson * dwarfdump.c, common.c: Update version string. 2016-04-27 David Anderson * dwarfdump.c, common.c: Update version string. 2016-04-27 David Anderson * dwarfdump.c: Update version string. Remove a field from printf on error as that duplicates the error number in the error string. 2016-04-25 David Anderson * esb.c, dwarfdump.c: Fix a couple indent mistakes. 2016-04-25 David Anderson * esb.h, esb.c: The typedef for 'string' is now gone, it was never helpful.. * dwarfdump.c: Remove 'string' use. * dwgetopt.c: Moved test-only function to getopttest.c. Added (void) argument to a the functions with no arguments. * getopttest.c: Repaired failures to to renaming to dwoptind etc and added the test-only function from dwgetopt.c * globals.h: Removed 'string' typedef. * print_die.c,print_frames.c, print_lines.c, print_strings.c, tag_attr.c, tag_tree.c: Removed use of 'string' type, use plain old char*. 2016-04-21 Carlos Alberto Enciso Printing using the 'esb' module was broken. It seems to work because the default internal buffer size (240), was big enough to receive the resulting output. * esb.c, esb.h: Missing prefix 'esb' for 'allocate_more'. Initial buffer size reduced to 16. New function 'esb_open_null_device': open 'null' device. New function 'esb_close_null_device': close 'null' device. New function 'esb_allocate_more_if_needed': allocate more space if required, leaving the contents unchanged, so the caller, does not need to worry about it. There are 2 cases: Windows: use the 'null' device to get the required space UNIX: use a big buffer (512). But if the result is bigger, the original problem will be shown. The function 'esb_append_printf_ap', now takes care of increasing the buffer if needed. * dwarfdump.c: In the case of windows, open and close the 'null' device, in order to setup the esb module. 2016-04-21 Carlos Alberto Enciso * globals.h: Do not define 'string' for a C++ build; it clashes with the 'std::string'. * print_die.c: Minor typo error. 2016-04-21 Carlos Alberto Enciso * For a WINDOWS version, display the 32/64 bits configuration. 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-17 David Anderson * print_die.c(print_one_die_section): One dieprint_cu_goffset Dwarf_Unsigned->Dwarf_Off. 2016-03-12 David Anderson * print_abbrevs.c(print_abbrevs): Printed output of an abbrev with code and tag but no attributes was simply wrong. Now fixed. Now avoids printing children flag on a null abbrev (a NUL byte meaning no abbrev is there at all, ending a list of abbrevs). * print_die.c: it was difficult, even with -G -v, to identify the actual offset (in .debug_abbrev) of the abbreviations. Now -i -G -v gives a bit more data on abbreviations. 2016-03-09 David Anderson * dwarfdump.c,globals.h,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_macro.c,print_pubnames.c: Remove the global dieprint_cu_offset, use local vars and pass around instead. Ensure the traverse() logic when checking type references do not evaluate references to other sections. Many argument lists got an additional argument or two. 2016-03-07 David Anderson * dwarfdump.c: Update version string. Added CU_low_address so CU_base_address is properly used only for the DWARF CU 'base address' notion. Print CU_low_address in PRINT_CU_INFO(). * common.c: Update version string * globals.h: New macro DROP_ERROR_INSTANCE(d,r,e) improves consistency where we need to drop a Dwarf_Error instance. * print_die.c: Support for CU_low_address. Use DROP_ERROR_INSTANCE where appropriate. * print_frames.c: Use DROP_ERROR_INSTANCE where appropriate. 2016-03-03 Carlos Alberto-Enciso * dwarfdump.c: Missing '_' just for consistency. Print any harmless errors only the required in command line * globals.h: Unused declaration. * print_die.c: When displaying a DW_AT_type offset error, uses the standard 0xdddddddd format. Wrap to 80 columns, a long line. 2016-02-17 Carlos Alberto-Enciso * dwarfdump/tag_attr_ext.list,dwarfdump/tag_common.h, dwarfdump/tag_tree_ext.list: Tighten up the list limits and add commentary about the list limits. 2016-02-14 DavidAnderson * dwarfdump.c,common.c: Updated version strings. * print_die.c,print_strings.c: fixed indent errors. 2016-02-14 Carlos Alberto-Enciso * tag_attr_ext.list, tag_tree_ext.list: Adding DW_TAG_GNU_template_parameter_pack,DW_TAG_GNU_formal_parameter_pack. * tag_tree.c: Printed wrong name from tag-tree table in a comment. * tag_common.h: Ext tag table rows count was higher than needed. Ext attr table rows increased to 11. 2016-02-13 David Anderson * dwarfdump.c,globals.h,print_aranges.c,print_die.c, print_frames.c,print_lines.c,print_locs.c,print_macro.c, print_pubnames.c,print_reloc.ckprint_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c, print_weaknames.c: Removed global Dwarf_Error err and provided local Dwarf_Error as needed. 2016-02-13 David Anderson * configure.in: Add -Wshadow to --enable-shared. Add else and cross-compile [] to the AC_TRY_RUN * configure: Regenerate. * dwarf_tsearchbal.c: Delete shadowed variable p, we use the original instead. * dwarfdump.c: Rename variables to avoid confusing duplicated names (found by -Wshadow). #if 0 the unused function old_get_cu_name(), which should get deleted. * globals.h: Fixed prototypes, #if 0 prototype of the unused function old_get_cu_name(). * print_abbrevs.c, print_aranges.c,print_debugfission.c, print_die.c,print_frames.c, print_gdbindex.c, print_lines.c, print_pubnames.c, print_ranges.c, print_sections.c, tag_attr.c, tag_tree.c: Add local Dwarf_Error and rename variables to avoid shadowing confusion. 2016-02-10 David Anderson * globals.h: Change enum val from std to singledw5. Some compilation environments reserve 'std'. * dwarfdump.c,print_lines.c: Use the new spelling. 2016-02-10 David Anderson * common.c,dwarfdump.c: Update version string. 2016-02-07 David Anderson * common.c,dwarfdump.c: Update version string. 2016-02-06 David Anderson * print_die.c,tag_attr.c,tag_tree.c: Remove trailing whitespace. 2016-02-06 David Anderson * warningcontrol.h: Defines UNUSEDARG macro as needed. * common.c,dwarf_tsearchbal.c,dwarfdump.c,globals.h, macrocheck.c: Now use UNUSEDARG macro so known-unused args do not cause spurious warnings. * configure.in: Sets HAVE_UNUSED_ATTRIBUTE if the compiler in use supports __attribute ((unused)). So we can have lots of warnings turned on without seeing the warnings we wish to ignore for now. * configure,config.h.in: Regenerated. 2016-02-06 David Anderson * print_frames.c: Was printing cie index, not fde index, in the fde output. Now prints more sensibly. Now tests do_print_dwarf, the flag it should have been using, to decide whether to print. 2016-02-02 David Anderson * dwarfdump.c: Get section sizes so we can do a better sanity check on ofsets (ie, call dwarf_get_section_max_offsets_c()). Check DWARF2 macros for sanity just as we do DWARF5 macros. Read DWARF2 macros per-cu, not as a standalone section. Add global data section_high_offsets_global, a struct with all known section sizes. * macrocheck.c: New section size argument for more complete size analysis. * globals.h: Declarations for section_high_offsets_global. * macrocheck.h: Update prototype of print_macro_statistics(). * print_die.c: Drop section-as-a-whole macro reporting for macinfo in favor of reporting per CU. * print_macros.c: Allow for print and check runs (not both at once). 2016-01-28 David Anderson * dwarfdump.c,common.c: Update version string. * print_die.c: Changed the most frequent global die offset values to print as GOFF=0x... for uniformity with -G and space saving from the string 'global die offset'. 2016-01-27 David Anderson * print_die.c: Added a helpertree find call on typedieoffset which is really a better check for known signed/unsigned. 2016-01-26 David Anderson * dwarfdump.c,common.c: Update version string. 2016-01-26 David Anderson * Makefile.in: Added helpertree.h, and .c. * dwarfdump.c: Added include helpertree.h * print_die.c: Now attempts (harder) to figure out if a constant is really signed or insigned when printing it. Fixes annoyance with printing attributes longer than 27 characters. Unifies a number of printf-style calls into functions, reducing the number of statically visible calls to sprintf. Attempts to remember whether some things are explicitly typed as signed or unsigned. * helpertree.h, helpertree.c: New. Simple use of tsearch to memo-ize signedness. 2016-01-20 * configure.in: Added more compiler optiosn to --enable-wall * configure: Regenerated * dwarf_tsearchbal.c: Fixed warnings. * dwarfdump.c: Fixed warnings. * dwconf.c: Fixed warnings. * dwconf.h: Fixed warnings. * esb.c: Fixed warnings. * globals.h: Fixed warnings. * print_debugfission.c: Fixed warnings. * print_die.c: Fixed warnings. * print_frames.c: Fixed warnings. * print_sections.c: Fixed warnings. 2016-01-20 * macrocheck.c: Remove trailing whitespace. * print_lines.c: Only print line context record if we do_print_dwarf is non-zero. The directory index was printing as 0 in the line_context record. Was a typo in the printf, now fixed. 2016-01-20 * configure.in: Now --enable-wall adds -Wdeclaration-after-statement etc. * configure: Regenerated. * dwarfdump.c: Now all functions have visible prototypes, no (). * dwconf.c: Now local func declared static. * dwgetopt.c: Added include dwgetopt.h. Unused function #if 0 so invisible. * globals.h: Now all functions have prototypes, no (). * macrocheck.c: Removed unused locals. Fixed a dwarf_twalk call to *tree (not just tree). * naming.c: Added include naming.h. * print_gdbindex.c: Made local function static. * tag_attr.c,tag_common.c: Made local function static. 2016-01-19 David Anderson * dwarf_tsearchbal.c: Deleted the unused function rotatex(). * dwarfdump.c: Remove duplicate trailing ; * esb.c(esb_append): Straighten out the logic and avoid doing append if the to-be-appended string is empty. * globals.h Add ifdef __cplusplus for extern "C". * esb.h,naming.h: Idempotent #ifndef and __cplusplus extern "C" added. * print_frames.c: Ensure local var starts at zero. Move statement to below declarations. * print_lines.c: Ensure declarations before executable statements. 2016-01-19 David Anderson * print_frames.c: Fix trailing whitespace and indentation. 2016-01-19 David Anderson * print_die.c,tag_tree.c: Change statement ;; by removing second semicolon. 2016-01-17 David Anderson * common.c: Update version string * dwarfdump.c: Made reset_overall_CU_error_data() a global. We now try to show CU name etc on case there is an error reading frame data. Update version strin. Added DEBUG_FRAME DEBUG_FRAME_EH to the PRINT_CU_INFO() tests. New function: load_CU_error_data(). * print_frames.c: Now uses a local Dwarf_Error in a few places (CU names for frames) instead of the global 'err' so we do not get the errors mixed up. We now try to show CU name etc on case there is an error reading frame data. 2016-01-14 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. Include macrocheck.h. Delete one accidental blank line. * dwarf_tsearchbal.c: Added comment about compiler warning. * dwarf_macrocheck.c: Added missing return statement. Removed trailing whitespace. Fixed broken qsort_compare() * macrocheck.h: Fixed trailing whitespace. * print_abbrevs.c: Generalized an attribute count warning a bit (see GENERAL_MAX_ATTRIB_COUNT). Fixed the code handling the abbrev_array to be correct and a bit simpler. Added new abbreviations tests. * print_die.c: Include macrocheck.h. Fix trailing whitespace. 2016-01-12 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. * print_abbrevs.c: If an abbreviation number is a bit goofy, accomodate it so we do not write to memory we did not allocate. It will be caught a bit later in the run as an invalid DIE or abbreviation. * print_die.c: When we switch sections inside a DIE print save and restore current_section_id to get the best reporting on errors/checks. 2016-01-12 David Anderson * common.c,dwarfdump.c: Update version string. 2016-01-12 David Anderson * Makefile.in: Adding macrocheck.h, and .c. Adding selftest of macrocheck.c. * dwarfdump.c: Now handles imported DWARF5 macros and adds support for -kw for macro section checking. * globals.h: Adding check_macros flag and macro_check_tree declaration and print_macros_5style_this_cu() declaration.. * print_die.c: Now prints imported macros using print_macros_5style_this_cu(). * print_macro.c: Now deals with imported macro units using macrocheck.c and .h. Fixed bug for DW_MACRO_define/undef where we did improper string validity check. libdwarf-20210528/dwarfdump/print_rnglists.c0000664000175000017500000002454313764006205015725 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* DWARF5 has the new .debug_rnglists section. Here we print that data. The raw printing covers all the content of the section but without relating it to any compilation unit. Printing the actual address means printing with the actual DIEs on hand. */ #include "config.h" #include "globals.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" static void print_sec_name(Dwarf_Debug dbg) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_rnglists", &truename,TRUE); printf("\n%s\n\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } static int print_offset_entry_table(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned offset_entry_count, Dwarf_Error *error) { Dwarf_Unsigned e = 0; unsigned colmax = 4; unsigned col = 0; int res = 0; int hasnewline = TRUE; for ( ; e < offset_entry_count; ++e) { Dwarf_Unsigned value = 0; if (e == 0) { printf(" Location Offset Table :\n"); } hasnewline = FALSE; res = dwarf_get_rnglist_offset_index_value(dbg, contextnum,e,&value,0,error); if (res != DW_DLV_OK) { return res; } if (col == 0) { printf(" [%2" DW_PR_DUu "]",e); } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx, value); col++; if (col == colmax) { printf("\n"); hasnewline = TRUE; col = 0; } } if (!hasnewline) { printf("\n"); } return DW_DLV_OK; } /* For printing the raw rangelist data from .debug_rnglists */ static int print_single_rle(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Unsigned contextnum, Dwarf_Unsigned lineoffset, Dwarf_Unsigned code, Dwarf_Unsigned v1, Dwarf_Unsigned v2, Dwarf_Unsigned entrylen) { int res = DW_DLV_OK; const char *name = ""; struct esb_s m; esb_constructor(&m); res = dwarf_get_RLE_name(code,&name); if (res != DW_DLV_OK) { /* ASSERT: res == DW_DLV_NO_ENTRY, see dwarf_names.c */ esb_append_printf_u(&m, "",code); } else { esb_append(&m,name); } printf(" "); printf("<0x%" DW_PR_XZEROS DW_PR_DUx "> %-20s", lineoffset,esb_get_string(&m)); switch(code) { case DW_RLE_end_of_list: printf(" "); printf(" "); break; case DW_RLE_base_addressx:{ printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ,v1); printf(" "); } break; case DW_RLE_startx_endx: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); } break; case DW_RLE_startx_length: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); } break; case DW_RLE_offset_pair: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); } break; case DW_RLE_base_address: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1); printf(" "); } break; case DW_RLE_start_end: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); } break; case DW_RLE_start_length: { printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); } break; default: printf(" ERROR: Unknown RLE code in .debug_rnglists. %s\n", esb_get_string(&m)); simple_err_return_msg_either_action(res, esb_get_string(&m)); break; } esb_destructor(&m); if (glflags.verbose > 1) { printf(" length %" DW_PR_DUu,entrylen); } printf("\n"); return res; } /* For printing raw rangelist data as found in .debug_rnglists */ static int print_entire_rangeslist(Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned offset_of_first_range, Dwarf_Unsigned offset_past_last_rangeentry, Dwarf_Error *error) { /* These offsets are rnglists section global offsets, not rnglist context local offsets. */ Dwarf_Unsigned curoffset = offset_of_first_range; Dwarf_Unsigned endoffset = offset_past_last_rangeentry; int res = 0; Dwarf_Unsigned ct = 0; int title_printed = FALSE; for ( ; curoffset < endoffset; ++ct ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned v1 = 0; Dwarf_Unsigned v2 = 0; if (!ct) { printf(" RangeEntries (raw)\n"); } res = dwarf_get_rnglist_rle(dbg,contextnumber, curoffset,endoffset, &entrylen, &code,&v1,&v2,error); if (res != DW_DLV_OK) { return res; } if (!title_printed) { title_printed = TRUE; printf(" Offset entryname " "val1 val2 entrylen\n"); } print_single_rle(dbg,contextnumber,curoffset, code,v1,v2,entrylen); curoffset += entrylen; if (curoffset > endoffset) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "DW_DLE_USER_DECLARED_ERROR: " "final RLE in " ".debug_rnglists runs past end of its area " "so current offset 0x%" DW_PR_DUx,curoffset); esb_append_printf_u(&m," exceeds context 1-past-end" " offset of 0x%" DW_PR_DUx ".",endoffset); dwarf_error_creation(dbg,error, esb_get_string(&m)); esb_destructor(&m); return DW_DLV_ERROR; } } return DW_DLV_OK; } /* For printing the raw rangelist data from .debug_rnglists */ int print_raw_all_rnglists(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned i = 0; res = dwarf_load_rnglists(dbg,&count,error); if (res != DW_DLV_OK) { return res; } print_sec_name(dbg); printf(" Number of rnglists contexts: %" DW_PR_DUu "\n", count); for (i = 0; i < count ; ++i) { Dwarf_Unsigned header_offset = 0; Dwarf_Small offset_size = 0; Dwarf_Small extension_size = 0; unsigned version = 0; /* 5 */ Dwarf_Small address_size = 0; Dwarf_Small segment_selector_size = 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned offset_of_offset_array = 0; Dwarf_Unsigned offset_of_first_rangeentry = 0; Dwarf_Unsigned offset_past_last_rangeentry = 0; res = dwarf_get_rnglist_context_basics(dbg,i, &header_offset,&offset_size,&extension_size, &version,&address_size,&segment_selector_size, &offset_entry_count,&offset_of_offset_array, &offset_of_first_rangeentry, &offset_past_last_rangeentry,error); if (res != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m,"ERROR: Getting debug_rnglists " "entry %u we unexpectedly stop early.",i); simple_err_return_msg_either_action(res, esb_get_string(&m)); esb_destructor(&m); return res; } printf(" Context number : %3" DW_PR_DUu "\n",i); printf(" Version : %3u\n",version); printf(" address size : %3u\n",address_size); printf(" offset size : %3u\n",offset_size); if (glflags.verbose) { printf(" extension size : %3u\n",extension_size); } printf(" segment selector size : %3u\n", segment_selector_size); printf(" offset entry count : %3" DW_PR_DUu "\n", offset_entry_count); printf(" context size in bytes : %3" DW_PR_DUu "\n", offset_past_last_rangeentry - header_offset); if (glflags.verbose) { printf(" Offset in section : 0x%" DW_PR_XZEROS DW_PR_DUx"\n", header_offset); printf(" Offset of offsets : 0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_of_offset_array); printf(" Offsetof first range : 0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_of_first_rangeentry); printf(" Offset past ranges : 0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_past_last_rangeentry); } if (offset_entry_count) { res = print_offset_entry_table(dbg,i,offset_entry_count, error); if (res == DW_DLV_ERROR) { return res; } } if ((offset_of_first_rangeentry+1) < offset_past_last_rangeentry) { res = print_entire_rangeslist(dbg,i, offset_of_first_rangeentry, offset_past_last_rangeentry, error); if (res != DW_DLV_OK) { return res; } } } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/tag_attr.list0000644000175000017500000004600213743575426015207 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* Entries for DWARF5 should not be considered final until the DWARF5 standard is released. list for semantic check of tag-attr relation. 0xffffffff is a "punctuation." The final line of this file must be 0xffffffff. The next line after each 0xffffffff (except the final line) is a tag. The lines after this line before the next 0xffffffff are the attributes that can be given to the tag." For example, 0xffffffff DW_TAG_access_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_name DW_AT_sibling 0xffffffff means "only DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line, DW_AT_accessibility, DW_AT_name and DW_AT_sibling can be given to DW_TAG_access_declaration." Since DWARF standards are descriptive, not formally prescriptive (for the most part) compilers may add attributes that do not appear in this list. Corrections to the list are always appreciated. And for extensions, the file tag_attr_ext.list is the right place to put such so they do not provoke pointless warnings. This file is applied to the preprocessor, thus any C comment and preprocessor control line is available. */ 0xffffffff DW_TAG_access_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_description DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_array_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_ordering DW_AT_rank DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_atomic_type /* DWARF5 */ DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_base_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_binary_scale DW_AT_bit_offset DW_AT_bit_size DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_data_bit_offset DW_AT_data_location DW_AT_decimal_scale DW_AT_decimal_sign DW_AT_description DW_AT_digit_count DW_AT_encoding DW_AT_endianity DW_AT_name DW_AT_picture_string DW_AT_sibling DW_AT_small 0xffffffff DW_TAG_call_site /* DWARF5 */ DW_AT_call_column DW_AT_call_file DW_AT_call_line DW_AT_call_origin DW_AT_call_pc DW_AT_call_return_pc DW_AT_call_tail_call DW_AT_call_target DW_AT_call_target_clobbered DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_call_site_parameter /* DWARF5 */ DW_AT_call_data_location DW_AT_call_data_value DW_AT_call_parameter DW_AT_call_value DW_AT_location DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_catch_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_class_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_calling_convention DW_AT_containing_type DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_coarray_type /* DWARF5 */ DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_bit_size DW_AT_byte_size DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_common_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_declaration DW_AT_description DW_AT_linkage_name DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_common_inclusion DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_common_reference DW_AT_declaration DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_compile_unit DW_AT_addr_base DW_AT_base_types DW_AT_comp_dir DW_AT_dwo_id DW_AT_dwo_name DW_AT_entry_pc DW_AT_identifier_case DW_AT_high_pc DW_AT_language DW_AT_loclists_base DW_AT_low_pc DW_AT_macro_info /* before DWARF5 */ DW_AT_macros /* DWARF5 */ DW_AT_main_subprogram DW_AT_name DW_AT_producer DW_AT_ranges DW_AT_rnglists_base DW_AT_segment DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_condition DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_const_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_constant DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_const_value DW_AT_declaration DW_AT_description DW_AT_endianity DW_AT_external DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_dwarf_procedure DW_AT_location 0xffffffff DW_TAG_dynamic_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_description DW_AT_name DW_AT_type DW_AT_sibling 0xffffffff DW_TAG_entry_point DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_address_class DW_AT_description DW_AT_frame_base DW_AT_linkage_name DW_AT_low_pc DW_AT_name DW_AT_return_addr DW_AT_segment DW_AT_sibling DW_AT_static_link DW_AT_type 0xffffffff DW_TAG_enumeration_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_byte_stride DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_enum_class DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_enumerator DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_const_value DW_AT_description DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_file_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_description DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_formal_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_artificial DW_AT_const_value DW_AT_default_value DW_AT_description DW_AT_endianity DW_AT_is_optional DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_type DW_AT_variable_parameter 0xffffffff DW_TAG_friend DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_friend DW_AT_sibling 0xffffffff DW_TAG_generic_subrange DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_byte_stride DW_AT_count DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_lower_bound DW_AT_name DW_AT_sibling DW_AT_threads_scaled DW_AT_type DW_AT_upper_bound DW_AT_visibility 0xffffffff DW_TAG_imported_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_description DW_AT_import DW_AT_name DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_immutable_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_type 0xffffffff DW_TAG_imported_module DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_import DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_imported_unit DW_AT_import 0xffffffff DW_TAG_inheritance DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_data_member_location DW_AT_sibling DW_AT_type DW_AT_virtuality 0xffffffff DW_TAG_inlined_subroutine DW_AT_abstract_origin DW_AT_call_column DW_AT_call_file DW_AT_call_line DW_AT_const_expr DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_return_addr DW_AT_segment DW_AT_sibling DW_AT_start_scope DW_AT_trampoline 0xffffffff DW_TAG_interface_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_alignment DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_start_scope 0xffffffff DW_TAG_label DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_description DW_AT_low_pc DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_lexical_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_description DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_name DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_member DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_alignment DW_AT_artificial DW_AT_bit_offset /* allowed in DWARF4 */ DW_AT_bit_size DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_const_value DW_AT_data_bit_offset DW_AT_data_member_location DW_AT_declaration DW_AT_description DW_AT_external DW_AT_mutable DW_AT_name DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_module DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_declaration DW_AT_description DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_name DW_AT_priority DW_AT_ranges DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_visibility 0xffffffff DW_TAG_namelist DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_declaration DW_AT_name DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_namelist_item DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_namelist_item DW_AT_sibling 0xffffffff DW_TAG_namespace DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_declaration DW_AT_description DW_AT_export_symbols DW_AT_extension DW_AT_export_symbols DW_AT_name DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_packed_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_partial_unit DW_AT_addr_base DW_AT_base_types DW_AT_comp_dir DW_AT_description DW_AT_dwo_name DW_AT_entry_pc DW_AT_identifier_case DW_AT_high_pc DW_AT_language DW_AT_low_pc DW_AT_macro_info DW_AT_macros DW_AT_main_subprogram DW_AT_name DW_AT_noreturn DW_AT_producer DW_AT_ranges DW_AT_rnglists_base DW_AT_segment DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_pointer_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_address_class DW_AT_alignment DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_ptr_to_member_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_abstract_origin DW_AT_address_class DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_containing_type DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_type DW_AT_use_location DW_AT_visibility 0xffffffff DW_TAG_reference_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_address_class DW_AT_alignment DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_restrict_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_rvalue_reference_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_address_class DW_AT_byte_size /* DW_AT_allocated */ /* DW_AT_associated */ /* DW_AT_data_location */ DW_AT_name /* DW_AT_sibling */ DW_AT_type 0xffffffff DW_TAG_set_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_start_scope DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_shared_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_alignment DW_AT_count DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_skeleton_unit DW_AT_addr_base DW_AT_comp_dir DW_AT_dwo_name DW_AT_high_pc DW_AT_low_pc DW_AT_stmt_list DW_AT_ranges DW_AT_rnglists_base DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_string_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_start_scope DW_AT_string_length DW_AT_string_length_bit_size DW_AT_string_length_byte_size DW_AT_visibility 0xffffffff DW_TAG_structure_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size DW_AT_byte_size DW_AT_calling_convention DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_export_symbols DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_subprogram DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_address_class DW_AT_alignment DW_AT_artificial DW_AT_call_all_calls DW_AT_call_all_tail_calls DW_AT_call_all_source_calls DW_AT_calling_convention DW_AT_containing_type DW_AT_declaration DW_AT_defaulted DW_AT_deleted DW_AT_description DW_AT_elemental DW_AT_entry_pc DW_AT_explicit DW_AT_external DW_AT_frame_base DW_AT_high_pc DW_AT_inline DW_AT_linkage_name DW_AT_low_pc DW_AT_main_subprogram DW_AT_name DW_AT_noreturn DW_AT_object_pointer DW_AT_prototyped DW_AT_pure DW_AT_ranges DW_AT_recursive DW_AT_reference DW_AT_return_addr DW_AT_rvalue_reference DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_static_link DW_AT_trampoline DW_AT_type DW_AT_visibility DW_AT_virtuality DW_AT_vtable_elem_location 0xffffffff DW_TAG_subrange_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_bit_stride DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_stride DW_AT_count DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_lower_bound DW_AT_name DW_AT_sibling DW_AT_threads_scaled DW_AT_type DW_AT_upper_bound DW_AT_visibility 0xffffffff DW_TAG_subroutine_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_address_class DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_object_pointer DW_AT_prototyped DW_AT_rvalue_reference DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_template_alias DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_template_type_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_default_value DW_AT_description DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_template_value_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_const_value DW_AT_default_value DW_AT_description DW_AT_location DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_thrown_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_try_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_typedef DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_type_unit DW_AT_comp_dir DW_AT_language DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_union_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_calling_convention DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_export_symbols DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_unspecified_parameters DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_artificial DW_AT_sibling 0xffffffff DW_TAG_unspecified_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_description DW_AT_name /* DW_AT_sibling ? */ 0xffffffff DW_TAG_variable DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_artificial DW_AT_byte_size DW_AT_bit_size DW_AT_const_expr DW_AT_const_value DW_AT_declaration DW_AT_description DW_AT_endianity DW_AT_external DW_AT_linkage_name DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_variant DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_abstract_origin DW_AT_declaration DW_AT_discr_list DW_AT_discr_value DW_AT_sibling 0xffffffff DW_TAG_variant_part DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_declaration DW_AT_discr DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_volatile_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line /* DW_AT_allocated ? */ /* DW_AT_associated ? */ /* DW_AT_data_location ? */ DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_with_stmt DW_AT_accessibility DW_AT_address_class DW_AT_declaration DW_AT_entry_pc DW_AT_high_pc DW_AT_location DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff libdwarf-20210528/dwarfdump/ChangeLog20100000664000175000017500000001245013644370703014553 000000000000002010-09-30 DavidAnderson * dwarfdump.c: Now -a no longer implies -c because the -c option is not guaranteed to work by the DWARF spec, nor is -c really necessary. * README: More tweaks on the 'install' issue. 2010-09-29 DavidAnderson * README, Makefile.in: Amplified make install instructions. 2010-09-20 DavidAnderson * print_die.c: If a location form is wrong report an error but continue operating. * dwarfdump.c: Implement print_error_and_continue(). Fix mistakes in usage message. * globals.h: Declare print_error_and_continue(). 2010-04-04 DavidAnderson * dwarfdump.c: New version date. * configure: regenerated. * addrmap.c: Added a comment to mention that tdestroy is GNU only, POSIX does not mention a way to delete the tsearch tree. Hence the code does #define USE_GNU 1 to expose the tdestroy function prototype. 2010-04-03 DavidAnderson * print_frames.h: Added new arguments to a function to get better function names printing. * configure.in: Added test for tsearch functions so dwarfdump will still compile if they are not present. See HAVE_TSEARCH macro. * configure: regenerated. * Makefile.in: Now names object for addrmap.c * addrmap.c: New file to map pc address to function names so fde printing gets functions named properly (using tsearch). * addrmap.h: New file to map pc address to function names so fde printing gets functions named properly (using tsearch). * print_lines.c: Correct the calculation of the number of error checks. * dwarfdump.c: Added fdes error check print. * config.h.in: Now handles the HAVE_TSEARCH macro. * globals.h: Added declarations for the fde error check globals. * print_frames.c: Now uses addrmap.h functions to do a better job of printing function names in the frame output. 2010-03-31 DavidAnderson * dwarfdump.1: Added some text about 'harmless' errors. * dwarfdump.c: Change the size of the harmless error list to 50. Change harmless error reporting to be associated with -k flags. * dwconf.c: Initialize uninitialized fields to satisfy a compiler warning. * globals.h: Declarations added for 'harmless' error reporting. * print_die.c: Added commentary. * print_frames.cc: Change harmless error reporting to be associated with -k flags. * print_aranges.c: Now calls dwarf_get_arange_info_b() allowing proper printing of DWARF4 segment-sensitive aranges. Change harmless error reporting to be associated with -k flags. 2010-03-28 DavidAnderson * dwarf_globals.h: Added interface to print_any_harmless_errors(). * dwarfdump.c: Added print_any_harmless_errors() implementation and we call it just before closing libdwarf. * print_frames.c: Call print_any_harmless_errors after getting cie/fde list. * dwarfdump.conf: Add abi named 'arm' for Arm users. * print_die.c: Initialize a local string pointer to NULL at the point of definition. 2010-02-14 DavidAnderson * print_die.c: Add newer DW_OP operators, remove bogus test of DW_OP_nop as the highest valid operator. Add table of DW_OPs to simplify testing for zero-operand operators. Revise so that the FORM of all attributes print with -M. Move a local variable declaration to the front of a block to match C 1990 rules. String searches now also match on attribute name. * tag_attr.list: Updated copyright. * dwarfdump.c: Remove a switch FALL THROUGH in the 'g' case. * tag_tree_ext.list, tag_attr_ext.list: Added GNU template parameter tags, attributes. Updated copyright. * tag_tree.list: Added template parameter tags. Added entry for nested classes. Updated copyright. * tag_common.h: Increased STD_TAG_TABLE_COLUMNS and EXT_ATTR_TABLE_COLS. 2010-01-30 DavidAnderson * print_die.c: Changed the spelling of one 'DW_AT_type offset does not point to type info' error message so one can distinguish which check lead to the message. 2010-01-26 DavidAnderson * dwarfdump.1, dwconf.c, dwconf.h, dwarfdump.conf: The default frame values in frame output are now generic registers like r0 to r99 instead of MIPS register names. For the MIPS register names use '-x abi=mips'. * print_frames.c: Added commentary. 2010-01-17 DavidAnderson * print_die.c: The special case DW_AT_SUN_func_offsets now prints identically in dwarfdump and dwarfdump2. 2010-01-03 DavidAnderson * tag_common.c, common.h, common.c: Remove line terminator characters. Update copyright year. * All other files: Update copyright year. libdwarf-20210528/dwarfdump/compiler_info.h0000644000175000017500000000437613767715461015514 00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMPILER_INFO_H #define COMPILER_INFO_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define COMPILER_TABLE_MAX 100 typedef struct anc { struct anc *next; char *item; } a_name_chain; typedef struct { int checks; int errors; } Dwarf_Check_Result; /* Records information about compilers (producers) found in the debug information, including the check results for several categories (see -k option). */ typedef struct { const char *name; Dwarf_Bool verified; a_name_chain *cu_list; a_name_chain *cu_last; Dwarf_Check_Result results[LAST_CATEGORY]; } Compiler; /* Compiler statistics. */ extern void update_compiler_target(const char *producer_name); extern void add_cu_name_compiler_target(char *name); extern void clean_up_compilers_detected(void); extern Dwarf_Bool checking_this_compiler(void); extern void reset_compiler_entry(Compiler *compiler); extern void print_checks_results(void); extern void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc); extern Dwarf_Bool record_producer(char *name); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* COMPILER_INFO_H */ libdwarf-20210528/dwarfdump/opscounttab.c0000664000175000017500000002532514054205620015177 00000000000000/* Generated expression ops table, do not edit. */ #include "opscounttab.h" struct dwarf_opscounttab_s dwarf_opscounttab[] = { {/* unused 0x00*/ -1}, {/* unused 0x01*/ -1}, {/* unused 0x02*/ -1}, {/* DW_OP_addr 0x03*/ 1}, {/* unused 0x04*/ -1}, {/* unused 0x05*/ -1}, {/* DW_OP_deref 0x06*/ 0}, {/* unused 0x07*/ -1}, {/* DW_OP_const1u 0x 8*/ 1}, {/* DW_OP_const1s 0x 9*/ 1}, {/* DW_OP_const2u 0x a*/ 1}, {/* DW_OP_const2s 0x b*/ 1}, {/* DW_OP_const4u 0x c*/ 1}, {/* DW_OP_const4s 0x d*/ 1}, {/* DW_OP_const8u 0x e*/ 1}, {/* DW_OP_const8s 0x f*/ 1}, {/* DW_OP_constu 0x10*/ 1}, {/* DW_OP_consts 0x11*/ 1}, {/* DW_OP_dup 0x12*/ 0}, {/* DW_OP_drop 0x13*/ 0}, {/* DW_OP_over 0x14*/ 0}, {/* DW_OP_pick 0x15*/ 1}, {/* DW_OP_swap 0x16*/ 0}, {/* DW_OP_rot 0x17*/ 0}, {/* DW_OP_xderef 0x18*/ 0}, {/* DW_OP_abs 0x19*/ 0}, {/* DW_OP_and 0x1a*/ 0}, {/* DW_OP_div 0x1b*/ 0}, {/* DW_OP_minus 0x1c*/ 0}, {/* DW_OP_mod 0x1d*/ 0}, {/* DW_OP_mul 0x1e*/ 0}, {/* DW_OP_neg 0x1f*/ 0}, {/* DW_OP_not 0x20*/ 0}, {/* DW_OP_or 0x21*/ 0}, {/* DW_OP_plus 0x22*/ 0}, {/* DW_OP_plus_uconst 0x23*/ 1}, {/* DW_OP_shl 0x24*/ 0}, {/* DW_OP_shr 0x25*/ 0}, {/* DW_OP_shra 0x26*/ 0}, {/* DW_OP_xor 0x27*/ 0}, {/* DW_OP_bra 0x28*/ 1}, {/* DW_OP_eq 0x29*/ 0}, {/* DW_OP_ge 0x2a*/ 0}, {/* DW_OP_gt 0x2b*/ 0}, {/* DW_OP_le 0x2c*/ 0}, {/* DW_OP_lt 0x2d*/ 0}, {/* DW_OP_ne 0x2e*/ 0}, {/* DW_OP_skip 0x2f*/ 1}, {/* DW_OP_lit0 0x30*/ 0}, {/* DW_OP_lit1 0x31*/ 0}, {/* DW_OP_lit2 0x32*/ 0}, {/* DW_OP_lit3 0x33*/ 0}, {/* DW_OP_lit4 0x34*/ 0}, {/* DW_OP_lit5 0x35*/ 0}, {/* DW_OP_lit6 0x36*/ 0}, {/* DW_OP_lit7 0x37*/ 0}, {/* DW_OP_lit8 0x38*/ 0}, {/* DW_OP_lit9 0x39*/ 0}, {/* DW_OP_lit10 0x3a*/ 0}, {/* DW_OP_lit11 0x3b*/ 0}, {/* DW_OP_lit12 0x3c*/ 0}, {/* DW_OP_lit13 0x3d*/ 0}, {/* DW_OP_lit14 0x3e*/ 0}, {/* DW_OP_lit15 0x3f*/ 0}, {/* DW_OP_lit16 0x40*/ 0}, {/* DW_OP_lit17 0x41*/ 0}, {/* DW_OP_lit18 0x42*/ 0}, {/* DW_OP_lit19 0x43*/ 0}, {/* DW_OP_lit20 0x44*/ 0}, {/* DW_OP_lit21 0x45*/ 0}, {/* DW_OP_lit22 0x46*/ 0}, {/* DW_OP_lit23 0x47*/ 0}, {/* DW_OP_lit24 0x48*/ 0}, {/* DW_OP_lit25 0x49*/ 0}, {/* DW_OP_lit26 0x4a*/ 0}, {/* DW_OP_lit27 0x4b*/ 0}, {/* DW_OP_lit28 0x4c*/ 0}, {/* DW_OP_lit29 0x4d*/ 0}, {/* DW_OP_lit30 0x4e*/ 0}, {/* DW_OP_lit31 0x4f*/ 0}, {/* DW_OP_reg0 0x50*/ 0}, {/* DW_OP_reg1 0x51*/ 0}, {/* DW_OP_reg2 0x52*/ 0}, {/* DW_OP_reg3 0x53*/ 0}, {/* DW_OP_reg4 0x54*/ 0}, {/* DW_OP_reg5 0x55*/ 0}, {/* DW_OP_reg6 0x56*/ 0}, {/* DW_OP_reg7 0x57*/ 0}, {/* DW_OP_reg8 0x58*/ 0}, {/* DW_OP_reg9 0x59*/ 0}, {/* DW_OP_reg10 0x5a*/ 0}, {/* DW_OP_reg11 0x5b*/ 0}, {/* DW_OP_reg12 0x5c*/ 0}, {/* DW_OP_reg13 0x5d*/ 0}, {/* DW_OP_reg14 0x5e*/ 0}, {/* DW_OP_reg15 0x5f*/ 0}, {/* DW_OP_reg16 0x60*/ 0}, {/* DW_OP_reg17 0x61*/ 0}, {/* DW_OP_reg18 0x62*/ 0}, {/* DW_OP_reg19 0x63*/ 0}, {/* DW_OP_reg20 0x64*/ 0}, {/* DW_OP_reg21 0x65*/ 0}, {/* DW_OP_reg22 0x66*/ 0}, {/* DW_OP_reg23 0x67*/ 0}, {/* DW_OP_reg24 0x68*/ 0}, {/* DW_OP_reg25 0x69*/ 0}, {/* DW_OP_reg26 0x6a*/ 0}, {/* DW_OP_reg27 0x6b*/ 0}, {/* DW_OP_reg28 0x6c*/ 0}, {/* DW_OP_reg29 0x6d*/ 0}, {/* DW_OP_reg30 0x6e*/ 0}, {/* DW_OP_reg31 0x6f*/ 0}, {/* DW_OP_breg0 0x70*/ 1}, {/* DW_OP_breg1 0x71*/ 1}, {/* DW_OP_breg2 0x72*/ 1}, {/* DW_OP_breg3 0x73*/ 1}, {/* DW_OP_breg4 0x74*/ 1}, {/* DW_OP_breg5 0x75*/ 1}, {/* DW_OP_breg6 0x76*/ 1}, {/* DW_OP_breg7 0x77*/ 1}, {/* DW_OP_breg8 0x78*/ 1}, {/* DW_OP_breg9 0x79*/ 1}, {/* DW_OP_breg10 0x7a*/ 1}, {/* DW_OP_breg11 0x7b*/ 1}, {/* DW_OP_breg12 0x7c*/ 1}, {/* DW_OP_breg13 0x7d*/ 1}, {/* DW_OP_breg14 0x7e*/ 1}, {/* DW_OP_breg15 0x7f*/ 1}, {/* DW_OP_breg16 0x80*/ 1}, {/* DW_OP_breg17 0x81*/ 1}, {/* DW_OP_breg18 0x82*/ 1}, {/* DW_OP_breg19 0x83*/ 1}, {/* DW_OP_breg20 0x84*/ 1}, {/* DW_OP_breg21 0x85*/ 1}, {/* DW_OP_breg22 0x86*/ 1}, {/* DW_OP_breg23 0x87*/ 1}, {/* DW_OP_breg24 0x88*/ 1}, {/* DW_OP_breg25 0x89*/ 1}, {/* DW_OP_breg26 0x8a*/ 1}, {/* DW_OP_breg27 0x8b*/ 1}, {/* DW_OP_breg28 0x8c*/ 1}, {/* DW_OP_breg29 0x8d*/ 1}, {/* DW_OP_breg30 0x8e*/ 1}, {/* DW_OP_breg31 0x8f*/ 1}, {/* DW_OP_regx 0x90*/ 1}, {/* DW_OP_fbreg 0x91*/ 1}, {/* DW_OP_bregx 0x92*/ 2}, {/* DW_OP_piece 0x93*/ 1}, {/* DW_OP_deref_size 0x94*/ 1}, {/* DW_OP_xderef_size 0x95*/ 1}, {/* DW_OP_nop 0x96*/ 0}, {/* DW_OP_push_object_address 0x97*/ 0}, {/* DW_OP_call2 0x98*/ 1}, {/* DW_OP_call4 0x99*/ 1}, {/* DW_OP_call_ref 0x9a*/ 1}, {/* DW_OP_form_tls_address 0x9b*/ 0}, {/* DW_OP_call_frame_cfa 0x9c*/ 0}, {/* DW_OP_bit_piece 0x9d*/ 2}, {/* DW_OP_implicit_value 0x9e*/ 2}, {/* DW_OP_stack_value 0x9f*/ 0}, {/* DW_OP_implicit_pointer 0xa0*/ 2}, {/* DW_OP_addrx 0xa1*/ 1}, {/* DW_OP_constx 0xa2*/ 1}, {/* DW_OP_entry_value 0xa3*/ 2}, {/* DW_OP_const_type 0xa4*/ 3}, {/* DW_OP_regval_type 0xa5*/ 2}, {/* DW_OP_deref_type 0xa6*/ 2}, {/* DW_OP_xderef_type 0xa7*/ 0}, {/* DW_OP_convert 0xa8*/ 1}, {/* DW_OP_reinterpret 0xa9*/ 1}, {/* unused 0xaa*/ -1}, {/* unused 0xab*/ -1}, {/* unused 0xac*/ -1}, {/* unused 0xad*/ -1}, {/* unused 0xae*/ -1}, {/* unused 0xaf*/ -1}, {/* unused 0xb0*/ -1}, {/* unused 0xb1*/ -1}, {/* unused 0xb2*/ -1}, {/* unused 0xb3*/ -1}, {/* unused 0xb4*/ -1}, {/* unused 0xb5*/ -1}, {/* unused 0xb6*/ -1}, {/* unused 0xb7*/ -1}, {/* unused 0xb8*/ -1}, {/* unused 0xb9*/ -1}, {/* unused 0xba*/ -1}, {/* unused 0xbb*/ -1}, {/* unused 0xbc*/ -1}, {/* unused 0xbd*/ -1}, {/* unused 0xbe*/ -1}, {/* unused 0xbf*/ -1}, {/* unused 0xc0*/ -1}, {/* unused 0xc1*/ -1}, {/* unused 0xc2*/ -1}, {/* unused 0xc3*/ -1}, {/* unused 0xc4*/ -1}, {/* unused 0xc5*/ -1}, {/* unused 0xc6*/ -1}, {/* unused 0xc7*/ -1}, {/* unused 0xc8*/ -1}, {/* unused 0xc9*/ -1}, {/* unused 0xca*/ -1}, {/* unused 0xcb*/ -1}, {/* unused 0xcc*/ -1}, {/* unused 0xcd*/ -1}, {/* unused 0xce*/ -1}, {/* unused 0xcf*/ -1}, {/* unused 0xd0*/ -1}, {/* unused 0xd1*/ -1}, {/* unused 0xd2*/ -1}, {/* unused 0xd3*/ -1}, {/* unused 0xd4*/ -1}, {/* unused 0xd5*/ -1}, {/* unused 0xd6*/ -1}, {/* unused 0xd7*/ -1}, {/* unused 0xd8*/ -1}, {/* unused 0xd9*/ -1}, {/* unused 0xda*/ -1}, {/* unused 0xdb*/ -1}, {/* unused 0xdc*/ -1}, {/* unused 0xdd*/ -1}, {/* unused 0xde*/ -1}, {/* unused 0xdf*/ -1}, {/* DW_OP_GNU_push_tls_address 0xe0*/ 0}, {/* unused 0xe1*/ -1}, {/* unused 0xe2*/ -1}, {/* unused 0xe3*/ -1}, {/* unused 0xe4*/ -1}, {/* unused 0xe5*/ -1}, {/* unused 0xe6*/ -1}, {/* unused 0xe7*/ -1}, {/* unused 0xe8*/ -1}, {/* unused 0xe9*/ -1}, {/* unused 0xea*/ -1}, {/* unused 0xeb*/ -1}, {/* unused 0xec*/ -1}, {/* unused 0xed*/ -1}, {/* unused 0xee*/ -1}, {/* unused 0xef*/ -1}, {/* DW_OP_GNU_uninit 0xf0*/ 0}, {/* DW_OP_GNU_encoded_addr 0xf1*/ 1}, {/* DW_OP_GNU_implicit_pointer 0xf2*/ 2}, {/* DW_OP_GNU_entry_value 0xf3*/ 2}, {/* DW_OP_GNU_const_type 0xf4*/ 3}, {/* DW_OP_GNU_regval_type 0xf5*/ 2}, {/* DW_OP_GNU_deref_type 0xf6*/ 2}, {/* DW_OP_GNU_convert 0xf7*/ 1}, {/* DW_OP_PGI_omp_thread_num 0xf8*/ 1}, {/* DW_OP_GNU_reinterpret 0xf9*/ 1}, {/* DW_OP_GNU_parameter_ref 0xfa*/ 1}, {/* DW_OP_GNU_addr_index 0xfb*/ 1}, {/* DW_OP_GNU_const_index 0xfc*/ 1}, {/* DW_OP_GNU_variable_value 0xfd*/ 1}, {/* unused 0xfe*/ -1}, {/* unused 0xff*/ -1}, }; libdwarf-20210528/dwarfdump/print_str_offsets.c0000664000175000017500000001252213764006205016413 00000000000000/* Copyright 2018-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" /* print data in .debug_str_offsets. There is no guarantee this will work because the DWARF5 standard is silent about whether arbitrary non-zero bytes, or odd alignments, or unused data spaces are allowed in the section */ int print_str_offsets_section(Dwarf_Debug dbg,Dwarf_Error *err) { int res = 0; Dwarf_Str_Offsets_Table sot = 0; Dwarf_Unsigned wasted_byte_count = 0; Dwarf_Unsigned table_count = 0; Dwarf_Unsigned tabnum = 0; res = dwarf_open_str_offsets_table_access(dbg, &sot,err); if (res == DW_DLV_NO_ENTRY) { /* No such table */ return res; } if (res == DW_DLV_ERROR) { return res; } for (;; ++tabnum) { Dwarf_Unsigned unit_length =0; Dwarf_Unsigned unit_length_offset =0; Dwarf_Unsigned table_start_offset =0; Dwarf_Half entry_size = 0; Dwarf_Half version =0; Dwarf_Half padding =0; Dwarf_Unsigned table_value_count =0; Dwarf_Unsigned i = 0; Dwarf_Unsigned table_entry_value = 0; unsigned rowlim = 4; unsigned count_in_row = 0; res = dwarf_next_str_offsets_table(sot, &unit_length, &unit_length_offset, &table_start_offset, &entry_size,&version,&padding, &table_value_count,err); if (res == DW_DLV_NO_ENTRY) { /* We have dealt with all tables */ break; } if (res == DW_DLV_ERROR) { dwarf_close_str_offsets_table_access(sot,err); return res; } if (tabnum == 0) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_str_offsets", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } else { printf("\n"); } printf(" table %" DW_PR_DUu "\n",tabnum); printf(" tableheader 0x%" DW_PR_XZEROS DW_PR_DUx "\n", unit_length_offset); printf(" arrayoffset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", table_start_offset); printf(" unit length 0x%" DW_PR_XZEROS DW_PR_DUx "\n", unit_length); printf(" entry size %u\n",entry_size); printf(" version %u\n",version); if (padding) { printf("Error: padding is non-zero. " "Something is wrong.\n"); } printf(" padding 0x%x\n",padding); printf(" arraysize %" DW_PR_DUu "\n",table_value_count); /* Lets print 4 per row. */ count_in_row = 0; for (i=0; i < table_value_count; ++i) { res = dwarf_str_offsets_value_by_index(sot,i, &table_entry_value,err); if (res != DW_DLV_OK) { dwarf_close_str_offsets_table_access(sot,err); return res; } if (!count_in_row) { printf(" Entry [%4" DW_PR_DUu "]: ",i); } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx , table_entry_value); ++count_in_row; if (count_in_row < rowlim) { continue; } printf("\n"); count_in_row = 0; } if (count_in_row) { printf("\n"); } res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,err); if (res == DW_DLV_OK) { printf(" wasted %" DW_PR_DUu " bytes\n", wasted_byte_count); } if (res == DW_DLV_ERROR) { res = dwarf_close_str_offsets_table_access(sot,err); return res; } } if (wasted_byte_count) { res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,err); if (res == DW_DLV_OK) { printf(" finalwasted %" DW_PR_DUu " bytes\n", wasted_byte_count); } else { res = dwarf_close_str_offsets_table_access(sot,err); return res; } } res = dwarf_close_str_offsets_table_access(sot,err); sot = 0; return res; } libdwarf-20210528/dwarfdump/print_sections.h0000664000175000017500000000266713653363342015724 00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_SECTIONS_H #define PRINT_SECTIONS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_names_print_on_error; Dwarf_Unsigned get_info_max_offset(Dwarf_Debug dbg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRINT_SECTIONS_H */ libdwarf-20210528/dwarfdump/macrocheck.h0000664000175000017500000001063213771202427014744 00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef MACROCHECK_H #define MACROCHECK_H /* tsearch trees used in macro checking. */ extern void * macro_check_tree; /* DWARF5 macros. */ extern void * macinfo_check_tree; /* DWARF2,3,4 macros */ extern void * macdefundeftree; /* DWARF5 style macros */ struct Macrocheck_Map_Entry_s { Dwarf_Unsigned mp_key; /* Key is offset */ Dwarf_Unsigned mp_len; /* len in bytes off this macro set */ /* We count number of uses. More than 1 primary is an error. Both primary and secondary is ok or error? */ Dwarf_Unsigned mp_refcount_primary; Dwarf_Unsigned mp_refcount_secondary; Dwarf_Unsigned mp_import_linenum; unsigned mp_import_from_filenum; /* So we go through each one just once. */ Dwarf_Bool mp_printed; }; /* for def/undef checking. */ struct macdef_entry_s { char * md_key; /* Tacked on this record. Do not free */ unsigned md_operatornum; unsigned int md_defined; unsigned int md_undefined; unsigned int md_defcount; unsigned int md_undefcount; unsigned md_operator; Dwarf_Unsigned md_line; Dwarf_Unsigned md_offset; Dwarf_Unsigned md_macro_unit_offset; char * md_string; /* see create entry. Do not free */ unsigned md_file_array_entry; }; typedef struct macdef_entry_s macdef_entry; /* for start-file end-file checking. */ struct macfile_entry_s { unsigned ms_operatornum; unsigned ms_operator; Dwarf_Unsigned ms_line; Dwarf_Unsigned ms_filenum; Dwarf_Unsigned ms_offset; Dwarf_Unsigned ms_macro_unit_offset; unsigned ms_array_number; /* position in macfile_array */ char * ms_filename; }; typedef struct macfile_entry_s macfile_entry; #define MACFILE_STACK_DEPTH_MAX 50 /* Arbitrary. Make bigger? */ extern unsigned macfile_stack_next_to_use; extern unsigned macfile_stack[MACFILE_STACK_DEPTH_MAX+1]; extern unsigned macfile_stack_max_seen; #define MACRO_IMPORT_STACK_DEPTH 20 /* Arbitrary. Make bigger? */ extern Dwarf_Unsigned macro_import_stack[MACRO_IMPORT_STACK_DEPTH +1]; extern unsigned macro_import_stack_next_to_use; extern unsigned macro_import_stack_max_seen; /* Returns DW_DLV_ERROR if the push could not done, which would be because full. Else returns DW_DLV_OK. */ int macro_import_stack_push(Dwarf_Unsigned offset); /* Returns DW_DLV_ERROR if the pop could not done, else returns DW_DLV_OK. */ int macro_import_stack_pop(void); /* Returns DW_DLV_OK if offset is in the stack or DW_DLV_NO_ENTRY if it is not in the stack. */ int macro_import_stack_present(Dwarf_Unsigned offset); void macro_import_stack_cleanout(void); void print_macro_import_stack(void); struct Macrocheck_Map_Entry_s * macrocheck_map_find( Dwarf_Unsigned offset, void **map); void add_macro_import(void **base,Dwarf_Bool is_primary, Dwarf_Unsigned offset, Dwarf_Unsigned linenum, unsigned mafile_file_number); void add_macro_import_sup(void **base,Dwarf_Unsigned offset); void add_macro_area_len(void **base, Dwarf_Unsigned offset, Dwarf_Unsigned len); int get_next_unprinted_macro_offset(void **base, Dwarf_Unsigned * off); void mark_macro_offset_printed(void **base, Dwarf_Unsigned offset); int print_macrocheck_statistics(const char *name,void **basep, int isdwarf5, Dwarf_Unsigned section_size,Dwarf_Error *err); void clear_macrocheck_statistics(void **basep); macfile_entry * macfile_from_array_index( unsigned index); #endif /* MACROCHECK_H */ libdwarf-20210528/dwarfdump/ChangeLog20150000664000175000017500000005122113644370703014557 000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-12-19 David Anderson * dwarfdump.c: Now we print macros alone by CU with -m (at least for DWARF5 macro format) * print_lines.c(print_source_intro): Minor local variable ordering change. * print_macro.c(print_source_intro): Minor local variable ordering change. 2015-12-19 David Anderson * print_macro.c: Print the actual macro offset size we will use. 2015-12-18 David Anderson * dwarfdump.c,globals.h print_die.c,print_lines.c, print_macro.c,print_pubnames.c,print_ranges.c: Removed globals elf_max_address and elf_address_size in favor of local variables and new global function get_address_size_and_max(). 2015-12-16 David Anderson * print_aranges.c, print_die.c: Ensure the four error-reporting globals DIE_[CU_][global_]_offset are set properly. 2015-12-16 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. Fix PRINT_CU_INFO() to do what was intended (and not have a side effect). * print_aranges.c: Folded a too-long line. * print_die.c: Folded a line so both offsets listed on same line. * print_macro.c: moved macro_context call above the print of ".debug_macro" so if the section does not exist we print nothing. 2015-12-15 David Anderson * print_macro.c: Much of printing DWARF5 macros now works. 2015-12-13 David Anderson * print_macro.c: Call new function dwarf_get_macro_ops_count() and print returned values. 2015-12-12 David Anderson * print_macro.c: Now does -vv intro with cu_die print too. * print_macros.c: Only print .debug_macro name if there are some. 2015-12-11 David Anderson * naming.h,naming.c: Added get_MACRO_name(). * print_macro.c: Now reads and prints macro5 header. 2015-12-11 David Anderson * esb.c: esb_append now checks for NULL string pointer. Added comment esb functions do NOT check for NULL pointers generally. 2015-12-10 David Anderson * esb.c: esb_get_copy() failed to account for the trailing NUL. esb_get_copy was not being tested by SELFTEST. Fixed both issues. 2015-12-08 David Anderson * common.c,dwarfdump.c: Update version string. * print_frames.c: Fix trailing whitespace. Implement an attempt at DW_CFA_METAWARE_info. 2015-12-08 David Anderson * print_frames.c: Fix indents and remove trailing whitespace. Add comments: Errors in DIE info just result in omitting procedure names, no warning/errors. * dwarfdump.c: Deleted Elf64_Ehdr *eh64 declaration that can never be used. 2015-11-30 David Anderson * print_frames.c: Remove trailing whitespace. 2015-11-30 David Anderson * Makefile.in: Add print_macro.o to build list. * dwarfdump.c: Add macro_flag flag to signal print of DWARF5 debug_macro data. * globals.h: Export new macro print function. * print_die.c: Call new macro print function, skip that attr in checking-only run.. 2015-11-28 David Anderson * globals.h: Added DEBUG_FRAME_EH_GNU define for consistency.. * print_frames.c: use the new dwarf_get_frame_section_name() and dwarf_get_frame_section_name_eh_gnu() functions for section names. * print_lines.c: Use the new dwarf_get_line_section_name_from_die() function for the section name. * print_locs.c,print_macros.c,print_pubnames.c,print_static_funcs.c, print_types.c,print_weaknames.c: Added comments. These are places where the section is either obsolete or the section name is rarely of any use. 2015-11-27 David Anderson * dwarfdump.1: Mentions that with zdebug sections offsets refer to expanded object section, not compressed section. * print_aranges.c,print_die.c,print_lines.c,print_ranges.c, print_strings.c: Get the real section name from libdwarf. 2015-11-26 David Anderson * common.c,dwarfdump.c: Updated version string. * config.h.in, configure.in, Makefile.in: Deals with zlib when present. 2015-11-15 David Anderson * Makefile.in: Now supports building in a clean separate directory. 2015-11-11 David Anderson * print_abbrevs.c(dwarf_get_array_info): Initialize local variable. * print_die.c(get_location_list): Initialize local variable.: * dwarf_loc.h: Add declaration of _dwarf_loc_block_sanity_check(). * dwarf_loc.c: Call new function _dwarf_loc_block_sanity_check * dwarf_loc2.c: Implement and call new function _dwarf_loc_block_sanity_check to avoid duplicating code. 2015-11-07 David Anderson * dwarfdump.1: Documented -x line5=. * dwarfdump.c: Revised -g so it no longer turns on -i. Revised the meaning of -g to mean use old loclist interfaces (for testing the older interfaces with dwarfdump). * print_die.c(get_small_encoding_integer_and_name): a dwarf_dealloc referenced err whereas *err was correct. Revised loclist output making it look a bit like DWARF5 even for DWARF2,3,4 output. Reads better, I think. * print_locs.c: -l gets a 'no longer supported' message as it was never safe to do anyway. 2015-11-01 David Anderson * configure.in: Add -O0 to --enable-wall. So if a coredump during debugging gdb will work really well. * configure: Regenerated. * print_frames.c: Ommitted a 'return' statement so some output duplicated. Added in the missing return. 2015-11-01 David Anderson * Makefile.in, configure.in: Implement --enable-wall for compile-time checking. * configure: Regenerate. * print_die.c: Add DWARF5 DW_OPs and .debug_loc.dwo loclists are handled. Now uses either latest (DWARF5) interfaces or earlier, repurposing the old -g option to select. * print_frames.c,print_frames.h: Printing expressions (in .debug_frame, .eh_frame) now honors -g so DWARF5 expressions handled. * print_lines.c: Fixed some formatting. * print_locs.c: Changes reflecting code calling into print_frames.c 2015-10-26 David Anderson * print_die.c: Removed debug printf.Corrected DW_OP_GNU_const_type handling (cannot be fully reported for certain new location operators). 2015-10-15 David Anderson * print_die.c: Added DW_FORM_strp_sup, same idea as DW_FORM_GNU_strp_alt. 2015-10-15 David Anderson * dwarfdump.c: Add enum line_flag_type_e so we can test all the srclines interfaces (4 of them). Expand -x for that too. * print_die.c: Support DW_FORM_GNU_strp_alt. * print_lines.c: Update for old and new srclines interfaces. * globals.h: Added the enum line_flag_e variable for recording -x line5= value. 2015-10-06 David Anderson * dwarfdump.c: Now allow selecting alternate line table reading code so line table routines can be tested thoroughly. * print_lines.c: Uses one of the selected line table routine sets. Adds new line access routine calls to test those too. * globals.h: Declares new flag line_skeleton_flag; * print_die.c: Moved a local declaration to where it is used. Added a missing DW_DLV_ERROR check so in case of error we do not leak memory. 2015-09-26 David Anderson * dwarfdump.c, common.c: Update version string. * print_lines.c: Added local variables for clarity in a call, changed the dwarf_srclines_dealloc() location to fully clean up after a two-level line table srcfiles call. 2015-09-26 David Anderson * dwarfdump.c, common.c: Update version string. 2015-09-24 David Anderson * dwarfdump.c, common.c: Update version string. * print_lines.c: IA in line header hint is really spelled IS. Fixed now. * dwarf_elf_access.c: Added R_IA64* and R_390 relocation ifdefs for cases where they are not in a test machines elf.h or the like. 2015-09-23 David Anderson * print_lines.c: Removed accidental newline from output. 2015-09-22 David Anderson * print_die.c: Removed trailing whitespace and fixed indentation mistake. * print_lines.c: Fixed indentation and inconsistencies in spelling line table field hints. Leaving IA as has been for a long time though it should be spelled IS. 2015-09-19 David Anderson * print_lines.c: Tweaking two-level line table code, mostly comments.. 2015-09-17 David Anderson * print_lines.c: Adding handling of experimental two-level line table. 2015-09-15 Carlos Alberto Enciso * common.c: For Windows version, add a symbol with the release date (taken from the distributed compressed archive), to be used by print_version_details() for better tracking of versions. * print_die.c: The text search (-S), now follows the DW_AT_specification and the DW_AT_abstract_origin attributes, to get the associated name; this finds the declaration and definitions DIEs for a member functions or the abstract and concrete instance DIEs for inlined functions. Fix some C99 issues with local variable declarations in get_attr_value(). * print_aranges.c: Add an extra newline in print_aranges(). 2015-09-15 David Anderson * print_die.c: for case DW_AT_dwo_id a c99-ism has been changed to be like C89. 2015-09-14 David Anderson * dwarfdump.c: Remove trailing space. * print_frames.c, globals.h: print_frame_inst_bytes() defined and used in one file, so made a static function, removed from globals.h 2015-09-13 David Anderson * dwarfdump.c, common.c: Update version string. 2015-09-11 David Anderson * dwarfdump.c: Update usage message to mention -x tied= and update version strings. * common.c: Update version string. 2015-09-11 David Anderson * dwarfdump.c: Fixed copy/paste errors so DebugFission code works (see tieddbg in the source). 2015-09-11 David Anderson * dwarfdump.c, dwarfdump.1: Added -x tied= option so one can get .debug_addr data when referencing a .dwp or .dwo. Tieing these together. * print_die.c: Fixed indent errors. 2015-09-05 David Anderson * tag_attr.list,tag_attr_ext.list,tag_tree.list: removed trailing whitespace. 2015-07-12 David Anderson * dwarfdump.c: Use dwoptind dwoptarg, not optind, optarg * dwgetopt.c,dwgetopt.h,dwgetopttest.c,tag_attr.c, tag_tree.c: Use dwoptind dwoptarg etc, not optind, optarg, optopt op6error etc. * print_die.c: updated commentary. 2015-05-07 David Anderson * common.c, dwarfdump.c: Update version string. * print_die.c: Print DW_AT_dwo_id properly as a Dwarf_Sig8 value. 2015-05-03 David Anderson * print_die.c: Print the fission data from the index section when we print cu header, not when printing cu DIE. Moved cu header/cu die print code to functions, simplifying calling code. 2015-05-01 David Anderson * tag_attr.list: Added a DW_AT_signature and moved a couple attributes to match the standard-document order of attributes. 2015-03-10 David Anderson * dwarfdump.c: Update version string. * common.c: Update version string. * dwgetopt.c: Was mishandling options missing their required argument and coredumping dwarfdump. * getopttest.c: Added new tests to ensure we have the dwgetopt() fixes working properly. * Makefile.in: Added new test runs to 'make test'. * print_die.c, print_lines.c: Removed instances of trailing whitespace. 2015-03-09 David Anderson * Makefile.in: added new tests of dwgetopt. Runs not only dwgetopt but system getopt. * dwarfdump.c: New function set_checks_off() so if printing we don't do checks (intended to be this way for a long time now). Updated version string. * common.c: Updated version string. * print_die.c: Was not always recognizing unit DIES DW_TAG_partial_unit or DW_TAG_type_unit where it saw DW_TAG_compile_unit. Now does so. * dwgetopt.c: Errors could lead to dwarfdump coredump. Fixed. * getopttest.c: Added several new tests. Now one can run single tests and run against either getopt or dwgetopt (set at compile time of getopttest.c). 2015-03-03 David Anderson * tag_attr.list: Removed DW_AT_sibling from DW_TAG_partial_unit. DW_TAG_compile_unit. Removed DW_AT_containing_type from DW_TAG_subprogram, DW_TAG_structure_type. * dwarfdump.c,common.c: Update version strings. * print_die.c: Fix indent mistakes. Add comment in _dwarf_print_one_expr_op() that one error is not presently realizable (FreeBSD compiler noticed the situation). * print_ranges.c: Fix indent mistakes. * tag_attr.c: Remove trailing whitespace from a #include line. 2015-03-03 Carlos Alberto Enciso * dwarfdump.c: Add allocate_range_array_info(), release_range_array_info() calls to help fix range checking. * globals.h: Add declarations of range checking functions. * print_die.c: Add check_range_array_info() call. Add record_range_array_info_entry() call. Move all the range check code out of print_die.c. Add handling of high_pc as an offset, not just as a value. * print_ranges.c: Delete unneeded includes. Add check_ranges_list() implementation moved from print_die.c. Add new ranges check functions. Range check error messages now appear later in the output, though the content is identical. * tag_attr_ext.list: Add DW_TAG_GNU_call_site and DW_TAG_GNU_call_site_parameter tag attr combinations. * tag_tree_ext.list: Add DW_TAG_GNU_call_site DW_TAG_call_site_parameter 2015-02-22 David Anderson * configure.in: removed getopt.h from tests, we use local dwgetopt now. * dwgetopt.h: Function name is dwgetopt. Prototype named right now. Copied from libdwarf dwgetopt.h * configure: regenerated * Makefile.in: build dwgetopt.o * dwgetopt.c: Copied from libdwarf source. * tag_attr.c,tag_tree.c: Now call dwgetopt() instead of getopt(). 2015-02-04 David Anderson * common.c,dwarfdump.c:Updated version string. * print_debugfission.c: Now we are using a Dwarf_Sig8 for fission hash so we introduce an esb_s to do the formatting. * tag_attr.c: Now we format a more detailed message when we detect an insufficient static tag_attr or tag_tree array instance. It's code only used at build time so just giving up is fine: someone changed dwarf.h. * tag_attr.list: Adding new TAGs and new Attrs from DWARF5. Since the DWARF5 standard not yet final these could change! * tag_attr_ext.list: Added new GNU attributes. * tag_common.h: updated DW_TAG_last and DW_AT_last STD_TAG_TABLE_ROWS STD_ATTR_TABLE_COLUMNS values due to dwarf.h updates. * tag_tree.list: New entries from DWARF5. 2015-01-31 David Anderson * DWARFDUMPCOPYRIGHT: updated to reflect changes today. Old versions of the copyright notices still shown here. * common.c,dwarfdump.c,dwconf.c,esb.c,makename.c,naming.c, print_abbrevs.c,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_locs.c,print_macros.c,print_pubnames.c, print_ranges.c,print_reloc.c,print_sections.c,print_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c,print_weaknames.c, strstrnocase.c,tag_attr.c,tag_attr.list,tag_attr_ext.list, tag_common.c,tag_tree.c,tag_tree.list,tag_tree_ext.list, uri.c,uritablebuild.c: Removed obsolete SGI postal address and web references. 2015-01-31 David Anderson * common.h,dwconf.h,esb.h,globals.h,makename.h,naming.h, print_frames.h,print_reloc.h,print_sections.h,tag_common.h,uri.h: The address and URI for SGI is obsolete and there is no replacement so deleted some lines from the copyright statements. 2015-01-30 David Anderson * common.c,dwarfdump.c: Update version string. * globals.h: Added format_sig8_string() to global functions. * print_debug_fission.c: Updated .debug_cu/tu_index hash signature code to match libdwarf (Dwarf_Sig8, not Dwarf_Unsigned). Allow for missing hash (?). * print_die.c: Use format_sig8_string(). 2015-01-29 David Anderson * print_die.c: Two places used C99-only variable declaration. Moved declarations up to conform to C90. 2015-01-24 David Anderson * dwgetopt.c,dwgetopt.h: Using NetBSD getopt source with modifications to support :: for uniform behavior for all users. Not all getopt are the same. Named dwgetopt(). * dwgetopttest.c: Does tests of dwgetopt() for conformance with dwarfdump requirements. See 'make selftest'. * Makefile.in: Now has selftest for dwgetopt and links dwgetopt.o into dwarfdump. * esb.c: Now prints PASS on success and counts errors. * dwarfdump.c: Now calls dwgetopt and includes dwgetopt.h Added a new global so we recognize where needed not to do some checks when checking ( for debugfission some things not sensible). * globals.h: Removed cu_offset (not needed) and added suppress_checking_on_dwp flags. * print_die.c:renamed cu_offset to be a static: dieprint_cu_offset Reset it when finished with a CU. (-k checks got into trouble when both .debug_info and .debug_types present). 2015-01-21 David Anderson * common.c, dwarfdump.c: Update version string. * print_die.c: For a DW_FORM_ref_sig8 type signature value, if not printing the actual FORM print so the hex value makes sense. It is obviously not a .debug_info global offset. Now prints debug fission (dwp) information for each CU with such. 2015-01-18 David Anderson * common.c, dwarfdump.c: Update version string. 2015-01-15 David Anderson * dwarfdump.c: dump_unique_errors_table() ifdef out of normal compiles, it is unused. Unused local variables removed. Update version string. * esb.c: Moved stdarg.h include just after stdio.h include for positioning consistency. * globals.h: Added stdarg.h include just after stdio.h include as we use va_list a lot and so stdarg.h is required. * print_debugfission.c: Remove two unused local variables. * print_frames.c: Remove trailing whitespace. * tag_attr.c: #include stdarg.h. Add {} to array initializers output to avoid compiler warning. * tag_common.c: Move stdarg.h include to just after stdio.h for positioning consistency. Update version string. * tag_tree.c: Revised include order to start with globals.h and to not duplicate includes of stdio.h etc. Add {} to array initializers output to avoid compiler warning. * testesb.c: Add include of stdarg.h. 2015-01-12 David Anderson * tag_common.c: Add comments about va_start, va_end. * esb.c: Add comments about va_start, va_end. Add va_end in the selftest code. * common.c: Update version string. * dwarfdump.c: Update version string. Add va_end() and comments about va_end. 2015-01-08 David Anderson and Carlos Alberto Enciso * Makefile.in: add selftest: rule, which tests esb.c * dwarfdump.c: Add new options -O file=path, -kD -kG -ku kuf. New checking and reporting features intended to give a report on attribute and tag usage. Update version string. * common.c: Update version string. * esb.c, esb.h: Added new interface using stdarg. Added self-test feature. * dwarf_makename.c: new #pragma (not Linux/Unix related). * print_die.c: Implements collecting the new statistics dwarfdump reports. * print_lines.c: New statistics collected. * tag_attr.c: New checks for the tag/attr table correctness. * tag_attr.list: Fixes duplicated entries. * tag_attr.list_ext: Adds APPLE attribute DW_AT_APPLE_optimized that llvm emits. * tag_common.c: bad_line_input() now allows stdarg calls so its easier to emit good error messages. * tag_common.h: bad_line_input() arg list changed a little. Stdarg now. * tag_tree.c: New tag tree checking done. New statistics available. * tag_tree.list: Adds DW_TAG_unspecified_type, DW_TAG_rvalue_reference_type, DW_TAG_restrict_type. * tag_tree_ext.list: Adds DW_TAG_GNU_template_template_parameter. Fixes duplication of entries. 2015-01-05 David Anderson * dwarfdump.c: Don't call dwarf_finish() if the dwarf-init call failed. * common.c,dwarfdump.c: Updated version string. 2015-01-01 David Anderson * A new year begins. libdwarf-20210528/dwarfdump/print_debug_names.c0000664000175000017500000000507313764006205016326 00000000000000/* Copyright 2017-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "sanitized.h" #include "esb.h" #include "esb_using_functions.h" int print_debug_names(Dwarf_Debug dbg,Dwarf_Error *error) { Dwarf_Dnames_Head dnhead = 0; Dwarf_Unsigned dn_count = 0; Dwarf_Unsigned dnindex = 0; int res = 0; if (!dbg) { printf("ERROR: Cannot print .debug_names, " "no Dwarf_Debug passed in"); return DW_DLV_NO_ENTRY; } glflags.current_section_id = DEBUG_NAMES; /* Only print anything if we know it has debug names present. And for now there is none. FIXME. */ res = dwarf_debugnames_header(dbg,&dnhead,&dn_count,error); if (res == DW_DLV_NO_ENTRY) { return res; } if (res == DW_DLV_ERROR) { return res; } /* Do nothing if not printing. */ if (glflags.gf_do_print_dwarf) { const char * section_name = ".debug_names"; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } if (glflags.gf_do_print_dwarf) { printf("names tables: %" DW_PR_DUu "\n",dn_count); } for ( ; dnindex < dn_count; ++dnindex) { if (glflags.gf_do_print_dwarf) { printf("names table %" DW_PR_DUu "\n",dnindex); } } dwarf_dealloc(dbg,dnhead,DW_DLA_DNAMES_HEAD); return DW_DLV_OK; } libdwarf-20210528/dwarfdump/esb.c0000664000175000017500000006301714003122342013400 00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2013-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* esb.c extensible string buffer. A simple means (vaguely like a C++ class) that enables safely saving strings of arbitrary length built up in small pieces. We really do allow only C strings here. NUL bytes in a string result in adding only up to the NUL (and in the case of certain interfaces here a warning to stderr). The functions assume that pointer arguments of all kinds are not NULL. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #include "esb.h" #define TRUE 1 /* INITIAL_ALLOC value takes no account of space for a trailing NUL, the NUL is accounted for in init_esb_string and in later tests against esb_allocated_size. */ #ifdef SELFTEST #define INITIAL_ALLOC 1 /* SELFTEST */ #define MALLOC_COUNT 1 #else /* There is nothing magic about this size. It is just big enough to avoid most resizing. */ #define INITIAL_ALLOC 100 #endif /* Allow for final NUL */ static size_t alloc_size = INITIAL_ALLOC; /* NULL device used when printing formatted strings */ static FILE *null_device_handle = 0; #ifdef _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ #ifdef MALLOC_COUNT unsigned long malloc_count = 0; unsigned long malloc_size = 0; #endif /* m must be a string, like "ESBERR..." for this to work */ #define ESBERR(m) esb_appendn_internal(data,m,sizeof(m)-1) #define INCRVALIDATENEXT(n) do { \ ++n ; \ if (!format[n]) { \ ESBERR("ESBERR_next_followedby_end"); \ return; \ } \ } while (0) FILE *esb_open_null_device(void) { if (!null_device_handle) { null_device_handle = fopen(NULL_DEVICE_NAME,"w"); } return null_device_handle; } /* Close the null device used during formatting printing */ void esb_close_null_device(void) { if (null_device_handle) { fclose(null_device_handle); null_device_handle = 0; } } /* min_len is overall space wanted for initial alloc. ASSERT: esb_allocated_size == 0 */ static void init_esb_string(struct esb_s *data, size_t min_len) { char* d; if (data->esb_allocated_size > 0) { return; } /* Only esb_constructor applied so far. Now Allow for string space. */ if (min_len < alloc_size) { min_len = alloc_size; } else { min_len++ ; /* Allow for NUL at end */ } d = malloc(min_len); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += min_len; #endif if (!d) { fprintf(stderr, "dwarfdump is out of memory allocating %lu bytes\n", (unsigned long) min_len); exit(5); } data->esb_string = d; data->esb_allocated_size = min_len; data->esb_string[0] = 0; data->esb_used_bytes = 0; } /* Make more room. Leaving contents unchanged, effectively. The NUL byte at end has room and this preserves that room. */ static void esb_allocate_more(struct esb_s *data, size_t len) { size_t new_size = 0; char* newd = 0; if (data->esb_rigid) { return; } if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } new_size = data->esb_allocated_size + len; if (new_size < alloc_size) { new_size = alloc_size; } if (data->esb_fixed) { newd = malloc(new_size); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len; #endif if (newd) { memcpy(newd,data->esb_string,data->esb_used_bytes+1); } } else { newd = realloc(data->esb_string, new_size); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len; #endif } if (!newd) { fprintf(stderr, "dwarfdump is out of memory allocating " "%lu bytes\n", (unsigned long) new_size); exit(5); } /* If the area was reallocated by realloc() the earlier space was free()d by realloc(). */ data->esb_string = newd; data->esb_allocated_size = new_size; data->esb_fixed = 0; } /* Ensure that the total buffer length is large enough that at least minlen bytes are available, unused, in the allocation. */ void esb_force_allocation(struct esb_s *data, size_t minlen) { size_t target_len = 0; if (data->esb_rigid) { return; } if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } target_len = data->esb_used_bytes + minlen; if (data->esb_allocated_size < target_len) { size_t needed = target_len - data->esb_allocated_size; esb_allocate_more(data,needed); } } /* The 'len' is believed. Do not pass in strings < len bytes long. For strlen(in_string) > len bytes we take the initial len bytes. len does not include the trailing NUL. */ static void esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len) { size_t remaining = 0; size_t needed = len; if (data->esb_allocated_size == 0) { size_t maxlen = (len >= alloc_size)? len:alloc_size; init_esb_string(data, maxlen); } /* ASSERT: data->esb_allocated_size > data->esb_used_bytes */ remaining = data->esb_allocated_size - data->esb_used_bytes - 1; if (remaining <= needed) { if (data->esb_rigid && len > remaining) { len = remaining; } else { size_t alloc_amt = needed - remaining; esb_allocate_more(data,alloc_amt); } } if (len == 0) { /* No room for anything more, or no more requested. */ return; } /* Might be that len < string len, so do not assume len+1 byte is a NUL byte. */ memcpy(&data->esb_string[data->esb_used_bytes],in_string,len); data->esb_used_bytes += len; /* Insist on explicit NUL terminator */ data->esb_string[data->esb_used_bytes] = 0; } /* len >= strlen(in_string) */ void esb_appendn(struct esb_s *data, const char * in_string, size_t len) { size_t full_len = strlen(in_string); if (full_len < len) { ESBERR("ESBERR_appendn bad call"); return; } esb_appendn_internal(data, in_string, len); } /* The length is gotten from the in_string itself, this is the usual way to add string data.. */ void esb_append(struct esb_s *data, const char * in_string) { size_t len = 0; if (in_string) { len = strlen(in_string); if (len) { esb_appendn_internal(data, in_string, len); } } } /* Always returns an empty string or a non-empty string. Never 0. */ char* esb_get_string(struct esb_s *data) { if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } return data->esb_string; } /* Sets esb_used_bytes to zero. The string is not freed and esb_allocated_size is unchanged. */ void esb_empty_string(struct esb_s *data) { if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } data->esb_used_bytes = 0; data->esb_string[0] = 0; } /* Return esb_used_bytes. */ size_t esb_string_len(struct esb_s *data) { return data->esb_used_bytes; } /* *data is presumed to contain garbage, not values, and is properly initialized here. */ void esb_constructor(struct esb_s *data) { memset(data, 0, sizeof(*data)); } /* ASSERT: buflen > 0 */ void esb_constructor_fixed(struct esb_s *data,char *buf,size_t buflen) { memset(data, 0, sizeof(*data)); if (buflen < 1) { return; } data->esb_string = buf; data->esb_string[0] = 0; data->esb_allocated_size = buflen; data->esb_used_bytes = 0; data->esb_rigid = 0; data->esb_fixed = 1; } /* The string is freed, contents of *data set to zeros. */ void esb_destructor(struct esb_s *data) { if (data->esb_fixed) { data->esb_allocated_size = 0; data->esb_used_bytes = 0; data->esb_string = 0; data->esb_rigid = 0; data->esb_fixed = 0; return; } if (data->esb_string) { free(data->esb_string); data->esb_string = 0; } esb_constructor(data); } /* To get all paths in the code tested, this sets the initial allocation/reallocation file-static which can be quite small but must not be zero The alloc_size variable is used for initializations. */ void esb_alloc_size(size_t size) { if (size < 1) { size = 1; } alloc_size = size; } size_t esb_get_allocated_size(struct esb_s *data) { return data->esb_allocated_size; } static void esb_appendn_internal_spaces(struct esb_s *data,size_t l) { static char spacebuf[] = {" "}; size_t charct = sizeof(spacebuf)-1; while (l > charct) { esb_appendn_internal(data,spacebuf,charct); l -= charct; } /* ASSERT: l > 0 */ esb_appendn_internal(data,spacebuf,l); } static void esb_appendn_internal_zeros(struct esb_s *data,size_t l) { static char zeros[] = {"0000000000000000000000000000000000000000"}; size_t charct = sizeof(zeros)-1; while (l > charct) { esb_appendn_internal(data,zeros,charct); l -= charct; } /* ASSERT: l > 0 */ esb_appendn_internal(data,zeros,l); } void esb_append_printf_s(struct esb_s *data, const char *format,const char *s) { size_t stringlen = strlen(s); size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; /* was %[-]fixedlen. Zero means no len provided. */ size_t fixedlen = 0; /* was %-, nonzero means left-justify */ long leftjustify = 0; size_t prefixlen = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } if (prefixlen) { esb_appendn_internal(data,format,prefixlen); } if (format[next] != '%') { /* No % operator found */ ESBERR("ESBERR..esb_append_printf_s has no percent operator"); return; } next++; if (format[next] == ' ') { ESBERR("ESBERR_pct_followedby_space_in_s"); return; } if (!format[next]) { ESBERR("ESBERR_pct_followedby_wrong_in_s"); return; } if (format[next] == '-') { leftjustify++; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); if (format[next] != 's') { ESBERR("ESBERR_pct_s_missing_in_s"); return; } next++; if (fixedlen && (fixedlen <= stringlen)) { leftjustify = 0; } if (leftjustify) { esb_appendn_internal(data,s,stringlen); if (fixedlen) { size_t trailingspaces = fixedlen - stringlen; esb_appendn_internal_spaces(data,trailingspaces); } } else { if (fixedlen && (fixedlen < stringlen)) { /* This lets us have fixedlen < stringlen by taking all the chars from s ignoring the fixedlen*/ esb_appendn_internal(data,s,stringlen); } else { if (fixedlen) { size_t leadingspaces = fixedlen - stringlen; size_t k = 0; for ( ; k < leadingspaces; ++k) { esb_appendn_internal(data," ",1); } } esb_appendn_internal(data,s,stringlen); } } if (!format[next]) { return; } { const char * startpt = format+next; size_t suffixlen = strlen(startpt); esb_appendn_internal(data,startpt,suffixlen); } return; } static char dtable[10] = { '0','1','2','3','4','5','6','7','8','9' }; static char xtable[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; static char Xtable[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; /* With gcc version 5.4.0 20160609 a version using const char *formatp instead of format[next] and deleting the 'next' variable is a few hundredths of a second slower, repeatably. We deal with formats like: %u %5u %05u (and ld and lld too). %x %5x %05x (and ld and lld too). */ void esb_append_printf_u(struct esb_s *data, const char *format,esb_unsigned v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = 0; size_t divisor = 0; size_t prefixlen = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } esb_appendn_internal(data,format,prefixlen); if (format[next] != '%') { /* No % operator found */ ESBERR("ESBERR..esb_append_printf_u has no percent operator"); return; } next++; if (format[next] == ' ') { ESBERR("ESBERR_pct_followedby_space_in_s"); return; } if (!format[next]) { ESBERR("ESBERR_pct_followedby_wrong_in_s"); return; } if (format[next] == '-') { ESBERR("ESBERR_printf_u - format not supported"); INCRVALIDATENEXT(next); } if (format[next] == '0') { leadingzero = 1; INCRVALIDATENEXT(next); } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { ESBERR("ESBERR_pct_scount_in_u"); return; } if ( (Xcount +xcount+dcount+ucount) > 1) { ESBERR("ESBERR_pct_xcount_etc_u"); /* error */ return; } if (lcount > 2) { ESBERR("ESBERR_pct_lcount_error_u"); /* error */ return; } if (dcount > 0) { ESBERR("ESBERR_pct_dcount_error_u"); /* error */ return; } if (ucount) { divisor = 10; ctable = dtable; } else { divisor = 16; if (xcount) { ctable = xtable; } else { ctable = Xtable; } } { char digbuf[36]; char *digptr = 0; size_t digcharlen = 0; esb_unsigned remaining = v; if (divisor == 16) { digptr = digbuf+sizeof(digbuf) -1; for ( ;; ) { esb_unsigned dig; dig = remaining & 0xf; remaining = remaining >> 4; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } else { digptr = digbuf+sizeof(digbuf) -1; *digptr = 0; --digptr; for ( ;; ) { esb_unsigned dig; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } if (fixedlen <= digcharlen) { esb_appendn_internal(data,digptr,digcharlen); } else { if (!leadingzero) { size_t justcount = fixedlen - digcharlen; esb_appendn_internal_spaces(data,justcount); esb_appendn_internal(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; esb_appendn_internal_zeros(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } } } if (format[next]) { size_t trailinglen = strlen(format+next); esb_appendn_internal(data,format+next,trailinglen); } } static char v32m[] = {"-2147483648"}; static char v64m[] = {"-9223372036854775808"}; /* We deal with formats like: %d %5d %05d %+d %+5d (and ld and lld too). */ void esb_append_printf_i(struct esb_s *data, const char *format,esb_int v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int pluscount = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = dtable; size_t prefixlen = 0; int done = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } esb_appendn_internal(data,format,prefixlen); if (format[next] != '%') { /* No % operator found */ ESBERR("ESBERR..esb_append_printf_i has no percent operator"); return; } next++; if (format[next] == ' ') { ESBERR("ESBERR_pct_followedby_space_in_s"); return; } if (!format[next]) { ESBERR("ESBERR_pct_followedby_wrong_in_s"); return; } if (format[next] == '-') { ESBERR("ESBERR_printf_i - format not supported"); INCRVALIDATENEXT(next); } if (format[next] == '+') { pluscount++; INCRVALIDATENEXT(next); } if (format[next] == '0') { leadingzero = 1; INCRVALIDATENEXT(next); } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { ESBERR("ESBERR_pct_scount_in_i"); return; } if (!dcount || (lcount >2) || (Xcount +xcount+dcount+ucount) > 1) { /* error */ ESBERR("ESBERR_xcount_etc_i"); return; } { char digbuf[36]; char *digptr = digbuf+sizeof(digbuf) -1; size_t digcharlen = 0; esb_int remaining = v; int vissigned = 0; esb_int divisor = 10; *digptr = 0; --digptr; if (v < 0) { vissigned = 1; /* This test is for twos-complement machines and would be better done via configure with a compile-time check so we do not need a size test at runtime. */ if (sizeof(v) == 8) { esb_unsigned vm = 0x7fffffffffffffffULL; if (vm == (esb_unsigned)~v) { memcpy(digbuf,v64m,sizeof(v64m)); digcharlen = sizeof(v64m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } } else if (sizeof(v) == 4) { esb_unsigned vm = 0x7fffffffL; if (vm == (esb_unsigned)~v) { memcpy(digbuf,v32m,sizeof(v32m)); digcharlen = sizeof(v32m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } }else { ESBERR("ESBERR_sizeof_v_i"); /* error */ return; } } if (!done) { for ( ;; ) { esb_unsigned dig = 0; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; digcharlen++; if (!remaining) { break; } --digptr; } if (vissigned) { --digptr; digcharlen++; *digptr = '-'; } else if (pluscount) { --digptr; digcharlen++; *digptr = '+'; } } if (fixedlen > 0) { if (fixedlen <= digcharlen) { esb_appendn_internal(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; if (!leadingzero) { esb_appendn_internal_spaces(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } else { if (*digptr == '-') { esb_appendn_internal(data,"-",1); esb_appendn_internal_zeros(data,prefixcount); digptr++; esb_appendn_internal(data, digptr,digcharlen-1); } else if (*digptr == '+') { esb_appendn_internal(data,"+",1); esb_appendn_internal_zeros(data,prefixcount); digptr++; esb_appendn_internal(data, digptr,digcharlen-1); } else { esb_appendn_internal_zeros(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } } } } else { esb_appendn_internal(data,digptr,digcharlen); } } if (format[next]) { size_t trailinglen = strlen(format+next); esb_appendn_internal(data,format+next,trailinglen); } } /* Append a formatted string */ void esb_append_printf(struct esb_s *data,const char *in_string, ...) { va_list ap; size_t len = 0; size_t len2 = 0; size_t remaining = 0; if (!null_device_handle) { if (!esb_open_null_device()) { esb_append(data," Unable to open null printf device on:"); esb_append(data,in_string); return; } } va_start(ap,in_string); len = vfprintf(null_device_handle,in_string,ap); va_end(ap); if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } remaining = data->esb_allocated_size - data->esb_used_bytes - 1; if (remaining < len) { if (data->esb_rigid) { /* No room, give up. */ return; } else { esb_allocate_more(data, len); } } va_start(ap,in_string); #ifdef HAVE_VSNPRINTF len2 = vsnprintf(&data->esb_string[data->esb_used_bytes], data->esb_allocated_size, in_string,ap); #else len2 = vsprintf(&data->esb_string[data->esb_used_bytes], in_string,ap); #endif va_end(ap); data->esb_used_bytes += len2; if (len2 > len) { /* We are in big trouble, this should be impossible. We have trashed something in memory. */ fprintf(stderr, "dwarfdump esb internal error, vsprintf botch " " %lu < %lu \n", (unsigned long) len2, (unsigned long) len); exit(5); } return; } /* Get a copy of the internal data buffer. It is up to the code calling this to free() the string using the pointer returned here. */ char* esb_get_copy(struct esb_s *data) { char* copy = NULL; /* is ok as is if esb_allocated_size is 0 */ size_t len = data->esb_used_bytes+1; if (len) { copy = (char*)malloc(len); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len+1; #endif memcpy(copy,data->esb_string,len); } return copy; } libdwarf-20210528/dwarfdump/globals.h0000664000175000017500000003221214013520107014252 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef globals_INCLUDED #define globals_INCLUDED #ifdef __cplusplus extern "C" { #endif #include "config.h" #ifdef DWARF_WITH_LIBELF /* Without libelf no need for _GNU_SOURCE */ #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) /* At a certain point libelf.h requires _GNU_SOURCE. here we assume the criteria in configure determined that usefully. */ #define _GNU_SOURCE 1 #endif #endif /* DWARF_WITH_LIBELF */ #include "warningcontrol.h" #define DWARF_SECNAME_BUFFER_SIZE 50 #define ESB_FIXED_ALLOC_SIZE 300 #include #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef DWARF_WITH_LIBELF #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_LIBELF_H # include #else /* !HAVE_LIBELF_H */ # ifdef HAVE_LIBELF_LIBELF_H # include # endif /* HAVE_LIBELF_LIBELF_H */ #endif /* HAVE_LIB_ELF */ #endif /* DWARF_WITH_LIBELF */ #include "dwarf.h" #include "libdwarf.h" #ifdef HAVE_REGEX #include #endif #include "checkutil.h" #include "defined_types.h" #include "glflags.h" /* Used to avoid leakage when we hide errors. Use carefully: doing err when you mean *err will not be caught by the compiler and will not do what one wants. Using *err when err is correct will be caught by the compiler. You are warned. */ #define DROP_ERROR_INSTANCE(d,r,e) \ if ((r) == DW_DLV_ERROR) { \ if (e) { \ dwarf_dealloc_error((d),(e)); \ (e) = 0; \ } \ } else { if ((r) != DW_DLV_OK && \ (r) != DW_DLV_NO_ENTRY) { \ report_caller_error_drop_error((r), \ __LINE__,__FILE__); \ } \ } /* Version 5 returns DW_AT_decl_file differently than earlier versions */ #define DWVERSION4 4 #define DWVERSION5 5 /* FALSE for the flags means off */ #define LOHIPC_SAWADDR 1 #define LOHIPC_SAWOFFSET 2 struct LoHiPc_s { Dwarf_Unsigned lopc; /* hival is either an address if sawhi ==LOHIPC_SAWADDR or an offset if sawhi_flag == LOWHIPC_SAWOFFSET. or zero (sawhi_flag == FALSE)*/ Dwarf_Unsigned hival; /* The result of adding lopc to hival. */ Dwarf_Unsigned hifinal; /* non-zero if DW_AT_lowpc seen */ Dwarf_Small sawlo_flag; /* non-zero if DW_AT_high_pc seen defaults FALSE, otherwise is LOHIPC_SAWADDR or LOHIPC_SAWOFFSET */ Dwarf_Small sawhi_flag; /* If non-zero, hifinal is set to the hipc address Defaults to FALSE*/ Dwarf_Small havefinal_flag; }; typedef struct LoHiPc_s LoHiPc; /* Calculate wasted space */ extern void calculate_attributes_usage(Dwarf_Half attr, Dwarf_Half theform, Dwarf_Unsigned value); extern Dwarf_Bool is_strstrnocase(const char *data, const char *pattern); /* Process TAGs for checking mode and reset pRangesInfo table if appropriate. */ extern void tag_specific_globals_setup(Dwarf_Debug dbg, Dwarf_Half val,int die_indent_level); extern int simple_err_return_msg_either_action(int res, const char *msg); extern int simple_err_return_action(int res,const char *msg); extern int simple_err_only_return_action(int res,const char *msg); extern void print_error_and_continue (Dwarf_Debug dbg, const char * msg,int res, Dwarf_Error err); extern void print_error (Dwarf_Debug dbg, const char * msg, int res, Dwarf_Error err); extern int print_line_numbers_this_cu (Dwarf_Debug dbg, Dwarf_Die in_die, char **srcfiles, Dwarf_Signed cnt, Dwarf_Error *err); extern int print_frames (Dwarf_Debug dbg,int want_eh, struct dwconf_s *, Dwarf_Die * cu_die_for_current_frame, void **, void **,Dwarf_Error *); extern void printreg(Dwarf_Unsigned reg,struct dwconf_s *config_data); extern int print_ranges (Dwarf_Debug dbg,Dwarf_Error *err); extern int print_raw_all_rnglists(Dwarf_Debug dbg, Dwarf_Error *err); extern int print_raw_all_loclists(Dwarf_Debug dbg, Dwarf_Error *err); extern int print_pubnames (Dwarf_Debug dbg,Dwarf_Error *); extern int print_infos (Dwarf_Debug dbg,Dwarf_Bool is_info, Dwarf_Error *); extern int print_locs (Dwarf_Debug dbg,Dwarf_Error *); extern int print_abbrevs (Dwarf_Debug dbg,Dwarf_Error *); extern int print_strings (Dwarf_Debug dbg,Dwarf_Error *); extern int print_aranges (Dwarf_Debug dbg,Dwarf_Error *); extern int print_static_funcs(Dwarf_Debug dbg,Dwarf_Error *); extern int print_static_vars(Dwarf_Debug dbg,Dwarf_Error *); enum type_type_e {SGI_TYPENAME, DWARF_PUBTYPES} ; extern int print_types(Dwarf_Debug dbg,enum type_type_e type_type, Dwarf_Error *); extern int print_weaknames(Dwarf_Debug dbg, Dwarf_Error *); extern int print_debug_names(Dwarf_Debug dbg,Dwarf_Error *); int print_debug_sup(Dwarf_Debug dbg, Dwarf_Error *error); int print_all_abbrevs_for_cu(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned abbrev_num_in, Dwarf_Unsigned *length_out, Dwarf_Unsigned *abbrev_num_out, Dwarf_Error *error); int print_all_pubnames_style_records(Dwarf_Debug dbg, const char * linetitle, const char * section_true_name, Dwarf_Global *globbuf, Dwarf_Signed count, Dwarf_Error *err); /* These three ELF only */ extern int print_object_header(Dwarf_Debug dbg,Dwarf_Error *); extern int print_relocinfo (Dwarf_Debug dbg, Dwarf_Error*); void clean_up_syms_malloc_data(void); /* Space used to record range information */ extern void allocate_range_array_info(void); extern void release_range_array_info(void); extern void record_range_array_info_entry(Dwarf_Off die_off, Dwarf_Off range_off); extern int check_range_array_info(Dwarf_Debug dbg,Dwarf_Error *); int should_skip_this_cu(Dwarf_Debug dbg,Dwarf_Bool *, Dwarf_Die cu_die); int get_address_size_and_max(Dwarf_Debug dbg, Dwarf_Half * size, Dwarf_Addr * max, Dwarf_Error *err); /* Returns the producer of the CU */ int get_cu_name(Dwarf_Debug dbg,Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, char **short_name,char **long_name, Dwarf_Error *err); /* Get number of abbreviations for a CU */ extern void get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset); /* Validate an abbreviation */ extern void validate_abbrev_code(Dwarf_Debug dbg, Dwarf_Unsigned abbrev_code); extern int print_one_die( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_offset, Dwarf_Bool print_information, int die_indent_level, char **srcfiles, Dwarf_Signed cnt, Dwarf_Bool *an_attr_duplicated, Dwarf_Bool ignore_die_stack, Dwarf_Error *err); /* Check for specific compiler */ extern Dwarf_Bool checking_this_compiler(void); extern void update_compiler_target(const char *producer_name); extern void add_cu_name_compiler_target(char *name); /* General error reporting routines. These were macros for a short time and when changed into functions they kept (for now) their capitalization. The capitalization will likely change. */ extern void PRINT_CU_INFO(void); extern void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_CHECK_ERROR_PRINT_CU(void); #define DWARF_CHECK_ERROR(c,d) DWARF_CHECK_ERROR3(c,d,0,0) #define DWARF_CHECK_ERROR2(c,d,e) DWARF_CHECK_ERROR3(c,d,e,0) extern void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category, const char *str1, const char *str2, const char *strexpl); extern int print_macinfo_by_offset(Dwarf_Debug dbg, Dwarf_Die cudie,Dwarf_Unsigned offset,Dwarf_Error *); void ranges_esb_string_destructor(void); void destruct_abbrev_array(void); int get_proc_name_by_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, struct esb_s *proc_name, Dwarf_Die *cu_die_for_print_frames, void **pcMap, Dwarf_Error *err); extern void dump_block(char *prefix, char *data, Dwarf_Signed len); extern int print_gdb_index(Dwarf_Debug dbg,Dwarf_Error *err); extern int print_debugfission_index(Dwarf_Debug dbg, const char *type, Dwarf_Error *); void clean_up_die_esb(void); void safe_strcpy(char *out, long outlen, const char *in, long inlen); int print_macros_5style_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, char **srcfiles, Dwarf_Signed cnt, int do_print_dwarf /* not relying on gf_do_print_dwarf here */, int descend_into_imports /* TRUE means follow imports */, Dwarf_Bool in_import_list /* helps make print readable */, Dwarf_Unsigned offset, Dwarf_Error *); /* Detailed attributes encoding space */ int print_attributes_encoding(Dwarf_Debug dbg,Dwarf_Error *); /* Detailed tag and attributes usage */ int print_tag_attributes_usage(void); void record_tag_usage(int tag); void reset_usage_rate_tag_trees(void); int print_section_groups_data(Dwarf_Debug dbg,Dwarf_Error *); void update_section_flags_per_groups(Dwarf_Debug dbg); void groups_restore_subsidiary_flags(void); int legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr); int legal_tag_tree_combination(Dwarf_Half parent_tag, Dwarf_Half child_tag); int print_str_offsets_section(Dwarf_Debug dbg,Dwarf_Error *); void print_any_harmless_errors(Dwarf_Debug dbg); void print_secname(Dwarf_Debug dbg,const char *secname); void report_caller_error_drop_error(int dwdlv, int line, char *filename); /* encoding_type_func used in print_die.c and print_lopc_hipc_attr.c */ typedef const char *(*encoding_type_func) (unsigned,int doprintingonerr); int dd_get_integer_and_name(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Unsigned * uval_out, const char *attr_name, struct esb_s* string_out, encoding_type_func val_as_string, Dwarf_Error * err, int show_form); int print_original_loclist_linecodes(Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char * attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * ebsp, Dwarf_Bool * bError); int print_llex_linecodes(Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char * attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * ebsp, Dwarf_Bool * bError); int print_debug_loclists_linecodes(Dwarf_Debug dbg, Dwarf_Bool checking, const char * tagname, const char * attrname, unsigned int llent, Dwarf_Small lle_value, Dwarf_Addr base_address, Dwarf_Addr rawlopc, Dwarf_Addr rawhipc, Dwarf_Bool debug_addr_unavailable, Dwarf_Addr lopc, Dwarf_Addr hipc, Dwarf_Unsigned locdesc_offset, struct esb_s * ebsp, Dwarf_Bool * bError); void loc_error_check( const char *tagname, const char *attrname, Dwarf_Addr lopcfinal, Dwarf_Addr rawlopc, Dwarf_Addr hipcfinal, Dwarf_Addr rawhipc, Dwarf_Unsigned offset, Dwarf_Addr base_address, Dwarf_Bool *bError); int print_hipc_lopc_attribute(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, int die_indent_level, Dwarf_Unsigned dieprint_cu_goffset, char ** srcfiles, Dwarf_Signed cnt, Dwarf_Attribute attrib, Dwarf_Half attr, Dwarf_Unsigned max_address, LoHiPc *lohipc, struct esb_s *valname, Dwarf_Error *err); #ifdef __cplusplus } #endif #endif /* globals_INCLUDED */ libdwarf-20210528/dwarfdump/tag_attr.c0000664000175000017500000004523614014247411014446 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include #include /* For va_start va_arg va_list */ #include /* For errno declaration. */ #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_ */ #ifdef HAVE_STDLIB_H #include /* For exit() declaration etc. */ #endif /* HAVE_STDLIB_H */ #include "globals.h" #include #include "libdwarf.h" #include "common.h" #include "esb.h" #include "tag_common.h" #include "dwgetopt.h" #include "libdwarf_version.h" Dwarf_Bool ellipsis = FALSE; /* So we can use dwarf_names.c */ /* Expected input format 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff ... The generated tag_attr_combination_table is used and generated quite differently for standard than for extended tags. For standard tags the generated table is indexed by tag number. All the columns are bit flags. For extended tags the generated table is indexed (call it j) by 0 - N-1 and [j][0] is the tag number and the rest of the columns (1 - N-1) are allowed attribute numbers. */ unsigned int tag_attr_combination_table[ATTR_TABLE_ROW_MAXIMUM] [ATTR_TABLE_COLUMN_MAXIMUM]; #ifdef HAVE_USAGE_TAG_ATTR /* Working array for a specific tag and will contain its valid attributes */ static Dwarf_Half tag_attr_vector[DW_AT_last] = {0}; static Dwarf_Half tag_parents[DW_TAG_last] = {0}; static Dwarf_Half tag_children[DW_TAG_last] = {0}; static Dwarf_Small tag_attr_legal[DW_TAG_last] = {0}; #endif /* HAVE_USAGE_TAG_ATTR */ static const char *usage[] = { "Usage: tag_attr_build ", " -i input-table-path", " -o output-table-path", " -s (Generate standard attribute table)", " -e (Generate extended attribute table (common extensions))", "" }; const char *program_name = 0; char *input_name = 0; char *output_name = 0; int standard_flag = FALSE; int extended_flag = FALSE; /* process arguments */ static void process_args(int argc, char *argv[]) { int c = 0; Dwarf_Bool usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:se")) != EOF) { switch (c) { case 'i': input_name = dwoptarg; break; case 'o': output_name = dwoptarg; break; case 'e': extended_flag = TRUE; break; case 's': standard_flag = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(argv[0],usage); exit(FAILED); } } /* Two new naming routines May 2016. Instead of directly calling dwarf_get_*() When bad tag/attr numbers are presented we return a warning string through the pointer. The thought is that eventually someone will notice the error. It might, of course, be better to emit an error message and stop. */ static void ta_get_AT_name(unsigned int attrnum,const char **nameout) { int res = 0; res = dwarf_get_AT_name(attrnum,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } static void ta_get_TAG_name(unsigned int tag,const char **nameout) { int res = 0; res = dwarf_get_TAG_name(tag,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } static unsigned maxrowused = 0; static unsigned maxcolused = 0; /* The argument sizes are declared in tag_common.h, so the max usable is toprow-1 and topcol-1. */ static void check_unused_combo(unsigned toprow,unsigned topcol) { if ((toprow-1) != maxrowused) { printf("Providing for %u rows but used 0-%u\n", toprow,maxrowused); printf("Giving up\n"); exit(1); } if ((topcol-1) != maxcolused) { printf("Providing for %u cols but used 0-%u\n", topcol,maxcolused); printf("Giving up\n"); exit(1); } } static void validate_row_col(const char *position, unsigned crow, unsigned ccol, unsigned maxrow, unsigned maxcol) { if (crow >= ATTR_TABLE_ROW_MAXIMUM) { printf("error generating row in tag-attr array, %s " "current row: %u size of static array decl: %u\n", position,crow, ATTR_TABLE_ROW_MAXIMUM); exit(1); } if (crow >= maxrow) { printf("error generating row in tag-attr array, %s " "current row: %u max allowed: %u\n", position,crow,maxrow-1); exit(1); } if (ccol >= ATTR_TABLE_COLUMN_MAXIMUM) { printf("error generating column in tag-attr array, %s " "current col: %u size of static array decl: %u\n", position,ccol, ATTR_TABLE_COLUMN_MAXIMUM); exit(1); } if (ccol >= maxcol) { printf("error generating column in tag-attr array, %s " "current row: %u max allowed: %u\n", position,ccol,maxcol-1); exit(1); } if (crow > maxrowused) { maxrowused = crow; } if (ccol > maxcolused) { maxcolused = ccol; } return; } int main(int argc, char **argv) { unsigned u = 0; unsigned int num = 0; int input_eof = 0; unsigned table_rows = 0; unsigned table_columns = 0; unsigned current_row = 0; FILE * fileInp = 0; FILE * fileOut = 0; const char *aname = 0; unsigned int index = 0; print_version_details(argv[0],FALSE); print_args(argc,argv); process_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename," " could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"w"); if (!fileOut) { fprintf(stderr,"Invalid output filename," " could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } if (standard_flag) { table_rows = STD_ATTR_TABLE_ROWS; table_columns = STD_ATTR_TABLE_COLUMNS; } else { table_rows = EXT_ATTR_TABLE_ROWS; table_columns = EXT_ATTR_TABLE_COLS; } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } /* Generate main header, regardless of contents */ fprintf(fileOut,"/* Generated code, do not edit. */\n"); fprintf(fileOut,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(fileOut,"\n/* BEGIN FILE */\n\n"); #ifdef HAVE_USAGE_TAG_ATTR /* Generate the data type to record the usage of the pairs tag-attr */ if (standard_flag) { fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#include \"dwarf.h\"\n"); fprintf(fileOut,"#include \"libdwarf.h\"\n\n"); fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," unsigned int count;" " /* Attribute count */\n"); fprintf(fileOut," Dwarf_Half attr;" " /* Attribute value */\n"); fprintf(fileOut,"} Usage_Tag_Attr;\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ while (!feof(stdin)) { unsigned int tag; unsigned int curcol = 0; unsigned int cur_attr = 0; unsigned int attr; input_eof = read_value(&tag,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } if (standard_flag) { /* In standard case, the row indexed by tag */ if (tag >= table_rows ) { bad_line_input("tag %u exceeds standard table size" " of %u rows",tag,table_rows); } } else { /* In extended case, the row indexed by 0-N and column zero has the tag number. */ if (current_row >= table_rows) { bad_line_input( "too many extended table rows. Have %u max %u", current_row,table_rows); } validate_row_col("Reading tag",current_row,0, table_rows,table_columns); tag_attr_combination_table[current_row][0] = tag; } input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } curcol = 1; cur_attr = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Check if we have duplicated tags */ if (standard_flag) { if (tag_parents[tag]) { bad_line_input("tag 0x%02x value already defined", tag); } tag_parents[tag] = tag; /* Clear out the working attribute vector */ memset(tag_attr_vector,0,DW_AT_last*sizeof(Dwarf_Half)); } #endif /* HAVE_USAGE_TAG_ATTR */ while (num != MAGIC_TOKEN_VALUE) { struct esb_s msg_buf; esb_constructor(&msg_buf); if (standard_flag) { unsigned idx = num / BITS_PER_WORD; unsigned bit = num % BITS_PER_WORD; if (idx >= table_columns) { esb_append_printf_i(&msg_buf, "too many attributes a: table incomplete " "index %d cols",idx); esb_append_printf_i(&msg_buf, " %d.",table_columns); bad_line_input(esb_get_string(&msg_buf)); } validate_row_col("Setting attr bit",tag,idx, table_rows,table_columns); tag_attr_combination_table[tag][idx] |= (((unsigned)1) << bit); } else { if (curcol >= table_columns) { esb_append_printf_i(&msg_buf, "too many attributes b: table incomplete " "index %d ",curcol); esb_append_printf_i(&msg_buf, "cols %d.",table_columns); bad_line_input(esb_get_string(&msg_buf)); } validate_row_col("Setting attr col", current_row,curcol, table_rows,table_columns); tag_attr_combination_table[current_row][curcol] = num; curcol++; } #ifdef HAVE_USAGE_TAG_ATTR /* Record the usage only for standard tables */ if (standard_flag) { /* Add attribute to current tag */ if (cur_attr >= DW_AT_last) { esb_empty_string(&msg_buf); esb_append_printf_i(&msg_buf, "too many attributes c: table incomplete " "index %d ",cur_attr); esb_append_printf_i(&msg_buf, "cols %d.",DW_AT_last); bad_line_input(esb_get_string(&msg_buf)); } /* Check for duplicated entries */ if (tag_attr_vector[cur_attr]) { bad_line_input( "duplicated attributes: table incomplete."); } tag_attr_vector[cur_attr] = num; cur_attr++; } #endif /* HAVE_USAGE_TAG_ATTR */ esb_destructor(&msg_buf); input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the tag-attributes vector for current tag */ if (standard_flag) { if (tag >= DW_TAG_last) { bad_line_input( "tag 0x%02x exceeds standard table size",tag); } if (tag_children[tag]) { bad_line_input("tag 0x%02x already defined",tag); } tag_children[tag] = tag; /* Generate reference vector */ aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname); fprintf(fileOut, "static Usage_Tag_Attr tag_attr_%02x[%d] = {\n", tag,cur_attr+1); for (index = 1; index < cur_attr; ++index) { attr = tag_attr_vector[index]; ta_get_AT_name(attr,&aname); fprintf(fileOut," {/* 0x%02x */ 0, %s},\n", attr,aname); } fprintf(fileOut," {/* %4s */ 0, 0}\n};\n\n"," "); /* Record allowed number of attributes */ tag_attr_legal[tag] = cur_attr - 1; } #endif /* HAVE_USAGE_TAG_ATTR */ ++current_row; } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the parent of the individual vectors */ check_unused_combo(table_rows,table_columns); if (standard_flag) { unsigned int tag; unsigned int legal; fprintf(fileOut, "static Usage_Tag_Attr *usage_tag_attr[%d] = {\n", DW_TAG_last+1); for (index = 0; index < DW_TAG_last; ++index) { tag = tag_children[index]; if (tag) { aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " tag_attr_%02x, /* 0x%02x - %s */\n", tag,tag,aname); } else { fprintf(fileOut," 0,\n"); } } fprintf(fileOut," 0\n};\n\n"); /* Generate table with allowed number of attributes */ fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," Dwarf_Small legal;" " /* Legal attributes */\n"); fprintf(fileOut," Dwarf_Small found;" " /* Found attributes */\n"); fprintf(fileOut,"} Rate_Tag_Attr;\n\n"); fprintf(fileOut, "static Rate_Tag_Attr rate_tag_attr[%d] = {\n", DW_TAG_last+1); for (tag = 0; tag < DW_TAG_last; ++tag) { if (tag_children[tag]) { legal = tag_attr_legal[tag]; aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " {%2d, 0, /* 0x%02x - %s */},\n", legal,tag,aname); } else { fprintf(fileOut," {0, 0},\n"); } } fprintf(fileOut," {0, 0}\n};\n\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ if (standard_flag) { fprintf(fileOut,"#define ATTR_TREE_ROW_COUNT %d\n\n", table_rows); fprintf(fileOut,"#define ATTR_TREE_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_table\n"); fprintf(fileOut, "[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = {\n"); } else { fprintf(fileOut,"/* Common extensions */\n"); fprintf(fileOut,"#define ATTR_TREE_EXT_ROW_COUNT %d\n\n", table_rows); fprintf(fileOut,"#define ATTR_TREE_EXT_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_ext_table\n"); fprintf(fileOut, " [ATTR_TREE_EXT_ROW_COUNT]" "[ATTR_TREE_EXT_COLUMN_COUNT]" " = {\n"); } for (u = 0; u < table_rows; u++) { unsigned j = 0; const char *name = 0; if (standard_flag) { ta_get_TAG_name(u,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u,name); } else { unsigned k = tag_attr_combination_table[u][0]; ta_get_TAG_name(k,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",k,name); } fprintf(fileOut," { "); for (j = 0; j < table_columns; ++j ) { if (j && j%5 == 0) { fprintf(fileOut,"\n "); } fprintf(fileOut,"0x%08x,", tag_attr_combination_table[u][j]); } fprintf(fileOut,"},\n"); } fprintf(fileOut,"};\n"); fprintf(fileOut,"\n/* END FILE */\n"); fclose(fileInp); fclose(fileOut); return (0); } /* A fake so we can use dwarf_names.c */ void print_error (UNUSEDARG Dwarf_Debug dbg, UNUSEDARG const char * msg, UNUSEDARG int res, UNUSEDARG Dwarf_Error localerr) { } libdwarf-20210528/dwarfdump/ChangeLog20120000664000175000017500000001443713644370703014564 000000000000002012-11-29 David Anderson * dwarfdump.c, common.c: Update version string. * dwarfdump.c, print_die.c: Now all follow dicheck indent rules. 2012-11-29 David Anderson * dwarfdump.c, common.c: Update version string. 2012-11-27 David Anderson * dwarfdump.c, common.c: Update version string. 2012-11-20 David Anderson * dwarfdump.c, common.c: Update version string. * print_reloc.c: Inserted missing 'const' qualifiers fixing 3 compiler warnings. 2012-11-17 David Anderson * configure regenerated with autoconf 2.69 * dwarfdump.c, common.c: Update version string. 2012-11-17 David Anderson * addrmap.c,checkutil.c,common.c,dwarfdump.c,dwconf.c, globals.h,naming.c,print_aranges.c,print_die.c,print_frames.c, print_locs.c,print_ranges.c,print_reloc.c,print_reloc.h, print_strings.c,strstrnocase.c,tag_attr.c,tag_common.c, tag_tree.c,uri.c, tag_attr_ext.list,tag_attr.list,tag_tree_ext.list, tag_tree.list : Update copyright year. 2012-11-15 CarlosAlbertoEnciso * addrmap.c: Consistent layout for if statements. * checkutil.c: Incorrect string prefix for .text linkonce section name, is '.text.' for the applicable linke once sections, not simply '.text' Added print of internal (debugging dwarfdump) data not previously printed. * common.c: Consistent layout for if statements. Include "config.h". Minor layout change for #ifdef _DEBUG. Add HAVE_STDAFX_H check. * dwarfdump.1: Changes for new options: -E*, -h, -ls, -kE, plus some minor typo corrections. * dwarfdump.c: Consistent layout for if, for statements. Expand -E option to print the full information for the ELF header (32-bit and 64-bit) to include additional fields (e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx). Also, depending on the additional option to -E, the index, address, size and name for sections is printed. The additional option follow the convention used for -o option and can include any of the letters: hliaprfoRstxd. -Eh print information for the ELF header -E{liaprfoRs} print information for debug related sections -Ex print information for .text section -Ed same as -E{liaprfoRstx}. -E print the ELF header and the info for all available sections. New option: -kE, the attribute encodings are checked to see if they can use fewer bytes when encoded using LEB128. Expand -l option to print line information with no offsets values (-ls). Useful for comparisons. Expand -S option to print number of occurrences for the searched pattern (-Sv. Remove support for internally quoted strings. Remove extra 'break' for case 'o' in 'process_args'. Include the value zero for -# (internal debug level) Fix layout for 'qsort_compare_compiler' and use compiler name in the sort to get a stable sort. Now that name strings are not qoted internally, ensure that we do not expect such quotes in checking compiler names. * dwconf.c: Consistent layout for if statements. * globals.h: Add externs and defines for the items newly needed globally. * naming.c: Consistent layout for if, for statements. * print_aranges.c: Consistent layout for if statements. * print_die.c: Consistent layout for if, for and switch statements. Remove unused symbols 'seen_PU_base_address', 'seen_PU_high_address'. Rename 'errno' to 'dwerrno' to avoid conflict with system symbol. Missing DWARF_CHECK_COUNT and DWARF_CHECK_ERROR when testing self references category. Support for counting number of occurrences of the pattern being searched (See -S option). Add support for new option -kE; the atrribute encodings are checked to see if they can use fewer bytes when encoded using LEB128. New functions 'check_attributes_encoding', 'print_attributes_encoding' and new data structure 'a_attr_encoding' were created. Include DW_TAG_template_alias in the function 'get_attr_value' as it refers to a type in the case of checks for type offsets. Remove support for internally quoted strings. Add space so DW_OP_bregx prints more readably. * print_frames.c: Consistent layout for if statements. * print_lines.c: Consistent layout for if statements. Implement the ability to print line information with no offset values (useful when comparisons are required, as the pc values can change but the basic line information remains the same). Minor layout changes. * print_locs.c: Consistent layout for if statements. * print_ranges.c: Consistent layout for if and for statements. * print_reloc.c: Consistent layout for if statements. Move names for relocation types to individual header files based on architecture (ARM, MIPS, PPC, PPC64, X86_64). Fix incorrect layout for 'set_relocation_table_names' function. Use condition compilation symbols (DWARF_RELOC_MIPS, DWARF_RELOC_PPC, DWARF_RELOC_PPC64, DWARF_RELOC_ARM, DWARF_RELOC_X86_64)in the function 'set_relocation_table_names' to get relocation table information. Add support for X86_64 architecture. * print_reloc.h: Move definitions for relocation types to individual header files based on architecture (ARM, MIPS, PPC, PPC64, X86_64). * print_strings.c: Consistent layout for if statements. * strstrnocase.c: Consistent layout for if and for statements. * tag_attr.c: Consistent layout for if and for statements. * tag_attr.list: Add some missing attributes and the complete set for DW_TAG_rvalue_reference_type; remove a duplicated DW_AT_name. * tag_common.c: Consistent layout for if statements. * tag_tree.c: Consistent layout for if and for statements. * tag_tree.list: Missing DW_TAG_union_type to allow verification of nested unions. * uri.c: Consistent layout for if and for statements. 2012-04-10 DavidAnderson * dwarfdump.c, common.c: Updated version string. libdwarf-20210528/dwarfdump/tag_tree_ext.list0000664000175000017500000000616613644370703016054 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-tree relation. See tag_tree.list for details. Notes: If new top level TAGs are added/removed, update EXT_TAG_TABLE_ROWS If new child TAGs are added/removed, update EXT_TAG_TABLE_COLS EXT_TAG_TABLE_ROWS is defined in tag_tree.c and specifies the maximum number of top level TAGs. Current value is 8. EXT_TAG_TABLE_COLS is defined in tag_tree.c and specifies the maximum number of entries for the top level TAGs. Current value is 5. */ /* Common DWARF extensions */ 0xffffffff DW_TAG_structure_type DW_TAG_variable /* GNU gcc usage. */ DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_class_type DW_TAG_variable /* GNU gcc usage. */ DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_lexical_block DW_TAG_GNU_call_site 0xffffffff DW_TAG_subprogram DW_TAG_GNU_call_site DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_union_type DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_inlined_subroutine DW_TAG_GNU_call_site 0xffffffff DW_TAG_GNU_call_site DW_TAG_GNU_call_site_parameter 0xffffffff DW_TAG_GNU_template_parameter_pack DW_TAG_template_type_parameter DW_TAG_template_value_parameter DW_TAG_GNU_template_template_parameter 0xffffffff DW_TAG_GNU_formal_parameter_pack DW_TAG_formal_parameter 0xffffffff libdwarf-20210528/dwarfdump/print_reloc.h0000664000175000017500000000301113762721636015166 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_RELOC_H_INCLUDED #define PRINT_RELOC_H_INCLUDED #include "dwarf_reloc_arm.h" #include "dwarf_reloc_mips.h" #include "dwarf_reloc_ppc.h" #include "dwarf_reloc_ppc64.h" #include "dwarf_reloc_x86_64.h" #include "dwarf_reloc_386.h" #endif /* PRINT_RELOC_H_INCLUDED */ libdwarf-20210528/dwarfdump/dwarfdump.10000664000175000017500000006757714021202272014556 00000000000000.TH DWARFDUMP .SH NAME dwarfdump \- dumps DWARF debug information of an ELF object .SH SYNOPSIS .B dwarfdump [options] \f2objectfilename\fP .SH DESCRIPTION The .B dwarfdump command prints or checks DWARF sections as requested by specific options. With no options (but with the required \f2objectfilename\fP ) all sections print (but some sections cannot be printed independently safely, so those are only printed at offsets where the .debug_info section refers to those sections). .PP For split-dwarf (DWARF5) object files see Split Object Files, DWARF5 section 7.3. .PP Nearly all options are available in the traditional (single-letter) form and in a long-options form with meaningful names. New options are only in the long-options form. .PP With no options .B dwarfdump prints a basic set of DWARF section information. If any option is given on the command line the basic set is ignored and one must tell .B dwarfdump what to print or check (for example by adding the .B \-a option). .PP As of June 2011 the printing options and the checking options are mutually exclusive (if checking options are selected the section details are not printed). When errors are encountered dwarfdump does attempt to print sufficient context so that one can understand exactly where the error is in the DWARF. This change makes checking really large object files much easier. .PP The format is intended to be human readable. If a script is to parse the output, the .BR \--format-dense\ (\-d) option is useful. .PP As of December 2020 DWARF expressions are broken out to print each expression (DW_OP_plus for example) in a block on a separate line. To restore the previous behavior, sort of like \--format-dense but only applying to blocks of DWARF expression operators (DW_OP*). the .BR \--format-expr-ops-joined is useful. If the option is placed in the dwarfdump.conf file (see the file itself for the format) it will apply without needing to put it on the command line. .PP Not all sections actually exist in any given object file. .PP The output format may change from release to release, so it is unwise to depend too heavily on the format. .PP Frame information (.debug_frame and .eh_frame) is heavily dependent on the ABI/ISA of the object file. By default we use a generic set of register names handling up to 100 registers named r0-r99. .PP As of 2020 there are three different ways compiler writers separate the DWARF information from an executable/shared-object. One is DWARF5 Split Dwarf (the \--file-tied option is useful for these). Another is GNU debuglink (libdwarf automatically finds the DWARF when given the name of the executable, use \--no-follow-debuglink to suppress this and make possible printing the backtrace data in section \.eh_frame). The third way is on MacOS: the debug DWARF is in a separate object (dwarfdump/libdwarf automatically find it if it is present, \--no-follow-debuglink suppresses this finding). .PP In many cases one can get additional detail by specifying \-v (sometimes \-v \-v gets even more, see the --verbose discussion below). When printing DIEs (Debugging Information Entries) the options \-G (showing global offsets) and \-M (naming the DW_FORM* of attributes) (or their -- counterparts) can be a great aid to understanding DWARF.. The .BR \--format-registers\ (\-R) option uses a built-in generic register name set handling up to 1200 registers named r0-r1199. .PP The .BR \--file-abi=\ (\-x\ abi=) description below shows how to name an abi and use that to guide the .BR \--print-frame\ (\-f) or .BR \--print-eh-frame\ (\-F) processing. .PP One of .BR \--print-frame\ (\-f) or .B \--print-eh-frame\ (\-F) implies lots of abi (register names, register counts) in the output, but sections other than frame sections may also need register names. .PP Unless the cpu for the object file being dumped has many registers, do not use .B \--format-registers or .B \-file-abi= as those can be needlessly slow dumping frame sections. Instead, use the correct abi (if it exists in dwarfdump.conf) or a generic such as .B \--file-abi=abi=generic100 or .B \--file-abi=abi=generic500 . .PP The most useful abi choices are likely .B mips or .B x86 or .B x86_64 or .B ppc or .B arm . Without .BR \--format-registers\ (\-R) or .BR \-file-abi=\ (\-x\ abi=) dwarfdump uses a compiled-in generic set of register names. If no .BR \--file-name=\ (\-x\ name=) is given, dwarfdump looks for "./dwarfdump.conf", "$HOME/dwarfdump.conf", "$HOME/.dwarfdump.conf", "/lib/dwarfdump.conf" and takes the first it finds. Use the \--show-dwarfdump-conf option to see what dwarfdump finds. If one or more .BR \--file-name=\ (\-x\ name=) is given the last of these is used and all other such files are ignored. .PP Some checking ( .BR \-k ) options (See "Check DWARF Integrity" in the help output) print so-called harmless errors. These are compiler errors that do not cause any known problem and are only detected inside libdwarf itself. These are difficult to properly report in dwarfdump and any error strings may not appear close to the time the error was encountered. .PP If zlib compression was used on the DWARF sections in the object file being read the real section names such as .zdebug_info etc will be reported by dwarfdump. When dwarfdump says something is at offset 55 of .zdebug_info (or the like) keep in mind that the offset applies to the uncompressed section (in memory), not the .zdebug_ compressed section in \f2objectfilename\fP. .SH URI-STYLE INPUT STRINGS .PP The and all the options taking name strings look for URIs and translate the URI strings to characters by default. So any single % character is treated as if the following two characters are hex digits representing the underlying true character. Various characters are meaningful to shells (such as bash or sh) and to getopt (such as the space character) If the URI translation does anything it prints the before and after of the URI translation on standard output, so inspection of the first lines of output will show if URI did anything. The actual options themselves are assumed to be non-URI. So in the option .BR \--format-producer=S&T\ (\-cS&T) the & character might cause input issues so .B \--format-producer=S%26T should be used instead. To actually input a single % character (in a name, for example), double it to %% on the command line (or use %25). .PP Options .BR \--format-suppress-uri\ (\-U) (turning off URI interpretation) and .BR \--format-suppress-uri-msg\ (\-q) (making finding URI sequences silent) give finer control of URI interpretation. .PP As an example, to get a string 'a b' make the string 'a%20b' (here the quote (') is for exposition not part of the string, though quote is certainly problematic in a name). Instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b'. Any characters can be typed in URI style, not just characters which are problematic to the shell or getopt. We strongly suggest you not type URI-style characters where such are not needed or use the % character itself in command line strings unless you must. .SH URI-STYLE OUTPUT (printing) .PP Dwarfdump translates any characters in strings which are not ordinary printable ASCII (and some which are ASCII) in the reverse of the previous section. It prints into a uri-style output in the form %xx, where xx are hex digits in the form of ASCII 0-9a-0f. The percent character(%) is printed as '%25' .P This is a clumsy way to deal with UTF-8 strings and sensible way to deal with the low ASCII values that on many systems cause one's terminal to behave oddly. Such translations are not idempotent so dwarfdump avoids doing the translation more than once on any string. See option \--format-suppress-sanitize below to eliminate the output transformation. .SH PRINTING OPTIONS .TP .BR \--print-all\ (\-a) Print each section as independently as possible. Sections that can safely be printed independently (like .debug_abbrev) have relevant info printed in the report (sometimes dependent on -v). .TP .BR \--print-abbrev\ (\-b) Print the .debug_abbrev section. Because the DWARF specifications do not rule out garbage data areas in .debug_abbrev (if they are not referenced from .debug_info) any garbage bytes can result in this print failing. .TP .BR \--print-loc\ (\-c) Print locations lists. .TP .BR \--print-debug-gnu Print the .debug_gnu_pubnames and .debug_gnu_typenames sections. .TP .BR \--print-fission Print the .gdb_index, .debug_cu_index, .debug_tu_index, .gnu.debuglink, and .note.gnu.build-id sections. .TP .BR \--print-gnu-debuglink Print .gnu_debuglink and .note.gnu.build-id sections .TP .BR \--elf\ (\-E) prints, for Elf objects, object file details. See the "Print ELF Section Headers" section of the help file for additional choices on elf printing. If libdwarf or dwarfdump is built without libelf this and related options are not available. .TP .BR \--print-frame\ (\-f) Print the .debug_frame section. .TP .BR \--print-eh-frame\ (\-F) Print the GNU .eh_frame section. .TP .BR \--print-info\ (\-i) Print the .debug_info section. .TP .BR \--print-fission\ (\-I) Print any .gdb_index, .debug_cu_index, and .debug_tu_index sections that exist in the object. .TP .BR \--print-gnu-debuglink If the .gnu_debuglink section is present its content is printed. If the .note.gnu.build-id section is present its content is printed. If a DWARF containing file named by the content of the .gnu_debuglink section exists the name will be printed. .TP .BR \--print-lines\ (\-l) Print the .debug_info section and the associated line section data. .TP .BR \--print-lines-short\ (\-ls) Print the .debug_info section and the associated line section data, but omit the address. Useful when a comparison of line sections from objects with slight differences is required. .TP .BR \--print-macinfo\ (\-m) Print the .debug_macinfo (DWARF 2,3,4) and .debug_macro (DWARF5) sections. The .debug_macro reporting may show output labeled MACRONOTES, mentioning macro content that might be questionable. See also \--check-macros\ (\-kw). .TP .BR \--print-ranges\ (\-N) Print .debug_ranges section. Because the DWARF specifications do not rule out garbage data areas in .debug_ranges (if they are not referenced from .debug_info) any garbage bytes can result in this print failing. .TP .BR \--print-pubnames\ (\-p) Print the .debug_pubnames section. .TP .B \--print-str-offsets Print the .debug_str_offsets section. .TP .BR \--print-aranges\ (\-r) Print the .debug_aranges section. .TP .BR \--print-strings\ (\-s) Print .debug_string section. .TP .BR \--print-static\ (\-ta) Print the IRIX only sections .debug_static_funcs and .debug_static_vars. .TP .BR \--print-type\ (\-y) Print the .debug_pubtypes section (and .debug_typenames, an SGI IRIX-only section). .PP Having dwarfdump print relocations may help establish whether dwarfdump understands any relocations that might exist. Other tools may be more useful than dwarfdump for printing object-file details. If dwarfdump or libelf is built without libelf the relocation options are not available. See "Print Elf Relocation Data" in the help output for additional relocation printing choices. .TP .BR \--reloc\ (\-o) Print all relocation records as well as we can manage. If libdwarf or dwarfdump were built without libelf this option is unavailable. .TP .BR \--version\ (\-V) Print a dwarfdump date/version string and stop. .SH CHECKING OPTIONS .TP .BR \--check-all\ (\-ka) Turns on all checking options except .BR \--check-frame-extended\ (\-kxe) (which might be slow enough one might not want to use it routinely.) .TP .BR \--check-abbrev\ (\-kb) Checks for certain abbreviations section errors when reading DIEs. .TP .BR \--check-macros\ (\-kw) Checks for issues in DWARF5 .debug_macro and identifies issues that might be questionable but not necessarily errors with the string MACRONOTES (and reports some MACRONOTES that \--print-macinfo will not show). It also checks .debug_macinfo, but less thoroughly and never emits MACRONOTES for .debug_macinfo. See also \--print-macinfo\ (\-m). (regrettably inconsistent spelling...). .TP .BR \--check-constants\ (\-kc) Checks for errors in constants in debug_info. .TP .BR \-check-show\ (\-kd) Turns on full reporting of error totals per producer. (the default shows less detail). .TP .BR \--check-silent \-ks Turns off some verbose checking detection. .TP .BR \--check-attr-dup\ (\-kD) Turns on reporting of duplicated attributes. Duplicated attributes on a single DW_TAG are improper DWARF, but at least one compiler emitted such. .TP .BR \--check-pubnames\ (\-ke) Turns on reading pubnames and checking for fde errors. .TP .BR \--check-frame-info\ (\-kf) Turns on checking for FDE errors (.debug_frame and .eh_frame). .TP .BR \--check-files-lines\ (\-kF) Turns on checking for line table errors. .TP .BR \--check-gaps\ (\-kg) Turns on checking for unused gaps in .debug_info (these gaps are not an error, just a waste of space). .TP .BR \--check-unique\ (\-kG) Print only unique errors. Error lines are simplified (hex numbers removed, for example) and when a given message string would otherwise appear again it is suppressed. .TP .BR \--check-summary\ (\-ki) Causes a summary of checking results per compiler (producer) to be printed at the end. .TP .B \--check-loc\ (\-kl) Turns on locations list checking. .TP .B \--check-ranges\ (\-km) Turns on checking of ranges. .TP .BR \--check-aranges\ (\-kM) Turns on checking of aranges. .TP .BR \--check-tag-attr\ (\-kr) Turns on DIE tag-attr combinations checking, looking for surprising attributes for DIE tags. Prints a DWARF-CHECK message for each such found. It does not report common extensions as errors. A summary of usage is printed at the end. Common extensions to the standard are allowed as if standard. See the \-C (\--format-extensions) option to show common extensions as DWARF-CHECK messages. See \-kuf (\--check-usage-extended) to add additional details to the summary report. .TP .BR \--check-usage\ (\-ku) The same as \-kr except only the summary is printed at the end, the detailed DWARF-CHECK messages per instance are not printed. .TP .BR \--check-attr-encodings\ (\-kE) Checks the integer encoding representation of constant FORMs in debug_info, computing whether these integer values could fit in fewer bytes if represented in LEB128 and reports the space saving that would achieve. .TP .BR \--check-forward-refs\ (\-kR) Turns on reading DIEs and checking for forward declarations from DW_AT_specification attributes. (which are not an error but can be a source of inefficiency for debuggers). .TP .BR \--check-self-refs\ (\-kS) Turns on checking DIE references for circular references. .TP .BR \--check-tag-tag\ (\-kt) Turns on tag-tag combinations checking, looking for surprising parent-child DIE relationships. It does not report common extensions as errors. Common extensions to the standard are allowed as if standard. See the \-C (\--format-extensions) option to show common extensions as errors. .TP .BR \--check-frame-basic\ (\-kx) Turns on basic frames checking for .debug_frame and .eh_frame). .TP .BR \--check-frame-extended\ (\-kxe) Turns off basic check_frames and turns on extended frame checking for .debug_frame and .eh_frame. This option can be slow. .TP .BR \--check-type\ (\-ky) Turns on type_offset checking (ensuring local attribute offsets refer to what they should) and that DW_AT_decl_file and some other offsets refer to appropriate locations. .SH OPTION MODIFIERS .TP .BR \--format-extensions\ (\-C) This is a secondary option after \--check-tag-tag\ (\-kt) or \--check-tag-attr\ (\-kr) or Normally when checking for tag-tag or tag-attribute combinations both the standard combinations and some common extensions are allowed (not reported). With this option the extensions are taken out of the class of allowed combinations. .TP .BR \-kuf\ (\--check-usage-extended) This modifies \--check-tag-attr\ (\-kr) or \--check-usage\ (\-ku) to print additional details in the summary. Add the \-kuf\ (\--check-usage-extended) before or after the option it modifies. .TP .BR \--format-dense\ (\-d) When printing DIEs, put all the attributes for each DIE on the same (long) line as the TAG. This makes searching for DIE information (as with grep) much simpler as the entire DIE is on one line. .TP .BR \--format-suppress-offsets\ (\-D) Turns off the display of section offsets and attribute values in printed output. So the .debug_info output is just TAGs and Attributes. For pubnames (and the like) it removes offsets from the output. For locations lists it removes offsets from the output, but that is useless since the attribute values don't show so neither does the location data. .TP .BR \--format-ellipsis\ (\-e) Turns on truncation of attribute and tag names. For example DW_TAG_foo becomes foo. Not compatible with checking, only useful for printing DIEs. .TP .BR \--format-global-offsets\ (\-G) When printing, add global offsets to the offsets printed. .TP .BR \--format-limit=\ (\-H\ number) When printing or checking .debug_info, this terminates the search after 'number' compilation units. When printing frame information this terminates the FDE reporting after 'number' FDEs and the CIE reporting (which occurs if one adds -v) after 'number' CIEs. Example '--format-limit=1' .TP .BR \--format-attr-name\ (\-M) When printing, show the FORM for each attribute. If a -v is added (or more than one) then details of any form indirection are also shown. .TP .BR \--format-suppress-lookup\ (\-n) When printing frames, this turns off the search for function names in inner scopes. Unless the language used to build the object file supports function definitions in inner scopes there is no point in looking for function names in inner scopes. And a really large object the search can take more time than one wants to wait. This option suppresses the inner scope search. .TP .BR \--file-output=\ (\-O file=) The will be used as the file name for output instead of writing to stdout (stdout is the default). .TP .BR \--format-suppress-data\ (\-Q) Suppresses section data printing (set automatically with a checking option). .TP .BR \--format-suppress-sanitize Suppresses the default string-printing translations so non-ascii and non-printable characters from the object file are printed as-is. See "URI-STYLE OUTPUT" above. .TP .BR \--format-suppress-uri\ (\-U) Suppresses the default URI translation of following options on the command line. See "URI-STYLE INPUT STRINGS" above. .TP .BR \--format-registers\ (\-R) When printing frames for ABIs with lots of registers, this allows up to 1200 registers to be named (like R999) without choosing an ABI with, for example '-x abi=ppc' or, equivalently, '--file-abi=ppc' .TP .BR \--verbose\ (\-v) Increases the detail shown when printing. In some sections, using more -v options will increase the detail (one to four are useful) or may change the report to show, for example, the actual line-data-commands instead of the resultant line-table. Two to four -v options make a difference when printing DIEs and rnglists (-i), lines (-l), frames (-f,-F), gdb_index(-I). Additional -v beyond four do not currently add-to or change the output. .TP .BR \--show-dwarfdump-conf Shows what files are checked to find a dwarfdump.conf and its register naming tables. .SH LIMITING OUTPUT .PP The simplest limiting option is to stop the examination/printing after compilation units. See -H and --format-limit above. This option also limits the number of FDEs and CIEs printed from any .debug_frame or .eh_frame section. .PP The --search (-S) options print information about the compilation unit and DIE where the string(s) appear. These cannot be combined with other options. At most one of each of the following is effective (so for example one can only have one 'match', but one can have a 'match', an 'any', and a 'regex'). Any --search (-S) causes the .debug_info section to be inspected. No checking options or printing options should be supplied with --search(-S) options. The strings should use URI-style to avoid any conflicts with the command-line parser applicable (bash, sh, ...) or getopt(), as well as using URI to deal with searching for strings in non-ASCII such as French, (etc) or the now-nearly-universal UTF8. These are particularly useful when the amount of DWARF information output by -i is multiple gigabytes of data. If -Sv used instead of -S , the number of occurrences is printed. (see below for an example). .TP .BR \--search-match=\ (\-S match=string) .TP .BR \--search-match-count=\ (\-S vmatch=string) When printing DIEs for each tag value or attribute name that matches 'string' exactly print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .TP .BR \--search-any=\ (\-S any=string) .TP .BR \--search-any-count=\ (\-Svany=string) When printing DIEs for each tag value or attribute name that contains 'string' somewhere in the tag or attribute (case insensitive) print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .TP .BR \--search-regex=string\ (\-S regex=string) .TP .BR \--search-regex-count=string\ (\-Svregex=string) When printing DIEs for each tag value or attribute name where the 'string' regular expression matches print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .PP The string cannot have spaces or other characters which are meaningful to getopt(3) and the shell will strip off quotes and other characters. So the string is assumed to be in URI style and is translated. In other words, to match 'a b' make the -S string 'a%20b' Instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b' (the ' are for exposition here, not part of the strings). Any characters can be typed in URI style, not just characters which are problematic to the shell or getopt. .PP The .BR \--search-any\ (\-S any) and .BR \--regex-any\ (\-S regex) options are only usable if regular-expression library functions required are found at configure time. .PP The .BR \--search-print\ (\-W) option is a modifier to the -S option, and increases the amount of output -S prints. An example v modifier to the -S option is shown below. And we show the -W in context with a -S option. .TP .BR \--search-match-count=string Prints information about the DIEs that -S matches and prints the count of occurrences. .TP .BR \-S\ match=string1\ \-W .TP .BR \--search-match=string1\ \--search-print-tree Prints the parent tree and the children tree for the DIEs that --search-match matches. .TP .BR \-S\ match=string2\ \-Wp .TP .BR \--search-match=string2\ \--search-print-parent Prints the parent tree for the DIEs that -S matches. .TP .BR \-S\ match=string3\ \-Wc .TP .BR \--search-match=string3\ \--search-print-children Prints the children tree for the DIEs that -S matches. .TP .BR \--format-gcc\ (\-cg) Restricts printing/checking to compilers whose producer string starts with 'GNU' and turns off -cs. .TP .BR \--format-snc\ (\-cs) Restricts printing/checking to compilers whose producer string starts with 'SN' and turns off -cg. .TP .BR \--format-producer=\ (\-c) Restricts printing/checking to compilers whose producer string contains 'name' (not case sensitive). The 'name' is read as a URI string. .SH OTHER OPTIONS .TP .BR \-x\ name= .TP .BR \--file-name=/p/a/t/h.conf\ (\-x name=/p/a/t/h.conf) The file path given is the name of a file assumed to be a dwarfdump.conf-like file. The file path is read as a URI string. .TP .BR \-x\ abi=ppc .TP .BR \--file-abi=ppc Selects the abi (from a dwarfdump.conf file) to be used in printing frame information (here using ppc as an example). The abi is read as a URI string. .TP .BR \--format-group-number=\ (\-x\ groupnumber=) For an object file with both DWARF5 split dwarf (.debug_info.dwo for example) and ordinary DWARF sections (.debug_info for example) in the single object file one must use .BR \--format-group-number=2 to print the dwo sections. Adding .BR \--file-tied= naming the object file ties in the non-dwo skeleton sections (the is to the skeleton object file when the main object file is dwo/dwp). .TP .BR \-x\ tied=/t/i/depath .TP .BR \--file-tied=/t/i/depath Used when opening a main object that is a .dwo or .dwp file. For example if /path/to/myapp.dwp is the split-dwarf object and /path/to/myapp is the executable, do "dwarfdump --file-tied=/path/to/myapp /path/to/myapp.dwp" . The tied file path names the executable which has the .debug_addr section that may be referred to from the main object. See Split Objects (aka Debug Fission) in the DWARF5 standard. This cannot be used with MacOS debug or GNU debuglink, such files do not have a Split Dwarf object file. .TP .BR \-x\ line5=s2l .TP .BR \--file-line5=s2l Normally used only to test libdwarf interfaces. There are 4 different interface function sets and to ensure they all work this option lets us choose which to use. The options are 's2l' (default, Allows standard and two-level line tables using the latest interface functions), 'std' (Allows standard single level line tables using the latest interface functions), 'orig' (allows DWARF2,3,4 original line tables using an older interface function set), 'orig2l' (allows original line tables and some two-level line tables using an older interface set). .TP .B \--print-producers .B \-P When checking this adds the list of compilation-unit names seen for each producer-compiler to the printed checking results. .TP .B \-q .TP .B \--format-suppress-uri-msg When a URI is found and translated while reading the command line, be quiet about the URI translation. That is, don't print the original and translated option strings. .TP .B \-u cuname .TP .B \--format-file= Turns on selective printing of DIEs (printing like -i). Only the DIEs for a compilation unit that match the name provided are printed. If the compilation unit is ./a/b/c.c the 'cuname' you provide should be c.c as the characters through the final path-separating / are ignored. If 'cuname' begins with a / then the entire name string of a compilation unit must match 'cuname'. The 'file' is read as a URI string. .TP .B \-U .TP .B \--format-suppress-uri Turn off the URI interpretation of the command line strings entirely. Must be be on the command line before any URI strings encountered to be fully effective. Likely something no one needs to do. .TP .B \-h .TP .B \--help Show this man page. .SH SPLIT DWARF With Split Dwarf (DWARF5) the main body of the DWARF is in a separate file, often having the name suffix .dwp or .dwo . .PP For example if /path/to/myapp.dwp is the split-dwarf object and /path/to/myapp is the executable, do "dwarfdump --file-tied=/path/to/myapp /path/to/myapp.dwp" . The tied file path names the executable which has the .debug_addr section and other sections that may be referred to from the .dwo/.dwp object. .PP See Split Object Files (sometimes called Debug Fission) in the DWARF5 standard, section 7.3. .SH FILES dwarfdump ./dwarfdump.conf $(HOME)/.dwarfdump.conf $(HOME)/dwarfdump.conf /lib/dwarfdump.conf .SH NOTES In some cases compilers use DW_FORM_data1 (for example) and in such cases the signedness of the value must be taken from context. Rather than attempt to determine the context, dwarfdump prints the value with both signedness whenever there is ambiguity about the correct interpretation. For example, "DW_AT_const_value 176(as signed = -80)". For normal DWARF consumers that correctly and fully evaluate all attributes there is no ambiguity of signedness: the ambiguity for dwarfdump is due to dwarfdump evaluating DIEs in a simple order and not keeping track of much context. .SH BUGS Support for printing certain DWARF5 location expressions is incomplete. Report problems to libdwarf-list -at- linuxmail -dot- org libdwarf-20210528/dwarfdump/tag_common.h0000664000175000017500000001004214014010123014740 00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2010 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef tag_common_INCLUDED #define tag_common_INCLUDED /* The following is the magic token used to distinguish real tags/attrs from group-delimiters. Blank lines have been eliminated by an awk script. */ #define MAGIC_TOKEN_VALUE 0xffffffff /* These next two should match the last DW_TAG+1 and last DW_AT+1 in the standard set from dwarf.h */ #define DW_TAG_last 0x4c #define DW_AT_last 0x8d /* TAG_TREE.LIST Expected input format 0xffffffff value of a tag value of a standard tag that may be a child of that tag ... 0xffffffff value of a tag value of a standard tag that may be a child of that tag ... 0xffffffff ... No blank lines or commentary allowed, no symbols, just numbers. */ /* TAG_ATTR.LIST Expected input format 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff ... No blank lines or commentary allowed, no symbols, just numbers. */ /* We don't need really long lines: the input file is simple. */ #define MAX_LINE_SIZE 1000 /* 1 more than the highest number in the DW_TAG defines, this is for standard TAGs. Number of rows. */ #define STD_TAG_TABLE_ROWS 75 /* Enough entries to have a bit for each standard legal tag. */ #define STD_TAG_TABLE_COLUMNS 3 /* TAG tree common extension maximums. */ #define EXT_TAG_TABLE_ROWS 9 #define EXT_TAG_TABLE_COLS 5 /* The following 2 used in tag_tree.c only. They must be large enough but they are only used declaring array during build (not compiled into dwarfdump) so if a bit too large there is no side effect on anything. */ #define TAG_TABLE_ROW_MAXIMUM 80 #define TAG_TABLE_COLUMN_MAXIMUM 8 /* Number of attributes columns per tag. The array is bit fields, BITS_PER_WORD fields per word. Dense and quick to inspect */ #define COUNT_ATTRIBUTE_STD 7 #define STD_ATTR_TABLE_ROWS 76 #define STD_ATTR_TABLE_COLUMNS 5 /* tag/attr tree common extension maximums. */ #define EXT_ATTR_TABLE_ROWS 19 #define EXT_ATTR_TABLE_COLS 15 /* The following 2 used in tag_attr.c only. They must be large enough but they are only used declaring an array during build (not compiled into dwarfdump) so if a bit too large there is no side effect on anything. */ #define ATTR_TABLE_ROW_MAXIMUM 80 #define ATTR_TABLE_COLUMN_MAXIMUM 16 /* Bits per 'int' to mark legal attrs. */ #define BITS_PER_WORD 32 #define IS_EOF 1 #define NOT_EOF 0 extern void bad_line_input(char *format,...); extern void trim_newline(char *line, int max); extern Dwarf_Bool is_blank_line(char *pLine); extern int read_value(unsigned int *outval,FILE *f); /* Define to 1 to support the generation of tag-attr usage */ #define HAVE_USAGE_TAG_ATTR 1 /* Define to 1 to support the generation of attr/formclass usage */ #define HAVE_USAGE_ATTR_FORMCLASS 1 #endif /* tag_common_INCLUDED */ libdwarf-20210528/dwarfdump/testobjLE32PE.test.c0000664000175000017500000000102613764006205016076 00000000000000/* This is the test file used to compile testobjLE32PE.exe under MinGW on Windows 8.1 These leading comments mean a recompile would not exactly match line numbers in the DWARF. This source file is hereby placed in the public domain. */ #include struct something { int a; unsigned b; }; int buffle(struct something *v ) { return v->a + 42; } int main(int argc, char **argv) { int x = 12; int y = 24; struct something so; so.a = x; x = buffle(&so); return x +y + 4 +argc; } libdwarf-20210528/dwarfdump/dwarfdump-tt-ext-table.h0000664000175000017500000000252714054205620017143 00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ #define TAG_TREE_EXT_COLUMN_COUNT 5 #define TAG_TREE_EXT_ROW_COUNT 9 /* Common extensions */ static unsigned int tag_tree_combination_ext_table [TAG_TREE_EXT_ROW_COUNT][TAG_TREE_EXT_COLUMN_COUNT] = { /* 0x13 - DW_TAG_structure_type */ { 0x00000013,0x00000034,0x00004106,0x00004107,0x00004108,}, /* 0x02 - DW_TAG_class_type */ { 0x00000002,0x00000034,0x00004106,0x00004107,0x00004108,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0000000b,0x00004109,0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0x0000002e,0x00004109,0x00004106,0x00004107,0x00004108,}, /* 0x17 - DW_TAG_union_type */ { 0x00000017,0x00004106,0x00004107,0x00004108,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x0000001d,0x00004109,0x00000000,0x00000000,0x00000000,}, /* 0x4109 - DW_TAG_GNU_call_site */ { 0x00004109,0x0000410a,0x00000000,0x00000000,0x00000000,}, /* 0x4107 - DW_TAG_GNU_template_parameter_pack */ { 0x00004107,0x0000002f,0x00000030,0x00004106,0x00000000,}, /* 0x4108 - DW_TAG_GNU_formal_parameter_pack */ { 0x00004108,0x00000005,0x00000000,0x00000000,0x00000000,}, }; /* END FILE */ libdwarf-20210528/dwarfdump/print_frames.h0000664000175000017500000000344713762722156015352 00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_FRAMES_H #define PRINT_FRAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int print_one_cie(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Cie cie, Dwarf_Unsigned cie_index, Dwarf_Half address_size, struct dwconf_s *config_data, Dwarf_Error *err); int print_location_operations(Dwarf_Debug dbg, Dwarf_Die die, int die_indent_level, Dwarf_Ptr bytes_in, Dwarf_Unsigned block_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct esb_s *out_string, Dwarf_Error *err); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRINT_FRAMES_H */ libdwarf-20210528/dwarfdump/command_options.h0000644000175000017500000000263213743575426016050 00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMMAND_OPTIONS_H #define COMMAND_OPTIONS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ const char *process_args(int argc, char *argv[]); const char *do_uri_translation(const char *s,const char *context); void uri_data_constructor(void); void uri_data_destructor(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* COMMAND_OPTIONS_H */ libdwarf-20210528/dwarfdump/testesb.c0000664000175000017500000003106214004637757014321 00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2013-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* testesb.c testing esb.c */ #include "config.h" #include "warningcontrol.h" #include "esb.h" #define TRUE 1 static int failcount = 0; static void validate_esb(int instance, struct esb_s* d, UNUSEDARG size_t explen, UNUSEDARG size_t expalloc, const char *expout, int line ) { if (esb_string_len(d) != explen) { ++failcount; printf(" FAIL instance %d esb_string_len()" " %u explen %u line %d\n", instance,(unsigned)esb_string_len(d), (unsigned)explen,line); } if (strcmp(esb_get_string(d),expout)) { ++failcount; printf(" FAIL instance %d esb_get_string" " %s expstr %s line %d\n", instance,esb_get_string(d),expout,line); } } int main() { #ifdef _WIN32 /* Open the null device used during formatting printing */ if (!esb_open_null_device()) { fprintf(stderr, "esb: Unable to open null device.\n"); exit(1); } #endif /* _WIN32 */ { /* First lets establish standard sprintf on cases of interest. */ struct esb_s d5; char bufs[4]; esb_int i = -33; /* After static alloc we add len, ie, 11 */ esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %d bbb",(int)i); validate_esb(201,&d5,11,15,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",(int)i); validate_esb(202,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",6); validate_esb(203,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",6); validate_esb(204,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %06u bbb",6); validate_esb(205,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %6u bbb",6); validate_esb(206,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %u bbb",12); validate_esb(207,&d5,10,14,"aaa 12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %06x bbb",12); validate_esb(208,&d5,14,18,"aaa 00000c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %6x bbb",12); validate_esb(209,&d5,14,18,"aaa c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",12); validate_esb(210,&d5,11,15,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+6d bbb",12); validate_esb(211,&d5,14,18,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",(int)i); validate_esb(212,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"a"); validate_esb(1,&d,1,2,"a",__LINE__); esb_append(&d,"b"); validate_esb(2,&d,2,3,"ab",__LINE__); esb_append(&d,"c"); validate_esb(3,&d,3,4,"abc",__LINE__); esb_empty_string(&d); validate_esb(4,&d,0,4,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"aa"); validate_esb(6,&d,2,3,"aa",__LINE__); esb_append(&d,"bbb"); validate_esb(7,&d,5,6,"aabbb",__LINE__); esb_append(&d,"c"); validate_esb(8,&d,6,7,"aabbbc",__LINE__); esb_empty_string(&d); validate_esb(9,&d,0,7,"",__LINE__); esb_destructor(&d); } { struct esb_s d; static char oddarray[7] = {'a','b',0,'c','c','d',0}; esb_constructor(&d); /* This used to provoke a msg on stderr. Bad input. Now inserts particular string instead. */ esb_appendn(&d,oddarray,6); validate_esb(10,&d,23,24,"ESBERR_appendn bad call",__LINE__); /* The next one just keeps the previous ESBERR* and adds a 'c' */ esb_appendn(&d,"cc",1); validate_esb(11,&d,24,25,"ESBERR_appendn bad callc",__LINE__); esb_empty_string(&d); validate_esb(12,&d,0,25,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_force_allocation(&d,7); esb_append(&d,"aaaa i"); validate_esb(13,&d,6,7,"aaaa i",__LINE__); esb_destructor(&d); } { struct esb_s d5; const char * s = "insert me %d"; esb_constructor(&d5); esb_force_allocation(&d5,50); esb_append(&d5,"aaa "); esb_append_printf_i(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(14,&d5,18,50,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d; struct esb_s e; char* result = NULL; esb_constructor(&d); esb_constructor(&e); esb_append(&d,"abcde fghij klmno pqrst"); validate_esb(15,&d,23,24,"abcde fghij klmno pqrst",__LINE__); result = esb_get_copy(&d); esb_append(&e,result); validate_esb(16,&e,23,24,"abcde fghij klmno pqrst",__LINE__); esb_destructor(&d); esb_destructor(&e); } { struct esb_s d5; char bufs[4]; char bufl[60]; const char * s = "insert me %d"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(17,&d5,18,19,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufl,sizeof(bufl)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(18,&d5,18,60,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; const char * s = "insert me"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %s bbb",s); validate_esb(19,&d5,17,18,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %12s bbb",s); validate_esb(20,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %-12s bbb",s); validate_esb(21,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_int i = -33; esb_unsigned u = 0; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(20,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",i); validate_esb(21,&d5,14,15,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(22,&d5,12,13,"aaa -002 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(23,&d5,14,15,"aaa -00002 bbb",__LINE__); esb_destructor(&d5); i = -200011; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(24,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(25,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); u = 0x80000000; u = 0x8000000000000000; i = u; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(26,&d5,28,29,"aaa -9223372036854775808 bbb", __LINE__); esb_destructor(&d5); i = 987665432; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(27,&d5,17,18,"aaa 987665432 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_unsigned u = 0; u = 37; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %u bbb",u); validate_esb(28,&d5,10,11,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(29,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(30,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %6u bbb",u); validate_esb(31,&d5,14,15,"aaa 37 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_int i = -33; char * middlelength = "0123456789aaaabbbb"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = 33; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa +33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); esb_constructor(&d5); esb_append_printf_s(&d5,"x%-15syyyy",middlelength); validate_esb(20,&d5,23,0,"x0123456789aaaabbbbyyyy",__LINE__); esb_destructor(&d5); } #ifdef _WIN32 /* Close the null device used during formatting printing */ esb_close_null_device(); #endif /* _WIN32 */ if (failcount) { printf("FAIL esb test\n"); exit(1); } printf("PASS esb test\n"); exit(0); } libdwarf-20210528/dwarfdump/print_debug_gnu.h0000664000175000017500000000267713701441253016025 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* To print .debug_gnu_pubnames, .debug_gnu_typenames */ int print_debug_gnu(Dwarf_Debug dbg,Dwarf_Error *error); libdwarf-20210528/dwarfdump/Makefile.in0000664000175000017500000047767214054252021014554 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = dwarfdump$(EXEEXT) subdir = dwarfdump ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(dwarfdumpdevdir)" PROGRAMS = $(bin_PROGRAMS) am_dwarfdump_OBJECTS = dwarfdump-addrmap.$(OBJEXT) \ dwarfdump-attr_form.$(OBJEXT) dwarfdump-checkutil.$(OBJEXT) \ dwarfdump-command_options.$(OBJEXT) dwarfdump-common.$(OBJEXT) \ dwarfdump-compiler_info.$(OBJEXT) \ dwarfdump-dwarfdump.$(OBJEXT) dwarfdump-dwarf_names.$(OBJEXT) \ dwarfdump-dwarf_tsearchbal.$(OBJEXT) \ dwarfdump-dwconf.$(OBJEXT) dwarfdump-dwgetopt.$(OBJEXT) \ dwarfdump-esb.$(OBJEXT) dwarfdump-glflags.$(OBJEXT) \ dwarfdump-helpertree.$(OBJEXT) dwarfdump-macrocheck.$(OBJEXT) \ dwarfdump-makename.$(OBJEXT) dwarfdump-naming.$(OBJEXT) \ dwarfdump-opscounttab.$(OBJEXT) \ dwarfdump-print_abbrevs.$(OBJEXT) \ dwarfdump-print_aranges.$(OBJEXT) \ dwarfdump-print_debugfission.$(OBJEXT) \ dwarfdump-print_die.$(OBJEXT) \ dwarfdump-print_debug_gnu.$(OBJEXT) \ dwarfdump-print_debug_names.$(OBJEXT) \ dwarfdump-print_debug_sup.$(OBJEXT) \ dwarfdump-print_frames.$(OBJEXT) \ dwarfdump-print_gdbindex.$(OBJEXT) \ dwarfdump-print_hipc_lopc_attr.$(OBJEXT) \ dwarfdump-print_lines.$(OBJEXT) \ dwarfdump-print_llex_codes.$(OBJEXT) \ dwarfdump-print_origloclist_codes.$(OBJEXT) \ dwarfdump-print_loclists.$(OBJEXT) \ dwarfdump-print_loclists_codes.$(OBJEXT) \ dwarfdump-print_locs.$(OBJEXT) \ dwarfdump-print_macinfo.$(OBJEXT) \ dwarfdump-print_macro.$(OBJEXT) \ dwarfdump-print_pubnames.$(OBJEXT) \ dwarfdump-print_ranges.$(OBJEXT) \ dwarfdump-print_rnglists.$(OBJEXT) \ dwarfdump-print_reloc.$(OBJEXT) \ dwarfdump-print_section_groups.$(OBJEXT) \ dwarfdump-print_sections.$(OBJEXT) \ dwarfdump-print_static_funcs.$(OBJEXT) \ dwarfdump-print_static_vars.$(OBJEXT) \ dwarfdump-print_str_offsets.$(OBJEXT) \ dwarfdump-print_strings.$(OBJEXT) \ dwarfdump-print_tag_attributes_usage.$(OBJEXT) \ dwarfdump-print_types.$(OBJEXT) \ dwarfdump-print_weaknames.$(OBJEXT) \ dwarfdump-sanitized.$(OBJEXT) \ dwarfdump-section_bitmaps.$(OBJEXT) \ dwarfdump-strstrnocase.$(OBJEXT) \ dwarfdump-true_section_name.$(OBJEXT) dwarfdump-uri.$(OBJEXT) dwarfdump_OBJECTS = $(am_dwarfdump_OBJECTS) dwarfdump_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dwarfdump_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dwarfdump_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dwarfdump-addrmap.Po \ ./$(DEPDIR)/dwarfdump-attr_form.Po \ ./$(DEPDIR)/dwarfdump-checkutil.Po \ ./$(DEPDIR)/dwarfdump-command_options.Po \ ./$(DEPDIR)/dwarfdump-common.Po \ ./$(DEPDIR)/dwarfdump-compiler_info.Po \ ./$(DEPDIR)/dwarfdump-dwarf_names.Po \ ./$(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po \ ./$(DEPDIR)/dwarfdump-dwarfdump.Po \ ./$(DEPDIR)/dwarfdump-dwconf.Po \ ./$(DEPDIR)/dwarfdump-dwgetopt.Po ./$(DEPDIR)/dwarfdump-esb.Po \ ./$(DEPDIR)/dwarfdump-glflags.Po \ ./$(DEPDIR)/dwarfdump-helpertree.Po \ ./$(DEPDIR)/dwarfdump-macrocheck.Po \ ./$(DEPDIR)/dwarfdump-makename.Po \ ./$(DEPDIR)/dwarfdump-naming.Po \ ./$(DEPDIR)/dwarfdump-opscounttab.Po \ ./$(DEPDIR)/dwarfdump-print_abbrevs.Po \ ./$(DEPDIR)/dwarfdump-print_aranges.Po \ ./$(DEPDIR)/dwarfdump-print_debug_gnu.Po \ ./$(DEPDIR)/dwarfdump-print_debug_names.Po \ ./$(DEPDIR)/dwarfdump-print_debug_sup.Po \ ./$(DEPDIR)/dwarfdump-print_debugfission.Po \ ./$(DEPDIR)/dwarfdump-print_die.Po \ ./$(DEPDIR)/dwarfdump-print_frames.Po \ ./$(DEPDIR)/dwarfdump-print_gdbindex.Po \ ./$(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po \ ./$(DEPDIR)/dwarfdump-print_lines.Po \ ./$(DEPDIR)/dwarfdump-print_llex_codes.Po \ ./$(DEPDIR)/dwarfdump-print_loclists.Po \ ./$(DEPDIR)/dwarfdump-print_loclists_codes.Po \ ./$(DEPDIR)/dwarfdump-print_locs.Po \ ./$(DEPDIR)/dwarfdump-print_macinfo.Po \ ./$(DEPDIR)/dwarfdump-print_macro.Po \ ./$(DEPDIR)/dwarfdump-print_origloclist_codes.Po \ ./$(DEPDIR)/dwarfdump-print_pubnames.Po \ ./$(DEPDIR)/dwarfdump-print_ranges.Po \ ./$(DEPDIR)/dwarfdump-print_reloc.Po \ ./$(DEPDIR)/dwarfdump-print_rnglists.Po \ ./$(DEPDIR)/dwarfdump-print_section_groups.Po \ ./$(DEPDIR)/dwarfdump-print_sections.Po \ ./$(DEPDIR)/dwarfdump-print_static_funcs.Po \ ./$(DEPDIR)/dwarfdump-print_static_vars.Po \ ./$(DEPDIR)/dwarfdump-print_str_offsets.Po \ ./$(DEPDIR)/dwarfdump-print_strings.Po \ ./$(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po \ ./$(DEPDIR)/dwarfdump-print_types.Po \ ./$(DEPDIR)/dwarfdump-print_weaknames.Po \ ./$(DEPDIR)/dwarfdump-sanitized.Po \ ./$(DEPDIR)/dwarfdump-section_bitmaps.Po \ ./$(DEPDIR)/dwarfdump-strstrnocase.Po \ ./$(DEPDIR)/dwarfdump-true_section_name.Po \ ./$(DEPDIR)/dwarfdump-uri.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dwarfdump_SOURCES) DIST_SOURCES = $(dwarfdump_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(dwarfdumpdev_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver COPYING ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_BIGENDIAN = @DWARF_BIGENDIAN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects dwarfdump_SOURCES = \ addrmap.c \ addrmap.h \ attr_form.h \ attr_form.c \ checkutil.c \ checkutil.h \ command_options.c \ command_options.h \ common.c \ common.h \ compiler_info.c \ compiler_info.h \ defined_types.h \ dwarfdump.c \ dwarfdump-af-table.h\ dwarfdump-tt-table.h\ dwarfdump-ta-table.h\ dwarfdump-tt-ext-table.h\ dwarfdump-ta-ext-table.h\ dwarf_names.c \ dwarf_names.h \ dwarf_tsearchbal.c \ dwarf_tsearch.h \ dwconf.c \ dwconf.h \ dwconf_using_functions.h \ dwgetopt.c \ dwgetopt.h \ esb.c \ esb.h \ esb_using_functions.h \ glflags.c \ glflags.h \ globals.h \ helpertree.c \ helpertree.h \ macrocheck.c \ macrocheck.h \ makename.c \ makename.h \ naming.c \ naming.h \ opscounttab.c \ opscounttab.h \ print_abbrevs.c \ print_aranges.c \ print_debugfission.c \ print_die.c \ print_debug_gnu.c \ print_debug_gnu.h \ print_debug_names.c \ print_debug_sup.c \ print_frames.c \ print_frames.h \ print_gdbindex.c \ print_hipc_lopc_attr.c \ print_lines.c \ print_llex_codes.c \ print_origloclist_codes.c \ print_loclists.c \ print_loclists_codes.c \ print_locs.c \ print_macinfo.c \ print_macro.c \ print_pubnames.c \ print_ranges.c \ print_rnglists.c \ print_reloc.c \ print_reloc.h \ print_section_groups.c \ print_sections.c \ print_sections.h \ print_static_funcs.c \ print_static_vars.c \ print_str_offsets.c \ print_strings.c \ print_tag_attributes_usage.c \ print_types.c \ print_weaknames.c \ sanitized.c \ sanitized.h \ section_bitmaps.c \ section_bitmaps.h \ strstrnocase.c \ true_section_name.c \ tag_common.h \ uri.c \ uri.h \ warningcontrol.h dwarfdump_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf dwarfdump_CFLAGS = $(DWARF_CFLAGS_WARN) "-DCONFPREFIX=@prefix@/share/dwarfdump" dwarfdump_LDADD = \ $(top_builddir)/libdwarf/libdwarf.la \ @DWARF_LIBS@ TESTS = runtests.sh AM_TESTS_ENVIRONMENT = DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR ; DWCOMPILERFLAGS='$(DWARF_CFLAGS_WARN)'; export DWCOMPILERFLAGS ; man_MANS = dwarfdump.1 dwarfdumpdevdir = $(datadir)/dwarfdump dwarfdumpdev_DATA = dwarfdump.conf EXTRA_DIST = \ $(man_MANS) \ COPYING \ DWARFDUMPCOPYRIGHT \ GPL.txt \ ChangeLog \ ChangeLog2006 \ ChangeLog2007 \ ChangeLog2008 \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ NEWS \ README \ README.testcases \ CODINGSTYLE \ attr_form_build.c \ buildopscounttab.c \ print_reloc_decls.h \ makename_test.c \ section_bitmaps_test.c \ helpertree_test.c \ print_reloc_test.c \ getopttest.c \ tag_common.c \ testesb.c \ test-mach-o-32.dSYM \ test-mach-o-32.base \ testobjLE32PE.exe \ testuriLE64ELf.obj \ testobjLE32PE.base \ testuriLE64ELf.base \ testobjLE32PE.test.c \ $(dwarfdumpdev_DATA) \ tag_attr.c \ tag_tree.c \ attr_formclass.list \ attr_formclass_ext.list \ tag_attr.list \ tag_attr_ext.list \ tag_tree.list \ tag_tree_ext.list CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfdump/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfdump/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dwarfdump$(EXEEXT): $(dwarfdump_OBJECTS) $(dwarfdump_DEPENDENCIES) $(EXTRA_dwarfdump_DEPENDENCIES) @rm -f dwarfdump$(EXEEXT) $(AM_V_CCLD)$(dwarfdump_LINK) $(dwarfdump_OBJECTS) $(dwarfdump_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-addrmap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-attr_form.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-checkutil.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-command_options.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-common.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-compiler_info.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarf_names.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarfdump.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwconf.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwgetopt.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-esb.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-glflags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-helpertree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-macrocheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-makename.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-naming.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-opscounttab.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_abbrevs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_aranges.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_debug_gnu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_debug_names.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_debug_sup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_debugfission.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_die.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_frames.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_gdbindex.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_lines.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_llex_codes.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_loclists.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_loclists_codes.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_locs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_macinfo.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_macro.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_origloclist_codes.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_pubnames.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_ranges.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_reloc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_rnglists.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_section_groups.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_sections.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_static_funcs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_static_vars.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_str_offsets.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_strings.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_types.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_weaknames.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-sanitized.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-section_bitmaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-strstrnocase.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-true_section_name.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-uri.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< dwarfdump-addrmap.o: addrmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-addrmap.o -MD -MP -MF $(DEPDIR)/dwarfdump-addrmap.Tpo -c -o dwarfdump-addrmap.o `test -f 'addrmap.c' || echo '$(srcdir)/'`addrmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-addrmap.Tpo $(DEPDIR)/dwarfdump-addrmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='addrmap.c' object='dwarfdump-addrmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-addrmap.o `test -f 'addrmap.c' || echo '$(srcdir)/'`addrmap.c dwarfdump-addrmap.obj: addrmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-addrmap.obj -MD -MP -MF $(DEPDIR)/dwarfdump-addrmap.Tpo -c -o dwarfdump-addrmap.obj `if test -f 'addrmap.c'; then $(CYGPATH_W) 'addrmap.c'; else $(CYGPATH_W) '$(srcdir)/addrmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-addrmap.Tpo $(DEPDIR)/dwarfdump-addrmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='addrmap.c' object='dwarfdump-addrmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-addrmap.obj `if test -f 'addrmap.c'; then $(CYGPATH_W) 'addrmap.c'; else $(CYGPATH_W) '$(srcdir)/addrmap.c'; fi` dwarfdump-attr_form.o: attr_form.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-attr_form.o -MD -MP -MF $(DEPDIR)/dwarfdump-attr_form.Tpo -c -o dwarfdump-attr_form.o `test -f 'attr_form.c' || echo '$(srcdir)/'`attr_form.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-attr_form.Tpo $(DEPDIR)/dwarfdump-attr_form.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='attr_form.c' object='dwarfdump-attr_form.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-attr_form.o `test -f 'attr_form.c' || echo '$(srcdir)/'`attr_form.c dwarfdump-attr_form.obj: attr_form.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-attr_form.obj -MD -MP -MF $(DEPDIR)/dwarfdump-attr_form.Tpo -c -o dwarfdump-attr_form.obj `if test -f 'attr_form.c'; then $(CYGPATH_W) 'attr_form.c'; else $(CYGPATH_W) '$(srcdir)/attr_form.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-attr_form.Tpo $(DEPDIR)/dwarfdump-attr_form.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='attr_form.c' object='dwarfdump-attr_form.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-attr_form.obj `if test -f 'attr_form.c'; then $(CYGPATH_W) 'attr_form.c'; else $(CYGPATH_W) '$(srcdir)/attr_form.c'; fi` dwarfdump-checkutil.o: checkutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-checkutil.o -MD -MP -MF $(DEPDIR)/dwarfdump-checkutil.Tpo -c -o dwarfdump-checkutil.o `test -f 'checkutil.c' || echo '$(srcdir)/'`checkutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-checkutil.Tpo $(DEPDIR)/dwarfdump-checkutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkutil.c' object='dwarfdump-checkutil.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-checkutil.o `test -f 'checkutil.c' || echo '$(srcdir)/'`checkutil.c dwarfdump-checkutil.obj: checkutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-checkutil.obj -MD -MP -MF $(DEPDIR)/dwarfdump-checkutil.Tpo -c -o dwarfdump-checkutil.obj `if test -f 'checkutil.c'; then $(CYGPATH_W) 'checkutil.c'; else $(CYGPATH_W) '$(srcdir)/checkutil.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-checkutil.Tpo $(DEPDIR)/dwarfdump-checkutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkutil.c' object='dwarfdump-checkutil.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-checkutil.obj `if test -f 'checkutil.c'; then $(CYGPATH_W) 'checkutil.c'; else $(CYGPATH_W) '$(srcdir)/checkutil.c'; fi` dwarfdump-command_options.o: command_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-command_options.o -MD -MP -MF $(DEPDIR)/dwarfdump-command_options.Tpo -c -o dwarfdump-command_options.o `test -f 'command_options.c' || echo '$(srcdir)/'`command_options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-command_options.Tpo $(DEPDIR)/dwarfdump-command_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='command_options.c' object='dwarfdump-command_options.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-command_options.o `test -f 'command_options.c' || echo '$(srcdir)/'`command_options.c dwarfdump-command_options.obj: command_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-command_options.obj -MD -MP -MF $(DEPDIR)/dwarfdump-command_options.Tpo -c -o dwarfdump-command_options.obj `if test -f 'command_options.c'; then $(CYGPATH_W) 'command_options.c'; else $(CYGPATH_W) '$(srcdir)/command_options.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-command_options.Tpo $(DEPDIR)/dwarfdump-command_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='command_options.c' object='dwarfdump-command_options.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-command_options.obj `if test -f 'command_options.c'; then $(CYGPATH_W) 'command_options.c'; else $(CYGPATH_W) '$(srcdir)/command_options.c'; fi` dwarfdump-common.o: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-common.o -MD -MP -MF $(DEPDIR)/dwarfdump-common.Tpo -c -o dwarfdump-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-common.Tpo $(DEPDIR)/dwarfdump-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='dwarfdump-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c dwarfdump-common.obj: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-common.obj -MD -MP -MF $(DEPDIR)/dwarfdump-common.Tpo -c -o dwarfdump-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-common.Tpo $(DEPDIR)/dwarfdump-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='dwarfdump-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` dwarfdump-compiler_info.o: compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-compiler_info.o -MD -MP -MF $(DEPDIR)/dwarfdump-compiler_info.Tpo -c -o dwarfdump-compiler_info.o `test -f 'compiler_info.c' || echo '$(srcdir)/'`compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-compiler_info.Tpo $(DEPDIR)/dwarfdump-compiler_info.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compiler_info.c' object='dwarfdump-compiler_info.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-compiler_info.o `test -f 'compiler_info.c' || echo '$(srcdir)/'`compiler_info.c dwarfdump-compiler_info.obj: compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-compiler_info.obj -MD -MP -MF $(DEPDIR)/dwarfdump-compiler_info.Tpo -c -o dwarfdump-compiler_info.obj `if test -f 'compiler_info.c'; then $(CYGPATH_W) 'compiler_info.c'; else $(CYGPATH_W) '$(srcdir)/compiler_info.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-compiler_info.Tpo $(DEPDIR)/dwarfdump-compiler_info.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compiler_info.c' object='dwarfdump-compiler_info.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-compiler_info.obj `if test -f 'compiler_info.c'; then $(CYGPATH_W) 'compiler_info.c'; else $(CYGPATH_W) '$(srcdir)/compiler_info.c'; fi` dwarfdump-dwarfdump.o: dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarfdump.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarfdump.Tpo -c -o dwarfdump-dwarfdump.o `test -f 'dwarfdump.c' || echo '$(srcdir)/'`dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarfdump.Tpo $(DEPDIR)/dwarfdump-dwarfdump.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfdump.c' object='dwarfdump-dwarfdump.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarfdump.o `test -f 'dwarfdump.c' || echo '$(srcdir)/'`dwarfdump.c dwarfdump-dwarfdump.obj: dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarfdump.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarfdump.Tpo -c -o dwarfdump-dwarfdump.obj `if test -f 'dwarfdump.c'; then $(CYGPATH_W) 'dwarfdump.c'; else $(CYGPATH_W) '$(srcdir)/dwarfdump.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarfdump.Tpo $(DEPDIR)/dwarfdump-dwarfdump.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfdump.c' object='dwarfdump-dwarfdump.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarfdump.obj `if test -f 'dwarfdump.c'; then $(CYGPATH_W) 'dwarfdump.c'; else $(CYGPATH_W) '$(srcdir)/dwarfdump.c'; fi` dwarfdump-dwarf_names.o: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_names.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_names.Tpo -c -o dwarfdump-dwarf_names.o `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_names.Tpo $(DEPDIR)/dwarfdump-dwarf_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='dwarfdump-dwarf_names.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_names.o `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c dwarfdump-dwarf_names.obj: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_names.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_names.Tpo -c -o dwarfdump-dwarf_names.obj `if test -f 'dwarf_names.c'; then $(CYGPATH_W) 'dwarf_names.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_names.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_names.Tpo $(DEPDIR)/dwarfdump-dwarf_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='dwarfdump-dwarf_names.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_names.obj `if test -f 'dwarf_names.c'; then $(CYGPATH_W) 'dwarf_names.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_names.c'; fi` dwarfdump-dwarf_tsearchbal.o: dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_tsearchbal.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo -c -o dwarfdump-dwarf_tsearchbal.o `test -f 'dwarf_tsearchbal.c' || echo '$(srcdir)/'`dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchbal.c' object='dwarfdump-dwarf_tsearchbal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_tsearchbal.o `test -f 'dwarf_tsearchbal.c' || echo '$(srcdir)/'`dwarf_tsearchbal.c dwarfdump-dwarf_tsearchbal.obj: dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_tsearchbal.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo -c -o dwarfdump-dwarf_tsearchbal.obj `if test -f 'dwarf_tsearchbal.c'; then $(CYGPATH_W) 'dwarf_tsearchbal.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_tsearchbal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchbal.c' object='dwarfdump-dwarf_tsearchbal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_tsearchbal.obj `if test -f 'dwarf_tsearchbal.c'; then $(CYGPATH_W) 'dwarf_tsearchbal.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_tsearchbal.c'; fi` dwarfdump-dwconf.o: dwconf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwconf.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwconf.Tpo -c -o dwarfdump-dwconf.o `test -f 'dwconf.c' || echo '$(srcdir)/'`dwconf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwconf.Tpo $(DEPDIR)/dwarfdump-dwconf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwconf.c' object='dwarfdump-dwconf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwconf.o `test -f 'dwconf.c' || echo '$(srcdir)/'`dwconf.c dwarfdump-dwconf.obj: dwconf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwconf.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwconf.Tpo -c -o dwarfdump-dwconf.obj `if test -f 'dwconf.c'; then $(CYGPATH_W) 'dwconf.c'; else $(CYGPATH_W) '$(srcdir)/dwconf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwconf.Tpo $(DEPDIR)/dwarfdump-dwconf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwconf.c' object='dwarfdump-dwconf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwconf.obj `if test -f 'dwconf.c'; then $(CYGPATH_W) 'dwconf.c'; else $(CYGPATH_W) '$(srcdir)/dwconf.c'; fi` dwarfdump-dwgetopt.o: dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwgetopt.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwgetopt.Tpo -c -o dwarfdump-dwgetopt.o `test -f 'dwgetopt.c' || echo '$(srcdir)/'`dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwgetopt.Tpo $(DEPDIR)/dwarfdump-dwgetopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwgetopt.c' object='dwarfdump-dwgetopt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwgetopt.o `test -f 'dwgetopt.c' || echo '$(srcdir)/'`dwgetopt.c dwarfdump-dwgetopt.obj: dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwgetopt.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwgetopt.Tpo -c -o dwarfdump-dwgetopt.obj `if test -f 'dwgetopt.c'; then $(CYGPATH_W) 'dwgetopt.c'; else $(CYGPATH_W) '$(srcdir)/dwgetopt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwgetopt.Tpo $(DEPDIR)/dwarfdump-dwgetopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwgetopt.c' object='dwarfdump-dwgetopt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwgetopt.obj `if test -f 'dwgetopt.c'; then $(CYGPATH_W) 'dwgetopt.c'; else $(CYGPATH_W) '$(srcdir)/dwgetopt.c'; fi` dwarfdump-esb.o: esb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-esb.o -MD -MP -MF $(DEPDIR)/dwarfdump-esb.Tpo -c -o dwarfdump-esb.o `test -f 'esb.c' || echo '$(srcdir)/'`esb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-esb.Tpo $(DEPDIR)/dwarfdump-esb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esb.c' object='dwarfdump-esb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-esb.o `test -f 'esb.c' || echo '$(srcdir)/'`esb.c dwarfdump-esb.obj: esb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-esb.obj -MD -MP -MF $(DEPDIR)/dwarfdump-esb.Tpo -c -o dwarfdump-esb.obj `if test -f 'esb.c'; then $(CYGPATH_W) 'esb.c'; else $(CYGPATH_W) '$(srcdir)/esb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-esb.Tpo $(DEPDIR)/dwarfdump-esb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esb.c' object='dwarfdump-esb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-esb.obj `if test -f 'esb.c'; then $(CYGPATH_W) 'esb.c'; else $(CYGPATH_W) '$(srcdir)/esb.c'; fi` dwarfdump-glflags.o: glflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-glflags.o -MD -MP -MF $(DEPDIR)/dwarfdump-glflags.Tpo -c -o dwarfdump-glflags.o `test -f 'glflags.c' || echo '$(srcdir)/'`glflags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-glflags.Tpo $(DEPDIR)/dwarfdump-glflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glflags.c' object='dwarfdump-glflags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-glflags.o `test -f 'glflags.c' || echo '$(srcdir)/'`glflags.c dwarfdump-glflags.obj: glflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-glflags.obj -MD -MP -MF $(DEPDIR)/dwarfdump-glflags.Tpo -c -o dwarfdump-glflags.obj `if test -f 'glflags.c'; then $(CYGPATH_W) 'glflags.c'; else $(CYGPATH_W) '$(srcdir)/glflags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-glflags.Tpo $(DEPDIR)/dwarfdump-glflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glflags.c' object='dwarfdump-glflags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-glflags.obj `if test -f 'glflags.c'; then $(CYGPATH_W) 'glflags.c'; else $(CYGPATH_W) '$(srcdir)/glflags.c'; fi` dwarfdump-helpertree.o: helpertree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-helpertree.o -MD -MP -MF $(DEPDIR)/dwarfdump-helpertree.Tpo -c -o dwarfdump-helpertree.o `test -f 'helpertree.c' || echo '$(srcdir)/'`helpertree.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-helpertree.Tpo $(DEPDIR)/dwarfdump-helpertree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpertree.c' object='dwarfdump-helpertree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-helpertree.o `test -f 'helpertree.c' || echo '$(srcdir)/'`helpertree.c dwarfdump-helpertree.obj: helpertree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-helpertree.obj -MD -MP -MF $(DEPDIR)/dwarfdump-helpertree.Tpo -c -o dwarfdump-helpertree.obj `if test -f 'helpertree.c'; then $(CYGPATH_W) 'helpertree.c'; else $(CYGPATH_W) '$(srcdir)/helpertree.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-helpertree.Tpo $(DEPDIR)/dwarfdump-helpertree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpertree.c' object='dwarfdump-helpertree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-helpertree.obj `if test -f 'helpertree.c'; then $(CYGPATH_W) 'helpertree.c'; else $(CYGPATH_W) '$(srcdir)/helpertree.c'; fi` dwarfdump-macrocheck.o: macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-macrocheck.o -MD -MP -MF $(DEPDIR)/dwarfdump-macrocheck.Tpo -c -o dwarfdump-macrocheck.o `test -f 'macrocheck.c' || echo '$(srcdir)/'`macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-macrocheck.Tpo $(DEPDIR)/dwarfdump-macrocheck.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macrocheck.c' object='dwarfdump-macrocheck.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-macrocheck.o `test -f 'macrocheck.c' || echo '$(srcdir)/'`macrocheck.c dwarfdump-macrocheck.obj: macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-macrocheck.obj -MD -MP -MF $(DEPDIR)/dwarfdump-macrocheck.Tpo -c -o dwarfdump-macrocheck.obj `if test -f 'macrocheck.c'; then $(CYGPATH_W) 'macrocheck.c'; else $(CYGPATH_W) '$(srcdir)/macrocheck.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-macrocheck.Tpo $(DEPDIR)/dwarfdump-macrocheck.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macrocheck.c' object='dwarfdump-macrocheck.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-macrocheck.obj `if test -f 'macrocheck.c'; then $(CYGPATH_W) 'macrocheck.c'; else $(CYGPATH_W) '$(srcdir)/macrocheck.c'; fi` dwarfdump-makename.o: makename.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-makename.o -MD -MP -MF $(DEPDIR)/dwarfdump-makename.Tpo -c -o dwarfdump-makename.o `test -f 'makename.c' || echo '$(srcdir)/'`makename.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-makename.Tpo $(DEPDIR)/dwarfdump-makename.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='makename.c' object='dwarfdump-makename.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-makename.o `test -f 'makename.c' || echo '$(srcdir)/'`makename.c dwarfdump-makename.obj: makename.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-makename.obj -MD -MP -MF $(DEPDIR)/dwarfdump-makename.Tpo -c -o dwarfdump-makename.obj `if test -f 'makename.c'; then $(CYGPATH_W) 'makename.c'; else $(CYGPATH_W) '$(srcdir)/makename.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-makename.Tpo $(DEPDIR)/dwarfdump-makename.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='makename.c' object='dwarfdump-makename.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-makename.obj `if test -f 'makename.c'; then $(CYGPATH_W) 'makename.c'; else $(CYGPATH_W) '$(srcdir)/makename.c'; fi` dwarfdump-naming.o: naming.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-naming.o -MD -MP -MF $(DEPDIR)/dwarfdump-naming.Tpo -c -o dwarfdump-naming.o `test -f 'naming.c' || echo '$(srcdir)/'`naming.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-naming.Tpo $(DEPDIR)/dwarfdump-naming.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='naming.c' object='dwarfdump-naming.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-naming.o `test -f 'naming.c' || echo '$(srcdir)/'`naming.c dwarfdump-naming.obj: naming.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-naming.obj -MD -MP -MF $(DEPDIR)/dwarfdump-naming.Tpo -c -o dwarfdump-naming.obj `if test -f 'naming.c'; then $(CYGPATH_W) 'naming.c'; else $(CYGPATH_W) '$(srcdir)/naming.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-naming.Tpo $(DEPDIR)/dwarfdump-naming.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='naming.c' object='dwarfdump-naming.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-naming.obj `if test -f 'naming.c'; then $(CYGPATH_W) 'naming.c'; else $(CYGPATH_W) '$(srcdir)/naming.c'; fi` dwarfdump-opscounttab.o: opscounttab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-opscounttab.o -MD -MP -MF $(DEPDIR)/dwarfdump-opscounttab.Tpo -c -o dwarfdump-opscounttab.o `test -f 'opscounttab.c' || echo '$(srcdir)/'`opscounttab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-opscounttab.Tpo $(DEPDIR)/dwarfdump-opscounttab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opscounttab.c' object='dwarfdump-opscounttab.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-opscounttab.o `test -f 'opscounttab.c' || echo '$(srcdir)/'`opscounttab.c dwarfdump-opscounttab.obj: opscounttab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-opscounttab.obj -MD -MP -MF $(DEPDIR)/dwarfdump-opscounttab.Tpo -c -o dwarfdump-opscounttab.obj `if test -f 'opscounttab.c'; then $(CYGPATH_W) 'opscounttab.c'; else $(CYGPATH_W) '$(srcdir)/opscounttab.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-opscounttab.Tpo $(DEPDIR)/dwarfdump-opscounttab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opscounttab.c' object='dwarfdump-opscounttab.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-opscounttab.obj `if test -f 'opscounttab.c'; then $(CYGPATH_W) 'opscounttab.c'; else $(CYGPATH_W) '$(srcdir)/opscounttab.c'; fi` dwarfdump-print_abbrevs.o: print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_abbrevs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_abbrevs.Tpo -c -o dwarfdump-print_abbrevs.o `test -f 'print_abbrevs.c' || echo '$(srcdir)/'`print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_abbrevs.Tpo $(DEPDIR)/dwarfdump-print_abbrevs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_abbrevs.c' object='dwarfdump-print_abbrevs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_abbrevs.o `test -f 'print_abbrevs.c' || echo '$(srcdir)/'`print_abbrevs.c dwarfdump-print_abbrevs.obj: print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_abbrevs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_abbrevs.Tpo -c -o dwarfdump-print_abbrevs.obj `if test -f 'print_abbrevs.c'; then $(CYGPATH_W) 'print_abbrevs.c'; else $(CYGPATH_W) '$(srcdir)/print_abbrevs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_abbrevs.Tpo $(DEPDIR)/dwarfdump-print_abbrevs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_abbrevs.c' object='dwarfdump-print_abbrevs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_abbrevs.obj `if test -f 'print_abbrevs.c'; then $(CYGPATH_W) 'print_abbrevs.c'; else $(CYGPATH_W) '$(srcdir)/print_abbrevs.c'; fi` dwarfdump-print_aranges.o: print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_aranges.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_aranges.Tpo -c -o dwarfdump-print_aranges.o `test -f 'print_aranges.c' || echo '$(srcdir)/'`print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_aranges.Tpo $(DEPDIR)/dwarfdump-print_aranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_aranges.c' object='dwarfdump-print_aranges.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_aranges.o `test -f 'print_aranges.c' || echo '$(srcdir)/'`print_aranges.c dwarfdump-print_aranges.obj: print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_aranges.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_aranges.Tpo -c -o dwarfdump-print_aranges.obj `if test -f 'print_aranges.c'; then $(CYGPATH_W) 'print_aranges.c'; else $(CYGPATH_W) '$(srcdir)/print_aranges.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_aranges.Tpo $(DEPDIR)/dwarfdump-print_aranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_aranges.c' object='dwarfdump-print_aranges.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_aranges.obj `if test -f 'print_aranges.c'; then $(CYGPATH_W) 'print_aranges.c'; else $(CYGPATH_W) '$(srcdir)/print_aranges.c'; fi` dwarfdump-print_debugfission.o: print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debugfission.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_debugfission.Tpo -c -o dwarfdump-print_debugfission.o `test -f 'print_debugfission.c' || echo '$(srcdir)/'`print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debugfission.Tpo $(DEPDIR)/dwarfdump-print_debugfission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debugfission.c' object='dwarfdump-print_debugfission.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debugfission.o `test -f 'print_debugfission.c' || echo '$(srcdir)/'`print_debugfission.c dwarfdump-print_debugfission.obj: print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debugfission.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_debugfission.Tpo -c -o dwarfdump-print_debugfission.obj `if test -f 'print_debugfission.c'; then $(CYGPATH_W) 'print_debugfission.c'; else $(CYGPATH_W) '$(srcdir)/print_debugfission.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debugfission.Tpo $(DEPDIR)/dwarfdump-print_debugfission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debugfission.c' object='dwarfdump-print_debugfission.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debugfission.obj `if test -f 'print_debugfission.c'; then $(CYGPATH_W) 'print_debugfission.c'; else $(CYGPATH_W) '$(srcdir)/print_debugfission.c'; fi` dwarfdump-print_die.o: print_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_die.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_die.Tpo -c -o dwarfdump-print_die.o `test -f 'print_die.c' || echo '$(srcdir)/'`print_die.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_die.Tpo $(DEPDIR)/dwarfdump-print_die.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_die.c' object='dwarfdump-print_die.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_die.o `test -f 'print_die.c' || echo '$(srcdir)/'`print_die.c dwarfdump-print_die.obj: print_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_die.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_die.Tpo -c -o dwarfdump-print_die.obj `if test -f 'print_die.c'; then $(CYGPATH_W) 'print_die.c'; else $(CYGPATH_W) '$(srcdir)/print_die.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_die.Tpo $(DEPDIR)/dwarfdump-print_die.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_die.c' object='dwarfdump-print_die.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_die.obj `if test -f 'print_die.c'; then $(CYGPATH_W) 'print_die.c'; else $(CYGPATH_W) '$(srcdir)/print_die.c'; fi` dwarfdump-print_debug_gnu.o: print_debug_gnu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_gnu.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_gnu.Tpo -c -o dwarfdump-print_debug_gnu.o `test -f 'print_debug_gnu.c' || echo '$(srcdir)/'`print_debug_gnu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_gnu.Tpo $(DEPDIR)/dwarfdump-print_debug_gnu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_gnu.c' object='dwarfdump-print_debug_gnu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_gnu.o `test -f 'print_debug_gnu.c' || echo '$(srcdir)/'`print_debug_gnu.c dwarfdump-print_debug_gnu.obj: print_debug_gnu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_gnu.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_gnu.Tpo -c -o dwarfdump-print_debug_gnu.obj `if test -f 'print_debug_gnu.c'; then $(CYGPATH_W) 'print_debug_gnu.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_gnu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_gnu.Tpo $(DEPDIR)/dwarfdump-print_debug_gnu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_gnu.c' object='dwarfdump-print_debug_gnu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_gnu.obj `if test -f 'print_debug_gnu.c'; then $(CYGPATH_W) 'print_debug_gnu.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_gnu.c'; fi` dwarfdump-print_debug_names.o: print_debug_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_names.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_names.Tpo -c -o dwarfdump-print_debug_names.o `test -f 'print_debug_names.c' || echo '$(srcdir)/'`print_debug_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_names.Tpo $(DEPDIR)/dwarfdump-print_debug_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_names.c' object='dwarfdump-print_debug_names.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_names.o `test -f 'print_debug_names.c' || echo '$(srcdir)/'`print_debug_names.c dwarfdump-print_debug_names.obj: print_debug_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_names.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_names.Tpo -c -o dwarfdump-print_debug_names.obj `if test -f 'print_debug_names.c'; then $(CYGPATH_W) 'print_debug_names.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_names.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_names.Tpo $(DEPDIR)/dwarfdump-print_debug_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_names.c' object='dwarfdump-print_debug_names.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_names.obj `if test -f 'print_debug_names.c'; then $(CYGPATH_W) 'print_debug_names.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_names.c'; fi` dwarfdump-print_debug_sup.o: print_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_sup.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_sup.Tpo -c -o dwarfdump-print_debug_sup.o `test -f 'print_debug_sup.c' || echo '$(srcdir)/'`print_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_sup.Tpo $(DEPDIR)/dwarfdump-print_debug_sup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_sup.c' object='dwarfdump-print_debug_sup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_sup.o `test -f 'print_debug_sup.c' || echo '$(srcdir)/'`print_debug_sup.c dwarfdump-print_debug_sup.obj: print_debug_sup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debug_sup.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_debug_sup.Tpo -c -o dwarfdump-print_debug_sup.obj `if test -f 'print_debug_sup.c'; then $(CYGPATH_W) 'print_debug_sup.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_sup.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debug_sup.Tpo $(DEPDIR)/dwarfdump-print_debug_sup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debug_sup.c' object='dwarfdump-print_debug_sup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debug_sup.obj `if test -f 'print_debug_sup.c'; then $(CYGPATH_W) 'print_debug_sup.c'; else $(CYGPATH_W) '$(srcdir)/print_debug_sup.c'; fi` dwarfdump-print_frames.o: print_frames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_frames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_frames.Tpo -c -o dwarfdump-print_frames.o `test -f 'print_frames.c' || echo '$(srcdir)/'`print_frames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_frames.Tpo $(DEPDIR)/dwarfdump-print_frames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_frames.c' object='dwarfdump-print_frames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_frames.o `test -f 'print_frames.c' || echo '$(srcdir)/'`print_frames.c dwarfdump-print_frames.obj: print_frames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_frames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_frames.Tpo -c -o dwarfdump-print_frames.obj `if test -f 'print_frames.c'; then $(CYGPATH_W) 'print_frames.c'; else $(CYGPATH_W) '$(srcdir)/print_frames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_frames.Tpo $(DEPDIR)/dwarfdump-print_frames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_frames.c' object='dwarfdump-print_frames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_frames.obj `if test -f 'print_frames.c'; then $(CYGPATH_W) 'print_frames.c'; else $(CYGPATH_W) '$(srcdir)/print_frames.c'; fi` dwarfdump-print_gdbindex.o: print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_gdbindex.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_gdbindex.Tpo -c -o dwarfdump-print_gdbindex.o `test -f 'print_gdbindex.c' || echo '$(srcdir)/'`print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_gdbindex.Tpo $(DEPDIR)/dwarfdump-print_gdbindex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_gdbindex.c' object='dwarfdump-print_gdbindex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_gdbindex.o `test -f 'print_gdbindex.c' || echo '$(srcdir)/'`print_gdbindex.c dwarfdump-print_gdbindex.obj: print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_gdbindex.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_gdbindex.Tpo -c -o dwarfdump-print_gdbindex.obj `if test -f 'print_gdbindex.c'; then $(CYGPATH_W) 'print_gdbindex.c'; else $(CYGPATH_W) '$(srcdir)/print_gdbindex.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_gdbindex.Tpo $(DEPDIR)/dwarfdump-print_gdbindex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_gdbindex.c' object='dwarfdump-print_gdbindex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_gdbindex.obj `if test -f 'print_gdbindex.c'; then $(CYGPATH_W) 'print_gdbindex.c'; else $(CYGPATH_W) '$(srcdir)/print_gdbindex.c'; fi` dwarfdump-print_hipc_lopc_attr.o: print_hipc_lopc_attr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_hipc_lopc_attr.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Tpo -c -o dwarfdump-print_hipc_lopc_attr.o `test -f 'print_hipc_lopc_attr.c' || echo '$(srcdir)/'`print_hipc_lopc_attr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Tpo $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_hipc_lopc_attr.c' object='dwarfdump-print_hipc_lopc_attr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_hipc_lopc_attr.o `test -f 'print_hipc_lopc_attr.c' || echo '$(srcdir)/'`print_hipc_lopc_attr.c dwarfdump-print_hipc_lopc_attr.obj: print_hipc_lopc_attr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_hipc_lopc_attr.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Tpo -c -o dwarfdump-print_hipc_lopc_attr.obj `if test -f 'print_hipc_lopc_attr.c'; then $(CYGPATH_W) 'print_hipc_lopc_attr.c'; else $(CYGPATH_W) '$(srcdir)/print_hipc_lopc_attr.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Tpo $(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_hipc_lopc_attr.c' object='dwarfdump-print_hipc_lopc_attr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_hipc_lopc_attr.obj `if test -f 'print_hipc_lopc_attr.c'; then $(CYGPATH_W) 'print_hipc_lopc_attr.c'; else $(CYGPATH_W) '$(srcdir)/print_hipc_lopc_attr.c'; fi` dwarfdump-print_lines.o: print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_lines.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_lines.Tpo -c -o dwarfdump-print_lines.o `test -f 'print_lines.c' || echo '$(srcdir)/'`print_lines.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_lines.Tpo $(DEPDIR)/dwarfdump-print_lines.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_lines.c' object='dwarfdump-print_lines.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_lines.o `test -f 'print_lines.c' || echo '$(srcdir)/'`print_lines.c dwarfdump-print_lines.obj: print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_lines.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_lines.Tpo -c -o dwarfdump-print_lines.obj `if test -f 'print_lines.c'; then $(CYGPATH_W) 'print_lines.c'; else $(CYGPATH_W) '$(srcdir)/print_lines.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_lines.Tpo $(DEPDIR)/dwarfdump-print_lines.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_lines.c' object='dwarfdump-print_lines.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_lines.obj `if test -f 'print_lines.c'; then $(CYGPATH_W) 'print_lines.c'; else $(CYGPATH_W) '$(srcdir)/print_lines.c'; fi` dwarfdump-print_llex_codes.o: print_llex_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_llex_codes.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_llex_codes.Tpo -c -o dwarfdump-print_llex_codes.o `test -f 'print_llex_codes.c' || echo '$(srcdir)/'`print_llex_codes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_llex_codes.Tpo $(DEPDIR)/dwarfdump-print_llex_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_llex_codes.c' object='dwarfdump-print_llex_codes.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_llex_codes.o `test -f 'print_llex_codes.c' || echo '$(srcdir)/'`print_llex_codes.c dwarfdump-print_llex_codes.obj: print_llex_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_llex_codes.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_llex_codes.Tpo -c -o dwarfdump-print_llex_codes.obj `if test -f 'print_llex_codes.c'; then $(CYGPATH_W) 'print_llex_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_llex_codes.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_llex_codes.Tpo $(DEPDIR)/dwarfdump-print_llex_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_llex_codes.c' object='dwarfdump-print_llex_codes.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_llex_codes.obj `if test -f 'print_llex_codes.c'; then $(CYGPATH_W) 'print_llex_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_llex_codes.c'; fi` dwarfdump-print_origloclist_codes.o: print_origloclist_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_origloclist_codes.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_origloclist_codes.Tpo -c -o dwarfdump-print_origloclist_codes.o `test -f 'print_origloclist_codes.c' || echo '$(srcdir)/'`print_origloclist_codes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_origloclist_codes.Tpo $(DEPDIR)/dwarfdump-print_origloclist_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_origloclist_codes.c' object='dwarfdump-print_origloclist_codes.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_origloclist_codes.o `test -f 'print_origloclist_codes.c' || echo '$(srcdir)/'`print_origloclist_codes.c dwarfdump-print_origloclist_codes.obj: print_origloclist_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_origloclist_codes.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_origloclist_codes.Tpo -c -o dwarfdump-print_origloclist_codes.obj `if test -f 'print_origloclist_codes.c'; then $(CYGPATH_W) 'print_origloclist_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_origloclist_codes.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_origloclist_codes.Tpo $(DEPDIR)/dwarfdump-print_origloclist_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_origloclist_codes.c' object='dwarfdump-print_origloclist_codes.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_origloclist_codes.obj `if test -f 'print_origloclist_codes.c'; then $(CYGPATH_W) 'print_origloclist_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_origloclist_codes.c'; fi` dwarfdump-print_loclists.o: print_loclists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_loclists.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_loclists.Tpo -c -o dwarfdump-print_loclists.o `test -f 'print_loclists.c' || echo '$(srcdir)/'`print_loclists.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_loclists.Tpo $(DEPDIR)/dwarfdump-print_loclists.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_loclists.c' object='dwarfdump-print_loclists.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_loclists.o `test -f 'print_loclists.c' || echo '$(srcdir)/'`print_loclists.c dwarfdump-print_loclists.obj: print_loclists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_loclists.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_loclists.Tpo -c -o dwarfdump-print_loclists.obj `if test -f 'print_loclists.c'; then $(CYGPATH_W) 'print_loclists.c'; else $(CYGPATH_W) '$(srcdir)/print_loclists.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_loclists.Tpo $(DEPDIR)/dwarfdump-print_loclists.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_loclists.c' object='dwarfdump-print_loclists.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_loclists.obj `if test -f 'print_loclists.c'; then $(CYGPATH_W) 'print_loclists.c'; else $(CYGPATH_W) '$(srcdir)/print_loclists.c'; fi` dwarfdump-print_loclists_codes.o: print_loclists_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_loclists_codes.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_loclists_codes.Tpo -c -o dwarfdump-print_loclists_codes.o `test -f 'print_loclists_codes.c' || echo '$(srcdir)/'`print_loclists_codes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_loclists_codes.Tpo $(DEPDIR)/dwarfdump-print_loclists_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_loclists_codes.c' object='dwarfdump-print_loclists_codes.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_loclists_codes.o `test -f 'print_loclists_codes.c' || echo '$(srcdir)/'`print_loclists_codes.c dwarfdump-print_loclists_codes.obj: print_loclists_codes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_loclists_codes.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_loclists_codes.Tpo -c -o dwarfdump-print_loclists_codes.obj `if test -f 'print_loclists_codes.c'; then $(CYGPATH_W) 'print_loclists_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_loclists_codes.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_loclists_codes.Tpo $(DEPDIR)/dwarfdump-print_loclists_codes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_loclists_codes.c' object='dwarfdump-print_loclists_codes.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_loclists_codes.obj `if test -f 'print_loclists_codes.c'; then $(CYGPATH_W) 'print_loclists_codes.c'; else $(CYGPATH_W) '$(srcdir)/print_loclists_codes.c'; fi` dwarfdump-print_locs.o: print_locs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_locs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_locs.Tpo -c -o dwarfdump-print_locs.o `test -f 'print_locs.c' || echo '$(srcdir)/'`print_locs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_locs.Tpo $(DEPDIR)/dwarfdump-print_locs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_locs.c' object='dwarfdump-print_locs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_locs.o `test -f 'print_locs.c' || echo '$(srcdir)/'`print_locs.c dwarfdump-print_locs.obj: print_locs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_locs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_locs.Tpo -c -o dwarfdump-print_locs.obj `if test -f 'print_locs.c'; then $(CYGPATH_W) 'print_locs.c'; else $(CYGPATH_W) '$(srcdir)/print_locs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_locs.Tpo $(DEPDIR)/dwarfdump-print_locs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_locs.c' object='dwarfdump-print_locs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_locs.obj `if test -f 'print_locs.c'; then $(CYGPATH_W) 'print_locs.c'; else $(CYGPATH_W) '$(srcdir)/print_locs.c'; fi` dwarfdump-print_macinfo.o: print_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macinfo.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_macinfo.Tpo -c -o dwarfdump-print_macinfo.o `test -f 'print_macinfo.c' || echo '$(srcdir)/'`print_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macinfo.Tpo $(DEPDIR)/dwarfdump-print_macinfo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macinfo.c' object='dwarfdump-print_macinfo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macinfo.o `test -f 'print_macinfo.c' || echo '$(srcdir)/'`print_macinfo.c dwarfdump-print_macinfo.obj: print_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macinfo.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_macinfo.Tpo -c -o dwarfdump-print_macinfo.obj `if test -f 'print_macinfo.c'; then $(CYGPATH_W) 'print_macinfo.c'; else $(CYGPATH_W) '$(srcdir)/print_macinfo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macinfo.Tpo $(DEPDIR)/dwarfdump-print_macinfo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macinfo.c' object='dwarfdump-print_macinfo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macinfo.obj `if test -f 'print_macinfo.c'; then $(CYGPATH_W) 'print_macinfo.c'; else $(CYGPATH_W) '$(srcdir)/print_macinfo.c'; fi` dwarfdump-print_macro.o: print_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macro.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_macro.Tpo -c -o dwarfdump-print_macro.o `test -f 'print_macro.c' || echo '$(srcdir)/'`print_macro.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macro.Tpo $(DEPDIR)/dwarfdump-print_macro.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macro.c' object='dwarfdump-print_macro.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macro.o `test -f 'print_macro.c' || echo '$(srcdir)/'`print_macro.c dwarfdump-print_macro.obj: print_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macro.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_macro.Tpo -c -o dwarfdump-print_macro.obj `if test -f 'print_macro.c'; then $(CYGPATH_W) 'print_macro.c'; else $(CYGPATH_W) '$(srcdir)/print_macro.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macro.Tpo $(DEPDIR)/dwarfdump-print_macro.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macro.c' object='dwarfdump-print_macro.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macro.obj `if test -f 'print_macro.c'; then $(CYGPATH_W) 'print_macro.c'; else $(CYGPATH_W) '$(srcdir)/print_macro.c'; fi` dwarfdump-print_pubnames.o: print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_pubnames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_pubnames.Tpo -c -o dwarfdump-print_pubnames.o `test -f 'print_pubnames.c' || echo '$(srcdir)/'`print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_pubnames.Tpo $(DEPDIR)/dwarfdump-print_pubnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_pubnames.c' object='dwarfdump-print_pubnames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_pubnames.o `test -f 'print_pubnames.c' || echo '$(srcdir)/'`print_pubnames.c dwarfdump-print_pubnames.obj: print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_pubnames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_pubnames.Tpo -c -o dwarfdump-print_pubnames.obj `if test -f 'print_pubnames.c'; then $(CYGPATH_W) 'print_pubnames.c'; else $(CYGPATH_W) '$(srcdir)/print_pubnames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_pubnames.Tpo $(DEPDIR)/dwarfdump-print_pubnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_pubnames.c' object='dwarfdump-print_pubnames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_pubnames.obj `if test -f 'print_pubnames.c'; then $(CYGPATH_W) 'print_pubnames.c'; else $(CYGPATH_W) '$(srcdir)/print_pubnames.c'; fi` dwarfdump-print_ranges.o: print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_ranges.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_ranges.Tpo -c -o dwarfdump-print_ranges.o `test -f 'print_ranges.c' || echo '$(srcdir)/'`print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_ranges.Tpo $(DEPDIR)/dwarfdump-print_ranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_ranges.c' object='dwarfdump-print_ranges.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_ranges.o `test -f 'print_ranges.c' || echo '$(srcdir)/'`print_ranges.c dwarfdump-print_ranges.obj: print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_ranges.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_ranges.Tpo -c -o dwarfdump-print_ranges.obj `if test -f 'print_ranges.c'; then $(CYGPATH_W) 'print_ranges.c'; else $(CYGPATH_W) '$(srcdir)/print_ranges.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_ranges.Tpo $(DEPDIR)/dwarfdump-print_ranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_ranges.c' object='dwarfdump-print_ranges.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_ranges.obj `if test -f 'print_ranges.c'; then $(CYGPATH_W) 'print_ranges.c'; else $(CYGPATH_W) '$(srcdir)/print_ranges.c'; fi` dwarfdump-print_rnglists.o: print_rnglists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_rnglists.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_rnglists.Tpo -c -o dwarfdump-print_rnglists.o `test -f 'print_rnglists.c' || echo '$(srcdir)/'`print_rnglists.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_rnglists.Tpo $(DEPDIR)/dwarfdump-print_rnglists.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_rnglists.c' object='dwarfdump-print_rnglists.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_rnglists.o `test -f 'print_rnglists.c' || echo '$(srcdir)/'`print_rnglists.c dwarfdump-print_rnglists.obj: print_rnglists.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_rnglists.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_rnglists.Tpo -c -o dwarfdump-print_rnglists.obj `if test -f 'print_rnglists.c'; then $(CYGPATH_W) 'print_rnglists.c'; else $(CYGPATH_W) '$(srcdir)/print_rnglists.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_rnglists.Tpo $(DEPDIR)/dwarfdump-print_rnglists.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_rnglists.c' object='dwarfdump-print_rnglists.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_rnglists.obj `if test -f 'print_rnglists.c'; then $(CYGPATH_W) 'print_rnglists.c'; else $(CYGPATH_W) '$(srcdir)/print_rnglists.c'; fi` dwarfdump-print_reloc.o: print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_reloc.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_reloc.Tpo -c -o dwarfdump-print_reloc.o `test -f 'print_reloc.c' || echo '$(srcdir)/'`print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_reloc.Tpo $(DEPDIR)/dwarfdump-print_reloc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_reloc.c' object='dwarfdump-print_reloc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_reloc.o `test -f 'print_reloc.c' || echo '$(srcdir)/'`print_reloc.c dwarfdump-print_reloc.obj: print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_reloc.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_reloc.Tpo -c -o dwarfdump-print_reloc.obj `if test -f 'print_reloc.c'; then $(CYGPATH_W) 'print_reloc.c'; else $(CYGPATH_W) '$(srcdir)/print_reloc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_reloc.Tpo $(DEPDIR)/dwarfdump-print_reloc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_reloc.c' object='dwarfdump-print_reloc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_reloc.obj `if test -f 'print_reloc.c'; then $(CYGPATH_W) 'print_reloc.c'; else $(CYGPATH_W) '$(srcdir)/print_reloc.c'; fi` dwarfdump-print_section_groups.o: print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_section_groups.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_section_groups.Tpo -c -o dwarfdump-print_section_groups.o `test -f 'print_section_groups.c' || echo '$(srcdir)/'`print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_section_groups.Tpo $(DEPDIR)/dwarfdump-print_section_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_section_groups.c' object='dwarfdump-print_section_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_section_groups.o `test -f 'print_section_groups.c' || echo '$(srcdir)/'`print_section_groups.c dwarfdump-print_section_groups.obj: print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_section_groups.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_section_groups.Tpo -c -o dwarfdump-print_section_groups.obj `if test -f 'print_section_groups.c'; then $(CYGPATH_W) 'print_section_groups.c'; else $(CYGPATH_W) '$(srcdir)/print_section_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_section_groups.Tpo $(DEPDIR)/dwarfdump-print_section_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_section_groups.c' object='dwarfdump-print_section_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_section_groups.obj `if test -f 'print_section_groups.c'; then $(CYGPATH_W) 'print_section_groups.c'; else $(CYGPATH_W) '$(srcdir)/print_section_groups.c'; fi` dwarfdump-print_sections.o: print_sections.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_sections.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_sections.Tpo -c -o dwarfdump-print_sections.o `test -f 'print_sections.c' || echo '$(srcdir)/'`print_sections.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_sections.Tpo $(DEPDIR)/dwarfdump-print_sections.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_sections.c' object='dwarfdump-print_sections.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_sections.o `test -f 'print_sections.c' || echo '$(srcdir)/'`print_sections.c dwarfdump-print_sections.obj: print_sections.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_sections.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_sections.Tpo -c -o dwarfdump-print_sections.obj `if test -f 'print_sections.c'; then $(CYGPATH_W) 'print_sections.c'; else $(CYGPATH_W) '$(srcdir)/print_sections.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_sections.Tpo $(DEPDIR)/dwarfdump-print_sections.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_sections.c' object='dwarfdump-print_sections.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_sections.obj `if test -f 'print_sections.c'; then $(CYGPATH_W) 'print_sections.c'; else $(CYGPATH_W) '$(srcdir)/print_sections.c'; fi` dwarfdump-print_static_funcs.o: print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_funcs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_funcs.Tpo -c -o dwarfdump-print_static_funcs.o `test -f 'print_static_funcs.c' || echo '$(srcdir)/'`print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_funcs.Tpo $(DEPDIR)/dwarfdump-print_static_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_funcs.c' object='dwarfdump-print_static_funcs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_funcs.o `test -f 'print_static_funcs.c' || echo '$(srcdir)/'`print_static_funcs.c dwarfdump-print_static_funcs.obj: print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_funcs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_funcs.Tpo -c -o dwarfdump-print_static_funcs.obj `if test -f 'print_static_funcs.c'; then $(CYGPATH_W) 'print_static_funcs.c'; else $(CYGPATH_W) '$(srcdir)/print_static_funcs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_funcs.Tpo $(DEPDIR)/dwarfdump-print_static_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_funcs.c' object='dwarfdump-print_static_funcs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_funcs.obj `if test -f 'print_static_funcs.c'; then $(CYGPATH_W) 'print_static_funcs.c'; else $(CYGPATH_W) '$(srcdir)/print_static_funcs.c'; fi` dwarfdump-print_static_vars.o: print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_vars.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_vars.Tpo -c -o dwarfdump-print_static_vars.o `test -f 'print_static_vars.c' || echo '$(srcdir)/'`print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_vars.Tpo $(DEPDIR)/dwarfdump-print_static_vars.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_vars.c' object='dwarfdump-print_static_vars.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_vars.o `test -f 'print_static_vars.c' || echo '$(srcdir)/'`print_static_vars.c dwarfdump-print_static_vars.obj: print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_vars.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_vars.Tpo -c -o dwarfdump-print_static_vars.obj `if test -f 'print_static_vars.c'; then $(CYGPATH_W) 'print_static_vars.c'; else $(CYGPATH_W) '$(srcdir)/print_static_vars.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_vars.Tpo $(DEPDIR)/dwarfdump-print_static_vars.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_vars.c' object='dwarfdump-print_static_vars.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_vars.obj `if test -f 'print_static_vars.c'; then $(CYGPATH_W) 'print_static_vars.c'; else $(CYGPATH_W) '$(srcdir)/print_static_vars.c'; fi` dwarfdump-print_str_offsets.o: print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_str_offsets.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_str_offsets.Tpo -c -o dwarfdump-print_str_offsets.o `test -f 'print_str_offsets.c' || echo '$(srcdir)/'`print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_str_offsets.Tpo $(DEPDIR)/dwarfdump-print_str_offsets.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_str_offsets.c' object='dwarfdump-print_str_offsets.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_str_offsets.o `test -f 'print_str_offsets.c' || echo '$(srcdir)/'`print_str_offsets.c dwarfdump-print_str_offsets.obj: print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_str_offsets.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_str_offsets.Tpo -c -o dwarfdump-print_str_offsets.obj `if test -f 'print_str_offsets.c'; then $(CYGPATH_W) 'print_str_offsets.c'; else $(CYGPATH_W) '$(srcdir)/print_str_offsets.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_str_offsets.Tpo $(DEPDIR)/dwarfdump-print_str_offsets.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_str_offsets.c' object='dwarfdump-print_str_offsets.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_str_offsets.obj `if test -f 'print_str_offsets.c'; then $(CYGPATH_W) 'print_str_offsets.c'; else $(CYGPATH_W) '$(srcdir)/print_str_offsets.c'; fi` dwarfdump-print_strings.o: print_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_strings.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_strings.Tpo -c -o dwarfdump-print_strings.o `test -f 'print_strings.c' || echo '$(srcdir)/'`print_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_strings.Tpo $(DEPDIR)/dwarfdump-print_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_strings.c' object='dwarfdump-print_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_strings.o `test -f 'print_strings.c' || echo '$(srcdir)/'`print_strings.c dwarfdump-print_strings.obj: print_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_strings.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_strings.Tpo -c -o dwarfdump-print_strings.obj `if test -f 'print_strings.c'; then $(CYGPATH_W) 'print_strings.c'; else $(CYGPATH_W) '$(srcdir)/print_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_strings.Tpo $(DEPDIR)/dwarfdump-print_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_strings.c' object='dwarfdump-print_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_strings.obj `if test -f 'print_strings.c'; then $(CYGPATH_W) 'print_strings.c'; else $(CYGPATH_W) '$(srcdir)/print_strings.c'; fi` dwarfdump-print_tag_attributes_usage.o: print_tag_attributes_usage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_tag_attributes_usage.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Tpo -c -o dwarfdump-print_tag_attributes_usage.o `test -f 'print_tag_attributes_usage.c' || echo '$(srcdir)/'`print_tag_attributes_usage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Tpo $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_tag_attributes_usage.c' object='dwarfdump-print_tag_attributes_usage.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_tag_attributes_usage.o `test -f 'print_tag_attributes_usage.c' || echo '$(srcdir)/'`print_tag_attributes_usage.c dwarfdump-print_tag_attributes_usage.obj: print_tag_attributes_usage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_tag_attributes_usage.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Tpo -c -o dwarfdump-print_tag_attributes_usage.obj `if test -f 'print_tag_attributes_usage.c'; then $(CYGPATH_W) 'print_tag_attributes_usage.c'; else $(CYGPATH_W) '$(srcdir)/print_tag_attributes_usage.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Tpo $(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_tag_attributes_usage.c' object='dwarfdump-print_tag_attributes_usage.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_tag_attributes_usage.obj `if test -f 'print_tag_attributes_usage.c'; then $(CYGPATH_W) 'print_tag_attributes_usage.c'; else $(CYGPATH_W) '$(srcdir)/print_tag_attributes_usage.c'; fi` dwarfdump-print_types.o: print_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_types.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_types.Tpo -c -o dwarfdump-print_types.o `test -f 'print_types.c' || echo '$(srcdir)/'`print_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_types.Tpo $(DEPDIR)/dwarfdump-print_types.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_types.c' object='dwarfdump-print_types.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_types.o `test -f 'print_types.c' || echo '$(srcdir)/'`print_types.c dwarfdump-print_types.obj: print_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_types.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_types.Tpo -c -o dwarfdump-print_types.obj `if test -f 'print_types.c'; then $(CYGPATH_W) 'print_types.c'; else $(CYGPATH_W) '$(srcdir)/print_types.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_types.Tpo $(DEPDIR)/dwarfdump-print_types.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_types.c' object='dwarfdump-print_types.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_types.obj `if test -f 'print_types.c'; then $(CYGPATH_W) 'print_types.c'; else $(CYGPATH_W) '$(srcdir)/print_types.c'; fi` dwarfdump-print_weaknames.o: print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_weaknames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_weaknames.Tpo -c -o dwarfdump-print_weaknames.o `test -f 'print_weaknames.c' || echo '$(srcdir)/'`print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_weaknames.Tpo $(DEPDIR)/dwarfdump-print_weaknames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_weaknames.c' object='dwarfdump-print_weaknames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_weaknames.o `test -f 'print_weaknames.c' || echo '$(srcdir)/'`print_weaknames.c dwarfdump-print_weaknames.obj: print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_weaknames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_weaknames.Tpo -c -o dwarfdump-print_weaknames.obj `if test -f 'print_weaknames.c'; then $(CYGPATH_W) 'print_weaknames.c'; else $(CYGPATH_W) '$(srcdir)/print_weaknames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_weaknames.Tpo $(DEPDIR)/dwarfdump-print_weaknames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_weaknames.c' object='dwarfdump-print_weaknames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_weaknames.obj `if test -f 'print_weaknames.c'; then $(CYGPATH_W) 'print_weaknames.c'; else $(CYGPATH_W) '$(srcdir)/print_weaknames.c'; fi` dwarfdump-sanitized.o: sanitized.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-sanitized.o -MD -MP -MF $(DEPDIR)/dwarfdump-sanitized.Tpo -c -o dwarfdump-sanitized.o `test -f 'sanitized.c' || echo '$(srcdir)/'`sanitized.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-sanitized.Tpo $(DEPDIR)/dwarfdump-sanitized.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sanitized.c' object='dwarfdump-sanitized.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-sanitized.o `test -f 'sanitized.c' || echo '$(srcdir)/'`sanitized.c dwarfdump-sanitized.obj: sanitized.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-sanitized.obj -MD -MP -MF $(DEPDIR)/dwarfdump-sanitized.Tpo -c -o dwarfdump-sanitized.obj `if test -f 'sanitized.c'; then $(CYGPATH_W) 'sanitized.c'; else $(CYGPATH_W) '$(srcdir)/sanitized.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-sanitized.Tpo $(DEPDIR)/dwarfdump-sanitized.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sanitized.c' object='dwarfdump-sanitized.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-sanitized.obj `if test -f 'sanitized.c'; then $(CYGPATH_W) 'sanitized.c'; else $(CYGPATH_W) '$(srcdir)/sanitized.c'; fi` dwarfdump-section_bitmaps.o: section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-section_bitmaps.o -MD -MP -MF $(DEPDIR)/dwarfdump-section_bitmaps.Tpo -c -o dwarfdump-section_bitmaps.o `test -f 'section_bitmaps.c' || echo '$(srcdir)/'`section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-section_bitmaps.Tpo $(DEPDIR)/dwarfdump-section_bitmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='section_bitmaps.c' object='dwarfdump-section_bitmaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-section_bitmaps.o `test -f 'section_bitmaps.c' || echo '$(srcdir)/'`section_bitmaps.c dwarfdump-section_bitmaps.obj: section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-section_bitmaps.obj -MD -MP -MF $(DEPDIR)/dwarfdump-section_bitmaps.Tpo -c -o dwarfdump-section_bitmaps.obj `if test -f 'section_bitmaps.c'; then $(CYGPATH_W) 'section_bitmaps.c'; else $(CYGPATH_W) '$(srcdir)/section_bitmaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-section_bitmaps.Tpo $(DEPDIR)/dwarfdump-section_bitmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='section_bitmaps.c' object='dwarfdump-section_bitmaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-section_bitmaps.obj `if test -f 'section_bitmaps.c'; then $(CYGPATH_W) 'section_bitmaps.c'; else $(CYGPATH_W) '$(srcdir)/section_bitmaps.c'; fi` dwarfdump-strstrnocase.o: strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-strstrnocase.o -MD -MP -MF $(DEPDIR)/dwarfdump-strstrnocase.Tpo -c -o dwarfdump-strstrnocase.o `test -f 'strstrnocase.c' || echo '$(srcdir)/'`strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-strstrnocase.Tpo $(DEPDIR)/dwarfdump-strstrnocase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strstrnocase.c' object='dwarfdump-strstrnocase.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-strstrnocase.o `test -f 'strstrnocase.c' || echo '$(srcdir)/'`strstrnocase.c dwarfdump-strstrnocase.obj: strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-strstrnocase.obj -MD -MP -MF $(DEPDIR)/dwarfdump-strstrnocase.Tpo -c -o dwarfdump-strstrnocase.obj `if test -f 'strstrnocase.c'; then $(CYGPATH_W) 'strstrnocase.c'; else $(CYGPATH_W) '$(srcdir)/strstrnocase.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-strstrnocase.Tpo $(DEPDIR)/dwarfdump-strstrnocase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strstrnocase.c' object='dwarfdump-strstrnocase.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-strstrnocase.obj `if test -f 'strstrnocase.c'; then $(CYGPATH_W) 'strstrnocase.c'; else $(CYGPATH_W) '$(srcdir)/strstrnocase.c'; fi` dwarfdump-true_section_name.o: true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-true_section_name.o -MD -MP -MF $(DEPDIR)/dwarfdump-true_section_name.Tpo -c -o dwarfdump-true_section_name.o `test -f 'true_section_name.c' || echo '$(srcdir)/'`true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-true_section_name.Tpo $(DEPDIR)/dwarfdump-true_section_name.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='true_section_name.c' object='dwarfdump-true_section_name.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-true_section_name.o `test -f 'true_section_name.c' || echo '$(srcdir)/'`true_section_name.c dwarfdump-true_section_name.obj: true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-true_section_name.obj -MD -MP -MF $(DEPDIR)/dwarfdump-true_section_name.Tpo -c -o dwarfdump-true_section_name.obj `if test -f 'true_section_name.c'; then $(CYGPATH_W) 'true_section_name.c'; else $(CYGPATH_W) '$(srcdir)/true_section_name.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-true_section_name.Tpo $(DEPDIR)/dwarfdump-true_section_name.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='true_section_name.c' object='dwarfdump-true_section_name.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-true_section_name.obj `if test -f 'true_section_name.c'; then $(CYGPATH_W) 'true_section_name.c'; else $(CYGPATH_W) '$(srcdir)/true_section_name.c'; fi` dwarfdump-uri.o: uri.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-uri.o -MD -MP -MF $(DEPDIR)/dwarfdump-uri.Tpo -c -o dwarfdump-uri.o `test -f 'uri.c' || echo '$(srcdir)/'`uri.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-uri.Tpo $(DEPDIR)/dwarfdump-uri.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uri.c' object='dwarfdump-uri.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-uri.o `test -f 'uri.c' || echo '$(srcdir)/'`uri.c dwarfdump-uri.obj: uri.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-uri.obj -MD -MP -MF $(DEPDIR)/dwarfdump-uri.Tpo -c -o dwarfdump-uri.obj `if test -f 'uri.c'; then $(CYGPATH_W) 'uri.c'; else $(CYGPATH_W) '$(srcdir)/uri.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-uri.Tpo $(DEPDIR)/dwarfdump-uri.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uri.c' object='dwarfdump-uri.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-uri.obj `if test -f 'uri.c'; then $(CYGPATH_W) 'uri.c'; else $(CYGPATH_W) '$(srcdir)/uri.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-dwarfdumpdevDATA: $(dwarfdumpdev_DATA) @$(NORMAL_INSTALL) @list='$(dwarfdumpdev_DATA)'; test -n "$(dwarfdumpdevdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dwarfdumpdevdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dwarfdumpdevdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dwarfdumpdevdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dwarfdumpdevdir)" || exit $$?; \ done uninstall-dwarfdumpdevDATA: @$(NORMAL_UNINSTALL) @list='$(dwarfdumpdev_DATA)'; test -n "$(dwarfdumpdevdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(dwarfdumpdevdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? runtests.sh.log: runtests.sh @p='runtests.sh'; \ b='runtests.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(dwarfdumpdevdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dwarfdump-addrmap.Po -rm -f ./$(DEPDIR)/dwarfdump-attr_form.Po -rm -f ./$(DEPDIR)/dwarfdump-checkutil.Po -rm -f ./$(DEPDIR)/dwarfdump-command_options.Po -rm -f ./$(DEPDIR)/dwarfdump-common.Po -rm -f ./$(DEPDIR)/dwarfdump-compiler_info.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarf_names.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarfdump.Po -rm -f ./$(DEPDIR)/dwarfdump-dwconf.Po -rm -f ./$(DEPDIR)/dwarfdump-dwgetopt.Po -rm -f ./$(DEPDIR)/dwarfdump-esb.Po -rm -f ./$(DEPDIR)/dwarfdump-glflags.Po -rm -f ./$(DEPDIR)/dwarfdump-helpertree.Po -rm -f ./$(DEPDIR)/dwarfdump-macrocheck.Po -rm -f ./$(DEPDIR)/dwarfdump-makename.Po -rm -f ./$(DEPDIR)/dwarfdump-naming.Po -rm -f ./$(DEPDIR)/dwarfdump-opscounttab.Po -rm -f ./$(DEPDIR)/dwarfdump-print_abbrevs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_aranges.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_gnu.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_names.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_sup.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debugfission.Po -rm -f ./$(DEPDIR)/dwarfdump-print_die.Po -rm -f ./$(DEPDIR)/dwarfdump-print_frames.Po -rm -f ./$(DEPDIR)/dwarfdump-print_gdbindex.Po -rm -f ./$(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po -rm -f ./$(DEPDIR)/dwarfdump-print_lines.Po -rm -f ./$(DEPDIR)/dwarfdump-print_llex_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_loclists.Po -rm -f ./$(DEPDIR)/dwarfdump-print_loclists_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_locs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_macinfo.Po -rm -f ./$(DEPDIR)/dwarfdump-print_macro.Po -rm -f ./$(DEPDIR)/dwarfdump-print_origloclist_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_pubnames.Po -rm -f ./$(DEPDIR)/dwarfdump-print_ranges.Po -rm -f ./$(DEPDIR)/dwarfdump-print_reloc.Po -rm -f ./$(DEPDIR)/dwarfdump-print_rnglists.Po -rm -f ./$(DEPDIR)/dwarfdump-print_section_groups.Po -rm -f ./$(DEPDIR)/dwarfdump-print_sections.Po -rm -f ./$(DEPDIR)/dwarfdump-print_static_funcs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_static_vars.Po -rm -f ./$(DEPDIR)/dwarfdump-print_str_offsets.Po -rm -f ./$(DEPDIR)/dwarfdump-print_strings.Po -rm -f ./$(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po -rm -f ./$(DEPDIR)/dwarfdump-print_types.Po -rm -f ./$(DEPDIR)/dwarfdump-print_weaknames.Po -rm -f ./$(DEPDIR)/dwarfdump-sanitized.Po -rm -f ./$(DEPDIR)/dwarfdump-section_bitmaps.Po -rm -f ./$(DEPDIR)/dwarfdump-strstrnocase.Po -rm -f ./$(DEPDIR)/dwarfdump-true_section_name.Po -rm -f ./$(DEPDIR)/dwarfdump-uri.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dwarfdumpdevDATA install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dwarfdump-addrmap.Po -rm -f ./$(DEPDIR)/dwarfdump-attr_form.Po -rm -f ./$(DEPDIR)/dwarfdump-checkutil.Po -rm -f ./$(DEPDIR)/dwarfdump-command_options.Po -rm -f ./$(DEPDIR)/dwarfdump-common.Po -rm -f ./$(DEPDIR)/dwarfdump-compiler_info.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarf_names.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po -rm -f ./$(DEPDIR)/dwarfdump-dwarfdump.Po -rm -f ./$(DEPDIR)/dwarfdump-dwconf.Po -rm -f ./$(DEPDIR)/dwarfdump-dwgetopt.Po -rm -f ./$(DEPDIR)/dwarfdump-esb.Po -rm -f ./$(DEPDIR)/dwarfdump-glflags.Po -rm -f ./$(DEPDIR)/dwarfdump-helpertree.Po -rm -f ./$(DEPDIR)/dwarfdump-macrocheck.Po -rm -f ./$(DEPDIR)/dwarfdump-makename.Po -rm -f ./$(DEPDIR)/dwarfdump-naming.Po -rm -f ./$(DEPDIR)/dwarfdump-opscounttab.Po -rm -f ./$(DEPDIR)/dwarfdump-print_abbrevs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_aranges.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_gnu.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_names.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debug_sup.Po -rm -f ./$(DEPDIR)/dwarfdump-print_debugfission.Po -rm -f ./$(DEPDIR)/dwarfdump-print_die.Po -rm -f ./$(DEPDIR)/dwarfdump-print_frames.Po -rm -f ./$(DEPDIR)/dwarfdump-print_gdbindex.Po -rm -f ./$(DEPDIR)/dwarfdump-print_hipc_lopc_attr.Po -rm -f ./$(DEPDIR)/dwarfdump-print_lines.Po -rm -f ./$(DEPDIR)/dwarfdump-print_llex_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_loclists.Po -rm -f ./$(DEPDIR)/dwarfdump-print_loclists_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_locs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_macinfo.Po -rm -f ./$(DEPDIR)/dwarfdump-print_macro.Po -rm -f ./$(DEPDIR)/dwarfdump-print_origloclist_codes.Po -rm -f ./$(DEPDIR)/dwarfdump-print_pubnames.Po -rm -f ./$(DEPDIR)/dwarfdump-print_ranges.Po -rm -f ./$(DEPDIR)/dwarfdump-print_reloc.Po -rm -f ./$(DEPDIR)/dwarfdump-print_rnglists.Po -rm -f ./$(DEPDIR)/dwarfdump-print_section_groups.Po -rm -f ./$(DEPDIR)/dwarfdump-print_sections.Po -rm -f ./$(DEPDIR)/dwarfdump-print_static_funcs.Po -rm -f ./$(DEPDIR)/dwarfdump-print_static_vars.Po -rm -f ./$(DEPDIR)/dwarfdump-print_str_offsets.Po -rm -f ./$(DEPDIR)/dwarfdump-print_strings.Po -rm -f ./$(DEPDIR)/dwarfdump-print_tag_attributes_usage.Po -rm -f ./$(DEPDIR)/dwarfdump-print_types.Po -rm -f ./$(DEPDIR)/dwarfdump-print_weaknames.Po -rm -f ./$(DEPDIR)/dwarfdump-sanitized.Po -rm -f ./$(DEPDIR)/dwarfdump-section_bitmaps.Po -rm -f ./$(DEPDIR)/dwarfdump-strstrnocase.Po -rm -f ./$(DEPDIR)/dwarfdump-true_section_name.Po -rm -f ./$(DEPDIR)/dwarfdump-uri.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-dwarfdumpdevDATA \ uninstall-man uninstall-man: uninstall-man1 .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-binPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-dwarfdumpdevDATA install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-dwarfdumpdevDATA uninstall-man \ uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libdwarf-20210528/dwarfdump/common.h0000644000175000017500000000256513743575426014154 00000000000000/* Copyright (C) 2009-2010 SN Systems. All Rights Reserved. Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMMON_INCLUDED_H #define COMMON_INCLUDED_H void print_args(int argc, char *argv[]); void print_version_details(const char *name, int alwaysprint); void print_usage_message(const char *program_name, const char **text); #endif /* COMMON_INCLUDED_H */ libdwarf-20210528/dwarfdump/addrmap.c0000664000175000017500000000706013764006205014247 00000000000000/* Copyright 2010-2012 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* If memory full we do not exit, we just keep going as if all were well. */ #include "globals.h" #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "addrmap.h" #include "dwarf_tsearch.h" static struct Addr_Map_Entry * addr_map_create_entry(Dwarf_Unsigned k,char *name) { struct Addr_Map_Entry *mp = (struct Addr_Map_Entry *)malloc( sizeof(struct Addr_Map_Entry)); if (!mp) { return 0; } mp->mp_key = k; if (name) { mp->mp_name = (char *)strdup(name); } else { mp->mp_name = 0; } return mp; } static void addr_map_free_func(void *mx) { struct Addr_Map_Entry *m = mx; if (!m) { return; } free(m->mp_name); m->mp_name = 0; free(m); return; } static int addr_map_compare_func(const void *l, const void *r) { const struct Addr_Map_Entry *ml = l; const struct Addr_Map_Entry *mr = r; if (ml->mp_key < mr->mp_key) { return -1; } if (ml->mp_key > mr->mp_key) { return 1; } return 0; } struct Addr_Map_Entry * addr_map_insert( Dwarf_Unsigned addr,char *name,void **tree1) { void *retval = 0; struct Addr_Map_Entry *re = 0; struct Addr_Map_Entry *e; e = addr_map_create_entry(addr,name); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, addr_map_compare_func); if (retval) { re = *(struct Addr_Map_Entry **)retval; if (re != e) { /* We returned an existing record, e not needed. */ addr_map_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } } return re; } struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr,void **tree1) { void *retval = 0; struct Addr_Map_Entry *re = 0; struct Addr_Map_Entry *e = 0; e = addr_map_create_entry(addr,NULL); retval = dwarf_tfind(e,tree1, addr_map_compare_func); if (retval) { re = *(struct Addr_Map_Entry **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ addr_map_free_func(e); return re; } void addr_map_destroy(void *map) { /* tdestroy is not part of Posix, it is a GNU libc function. */ if (map) { dwarf_tdestroy(map,addr_map_free_func); } } libdwarf-20210528/dwarfdump/dwarfdump-af-table.h0000664000175000017500000003035014054205620016277 00000000000000/* Generated table, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ #ifndef DWARFDUMP_AF_TABLE_H #define DWARFDUMP_AF_TABLE_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct af_table_s { Dwarf_Half attr; Dwarf_Half formclass; unsigned char section; } attr_formclass_table[] = { {0x31,10,1},/*DW_AT_abstract_origin DW_FORM_CLASS_REFERENCE Std*/ {0x32, 3,1},/*DW_AT_accessibility DW_FORM_CLASS_CONSTANT Std*/ {0x73,14,1},/*DW_AT_addr_base DW_FORM_CLASS_ADDRPTR Std*/ {0x33, 3,1},/*DW_AT_address_class DW_FORM_CLASS_CONSTANT Std*/ {0x88, 3,1},/*DW_AT_alignment DW_FORM_CLASS_CONSTANT Std*/ {0x4e, 3,1},/*DW_AT_allocated DW_FORM_CLASS_CONSTANT Std*/ {0x4e, 4,1},/*DW_AT_allocated DW_FORM_CLASS_EXPRLOC Std*/ {0x4e,10,1},/*DW_AT_allocated DW_FORM_CLASS_REFERENCE Std*/ {0x34, 5,1},/*DW_AT_artificial DW_FORM_CLASS_FLAG Std*/ {0x4f, 3,1},/*DW_AT_associated DW_FORM_CLASS_CONSTANT Std*/ {0x4f, 4,1},/*DW_AT_associated DW_FORM_CLASS_EXPRLOC Std*/ {0x4f,10,1},/*DW_AT_associated DW_FORM_CLASS_REFERENCE Std*/ {0x35,10,1},/*DW_AT_base_types DW_FORM_CLASS_REFERENCE Std*/ {0x5b, 3,1},/*DW_AT_binary_scale DW_FORM_CLASS_CONSTANT Std*/ {0x0c, 3,1},/*DW_AT_bit_offset DW_FORM_CLASS_CONSTANT Std*/ {0x0c, 2,1},/*DW_AT_bit_offset DW_FORM_CLASS_BLOCK Std*/ {0x0c,10,1},/*DW_AT_bit_offset DW_FORM_CLASS_REFERENCE Std*/ {0x0d, 3,1},/*DW_AT_bit_size DW_FORM_CLASS_CONSTANT Std*/ {0x0d, 2,1},/*DW_AT_bit_size DW_FORM_CLASS_BLOCK Std*/ {0x0d,10,1},/*DW_AT_bit_size DW_FORM_CLASS_REFERENCE Std*/ {0x2e, 3,1},/*DW_AT_bit_stride DW_FORM_CLASS_CONSTANT Std*/ {0x2e, 4,1},/*DW_AT_bit_stride DW_FORM_CLASS_EXPRLOC Std*/ {0x2e,10,1},/*DW_AT_bit_stride DW_FORM_CLASS_REFERENCE Std*/ {0x0b, 3,1},/*DW_AT_byte_size DW_FORM_CLASS_CONSTANT Std*/ {0x0b, 4,1},/*DW_AT_byte_size DW_FORM_CLASS_EXPRLOC Std*/ {0x0b,10,1},/*DW_AT_byte_size DW_FORM_CLASS_REFERENCE Std*/ {0x51, 3,1},/*DW_AT_byte_stride DW_FORM_CLASS_CONSTANT Std*/ {0x51, 4,1},/*DW_AT_byte_stride DW_FORM_CLASS_EXPRLOC Std*/ {0x51,10,1},/*DW_AT_byte_stride DW_FORM_CLASS_REFERENCE Std*/ {0x7a, 5,1},/*DW_AT_call_all_calls DW_FORM_CLASS_FLAG Std*/ {0x7b, 5,1},/*DW_AT_call_all_source_calls DW_FORM_CLASS_FLAG Std*/ {0x7c, 5,1},/*DW_AT_call_all_tail_calls DW_FORM_CLASS_FLAG Std*/ {0x57, 3,1},/*DW_AT_call_column DW_FORM_CLASS_CONSTANT Std*/ {0x85, 4,1},/*DW_AT_call_data_location DW_FORM_CLASS_EXPRLOC Std*/ {0x86, 4,1},/*DW_AT_call_data_value DW_FORM_CLASS_EXPRLOC Std*/ {0x58, 3,1},/*DW_AT_call_file DW_FORM_CLASS_CONSTANT Std*/ {0x36, 3,1},/*DW_AT_calling_convention DW_FORM_CLASS_CONSTANT Std*/ {0x59, 3,1},/*DW_AT_call_line DW_FORM_CLASS_CONSTANT Std*/ {0x7f, 4,1},/*DW_AT_call_origin DW_FORM_CLASS_EXPRLOC Std*/ {0x7f,10,1},/*DW_AT_call_origin DW_FORM_CLASS_REFERENCE Std*/ {0x80,10,1},/*DW_AT_call_parameter DW_FORM_CLASS_REFERENCE Std*/ {0x81, 1,1},/*DW_AT_call_pc DW_FORM_CLASS_ADDRESS Std*/ {0x7d, 1,1},/*DW_AT_call_return_pc DW_FORM_CLASS_ADDRESS Std*/ {0x82, 5,1},/*DW_AT_call_tail_call DW_FORM_CLASS_FLAG Std*/ {0x83, 4,1},/*DW_AT_call_target DW_FORM_CLASS_EXPRLOC Std*/ {0x84, 4,1},/*DW_AT_call_target_clobbered DW_FORM_CLASS_EXPRLOC Std*/ {0x7e, 4,1},/*DW_AT_call_value DW_FORM_CLASS_EXPRLOC Std*/ {0x1a,10,1},/*DW_AT_common_reference DW_FORM_CLASS_REFERENCE Std*/ {0x1b,11,1},/*DW_AT_comp_dir DW_FORM_CLASS_STRING Std*/ {0x6c, 5,1},/*DW_AT_const_expr DW_FORM_CLASS_FLAG Std*/ {0x1c, 3,1},/*DW_AT_const_value DW_FORM_CLASS_CONSTANT Std*/ {0x1c, 2,1},/*DW_AT_const_value DW_FORM_CLASS_BLOCK Std*/ {0x1c,11,1},/*DW_AT_const_value DW_FORM_CLASS_STRING Std*/ {0x1d,10,1},/*DW_AT_containing_type DW_FORM_CLASS_REFERENCE Std*/ {0x37, 3,1},/*DW_AT_count DW_FORM_CLASS_CONSTANT Std*/ {0x37, 4,1},/*DW_AT_count DW_FORM_CLASS_EXPRLOC Std*/ {0x37,10,1},/*DW_AT_count DW_FORM_CLASS_REFERENCE Std*/ {0x6b, 3,1},/*DW_AT_data_bit_offset DW_FORM_CLASS_CONSTANT Std*/ {0x50, 4,1},/*DW_AT_data_location DW_FORM_CLASS_EXPRLOC Std*/ {0x38, 3,1},/*DW_AT_data_member_location DW_FORM_CLASS_CONSTANT Std*/ {0x38, 4,1},/*DW_AT_data_member_location DW_FORM_CLASS_EXPRLOC Std*/ {0x38,15,1},/*DW_AT_data_member_location DW_FORM_CLASS_LOCLIST Std*/ {0x5c, 3,1},/*DW_AT_decimal_scale DW_FORM_CLASS_CONSTANT Std*/ {0x5e, 3,1},/*DW_AT_decimal_sign DW_FORM_CLASS_CONSTANT Std*/ {0x3c, 5,1},/*DW_AT_declaration DW_FORM_CLASS_FLAG Std*/ {0x39, 3,1},/*DW_AT_decl_column DW_FORM_CLASS_CONSTANT Std*/ {0x3a, 3,1},/*DW_AT_decl_file DW_FORM_CLASS_CONSTANT Std*/ {0x3b, 3,1},/*DW_AT_decl_line DW_FORM_CLASS_CONSTANT Std*/ {0x8b, 3,1},/*DW_AT_defaulted DW_FORM_CLASS_CONSTANT Std*/ {0x8a, 5,1},/*DW_AT_deleted DW_FORM_CLASS_FLAG Std*/ {0x5a,11,1},/*DW_AT_description DW_FORM_CLASS_STRING Std*/ {0x5f, 3,1},/*DW_AT_digit_count DW_FORM_CLASS_CONSTANT Std*/ {0x15,10,1},/*DW_AT_discr DW_FORM_CLASS_REFERENCE Std*/ {0x3d, 2,1},/*DW_AT_discr_list DW_FORM_CLASS_BLOCK Std*/ {0x16, 3,1},/*DW_AT_discr_value DW_FORM_CLASS_CONSTANT Std*/ {0x75,10,1},/*DW_AT_dwo_id DW_FORM_CLASS_REFERENCE Std*/ {0x76,11,1},/*DW_AT_dwo_name DW_FORM_CLASS_STRING Std*/ {0x66, 5,1},/*DW_AT_elemental DW_FORM_CLASS_FLAG Std*/ {0x3e, 3,1},/*DW_AT_encoding DW_FORM_CLASS_CONSTANT Std*/ {0x65, 3,1},/*DW_AT_endianity DW_FORM_CLASS_CONSTANT Std*/ {0x52, 1,1},/*DW_AT_entry_pc DW_FORM_CLASS_ADDRESS Std*/ {0x52, 3,1},/*DW_AT_entry_pc DW_FORM_CLASS_CONSTANT Std*/ {0x6d, 5,1},/*DW_AT_enum_class DW_FORM_CLASS_FLAG Std*/ {0x63, 5,1},/*DW_AT_explicit DW_FORM_CLASS_FLAG Std*/ {0x89, 5,1},/*DW_AT_export_symbols DW_FORM_CLASS_FLAG Std*/ {0x54,10,1},/*DW_AT_extension DW_FORM_CLASS_REFERENCE Std*/ {0x3f, 5,1},/*DW_AT_external DW_FORM_CLASS_FLAG Std*/ {0x40, 4,1},/*DW_AT_frame_base DW_FORM_CLASS_EXPRLOC Std*/ {0x40,15,1},/*DW_AT_frame_base DW_FORM_CLASS_LOCLIST Std*/ {0x41,10,1},/*DW_AT_friend DW_FORM_CLASS_REFERENCE Std*/ {0x12, 3,1},/*DW_AT_high_pc DW_FORM_CLASS_CONSTANT Std*/ {0x12, 1,1},/*DW_AT_high_pc DW_FORM_CLASS_ADDRESS Std*/ {0x42, 3,1},/*DW_AT_identifier_case DW_FORM_CLASS_CONSTANT Std*/ {0x18,10,1},/*DW_AT_import DW_FORM_CLASS_REFERENCE Std*/ {0x20, 3,1},/*DW_AT_inline DW_FORM_CLASS_CONSTANT Std*/ {0x21, 5,1},/*DW_AT_is_optional DW_FORM_CLASS_FLAG Std*/ {0x13, 3,1},/*DW_AT_language DW_FORM_CLASS_CONSTANT Std*/ {0x6e,11,1},/*DW_AT_linkage_name DW_FORM_CLASS_STRING Std*/ {0x02, 4,1},/*DW_AT_location DW_FORM_CLASS_EXPRLOC Std*/ {0x02,15,1},/*DW_AT_location DW_FORM_CLASS_LOCLIST Std*/ {0x02, 7,1},/*DW_AT_location DW_FORM_CLASS_LOCLISTPTR Std*/ {0x8c,16,1},/*DW_AT_loclists_base DW_FORM_CLASS_LOCLISTSPTR Std*/ {0x22, 3,1},/*DW_AT_lower_bound DW_FORM_CLASS_CONSTANT Std*/ {0x22, 4,1},/*DW_AT_lower_bound DW_FORM_CLASS_EXPRLOC Std*/ {0x22,10,1},/*DW_AT_lower_bound DW_FORM_CLASS_REFERENCE Std*/ {0x11, 1,1},/*DW_AT_low_pc DW_FORM_CLASS_ADDRESS Std*/ {0x43, 8,1},/*DW_AT_macro_info DW_FORM_CLASS_MACPTR Std*/ {0x79,13,1},/*DW_AT_macros DW_FORM_CLASS_MAXCROPTR Std*/ {0x6a,11,1},/*DW_AT_main_subprogram DW_FORM_CLASS_STRING Std*/ {0x61, 5,1},/*DW_AT_mutable DW_FORM_CLASS_FLAG Std*/ {0x03,11,1},/*DW_AT_name DW_FORM_CLASS_STRING Std*/ {0x44,10,1},/*DW_AT_namelist_item DW_FORM_CLASS_REFERENCE Std*/ {0x87, 5,1},/*DW_AT_noreturn DW_FORM_CLASS_FLAG Std*/ {0x64,10,1},/*DW_AT_object_pointer DW_FORM_CLASS_REFERENCE Std*/ {0x09, 3,1},/*DW_AT_ordering DW_FORM_CLASS_CONSTANT Std*/ {0x60,11,1},/*DW_AT_picture_string DW_FORM_CLASS_STRING Std*/ {0x45,10,1},/*DW_AT_priority DW_FORM_CLASS_REFERENCE Std*/ {0x25,11,1},/*DW_AT_producer DW_FORM_CLASS_STRING Std*/ {0x27, 5,1},/*DW_AT_prototyped DW_FORM_CLASS_FLAG Std*/ {0x67, 5,1},/*DW_AT_pure DW_FORM_CLASS_FLAG Std*/ {0x55,17,1},/*DW_AT_ranges DW_FORM_CLASS_RNGLIST Std*/ {0x55, 9,1},/*DW_AT_ranges DW_FORM_CLASS_RANGELISTPTR Std*/ {0x55,18,1},/*DW_AT_ranges DW_FORM_CLASS_RNGLISTSPTR Std*/ {0x71, 3,1},/*DW_AT_rank DW_FORM_CLASS_CONSTANT Std*/ {0x71, 4,1},/*DW_AT_rank DW_FORM_CLASS_EXPRLOC Std*/ {0x68, 5,1},/*DW_AT_recursive DW_FORM_CLASS_FLAG Std*/ {0x77, 5,1},/*DW_AT_reference DW_FORM_CLASS_FLAG Std*/ {0x2a, 4,1},/*DW_AT_return_addr DW_FORM_CLASS_EXPRLOC Std*/ {0x2a,15,1},/*DW_AT_return_addr DW_FORM_CLASS_LOCLIST Std*/ {0x74,18,1},/*DW_AT_rnglists_base DW_FORM_CLASS_RNGLISTSPTR Std*/ {0x78, 5,1},/*DW_AT_rvalue_reference DW_FORM_CLASS_FLAG Std*/ {0x46, 4,1},/*DW_AT_segment DW_FORM_CLASS_EXPRLOC Std*/ {0x46,15,1},/*DW_AT_segment DW_FORM_CLASS_LOCLIST Std*/ {0x01,10,1},/*DW_AT_sibling DW_FORM_CLASS_REFERENCE Std*/ {0x69,10,1},/*DW_AT_signature DW_FORM_CLASS_REFERENCE Std*/ {0x5d,10,1},/*DW_AT_small DW_FORM_CLASS_REFERENCE Std*/ {0x47,10,1},/*DW_AT_specification DW_FORM_CLASS_REFERENCE Std*/ {0x2c, 3,1},/*DW_AT_start_scope DW_FORM_CLASS_CONSTANT Std*/ {0x2c,17,1},/*DW_AT_start_scope DW_FORM_CLASS_RNGLIST Std*/ {0x48, 4,1},/*DW_AT_static_link DW_FORM_CLASS_EXPRLOC Std*/ {0x48,15,1},/*DW_AT_static_link DW_FORM_CLASS_LOCLIST Std*/ {0x10, 6,1},/*DW_AT_stmt_list DW_FORM_CLASS_LINEPTR Std*/ {0x19, 2,1},/*DW_AT_string_length DW_FORM_CLASS_BLOCK Std*/ {0x19, 7,1},/*DW_AT_string_length DW_FORM_CLASS_LOCLISTPTR Std*/ {0x6f, 3,1},/*DW_AT_string_length_bit_size DW_FORM_CLASS_CONSTANT Std*/ {0x70, 3,1},/*DW_AT_string_length_byte_size DW_FORM_CLASS_CONSTANT Std*/ {0x72,19,1},/*DW_AT_str_offsets_base DW_FORM_CLASS_STROFFSETSPTR Std*/ {0x62, 5,1},/*DW_AT_threads_scaled DW_FORM_CLASS_FLAG Std*/ {0x56,10,1},/*DW_AT_trampoline DW_FORM_CLASS_REFERENCE Std*/ {0x56, 1,1},/*DW_AT_trampoline DW_FORM_CLASS_ADDRESS Std*/ {0x56, 5,1},/*DW_AT_trampoline DW_FORM_CLASS_FLAG Std*/ {0x56,11,1},/*DW_AT_trampoline DW_FORM_CLASS_STRING Std*/ {0x49,10,1},/*DW_AT_type DW_FORM_CLASS_REFERENCE Std*/ {0x2f, 3,1},/*DW_AT_upper_bound DW_FORM_CLASS_CONSTANT Std*/ {0x2f, 4,1},/*DW_AT_upper_bound DW_FORM_CLASS_EXPRLOC Std*/ {0x2f,10,1},/*DW_AT_upper_bound DW_FORM_CLASS_REFERENCE Std*/ {0x4a, 4,1},/*DW_AT_use_location DW_FORM_CLASS_EXPRLOC Std*/ {0x4a,15,1},/*DW_AT_use_location DW_FORM_CLASS_LOCLIST Std*/ {0x53, 5,1},/*DW_AT_use_UTF8 DW_FORM_CLASS_FLAG Std*/ {0x4b, 5,1},/*DW_AT_variable_parameter DW_FORM_CLASS_FLAG Std*/ {0x4c, 3,1},/*DW_AT_virtuality DW_FORM_CLASS_CONSTANT Std*/ {0x17, 3,1},/*DW_AT_visibility DW_FORM_CLASS_CONSTANT Std*/ {0x4d, 4,1},/*DW_AT_vtable_elem_location DW_FORM_CLASS_EXPRLOC Std*/ {0x4d,15,1},/*DW_AT_vtable_elem_location DW_FORM_CLASS_LOCLIST Std*/ /* end af_table standard */ {0x2133,14,2},/*DW_AT_GNU_addr_base DW_FORM_CLASS_ADDRPTR Ext*/ {0x2117, 5,2},/*DW_AT_GNU_all_call_sites DW_FORM_CLASS_FLAG Ext*/ {0x2116, 5,2},/*DW_AT_GNU_all_tail_call_sites DW_FORM_CLASS_FLAG Ext*/ {0x2112, 4,2},/*DW_AT_GNU_call_site_data_value DW_FORM_CLASS_EXPRLOC Ext*/ {0x2113, 4,2},/*DW_AT_GNU_call_site_target DW_FORM_CLASS_EXPRLOC Ext*/ {0x2111, 4,2},/*DW_AT_GNU_call_site_value DW_FORM_CLASS_EXPRLOC Ext*/ {0x2304, 3,2},/*DW_AT_GNU_denominator DW_FORM_CLASS_CONSTANT Ext*/ {0x2136, 3,2},/*DW_AT_GNU_discriminator DW_FORM_CLASS_CONSTANT Ext*/ {0x2131,10,2},/*DW_AT_GNU_dwo_id DW_FORM_CLASS_REFERENCE Ext*/ {0x2131, 3,2},/*DW_AT_GNU_dwo_id DW_FORM_CLASS_CONSTANT Ext*/ {0x2130,11,2},/*DW_AT_GNU_dwo_name DW_FORM_CLASS_STRING Ext*/ {0x2119,13,2},/*DW_AT_GNU_macros DW_FORM_CLASS_MAXCROPTR Ext*/ {0x2303, 3,2},/*DW_AT_GNU_numerator DW_FORM_CLASS_CONSTANT Ext*/ {0x210f, 3,2},/*DW_AT_GNU_odr_signature DW_FORM_CLASS_CONSTANT Ext*/ {0x210f,10,2},/*DW_AT_GNU_odr_signature DW_FORM_CLASS_REFERENCE Ext*/ {0x2134,10,2},/*DW_AT_GNU_pubnames DW_FORM_CLASS_REFERENCE Ext*/ {0x2134, 5,2},/*DW_AT_GNU_pubnames DW_FORM_CLASS_FLAG Ext*/ {0x2134, 3,2},/*DW_AT_GNU_pubnames DW_FORM_CLASS_CONSTANT Ext*/ {0x2135,10,2},/*DW_AT_GNU_pubtypes DW_FORM_CLASS_REFERENCE Ext*/ {0x2135, 5,2},/*DW_AT_GNU_pubtypes DW_FORM_CLASS_FLAG Ext*/ {0x2135, 3,2},/*DW_AT_GNU_pubtypes DW_FORM_CLASS_CONSTANT Ext*/ {0x2132,18,2},/*DW_AT_GNU_ranges_base DW_FORM_CLASS_RNGLISTSPTR Ext*/ {0x2115, 5,2},/*DW_AT_GNU_tail_call DW_FORM_CLASS_FLAG Ext*/ {0x2009,11,2},/*DW_AT_MIPS_abstract_name DW_FORM_CLASS_STRING Ext*/ {0x2001,12,2},/*DW_AT_MIPS_fde DW_FORM_CLASS_FRAMEPTR Ext*/ {0x200b, 5,2},/*DW_AT_MIPS_has_inlines DW_FORM_CLASS_FLAG Ext*/ {0x2007,11,2},/*DW_AT_MIPS_linkage_name DW_FORM_CLASS_STRING Ext*/ {0x2226,11,2},/*DW_AT_SUN_link_name DW_FORM_CLASS_STRING Ext*/ {0x2225,11,2},/*DW_AT_SUN_part_link_name DW_FORM_CLASS_STRING Ext*/ {0x2083, 3,2},/*DW_AT_ghs_rsm DW_FORM_CLASS_CONSTANT Ext*/ {0x2085, 3,2},/*DW_AT_ghs_frsm DW_FORM_CLASS_CONSTANT Ext*/ {0x2086, 3,2},/*DW_AT_ghs_frames DW_FORM_CLASS_CONSTANT Ext*/ {0x2087, 3,2},/*DW_AT_ghs_rso DW_FORM_CLASS_CONSTANT Ext*/ {0x2092, 3,2},/*DW_AT_ghs_subcpu DW_FORM_CLASS_CONSTANT Ext*/ { 0,0,0 } }; /* end af_table extended */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* DWARFDUMP_AF_TABLE_H */ libdwarf-20210528/dwarfdump/naming.c0000664000175000017500000002060714012575576014123 00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* SGI has moved from the Crittenden Lane address. */ /* naming.c */ #include "globals.h" #include "dwarf.h" #include "libdwarf.h" #include "makename.h" #include "naming.h" #include "esb.h" #ifndef TRIVIAL_NAMING static const char * skipunder(const char *v) { const char *cp = v; int undercount = 0; for (; *cp ; ++cp) { if (*cp == '_') { ++undercount; if (undercount == 2) { return cp+1; } } } return ""; } #endif /* TRIVIAL_NAMING */ static const char * ellipname(int res, int val_in, const char *v, const char *ty, int printonerr) { #ifndef TRIVIAL_NAMING if (glflags.gf_check_dwarf_constants && checking_this_compiler()) { DWARF_CHECK_COUNT(dwarf_constants_result,1); } #endif if (res != DW_DLV_OK) { char buf[100]; char *n; struct esb_s eb; esb_constructor_fixed(&eb,buf,sizeof(buf)); esb_append_printf_s(&eb, "",val_in); /* Capture any name error in DWARF constants */ #ifndef TRIVIAL_NAMING if (printonerr && glflags.gf_check_dwarf_constants && checking_this_compiler()) { if (glflags.gf_check_verbose_mode) { printf("%s of %d (0x%x) is unknown to dwarfdump. " "Continuing. \n",ty,val_in,val_in ); } DWARF_ERROR_COUNT(dwarf_constants_result,1); DWARF_CHECK_ERROR_PRINT_CU(); } #else /* This is for the tree-generation, not dwarfdump itself. */ if (printonerr) { fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. " "Continuing. \n",ty,val_in,val_in ); } #endif n = makename(esb_get_string(&eb)); esb_destructor(&eb); return n; } #ifndef TRIVIAL_NAMING if (glflags.ellipsis) { return skipunder(v); } #endif return v; } const char * get_TAG_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_TAG_name(val_in,&v); return ellipname(res,val_in,v,"TAG",printonerr); } const char * get_children_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_children_name(val_in,&v); return ellipname(res,val_in,v,"children",printonerr); } const char * get_FORM_CLASS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_FORM_CLASS_name(val_in,&v); return ellipname(res,val_in,v,"FORM_CLASS",printonerr); } const char * get_FORM_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_FORM_name(val_in,&v); return ellipname(res,val_in,v,"FORM",printonerr); } const char * get_AT_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_AT_name(val_in,&v); return ellipname(res,val_in,v,"AT",printonerr); } const char * get_OP_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_OP_name(val_in,&v); return ellipname(res,val_in,v,"OP",printonerr); } const char * get_ATE_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ATE_name(val_in,&v); return ellipname(res,val_in,v,"ATE",printonerr); } const char * get_DS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_DS_name(val_in,&v); return ellipname(res,val_in,v,"DS",printonerr); } const char * get_END_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_END_name(val_in,&v); return ellipname(res,val_in,v,"END",printonerr); } const char * get_ATCF_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ATCF_name(val_in,&v); return ellipname(res,val_in,v,"ATCF",printonerr); } const char * get_ACCESS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ACCESS_name(val_in,&v); return ellipname(res,val_in,v,"ACCESS",printonerr); } const char * get_VIS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_VIS_name(val_in,&v); return ellipname(res,val_in,v,"VIS",printonerr); } const char * get_VIRTUALITY_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_VIRTUALITY_name(val_in,&v); return ellipname(res,val_in,v,"VIRTUALITY",printonerr); } const char * get_LANG_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LANG_name(val_in,&v); return ellipname(res,val_in,v,"LANG",printonerr); } const char * get_ID_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ID_name(val_in,&v); return ellipname(res,val_in,v,"ID",printonerr); } const char * get_CC_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CC_name(val_in,&v); return ellipname(res,val_in,v,"CC",printonerr); } const char * get_INL_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_INL_name(val_in,&v); return ellipname(res,val_in,v,"INL",printonerr); } const char * get_ORD_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ORD_name(val_in,&v); return ellipname(res,val_in,v,"ORD",printonerr); } const char * get_DSC_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_DSC_name(val_in,&v); return ellipname(res,val_in,v,"DSC",printonerr); } const char * get_LNS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LNS_name(val_in,&v); return ellipname(res,val_in,v,"LNS",printonerr); } const char * get_LNE_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LNE_name(val_in,&v); return ellipname(res,val_in,v,"LNE",printonerr); } const char * get_MACINFO_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_MACINFO_name(val_in,&v); return ellipname(res,val_in,v,"MACINFO",printonerr); } const char * get_MACRO_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_MACRO_name(val_in,&v); return ellipname(res,val_in,v,"MACRO",printonerr); } const char * get_CFA_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CFA_name(val_in,&v); return ellipname(res,val_in,v,"CFA",printonerr); } const char * get_EH_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_EH_name(val_in,&v); return ellipname(res,val_in,v,"EH",printonerr); } const char * get_FRAME_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_FRAME_name(val_in,&v); return ellipname(res,val_in,v,"FRAME",printonerr); } const char * get_CHILDREN_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CHILDREN_name(val_in,&v); return ellipname(res,val_in,v,"CHILDREN",printonerr); } const char * get_ADDR_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ADDR_name(val_in,&v); return ellipname(res,val_in,v,"ADDR",printonerr); } libdwarf-20210528/dwarfdump/strstrnocase.c0000664000175000017500000000660613767716172015414 00000000000000/* Copyright (C) 2009-2016 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This tries to find the string 'contained' in the string 'container'. it returns true if found, else false. The comparisons are independent of case. Regrettably there is no generally accepted version that does this job, though GNU Linux has strcasestr() which does what we need. Our code here do not behave like strstr or strcasestr in the case of an empty 'contained' argument: we return FALSE (this case is not interesting for dwarfdump). There is a public domain stristr(). But given that dwarfdump is GPL, it would seem (IANAL) that we cannot mix public domain code into the release. The software here is independently written and indeed trivial. The POSIX function tolower() is only properly defined on unsigned char, hence the ugly casts. strstrnocase.c */ #include #include #include "globals.h" Dwarf_Bool is_strstrnocase(const char * container, const char * contained) { const unsigned char *ct = (const unsigned char *)container; for (; *ct; ++ct ) { const unsigned char * cntnd = (const unsigned char *)contained; for (; *cntnd && *ct ; ++cntnd,++ct) { unsigned char lct = tolower(*ct); unsigned char tlc = tolower(*cntnd); if (lct != tlc) { break; } } if (!*cntnd) { /* We matched all the way to end of contained */ /* ASSERT: innerwrong = FALSE */ return TRUE; } if (!*ct) { /* Ran out of container before contained, so no future match of contained is possible. */ return FALSE; } /* No match so far. See if there is more in container to check. */ } return FALSE; } #ifdef TEST static void test(const char *t1, const char *t2,int resexp) { Dwarf_Bool res = is_strstrnocase(t1,t2); if (res == resexp) { return; } printf("Error,mismatch %s and %s. Expected %d got %d\n", t1,t2,resexp,res); } int main() { test("aaaaa","a",1); test("aaaaa","b",0); test("abaaba","ba",1); test("abaaxa","x",1); test("abaabA","Ba",1); test("a","ab",0); test("b","c",0); test("b","",0); test("","c",0); test("","",0); test("aaaaa","aaaaaaaa",0); } #endif libdwarf-20210528/dwarfdump/sanitized.h0000664000175000017500000000333213767717120014644 00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SANITIZED_H #define SANITIZED_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Eliminate control characters from the input, leaving the input unchanged. Return pointer to an ephemeral location (only callfor printf, and only once per printf! */ const char * sanitized(const char *s); void sanitized_string_destructor(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* SANITIZED_H */ libdwarf-20210528/dwarfdump/print_locs.c0000664000175000017500000001371513771431250015017 00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* print data in .debug_loc There is no guarantee this will work because we are assuming that all bytes are valid loclist data, that there are no odd padding or garbage bytes. In normal use one gets into here via an offset from .debug_info, so it could be that bytes not referenced from .debug_info are garbage or even zero padding. So this can fail (error off) as such bytes can lead dwarf_get_loclist_entry() astray. It's also wrong because we don't know what CU or frame each loclist is from, so we don't know the address_size for sure. */ extern int print_locs(Dwarf_Debug dbg, Dwarf_Error *err) { Dwarf_Unsigned offset = 0; Dwarf_Addr hipc_offset = 0; Dwarf_Addr lopc_offset = 0; Dwarf_Ptr data = 0; Dwarf_Unsigned entry_len = 0; Dwarf_Unsigned next_entry = 0; int index = 0; int lres = 0; int fres = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; Dwarf_Half version = 2; /* FAKE */ struct esb_s exprstring; unsigned loopct = 0; struct esb_s secname; glflags.current_section_id = DEBUG_LOC; /* Do nothing if not printing. */ if (!glflags.gf_do_print_dwarf) { return DW_DLV_OK; } if (!glflags.gf_use_old_dwarf_loclist) { printf("\n"); printf("Printing location lists with -c is " "no longer supported\n"); return DW_DLV_OK; } esb_constructor(&exprstring); esb_constructor(&secname); fres = dwarf_get_address_size(dbg, &address_size, err); if (fres != DW_DLV_OK) { esb_destructor(&exprstring); return simple_err_return_msg_either_action(fres, "\nERROR: dwarf_get_address_size() fails."); } fres = dwarf_get_offset_size(dbg, &offset_size, err); if (fres != DW_DLV_OK) { esb_destructor(&exprstring); return simple_err_return_msg_either_action(fres, "\nERROR: dwarf_get_offset_size() fails."); } { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_loc", &truename,TRUE); esb_append(&secname,sanitized(esb_get_string(&truename))); esb_destructor(&truename); } printf("Format : " "index section-offset begin-addr end-addr " "length-of-block-entry\n"); /* Pre=October 2015 version. */ for (loopct = 0; ; ++loopct) { lres = dwarf_get_loclist_entry(dbg, offset, &hipc_offset, &lopc_offset, &data, &entry_len, &next_entry, err); if (lres != DW_DLV_OK) { break; } fres = print_location_operations(dbg, 0, /* passing null, no die known. */ /* indent level*/ 4, data, entry_len,address_size, offset_size, version, &exprstring,err); if (fres == DW_DLV_ERROR) { esb_destructor(&exprstring); esb_destructor(&secname); return simple_err_only_return_action(fres, "\nERROR: getting location entry data fails."); } /* Display offsets */ if (!loopct) { print_secname(dbg,esb_get_string(&secname)); } if (glflags.gf_display_offsets) { ++index; printf(" [%8d] 0x%" DW_PR_XZEROS DW_PR_DUx, index, offset); if (glflags.verbose) { printf(" ", next_entry - entry_len); } } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %8" DW_PR_DUu " %s\n", (Dwarf_Unsigned) lopc_offset, (Dwarf_Unsigned) hipc_offset, entry_len, esb_get_string(&exprstring)); esb_empty_string(&exprstring); offset = next_entry; } if (!loopct) { /* Nothing happened, so announce the section name anyway */ print_secname(dbg,esb_get_string(&secname)); } esb_destructor(&exprstring); esb_destructor(&secname); if (lres == DW_DLV_ERROR) { int rval = 0; struct esb_s m; esb_constructor(&m); esb_append(&m, "\nERROR: dwarf_get_address_size() fails."); esb_append_printf_u(&m, " Offset is 0x%" DW_PR_DUx ".\n",offset); rval = simple_err_only_return_action(lres, esb_get_string(&m)); esb_destructor(&m); return rval; } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/dwarfdump-ta-ext-table.h0000664000175000017500000001152614054205620017117 00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2021-05-28 08:25:09-07:00 */ /* BEGIN FILE */ /* Common extensions */ #define ATTR_TREE_EXT_ROW_COUNT 19 #define ATTR_TREE_EXT_COLUMN_COUNT 15 static unsigned int tag_attr_combination_ext_table [ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = { /* 0x13 - DW_TAG_structure_type */ { 0x00000013,0x0000001d,0x00002007,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x11 - DW_TAG_compile_unit */ { 0x00000011,0x00003fe1,0x00002131,0x00002134,0x00002135, 0x00002130,0x00002132,0x00002133,0x00002119,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4a - DW_TAG_skeleton_unit */ { 0x0000004a,0x00002131,0x00002134,0x00002135,0x00002130, 0x00002132,0x00002133,0x00002119,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x3c - DW_TAG_partial_unit */ { 0x0000003c,0x00000075,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x0000000d,0x00002108,0x00002109,0x0000210a,0x0000210b, 0x00002007,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x04 - DW_TAG_enumeration_type */ { 0x00000004,0x0000003e,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00000001,0x00002107,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0x0000002e,0x00002007,0x00002001,0x0000210c,0x0000210d, 0x0000210e,0x00003fe7,0x00003fe1,0x00002116,0x00002117, 0x00002083,0x00002085,0x00002087,0x00002086,0x00002092,}, /* 0x41 - DW_TAG_type_unit */ { 0x00000041,0x00002133,0x00002130,0x0000210f,0x00002134, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x34 - DW_TAG_variable */ { 0x00000034,0x00002007,0x00002108,0x00002109,0x0000210a, 0x0000210b,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4106 - DW_TAG_GNU_template_template_parameter*/ { 0x00004106,0x00000039,0x0000003a,0x0000003b,0x00000003, 0x00002110,0x00002108,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4107 - DW_TAG_GNU_template_parameter_pack */ { 0x00004107,0x00000039,0x0000003a,0x0000003b,0x00000003, 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4108 - DW_TAG_GNU_formal_parameter_pack */ { 0x00004108,0x00000039,0x0000003a,0x0000003b,0x00000003, 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4109 - DW_TAG_GNU_call_site */ { 0x00004109,0x00000031,0x00002113,0x00000011,0x00000001, 0x00002115,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x410a - DW_TAG_GNU_call_site_parameter */ { 0x0000410a,0x00002111,0x00002112,0x00000031,0x00000002, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x27 - DW_TAG_constant */ { 0x00000027,0x00002303,0x00002304,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x21 - DW_TAG_subrange_type */ { 0x00000021,0x00002305,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x0000001d,0x00002136,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0000000b,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, }; /* END FILE */ libdwarf-20210528/dwarfdump/dwconf.c0000664000175000017500000013253314053210246014115 00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "globals.h" #include "sanitized.h" #include "esb.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if defined(_WIN32) && defined(HAVE_WINDOWS_H) #include #endif /* HAVE_WINDOWS_H */ #include "globals.h" #include "dwarf.h" #include "libdwarf.h" #include #include "dwconf.h" #include "makename.h" /* The nesting level is arbitrary, 2 should suffice. But at least this prevents an infinite loop. */ #define MAX_NEST_LEVEL 3 struct token_s { unsigned tk_len; char *tk_data; }; enum linetype_e { LT_ERROR, LT_COMMENT, LT_BLANK, LT_BEGINABI, LT_REG, LT_FRAME_INTERFACE, LT_CFA_REG, LT_INITIAL_REG_VALUE, LT_SAME_VAL_REG, LT_UNDEFINED_VAL_REG, LT_REG_TABLE_SIZE, LT_ADDRESS_SIZE, LT_INCLUDEABI, LT_ENDABI, LT_OPTION }; struct comtable_s { enum linetype_e type; char *name; size_t namelen; }; static int errcount = 0; /* Count errors found in this scan of the configuration file. */ static char name_begin_abi[] = "beginabi:"; static char name_reg[] = "reg:"; static char name_frame_interface[] = "frame_interface:"; static char name_cfa_reg[] = "cfa_reg:"; static char name_initial_reg_value[] = "initial_reg_value:"; static char name_same_val_reg[] = "same_val_reg:"; static char name_undefined_val_reg[] = "undefined_val_reg:"; static char name_reg_table_size[] = "reg_table_size:"; static char name_address_size[] = "address_size:"; static char name_includeabi[] = "includeabi:"; static char name_endabi[] = "endabi:"; static char name_option[] = "option:"; /* The namelen field is filled in at runtime with the correct value. Filling in a fake '1' avoids a compiler warning. */ static struct comtable_s comtable[] = { {LT_BEGINABI, name_begin_abi,1}, {LT_REG, name_reg,1}, {LT_FRAME_INTERFACE, name_frame_interface,1}, {LT_CFA_REG, name_cfa_reg,1}, {LT_INITIAL_REG_VALUE, name_initial_reg_value,1}, {LT_SAME_VAL_REG, name_same_val_reg,1}, {LT_UNDEFINED_VAL_REG, name_undefined_val_reg,1}, {LT_REG_TABLE_SIZE, name_reg_table_size,1}, {LT_ADDRESS_SIZE, name_address_size,1}, {LT_INCLUDEABI, name_includeabi,1}, {LT_ENDABI, name_endabi,1}, {LT_OPTION, name_option,1}, }; struct conf_internal_s { unsigned long beginabi_lineno; unsigned long frame_interface_lineno; unsigned long initial_reg_value_lineno; unsigned long reg_table_size_lineno; unsigned long address_size_lineno; unsigned long same_val_reg_lineno; unsigned long undefined_val_reg_lineno; unsigned long cfa_reg_lineno; unsigned long regcount; struct dwconf_s * conf_out; const char * conf_name_used; char ** conf_defaults; }; static void init_conf_internal(struct conf_internal_s *s, struct dwconf_s * conf_out) { s->beginabi_lineno = 0; s->frame_interface_lineno = 0; s->initial_reg_value_lineno = 0; s->reg_table_size_lineno = 0; s->address_size_lineno = 0; s->same_val_reg_lineno = 0; s->undefined_val_reg_lineno = 0; s->cfa_reg_lineno = 0; s->cfa_reg_lineno = 0; s->conf_name_used = 0; s->conf_defaults = 0; s->regcount = 0; s->conf_out = conf_out; } static unsigned size_of_comtable = sizeof(comtable) / sizeof(comtable[0]); static FILE *find_a_file(const char *named_file, char **defaults, const char** name_used); static int find_abi_start(FILE * stream, const char *abi_name, long *offset, unsigned long *lineno_out); static int parse_abi(FILE * stream, const char *fname, const char *abiname, struct conf_internal_s *out, unsigned long lineno, unsigned nest_level); static char *get_token(char *cp, struct token_s *outtok); /* This finds a dwarfdump.conf file and then parses it. It updates conf_out as appropriate. This finds the first file (looking in a set of places) with that name. It then looks for the right ABI entry. If the first file it finds does not have that ABI entry it gives up. It would also be reasonable to search every 'dwarfdump.conf' it finds for the abi. But we stop at the first dwarfdump.conf we find. This is the internal call to get the conf data to implement a crude 'includeabi' feature. Each call here starts at offset 0 of a new stream. Returns 0 if no errors found, else returns > 0. */ static int find_conf_file_and_read_config_inner(const char *named_file, const char *named_abi, struct conf_internal_s *conf_internal, unsigned nest_level) { FILE *conf_stream = 0; const char *name_used = 0; long offset = 0; int res = FALSE; unsigned long lineno = 0; errcount = 0; conf_stream = find_a_file(named_file, conf_internal->conf_defaults, &name_used); if (!conf_stream) { ++errcount; if (!named_file || !strlen(named_file)) { printf("dwarfdump found no dwarfdump.conf file " "in any of the standard places\n" "(precede all arguments" "with option --show-dwarfdump-conf to see " "what file paths tried)\n" "If no print/check arguments also provided " "dwarfdump may silently just stop.\n"); } else { printf("dwarfdump found no dwarfdump.conf " "file \"%s\"\n" "If no print/check arguments also provided " "dwarfdump may silently just stop.\n", sanitized(named_file)); } return FOUND_ERROR; } if (glflags.gf_show_dwarfdump_conf) { printf("dwarfdump using configuration " "file \"%s\"\n", sanitized(name_used)); } conf_internal->conf_name_used = name_used; /* And option: lines must come before any abi data. */ res = find_abi_start(conf_stream, named_abi, &offset, &lineno); if (res == FOUND_DONE ||res == FOUND_OPTION) { /* nothing more to do */ fclose(conf_stream); return FOUND_DONE; } if (res == FOUND_ERROR) { ++errcount; fclose(conf_stream); printf("dwarfdump found no usable abi \"%s\" " "in file \"%s\".\n", named_abi?named_abi:"", name_used); return FOUND_ERROR; } /* res == FOUND_ABI_START */ res = fseek(conf_stream, offset, SEEK_SET); if (res != 0) { ++errcount; fclose(conf_stream); printf("dwarfdump seek to %ld offset in %s failed!\n", offset, name_used); return FOUND_ERROR; } parse_abi(conf_stream, name_used, named_abi, conf_internal, lineno, nest_level); fclose(conf_stream); if (errcount) { return FOUND_ERROR; } return FOUND_ABI_START; } /* This is the external-facing call to get the conf data. */ int find_conf_file_and_read_config(const char *named_file, const char *named_abi, char **defaults, struct dwconf_s *conf_out) { int res = 0; struct conf_internal_s conf_internal; init_conf_file_data(conf_out); init_conf_internal(&conf_internal,conf_out); conf_internal.conf_defaults = defaults; res = find_conf_file_and_read_config_inner(named_file, named_abi, &conf_internal,0); return res; } /* Given path strings, attempt to make a canonical file name: that is, avoid superfluous '/' so that no '//' (or worse) is created in the output. The path components are to be separated so at least one '/' is to appear between the two 'input strings' when creating the output. */ #if defined(BUILD_FOR_TEST) || !defined(_WIN32) static char * canonical_append(char *target, unsigned int target_size, const char *first_string, const char *second_string) { size_t firstlen = strlen(first_string); /* +1 +1: Leave room for added "/" and final NUL, though that is overkill, as we drop a NUL byte too. */ if ((firstlen + strlen(second_string) + 1 + 1) >= target_size) { /* Not enough space. */ return NULL; } for (; *second_string == '/'; ++second_string) { } for (; firstlen > 0 && first_string[firstlen - 1] == '/'; --firstlen) { } target[0] = 0; if (firstlen > 0) { strncpy(target, first_string, firstlen); target[firstlen + 1] = 0; } target[firstlen] = '/'; firstlen++; target[firstlen] = 0; strcat(target, second_string); return target; } #endif /* defined(BUILD_FOR_TEST) || !defined(_WIN32) */ #ifdef BUILD_FOR_TEST #define CANBUF 25 struct canap_s { char *res_exp; char *first; char *second; } canap[] = { { "ab/c", "ab", "c"}, { "ab/c", "ab/", "c"}, { "ab/c", "ab", "/c"}, { "ab/c", "ab////", "/////c"}, { "ab/", "ab", ""}, { "ab/", "ab////", ""}, { "ab/", "ab////", ""}, { "/a", "", "a"}, { 0, "/abcdefgbijkl", "pqrstuvwxyzabcd"}, { 0, 0, 0} }; static void test_canonical_append(void) { /* Make buf big, this is test code, so be safe. */ char lbuf[1000]; unsigned i; unsigned failcount = 0; printf("Entry test_canonical_append\n"); for (i = 0;; ++i) { char *res = 0; if (canap[i].first == 0 && canap[i].second == 0) break; res = canonical_append(lbuf, CANBUF, canap[i].first, canap[i].second); if (res == 0) { if (canap[i].res_exp == 0) { /* GOOD */ printf("PASS %u\n", i); } else { ++failcount; printf("FAIL: entry %u wrong, expected " "%s, got NULL\n", i, canap[i].res_exp); } } else { if (canap[i].res_exp == 0) { ++failcount; printf("FAIL: entry %u wrong, got %s " "expected NULL\n", i, res); } else { if (strcmp(res, canap[i].res_exp) == 0) { printf("PASS %u\n", i); /* GOOD */ } else { ++failcount; printf("FAIL: entry %u wrong, " "expected %s got %s\n", i, canap[i].res_exp, res); } } } } printf("FAIL count %u\n", failcount); } #endif /* BUILD_FOR_TEST */ /* Try to find a file as named and open for read. We treat each name as a full name, we are not combining separate name and path components. This is an arbitrary choice... The defaults are listed in command_options.c in the array config_file_defaults[]. Since named_file comes from an esb_get_string, lname may be non-null but pointing to empty string to mean no-name. */ static FILE * find_a_file(const char *named_file, char **defaults, const char ** name_used) { FILE *fin = 0; const char *lname = named_file; const char *type = "r"; int i = 0; #ifdef BUILD_FOR_TEST test_canonical_append(); #endif /* BUILD_FOR_TEST */ if (lname && (strlen(lname) > 0)) { /* Name given, just assume it is fully correct, try no other. */ printf("dwarfdump looking for" " configuration as \"%s\"\n", lname); fin = fopen(lname, type); if (fin) { *name_used = lname; return fin; } return 0; } /* No name given, find a default, if we can. */ for (i = 0; defaults[i]; ++i) { lname = defaults[i]; #ifdef _WIN32 /* Open the configuration file, located in the directory where the tool is loaded from */ { static char szPath[MAX_PATH]; if (GetModuleFileName(NULL,szPath,MAX_PATH)) { char *pDir = strrchr(szPath,'/'); size_t len = 0; if (!pDir) { pDir = strrchr(szPath,'\\'); if (!pDir) { /* No file was found */ return 0; } } /* Add the configuration name to the pathname */ ++pDir; len = pDir - szPath; safe_strcpy(pDir,sizeof(szPath)-len, "dwarfdump.conf",14); lname = szPath; } } #else /* non-Win */ if (strncmp(lname, "HOME/", 5) == 0) { /* arbitrary size */ char buf[2000]; char *homedir = getenv("HOME"); if (homedir) { char *cp = canonical_append(buf, sizeof(buf), homedir, lname + 5); if (!cp) { /* OOps, ignore this one. */ continue; } lname = makename(buf); } } #endif /* _WIN32 */ if (glflags.gf_show_dwarfdump_conf) { if (!lname || !strlen(lname)) { lname=""; } printf("dwarfdump looking for" " configuration as: \"%s\"\n", lname); } fin = fopen(lname, type); if (fin) { *name_used = lname; return fin; } } return 0; } /* Start at a token begin, see how long it is, return length. */ static unsigned find_token_len(char *cp) { unsigned len = 0; for (; *cp; ++cp) { if (isspace(*cp)) { return len; } if (*cp == '#') { return len; /* begins comment */ } ++len; } return len; } /* Skip past all whitespace: the only code that even knows what whitespace is. */ static char * skipwhite(char *cp) { for (; *cp; ++cp) { if (!isspace(*cp)) { return cp; } } return cp; } /* Return TRUE if ok. FALSE if find more tokens. Emit error message if error. */ static int ensure_has_no_more_tokens(char *cp, const char *fname, unsigned long lineno) { struct token_s tok; get_token(cp, &tok); if (tok.tk_len > 0) { printf("dwarfdump.conf error: " "extra characters after command operands, found " "\"%s\" in %s line %lu\n", tok.tk_data, fname, lineno); ++errcount; return FALSE; } return TRUE; } /* There may be many beginabi: lines in a dwarfdump.conf file, find the one we want and return its file offset. */ static int find_abi_start(FILE * stream, const char *abi_name, long *offset, unsigned long *lineno_out) { char buf[100]; unsigned long lineno = 0; for (; !feof(stream);) { struct token_s tok; char *line = 0; long loffset = ftell(stream); line = fgets(buf, sizeof(buf), stream); ++lineno; if (!line) { if (!abi_name) { return FOUND_DONE; } ++errcount; return FOUND_ERROR; } line = get_token(buf, &tok); if (!strcmp(tok.tk_data, "option:")) { get_token(line, &tok); if (tok.tk_data && !strcmp(tok.tk_data, "--format-expr-ops-joined")) { /* print expr ops joined onto one line: matching historical behavior. */ glflags.gf_expr_ops_joined = TRUE; } else { printf("ERROR: option command %s is not understood" " giving up\n",tok.tk_data); ++errcount; return FOUND_ERROR; } continue; } if (strcmp(tok.tk_data, "beginabi:")) { continue; } /* Is beginabi: */ if (!abi_name) { continue; } get_token(line, &tok); if (strcmp(tok.tk_data, abi_name)) { continue; } *offset = loffset; *lineno_out = lineno; return FOUND_ABI_START; } if (!abi_name) { /* All is ok */ return FOUND_DONE; } ++errcount; return FALSE; } /* Turn a non-delimited input char array into a NUL-terminated C string (with the help of makename() to get a permanent address for the result ing string). */ static char * build_string(unsigned tlen, char *cp) { struct esb_s x; char buffer[32]; char *ret = 0; esb_constructor_fixed(&x,buffer,sizeof(buffer)); esb_appendn(&x,cp,tlen); ret = makename(esb_get_string(&x)); esb_destructor(&x); return ret; } /* The tokenizer for our simple parser. */ static char * get_token(char *cp, struct token_s *outtok) { char *lcp = skipwhite(cp); unsigned tlen = find_token_len(lcp); outtok->tk_len = tlen; if (tlen > 0) { outtok->tk_data = build_string(tlen, lcp); } else { outtok->tk_data = ""; } return lcp + tlen; } /* We can't get all the field set up statically very easily, so we get the command string length set here. */ static void finish_comtable_setup(void) { unsigned i; for (i = 0; i < size_of_comtable; ++i) { comtable[i].namelen = strlen(comtable[i].name); } } /* Given a line of the table, determine if it is a command or not, and if a command, which one is it. Return LT_ERROR if it's not recognized. */ static enum linetype_e which_command(char *cp, struct comtable_s **tableentry) { unsigned i = 0; struct token_s tok; if (*cp == '#') return LT_COMMENT; if (!*cp) return LT_BLANK; get_token(cp, &tok); for (i = 0; i < size_of_comtable; ++i) { if (tok.tk_len == comtable[i].namelen && strcmp(comtable[i].name, tok.tk_data) == 0) { *tableentry = &comtable[i]; return comtable[i].type; } } return LT_ERROR; } static int parseoption(char *cp, const char *fname,unsigned long lineno, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; cp = cp + clen + 1; cp = skipwhite(cp); get_token(cp, &tok); if (!tok.tk_data) { printf("ERROR: empty option: command is ignored"); return FALSE; } ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno); if (!strcmp(tok.tk_data,"--format-expr-ops-joined")) { glflags.gf_expr_ops_joined = TRUE; } else { printf("ERROR: option command %s is not understood" " and is ignored",tok.tk_data); return FALSE; } return TRUE; } /* We are promised it's an abiname: command find the name on the line. */ static int parsebeginabi(char *cp, const char *fname, const char *abiname, unsigned long lineno, struct comtable_s *comtab) { size_t clen = comtab->namelen; size_t abinamelen = strlen(abiname); struct token_s tok; cp = cp + clen + 1; cp = skipwhite(cp); get_token(cp, &tok); if (tok.tk_len != abinamelen || strncmp(cp, abiname, abinamelen)) { printf("dwarfdump internal error: " "mismatch \"%s\" with \"%s\" \"%s\" line %lu\n", cp, tok.tk_data, fname, lineno); ++errcount; return FALSE; } ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno); return TRUE; } /* This expands register names as required, but does not ensure no names duplicated. */ #define CONF_TABLE_OVERSIZE 100 static void add_to_reg_table(struct dwconf_s *conf, char *rname, unsigned long rval, const char *fname, unsigned long lineno) { if (conf->cf_regs_malloced == 0) { conf->cf_regs = 0; conf->cf_named_regs_table_size = 0; } if (rval >= conf->cf_named_regs_table_size) { char **newregs = 0; unsigned long newtablen = rval + CONF_TABLE_OVERSIZE; unsigned long newtabsize = newtablen * sizeof(char *); unsigned long oldtabsize = conf->cf_named_regs_table_size * sizeof(char *); newregs = realloc(conf->cf_regs, newtabsize); if (!newregs) { printf("dwarfdump: unable to malloc table %lu bytes. " " %s line %lu\n", newtabsize, fname, lineno); exit(1); } /* Zero out the new entries. */ memset((char *) newregs + (oldtabsize), 0, (newtabsize - oldtabsize)); conf->cf_named_regs_table_size = (unsigned long) newtablen; conf->cf_regs = newregs; conf->cf_regs_malloced = 1; } conf->cf_regs[rval] = rname; return; } /* Our input is supposed to be a number. Determine the value (and return it) or generate an error message. */ static int make_a_number(char *cmd, const char *filename, unsigned long lineno, struct token_s *tok, unsigned long *val_out) { char *endnum = 0; unsigned long val = 0; val = strtoul(tok->tk_data, &endnum, 0); if (val == 0 && endnum == (tok->tk_data)) { printf("dwarfdump.conf error: " "%s missing register number (\"%s\" " "not valid) %s line %lu\n", cmd, tok->tk_data, filename, lineno); ++errcount; return FALSE; } if (endnum != (tok->tk_data + tok->tk_len)) { printf("dwarfdump.conf error: " "%s Missing register number (\"%s\" " "not valid) %s line %lu\n", cmd, tok->tk_data, filename, lineno); ++errcount; return FALSE; } *val_out = val; return TRUE; } /* We are guaranteed it's a reg: command, so parse that command and record the interesting data. */ static int parsereg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s regnum; struct token_s tokreg; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tokreg); cp = get_token(cp, ®num); if (tokreg.tk_len == 0) { printf("dwarfdump.conf error: " "reg: missing register name %s line %lu", fname, lineno); ++errcount; return FALSE; } if (regnum.tk_len == 0) { printf("dwarfdump.conf error: " "reg: missing register number %s line %lu", fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, ®num, &val); if (!ok) { ++errcount; return FALSE; } add_to_reg_table(conf->conf_out, tokreg.tk_data, val, fname, lineno); res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an frame_interface: command. Parse it and record the value data. */ static int parseframe_interface(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing interface number %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } if (val != 2 && val != 3) { printf("dwarfdump.conf error: " "%s only interface numbers 2 or 3 are allowed, " " not %lu. %s line %lu", comtab->name, val, fname, lineno); ++errcount; return FALSE; } conf->conf_out->cf_interface_number = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a cfa_reg: command. Parse it and record the important data. */ static int parsecfa_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing cfa_reg number %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_cfa_reg = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an initial_reg_value: command, parse it and put the reg value where it will be remembered. */ static int parseinitial_reg_value(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing initial reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_initial_rule_value = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parsesame_val_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing same_reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_same_val = val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parseundefined_val_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing undefined_reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_undefined_val = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a table size command, parse it and record the table size. */ static int parsereg_table_size(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing reg table size value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_table_entry_count = (unsigned long) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a table size command, parse it and record the table size. */ static int parseaddress_size(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing address size value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_address_size = (unsigned long) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an endabi: command, parse it and check we have the right abi. */ static int parseendabi(char *cp, const char *fname, const char *abiname, unsigned long lineno, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; int res = 0; cp = cp + clen + 1; cp = get_token(cp, &tok); if (strcmp(abiname, tok.tk_data) != 0) { printf("%s error: " "mismatch abi name %s (here) vs. " "%s (beginabi:) %s line %lu\n", comtab->name, tok.tk_data, abiname, fname, lineno); ++errcount; return FALSE; } res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parseincludeabi(char *cp, const char *fname, unsigned long lineno, char **abiname_out, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; char *name = 0; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); name = makename(tok.tk_data); *abiname_out = name; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* Return TRUE if we succeeded and filed in *out. Return FALSE if we failed (and fill in nothing). beginabi: reg: frame_interface: cfa_reg: initial_reg_value: reg_table_size: endabi: We are positioned at the start of a beginabi: line when called. */ static int parse_abi(FILE * stream, const char *fname, const char *abiname, struct conf_internal_s *conf_internal, unsigned long lineno, unsigned int nest_level) { struct dwconf_s *localconf = conf_internal->conf_out; char buf[1000]; int comtype = 0; static int first_time_done = 0; struct comtable_s *comtabp = 0; int inourabi = FALSE; if (nest_level > MAX_NEST_LEVEL) { ++errcount; printf("dwarfdump.conf: includeabi nest " "too deep in %s at line %lu\n", fname, lineno); return FALSE; } if (first_time_done == 0) { finish_comtable_setup(); first_time_done = 1; } for (; !feof(stream);) { char *line = 0; /* long loffset = ftell(stream); */ line = fgets(buf, sizeof(buf), stream); if (!line) { ++errcount; printf("dwarfdump: end of file or error" " before endabi: in %s, line %lu\n", fname, lineno); return FALSE; } ++lineno; line = skipwhite(line); comtype = which_command(line, &comtabp); switch (comtype) { case LT_OPTION: if (!inourabi) break; parseoption(line, fname, lineno,comtabp); break; case LT_ERROR: ++errcount; printf ("dwarfdump: Unknown text in %s is \"%s\" " "at line %lu\n", fname, line, lineno); break; case LT_COMMENT: break; case LT_BLANK: break; case LT_BEGINABI: if (conf_internal->beginabi_lineno > 0) { ++errcount; printf("dwarfdump: Encountered beginabi: " "when not expected. " "%s line %lu previous beginabi line %lu\n", fname, lineno, conf_internal->beginabi_lineno); } conf_internal->beginabi_lineno = lineno; inourabi = parsebeginabi(line, fname, abiname, lineno, comtabp); break; case LT_REG: if (!inourabi) break; parsereg(line, fname, lineno, conf_internal, comtabp); conf_internal->regcount++; break; case LT_FRAME_INTERFACE: if (!inourabi) break; if (conf_internal->frame_interface_lineno > 0) { ++errcount; printf("dwarfdump: Encountered duplicate " "frame_interface: " "%s line %lu previous frame_interface: " "line %lu\n", fname, lineno, conf_internal->frame_interface_lineno); } conf_internal->frame_interface_lineno = lineno; parseframe_interface(line, fname, lineno, conf_internal, comtabp); break; case LT_CFA_REG: if (!inourabi) break; if (conf_internal->cfa_reg_lineno > 0) { printf("dwarfdump: Encountered duplicate cfa_reg: " "%s line %lu previous cfa_reg line %lu\n", fname, lineno, conf_internal->cfa_reg_lineno); ++errcount; } conf_internal->cfa_reg_lineno = lineno; parsecfa_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_INITIAL_REG_VALUE: if (!inourabi) break; if (conf_internal->initial_reg_value_lineno > 0) { printf ("dwarfdump: Encountered duplicate " "initial_reg_value: " "%s line %lu previous initial_reg_value: " "line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); ++errcount; } conf_internal->initial_reg_value_lineno = lineno; parseinitial_reg_value(line, fname, lineno, conf_internal, comtabp); break; case LT_SAME_VAL_REG: if (!inourabi) break; if (conf_internal->same_val_reg_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered duplicate " "same_val_reg: " "%s line %lu previous initial_reg_value: " "line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); } conf_internal->same_val_reg_lineno = lineno; parsesame_val_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_UNDEFINED_VAL_REG: if (!inourabi) break; if (conf_internal->undefined_val_reg_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered duplicate " "undefined_val_reg: " "%s line %lu previous initial_reg_value: " "line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); } if (!inourabi) break; conf_internal->undefined_val_reg_lineno = lineno; parseundefined_val_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_REG_TABLE_SIZE: if (!inourabi) break; if (conf_internal->reg_table_size_lineno > 0) { printf("dwarfdump: duplicate reg_table_size: " "%s line %lu previous reg_table_size: line %lu\n", fname, lineno, conf_internal->reg_table_size_lineno); ++errcount; } conf_internal->reg_table_size_lineno = lineno; parsereg_table_size(line, fname, lineno, conf_internal, comtabp); break; case LT_ENDABI: if (!inourabi) break; parseendabi(line, fname, abiname, lineno, comtabp); if (conf_internal->regcount > localconf->cf_table_entry_count) { printf("dwarfdump: more registers named than " " in %s ( %lu named vs %s %lu)" " %s line %lu\n", abiname, (unsigned long) conf_internal->regcount, name_reg_table_size, (unsigned long) localconf->cf_table_entry_count, fname, (unsigned long) lineno); ++errcount; } inourabi = FALSE; return TRUE; case LT_ADDRESS_SIZE: if (!inourabi) break; if (conf_internal->address_size_lineno > 0) { printf("dwarfdump: duplicate address_size: " "%s line %lu previous address_size:" " line %lu\n", fname, lineno, conf_internal->address_size_lineno); ++errcount; } conf_internal->address_size_lineno = lineno; parseaddress_size(line, fname, lineno, conf_internal, comtabp); break; case LT_INCLUDEABI: { char *abiname_inner = 0; unsigned long abilno = conf_internal->beginabi_lineno; int ires = 0; if (!inourabi) break; ires = parseincludeabi(line,fname,lineno, &abiname_inner,comtabp); if (ires == FALSE) { return FALSE; } /* For the nested abi read, the abi line number must be set as if not-yet-read and then restored. */ conf_internal->beginabi_lineno = 0; ires = find_conf_file_and_read_config_inner( conf_internal->conf_name_used, abiname_inner, conf_internal,nest_level+1); if (ires == FOUND_ERROR) { return ires; } conf_internal->beginabi_lineno = abilno; } break; default: printf("dwarfdump internal error," " impossible line type %d %s %lu \n", (int) comtype, fname, lineno); exit(1); } } ++errcount; printf("End of file, no endabi: found. %s, line %lu\n", fname, lineno); return FALSE; } /* MIPS/IRIX frame register names. For alternate name sets, use dwarfdump.conf or revise dwarf.h and libdwarf.h and this table. */ static char *regnames[] = { "cfa", "r1/at", "r2/v0", "r3/v1", "r4/a0", "r5/a1", "r6/a2", "r7/a3", "r8/t0", "r9/t1", "r10/t2", "r11/t3", "r12/t4", "r13/t5", "r14/t6", "r15/t7", "r16/s0", "r17/s1", "r18/s2", "r19/s3", "r20/s4", "r21/s5", "r22/s6", "r23/s7", "r24/t8", "r25/t9", "r26/k0", "r27/k1", "r28/gp", "r29/sp", "r30/s8", "r31", "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", "ra", "slk", }; /* Naming a few registers makes printing these just a little bit faster. */ static char *genericregnames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20" }; /* This is a simple generic set of registers. The table entry count is pretty arbitrary. */ void init_conf_file_data(struct dwconf_s *config_file_data) { unsigned generic_table_count; config_file_data->cf_abi_name = ""; config_file_data->cf_config_file_path = ""; config_file_data->cf_interface_number = 3; config_file_data->cf_table_entry_count = 100; config_file_data->cf_initial_rule_value = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = DW_FRAME_SAME_VAL; config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_regs = genericregnames; generic_table_count = sizeof(genericregnames) / sizeof(genericregnames[0]); config_file_data->cf_named_regs_table_size = generic_table_count; config_file_data->cf_regs_malloced = 0; } /* These defaults match MIPS/IRIX ABI defaults, but this function is not actually used. For a 'generic' ABI, see -R or init_conf_file_data(). To really get the old MIPS, use '-x abi=mips'. For other ABIs, see -x abi= to configure dwarfdump (and libdwarf) frame data reporting at runtime. */ void init_mips_conf_file_data(struct dwconf_s *config_file_data) { unsigned long base_table_count = sizeof(regnames) / sizeof(regnames[0]); memset(config_file_data, 0, sizeof(*config_file_data)); /* Interface 2 is deprecated, but for testing purposes is acceptable. */ config_file_data->cf_interface_number = 2; config_file_data->cf_table_entry_count = DW_REG_TABLE_SIZE; config_file_data->cf_initial_rule_value = DW_FRAME_REG_INITIAL_VALUE; config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = DW_FRAME_SAME_VAL; config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_regs = regnames; config_file_data->cf_named_regs_table_size = base_table_count; config_file_data->cf_regs_malloced = 0; if (config_file_data->cf_table_entry_count != base_table_count) { printf("dwarfdump: improper base table initialization, " "header files wrong: " "DW_REG_TABLE_SIZE %u != string table size %lu\n", (unsigned) DW_REG_TABLE_SIZE, (unsigned long) base_table_count); exit(1); } return; } /* A 'generic' ABI. For up to 1200 registers. Perhaps cf_initial_rule_value should be d UNDEFINED VALUE (1034) instead, but for the purposes of getting the dwarfdump output correct either will work. */ void init_generic_config_1200_regs(struct dwconf_s *config_file_data) { unsigned long generic_table_count = sizeof(genericregnames) / sizeof(genericregnames[0]); config_file_data->cf_interface_number = 3; config_file_data->cf_table_entry_count = 1200; /* There is no defined name for cf_initial_rule_value, cf_same_val, or cf_undefined_val in libdwarf.h, these must just be high enough to be higher than any real register number. DW_FRAME_CFA_COL3 must also be higher than any real register number. */ config_file_data->cf_initial_rule_value = 1235; /* SAME VALUE */ config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = 1235; config_file_data->cf_undefined_val = 1234; config_file_data->cf_regs = genericregnames; config_file_data->cf_named_regs_table_size = generic_table_count; config_file_data->cf_regs_malloced = 0; } /* Print the 'right' string for the register we are given. Deal sensibly with the special regs as well as numbers we know and those we have not been told about. We are not allowing negative register numbers. */ void print_reg_from_config_data(Dwarf_Unsigned reg, struct dwconf_s *config_data) { char *name = 0; if (reg == config_data->cf_cfa_reg) { fputs("cfa",stdout); return; } if (reg == config_data->cf_undefined_val) { fputs("u",stdout); return; } if (reg == config_data->cf_same_val) { fputs("s",stdout); return; } if (config_data->cf_regs == 0 || reg >= config_data->cf_named_regs_table_size) { printf("r%" DW_PR_DUu "",reg); return; } name = config_data->cf_regs[reg]; if (!name) { /* Can happen, the reg names table can be sparse. */ printf("r%" DW_PR_DUu "", reg); return; } fputs(name,stdout); return; } void free_all_dwconf(struct dwconf_s *conf) { if (conf->cf_regs_malloced) { free(conf->cf_regs); } conf->cf_regs = 0; conf->cf_named_regs_table_size =0; conf->cf_regs_malloced = 0; } libdwarf-20210528/dwarfdump/checkutil.h0000644000175000017500000000747313762722344014634 00000000000000/* Copyright (C) 2011 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef CHECKUTIL_H #define CHECKUTIL_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Map information. Depending on the specific functions used various fields here are either used or ignored. */ typedef struct { Dwarf_Bool bFlag; /* General flag */ const char *name; /* Generic name */ Dwarf_Addr key; /* Used for binary search, the key is either a pc address or a DIE offset depending on which bucket table is in use. */ Dwarf_Addr base; /* Used for base address */ Dwarf_Addr low; /* Used for Low PC */ Dwarf_Addr high; /* Used for High PC */ } Bucket_Data; /* This groups Bucket_Data records into a 'bucket' so that a single malloc creates BUCKET_SIZE entries. The intent is to reduce overhead (as compared to having next/previous pointers in each Bucket_Data and mallocing each Bucket_Data individually. */ #define BUCKET_SIZE 2040 typedef struct bucket { int nEntries; Bucket_Data Entries[BUCKET_SIZE]; struct bucket *pNext; } Bucket; /* This Forms the head record of a list of Buckets. */ typedef struct { int kind; /* Kind of bucket */ Dwarf_Addr lower; /* Lower value for data */ Dwarf_Addr upper; /* Upper value for data */ Bucket_Data *pFirst; /* First sentinel */ Bucket_Data *pLast; /* Last sentinel */ Bucket *pHead; /* First bucket in set */ Bucket *pTail; /* Last bucket in set */ } Bucket_Group; Bucket_Group *AllocateBucketGroup(int kind); void ReleaseBucketGroup(Bucket_Group *pBucketGroup); void ResetBucketGroup(Bucket_Group *pBucketGroup); void ResetSentinelBucketGroup(Bucket_Group *pBucketGroup); void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull); void AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key,Dwarf_Addr base,Dwarf_Addr low,Dwarf_Addr high, const char *name, Dwarf_Bool bFlag); Dwarf_Bool DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key); Dwarf_Bool FindAddressInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr address); Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key); Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key); Bucket_Data *FindNameInBucketGroup(Bucket_Group *pBucketGroup, char *name); Dwarf_Bool IsValidInBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr pc); void ResetLimitsBucketSet(Bucket_Group *pBucketGroup); void SetLimitsBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr lower,Dwarf_Addr upper); Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo, const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* CHECKUTIL_H */ libdwarf-20210528/dwarfdump/print_loclists.c0000664000175000017500000002630013770743770015721 00000000000000/* Copyright (C) 2020 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* DWARF5 has the new .debug_loclists section. Here we print that data. The raw printing covers all the content of the section but without relating it to any compilation unit. Printing the actual address means printing with the actual DIEs on hand. */ #include "config.h" #include "globals.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" static void print_sec_name(Dwarf_Debug dbg) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_loclists", &truename,TRUE); printf("\n%s\n\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } static int print_offset_entry_table(Dwarf_Debug dbg, Dwarf_Unsigned contextnum, Dwarf_Unsigned offset_entry_count, Dwarf_Error *error) { Dwarf_Unsigned e = 0; unsigned colmax = 4; unsigned col = 0; int res = 0; int hasnewline = TRUE; for ( ; e < offset_entry_count; ++e) { Dwarf_Unsigned value = 0; if (e == 0) { printf(" Location Offset Table :\n"); } hasnewline = FALSE; res = dwarf_get_loclist_offset_index_value(dbg, contextnum,e,&value,0,error); if (res != DW_DLV_OK) { return res; } if (col == 0) { printf(" [%2" DW_PR_DUu "]",e); } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx, value); col++; if (col == colmax) { printf("\n"); hasnewline = TRUE; col = 0; } } if (!hasnewline) { printf("\n"); } return DW_DLV_OK; } static void print_opsbytes(Dwarf_Unsigned expr_ops_blocklen, Dwarf_Small* expr_ops) { Dwarf_Unsigned i = 0; if (!expr_ops_blocklen) { return; } printf(" opsbytes:"); for ( ; i < expr_ops_blocklen; ++i ) { Dwarf_Small *b = expr_ops+i; printf(" %02x", *b); } printf(" "); } /* Print single raw lle */ static int print_single_lle(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Unsigned contextnum, Dwarf_Unsigned lineoffset, Dwarf_Unsigned code, Dwarf_Unsigned v1, Dwarf_Unsigned v2, Dwarf_Unsigned expr_ops_blocklen, UNUSEDARG Dwarf_Unsigned expr_ops_offset, Dwarf_Small *expr_ops, Dwarf_Unsigned entrylen) { int res = DW_DLV_OK; const char *name = ""; struct esb_s m; esb_constructor(&m); res = dwarf_get_LLE_name(code,&name); if (res != DW_DLV_OK) { /* ASSERT: res == DW_DLV_NO_ENTRY, see dwarf_names.c */ esb_append_printf_u(&m, "",code); } else { esb_append(&m,name); } printf(" "); printf("<0x%" DW_PR_XZEROS DW_PR_DUx "> %-20s", lineoffset,esb_get_string(&m)); switch(code) { case DW_LLE_end_of_list: printf(" "); printf(" "); break; case DW_LLE_base_addressx: printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ,v1); printf(" "); break; case DW_LLE_startx_endx: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; case DW_LLE_startx_length: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; case DW_LLE_offset_pair: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; case DW_LLE_default_location: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; case DW_LLE_base_address: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1); printf(" "); break; case DW_LLE_start_end: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; case DW_LLE_start_length: printf( " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ,v1,v2); break; default: printf(" ERROR: Unknown LLE code in .debug_loclists. %s\n", esb_get_string(&m)); simple_err_return_msg_either_action(res, esb_get_string(&m)); break; } printf( " %" DW_PR_DUu,entrylen); esb_destructor(&m); if (glflags.verbose && expr_ops_blocklen > 0) { printf("\n"); printf(" "); printf(" opslen %" DW_PR_DUu,expr_ops_blocklen); print_opsbytes(expr_ops_blocklen,expr_ops); } printf("\n"); return res; } /* Prints the raw content. Exactly as in .debug_loclists */ static int print_entire_loclist(Dwarf_Debug dbg, Dwarf_Unsigned contextnumber, Dwarf_Unsigned offset_of_first_loc, Dwarf_Unsigned offset_past_last_locentry, Dwarf_Error *error) { /* These offsets are rnglists section global offsets, not rnglist context local offsets. */ Dwarf_Unsigned curoffset = offset_of_first_loc; Dwarf_Unsigned endoffset = offset_past_last_locentry; int res = 0; Dwarf_Unsigned ct = 0; for ( ; curoffset < endoffset; ++ct ) { unsigned entrylen = 0; unsigned code = 0; Dwarf_Unsigned v1 = 0; Dwarf_Unsigned v2 = 0; Dwarf_Unsigned expr_ops_blocksize = 0; Dwarf_Unsigned expr_ops_offset = 0; Dwarf_Small *expr_ops_data = 0; if (!ct) { printf(" Loc (raw)\n"); printf(" Offset entryname val1 " " val2 entrylen\n"); } /* This returns ops data as in DWARF. No application of base addresses or anything. */ res = dwarf_get_loclist_lle(dbg,contextnumber, curoffset,endoffset, &entrylen, &code,&v1,&v2, &expr_ops_blocksize,&expr_ops_offset,&expr_ops_data, error); if (res != DW_DLV_OK) { return res; } print_single_lle(dbg,contextnumber,curoffset, code,v1,v2,expr_ops_blocksize,expr_ops_offset, expr_ops_data,entrylen); curoffset += entrylen; if (curoffset > endoffset) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m, "DW_DLE_USER_DECLARED_ERROR: " "final RLE in " ".debug_rnglists runs past end of its area " "so current offset 0x%" DW_PR_DUx,curoffset); esb_append_printf_u(&m," exceeds context 1-past-end" " offset of 0x%" DW_PR_DUx ".",endoffset); dwarf_error_creation(dbg,error, esb_get_string(&m)); esb_destructor(&m); return DW_DLV_ERROR; } } return DW_DLV_OK; } int print_raw_all_loclists(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned i = 0; res = dwarf_load_loclists(dbg,&count,error); if (res != DW_DLV_OK) { return res; } print_sec_name(dbg); printf(" Number of loclists contexts: %" DW_PR_DUu "\n", count); for (i = 0; i < count ; ++i) { Dwarf_Unsigned header_offset = 0; Dwarf_Small offset_size = 0; Dwarf_Small extension_size = 0; unsigned version = 0; /* 5 */ Dwarf_Small address_size = 0; Dwarf_Small segment_selector_size = 0; Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned offset_of_offset_array = 0; Dwarf_Unsigned offset_of_first_locentry = 0; Dwarf_Unsigned offset_past_last_locentry = 0; res = dwarf_get_loclist_context_basics(dbg,i, &header_offset, &offset_size, &extension_size, &version,&address_size,&segment_selector_size, &offset_entry_count,&offset_of_offset_array, &offset_of_first_locentry, &offset_past_last_locentry, error); if (res != DW_DLV_OK) { struct esb_s m; esb_constructor(&m); esb_append_printf_u(&m,"ERROR: Getting debug_rnglists " "entry %u we unexpectedly stop early.",i); simple_err_return_msg_either_action(res, esb_get_string(&m)); esb_destructor(&m); return res; } printf(" Context number : %3" DW_PR_DUu "\n",i); printf(" Version : %3u\n",version); printf(" address size : %3u\n",address_size); printf(" offset size : %3u\n",offset_size); if (glflags.verbose) { printf(" extension size : %3u\n",extension_size); } printf(" segment selector size : %3u\n", segment_selector_size); printf(" offset entry count : %3" DW_PR_DUu "\n", offset_entry_count); printf(" context size in bytes : %3" DW_PR_DUu "\n", offset_past_last_locentry - header_offset); if (glflags.verbose) { printf(" Offset in section : " "0x%" DW_PR_XZEROS DW_PR_DUx"\n", header_offset); printf(" Offset of offsets : " "0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_of_offset_array); printf(" Offsetof first loc : " "0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_of_first_locentry); printf(" Offset past locations : " "0x%" DW_PR_XZEROS DW_PR_DUx"\n", offset_past_last_locentry); } if (offset_entry_count) { res = print_offset_entry_table(dbg,i,offset_entry_count, error); if (res == DW_DLV_ERROR) { return res; } } if ((offset_of_first_locentry+1) < offset_past_last_locentry) { res = print_entire_loclist(dbg,i, offset_of_first_locentry, offset_past_last_locentry, error); if (res != DW_DLV_OK) { return res; } } } return DW_DLV_OK; } libdwarf-20210528/dwarfdump/ChangeLog20110000664000175000017500000003753113644370703014563 000000000000002011-12-14 DavidAnderson * print_die.c: Add support for newer DW_OP_GNU_* . 2011-12-13 DavidAnderson * dwarfdump.c, common.c: Update version string. * tag_attr_ext.list, tag_common.h: New information on GNU attributes meant allowing a larger row count. 2011-12-13 DavidAnderson * tag_common.h: A new attr in the .list means increasing the column count. 2011-12-13 DavidAnderson * print_lines.c: Now prints no-column as 0 not -1. And prints the DWARF3/4 line table values when present. * tag_attr_ext.list: Add a GNU extension. 2011-10-30 DavidAnderson * configure.in: Removed a couple bogus lines which were reporting strange shell errors. * configure: Regenerated. * dwarfdump.c: Refine the error outputs so bogus reports do not print. Refactor the debuginfo/types prints for better reporting of errors. * globals.h: Refactoring meant changing one prototype here, the print_infos() prototype. * print_die.c: Refactor the debuginfo/types prints for better reporting of errors. Remove an 'error' report about DW_DLE_REF_SIG8_NOT_HANDLED. It's unclear what we might want to do here in future, but an error report is misleading. 2011-10-29 DavidAnderson * dwarfdump.c, common.c: Update version strings. 2011-10-29 DavidAnderson * dwarfdump.c: Reset the CU hints at each new section. Set up reloc flags so debug_types gets relocated if necessary. * globals.h: Add DEBUG_TYPES for the .debug_types section. Add a type-unit signature pretty-printer function. Add DW_SECTION_REL_DEBUG_TYPES so debug_types can be relocated. * print_reloc.c: Add entries so debug_types can get relocated. * print_die.c: Now we handle both debug_info and debug_types sections. Moved some CU header print operations to little helper functions to clarify the code. Refactored print_infos() to deal with debug_types and debug_info. Using the new libdwarf functions that allow debug_types. * print_lines.c: Delete unused local variable and its setting code. 2011-10-26 DavidAnderson * Makefile.in, README: Added Make settings of PREINCS POSTINCS PRELIBS, POSTLIBS to simplify building when libdwarf or libelf are not in the normal locations. Documented usable ways to deal with unusual situations at build time. 2011-10-24 DavidAnderson * common.c: Update version string. * dwarfdump.c: Update version string. To get '-c cu-name' to work we need to set a local flag which is now set. * dwarfdump.1: Clearly identify the command line options where URI style input is expected. 2011-10-23 DavidAnderson * dwarfdump.c: Fix omission of a 'break' statement for case 'q'. 2011-10-23 DavidAnderson * dwarfdump.1: Now command line input strings are translated from uri-style * dwarfdump.c: Translate input strings to from uri style to characters. Fix indentation mistakes. Fix constness issues on character strings. * dwconf.c: Fix constness issues on character strings. * dwconf.h: Fix constness issues on character strings. * globals.h: Fix constness issues on character strings. * makename.c: Fix constness issues on character strings. * makename.h: Fix constness issues on character strings. * uri.c: Fix indentation mistakes. 2011-10-22 DavidAnderson * common.c :Update version string. * dwarfdump.c: Update version string. Do not set ranges_flag with -a because that is unsafe to print seperately in general. * dwarfdump.1: Rewrite the man page for completeness and accuracy. 2011-10-11 DavidAnderson * common.c: Update version string. * dwarfdump.c: Update version string and translate -S strings from uri-style to standard strings so spaces and other standard characters are easily represented (no quoting problems). Update version string. * print_die.c: For -S -W we were printing the wrong die-level. * uri.h,uri.c: Add the translate_from_uri() function. Fix some of the tests in uri.c to match to- and from-uri. 2011-10-09 DavidAnderson * common.c, dwarfdump.c: Update version strings. 2011-10-09 DavidAnderson * dwconf.c,print_die.c, print_frames.c: Fix bad indentation. 2011-10-09 DavidAnderson * print_die.c (get_location_list): Tests for DW_DLV_ERROR were written without {}, added in the braces. 2011-10-08 DavidAnderson * dwarfdump.cc: If doing any relevant checking, instantiate all three possibly-usable BucketGroup objects. That makes it simpler to avoid a coredump when the user provides a nonsensical option set -- at a cost of a very small amount of memory. 2011-10-06 DavidAnderson * dwarfdump.c: Removed a newline in a printf to match dwarfdump2. Calls of get_attr_value() now have extra argument, so fix them. * dwarfdump.conf: Having 'mips' be an ABI which really reflected the IRIX abi and IRIX compilers was a mistake. Now that abi works for modern MIPS. * globals.h: get_attr_value() adds an argument. * print_die.c: Expanded the error messages in a couple type_offset_result checks. Worked around the global nature of esb_base by saving it locally while we recursively traverse DW_AT_type like things looking for bad references. Added a 'verbose' argument a few places so (at a critical point) show_form_itself won't add a form string when we really don't want it to. * print_static_funcs.c: Fixed an error string so it says static funcs, not pubnames. * print_lines.c: Ensure we only check for errors when we request such checking. * print_reloc.c: Ensure we don't index off the end of scn_names. Deal with missing names and bad symbol indexes consistently. When working with a .rela, report name as the section name instead of calling it .rel in the relocations output. 2011-10-05 DavidAnderson * dwarfdump.c: Increased COMPILER_TABLE_MAX for better reporting. Provide a 'HARMLESS ERROR' title in output if there are any such. One issue is (for relocatable objects) libdwarf attempts to continue even if relocations fail, and a relocation failure is now counted as a harmless error (even if it turns out to be harmful!). When sorting compilers_detected, use the producer name to sort when error counts are identical. If the compiler table fills up, print a note. With -ka, no longer explicitly turn check_frames_extended off, it is off already unless the user turned it on explicitly with -kxe. * print_die.c: The check for a file number (decl_file) was simply wrong. Made some detail changes to reporting. * print_frames.c: Added comments about the inefficiency for getting function names when printing frames (dwarfdump2 does not suffer the same inefficiency). * print_locs.c: Do not use a side effect for updating the index before printing in print_locs(). 2011-10-03 DavidAnderson * dwarfdump.c: for -kF, add check_lines. Ensure uniformity in the usage-text ending. * print_lines.c: Ensure lines printing suppresses some error reporting when appropriate. 2011-10-03 DavidAnderson * print_die.c: Fix the formx code by removing recently-added use of llabs(). Fix format botch, and correct small error string mistakes. Empty esb_extra string when it is no longer valid. 2011-10-03 DavidAnderson * dwarfdump.c: Minor formatting changes. * print_die.c: Initialize some local varables at definition. Ensure that we do not get a FORM name in a name string (so a test works right). And also ensure a FORM name does not get into a compiler-target setting. Refine the formx_print_value() so it is more complete (like dwarfdump2). Ensure show_form_itself() uses the argument, not a global, for the show-form test. * naming.c: Introduce a {} pair on an 'if' to reduce the possibility of future errors. * print_pubnames.c: Add error details to match dwarfdump2. * print_ranges.c: If not printing, return immediately. * print_reloc.c: A test was coded with = where == was needed. * print_types.c: Move local variable definitions to the block they are used in. 2011-09-29 DavidAnderson * dwarfdump.c: Amplifying the -n help string. * print_abbrev.c: Adding the standard test of the section print option before printing the header line for the abbrevs section. * print_die.c: Added a {} pair to avoid eventual bug. * print_frames.c: Reformatted a comment for readability. * print_lines.c: Added a status test for consistency with the rest of the code. * print_reloc.c: One of the assign-and-test removal changes in the previous changes was wrong. 2011-09-26 DavidAnderson * dwarfdump.c: Removed duplicate usage_text strings. * print_reloc.c: In case we don't have ELF64 headers, do the last-best-hope internal define in the right place so it actually helps. For some local variables, ensure they have values defined at the definition point. Switch some assign-and-test into two lines. 2011-09-20 DavidAnderson * Makefile.in: Fixed typo in comment. * common.c: Use snprintf, not sprintf. Updated version string. * dwarfdump.c: Correct typo and move usage_text to a source position corresponding to that in dwarfdump.cc. Updated version string. 2011-09-16 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-15 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-14 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-08 DavidAnderson * config.h, configure.in, dwconf.c, globals.h: Switch compile dependency to configure time HAVE_STDAFX_H instead a system-dependent ifdef. * configure: regenerate. 2011-09-08 DavidAnderson * print_frames.c: Ensure each tsearch tree pointer is zeroed after emptying the tree. * addrmap.c: Now we actually free all the records, we were misusing tsearch a little bit. 2011-09-05 DavidAnderson * print_frames.c: Now only check duplicate fdes if checking frames. * dwarfdump.conf: Updated to use address_size and includeabi. * dwconf.h, dwconf.c: Adding configure keywords address_size and includeabi. 2011-09-02 DavidAnderson * common.c,dwarfdump.c: Update version string. 2011-06-07 DavidAnderson * dwarfdump.c,common.c: Updated version string. * dwarfdump.c: Refactor setting of do_print_dwarf and do_check_dwarf into a function. Ensure that one of the refactored new functions is called in every case an option requires such call. Ensured indents ok. * print_lines.c (print_line_numbers_this_cu): When not checking added a check to insure we don't try to call a checking-related function. 2011-06-07 DavidAnderson * CODINGSTYLE: Added this new document. * common.c: Updated version string. * dwarfdump.c: Updated version string, fixed indentation. * print_lines.c: Two line table checks moved from decl_file to line_table sections of the summary report and both now show the possibly-wrong pc. Since one is not necessarily a bug, the wording of the message now has 'possibly' in it. * print_die.c: Reinitialize subprogram-relative pc high/low seen_PU_high_address whenever compilation unit changes, and use that field to avoid an erroneous comparison (when checking for an error). Fix some indentation errors introduced recently. 2011-06-06 DavidAnderson * dwarfdump.c: Changed the missing-producer-attribute default string used in summary/error outputs to "" so it is this string clearer. 2011-06-06 DavidAnderson * print_die.c: Now we strip off quotes dwarfdump added so -S match=main and the like work. 2011-06-06 DavidAnderson * common.c: Updated version string. * dwarfdump.c: Updated version string. * print_die.c: Corrected handling of DW_AT_data_member_location. Corrected handling of 'class constant' function formxdata_print_value() so it does not leak memory. 2011-06-05 DavidAnderson * dwarfdump.c: Updated version string. Now -kd forces a summary error report, always. Even if no errors found or even checked-for. * common.c: Updated version string. 2011-06-05 DavidAnderson * dwarfdump.c,print_aranges.c,print_reloc.c: A few indents did not match the standard multiple-of-4-spaces. Corrected. 2011-06-03 DavidAnderson * checkutil.c (ProcessBucketGroup): Deleted unused local variables. * common.c: Updated version string. * dwarfdump.1: Made the -k discussion more complete and accurate. Most option details are in the dwarfdump help/usage message, not in dwarfdump.1, to keep the man page small. * dwarfdump.c: Updated version string. Made more variables static in recognition they are only touched in this file. Added {} on some if statements to make the body clear. Parenthesized a complex test with && || to clarify intent. Added sanity testing of the 'current compiler' count and its use. * globals.h: Added safe_strcpy() prototype as it is used by multiple source files so we need a visible prototype. * print_aranges.c: Add 'arange end' printing (it is a real DWARF record type, so should be printed). Add a test to avoid duplicated die printing and error-counting when it is not requested. * print_die.c: An = in an if corrected to ==. Parenthesized a complex test with && || to clarify intent. Deleted an unused local variable. * print_lines.c: Deleted unused local variables. Added {} for each struct in an array so the initialization gets done right. * tag_attr.c: Deleted an unused local variable. * tag_tree.c: Deleted an unused local variable. 2011-04-23 DavidAnderson * dwarfdump.c, common.c: Updated DWARF_VERSION string. 2011-01-04 DavidAnderson * print_frames.h print_static_vars.c Makefile.in print_static_funcs.c print_sections.c print_strings.c print_locs.c print_die.c print_reloc.c print_reloc.h print_lines.c print_pubnames.c dwarfdump.c strstrnocase.c tag_tree.c print_ranges.c print_abbrevs.c print_macros.c configure.in tag_attr.c dwarfdump.1 naming.c esb.c checkutil.c makename.c dwconf.c print_types.c checkutil.h tag_tree.list print_weaknames.c globals.h common.c print_frames.c print_aranges.c common.h: New correctness tests and new formatting of various reports. libdwarf-20210528/dwarfdump/dwarf_tsearchbal.c0000664000175000017500000007036214003122556016132 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2 And based on chapter 6.2.3 Balanced Trees (sometimes call AVL trees) Algorithm A and the sketch on deletion. The wikipedia page on AVL trees is also quite useful. A Key equation is: bal-factor-node-k = height-left-subtree - height-right-subtree We don't know the absolute height, but we do know the balance factor of the pointed-to subtrees (-1,0, or 1). And we always know if we are adding or deleting a node. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #ifdef HAVE_STDLIB_H #include "stdlib.h" /* for free() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include /* for printf */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define IMPLEMENTD15 1 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* head is a special link. rlink points to root node. head-> llink is a tree depth value. Using a pointer. root = head->rlink. The keypointer and balance fields of the head node are not used. Might be sensible to use the head balance field as a tree depth instead of using llink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. We will request free, so const void * is not quite right. */ void *keyptr; int balance; /* Knuth 6.2.3 algorithm A */ struct ts_entry * llink; struct ts_entry * rlink; }; static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[40]; /* This is a safe sprintf. No need for esb here. */ len = sprintf(number,"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging, mainly. We print the tree with the head node unnumbered and the root node called level 0. In Knuth algorithms where we have p[k] when k is zero k refers to the head node. Handy as then the root node is not special at all. But here it just looks better as shown, perhaps. The ordering here is so that if you turned an output page with the left side at the top then the tree sort of just shows up nicely in what most think of as a normal way. */ static void tdump_inner(struct ts_entry *t, char *(keyprint)(const void *), const char *descr, int level) { const char * keyv = ""; if (!t) { return; } tdump_inner(t->rlink,keyprint,"right",level+1); printlevel(level); if (t->keyptr) { keyv = keyprint(t->keyptr); } printf("0x%08" DW_PR_DUx " " "<%s %s> " " " "%s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", keyv, t->balance, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); tdump_inner(t->llink,keyprint,"left ",level+1); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the depth. */ int dwarf_check_balance_inner(struct ts_entry *t,int level, int maxdepth, int *founderror, const char *prefix) { int l = 0; int r = 0; if (level > maxdepth) { printf("%s Likely internal erroneous link loop, " "got to depth %d.\n", prefix,level); exit(1); } if (!t) { return 0; } if (!t->llink && !t->rlink) { if (t->balance != 0) { printf("%s: Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return 1; } l = dwarf_check_balance_inner(t->llink,level+1,maxdepth, founderror,prefix); r = dwarf_check_balance_inner(t->rlink,level+1,maxdepth, founderror,prefix); if (l ==r && t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " d should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; return l+1; } if (l > r) { if ( (l-r) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " l %d r %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, l,r); (*founderror)++; } if (t->balance != -1) { printf("%s Balance at 0x%" DW_PR_DUx " should be -1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return l+1; } if (r != l) { if ( (r-l) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " r %d l %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, r,l); (*founderror)++; } if (t->balance != 1) { printf("%s Balance at 0x%" DW_PR_DUx " should be 1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } else { if (t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } return r+1; } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 0; size_t headdepth = 0; int errcount = 0; int depth = 0; struct ts_entry*root = 0; if (finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } if (!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; headdepth = head->llink - (struct ts_entry *)0; if (!root) { printf("%s check balance null tree ptr\n",prefix); return; } maxdepth = headdepth+10; /* Counting in levels, not level number of top level. */ headdepth++; depth = dwarf_check_balance_inner(root,depth,maxdepth, &errcount,prefix); if (depth != headdepth) { printf("%s Head node says depth %lu, it is really %d\n", prefix, (unsigned long)headdepth, depth); ++errcount; } if (errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* Dumping the tree to stdout. */ void dwarf_tdump(const void*headp_in, char *(*keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)headp_in; struct ts_entry *root = 0; size_t headdepth = 0; if (!head) { printf("dumptree null tree ptr : %s\n",msg); return; } headdepth = head->llink - (struct ts_entry *)0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " tree-depth %d: %s\n", (Dwarf_Unsigned)(uintptr_t)head, (int)headdepth, msg); root = head->rlink; if (!root) { printf("Empty tree\n"); return; } tdump_inner(root,keyprint,"top",0); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if (a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if (a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } /* We will eventually ask it be freed, so being const void * in is not quite right. */ e->keyptr = (void *)key; e->balance = 0; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *q = allocate_ts_entry(key); if (!q) { /* out of memory */ return NULL; } setlink(p,kc,q); /* Non-NULL means inserted. */ return q; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if (q) { *inserted = 1; } return q; } /* Algorithm A of Knuth 6.2.3, balanced tree. key is pointer to a user data area containing the key and possibly more. We could recurse on this routine, but instead we iterate (like Knuth does, but using for (;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* head, int (*compar)(const void *, const void *), int*inserted, UNUSEDARG struct ts_entry **nullme, UNUSEDARG int * comparres) { /* t points to parent of p */ struct ts_entry *t = head; /* p moves down tree, p starts as root. */ struct ts_entry *p = head->rlink; /* s points where rebalancing may be needed. */ struct ts_entry *s = p; struct ts_entry *r = 0; struct ts_entry *q = 0; int a = 0; int kc = 0; for (;;) { /* A2. */ kc = compar(key,p->keyptr); if (kc) { /* A3 and A4 handled here. */ q = getlink(p,kc); if (!q) { /* Does step A5. */ q = tsearch_inner_do_insert(key,kc,inserted,p); if (!q) { /* Out of memory. */ return q; } break; /* to A5. */ } if (q->balance) { t = p; s = q; } p = q; continue; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* A5: work already done. */ /* A6: */ { /* Balance factors on nodes betwen S and Q need to be changed from zero to +-1 */ int kc2 = compar(key,s->keyptr); if (kc2 < 0) { a = -1; } else { a = 1; } r = p = getlink(s,a); while (p != q) { int kc3 = compar(key,p->keyptr); if (kc3 < 0) { p->balance = -1; p = p->llink; } else if (kc3 > 0) { p->balance = 1; p = p->rlink; } else { /* ASSERT: p == q */ break; } } } /* A7: */ { if (! s->balance) { /* Tree has grown higher. */ s->balance = a; /* Counting in pointers, not integers. Ugh. */ head->llink = head->llink + 1; return q; } if (s->balance == -a) { /* Tree is more balanced */ s->balance = 0; return q; } if (s->balance == a) { /* Rebalance. */ if (r->balance == a) { /* single rotation, step A8. */ p = r; setlink(s,a,getlink(r,-a)); setlink(r,-a,s); s->balance = 0; r->balance = 0; } else if (r->balance == -a) { /* double rotation, step A9. */ p = getlink(r,-a); setlink(r,-a,getlink(p,a)); setlink(p,a,r); setlink(s,a,getlink(p,-a)); setlink(p,-a,s); if (p->balance == a) { s->balance = -a; r->balance = 0; } else if (p->balance == 0) { s->balance = 0; r->balance = 0; } else if (p->balance == -a) { s->balance = 0; r->balance = a; } p->balance = 0; } else { fprintf(stderr,"Impossible balanced " "tree situation!\n"); /* Impossible. Cannot be here. */ exit(1); } } else { fprintf(stderr,"Impossible balanced tree situation!!\n"); /* Impossible. Cannot be here. */ exit(1); } } /* A10: */ if (s == t->rlink) { t->rlink = p; } else { t->llink = p; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headin; struct ts_entry *head = 0; struct ts_entry *r = 0; int inserted = 0; /* kcomparv should be ignored */ int kcomparv = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!headp) { return NULL; } head = *headp; if (!head) { struct ts_entry *root = 0; head = allocate_ts_entry(0); if (!head) { return NULL; } root = allocate_ts_entry(key); if (!root) { free(head); return NULL; } head->rlink = root; /* head->llink is used for the depth, as a count */ /* head points to the special head node ... */ *headin = head; return (void *)(&(root->keyptr)); } r = tsearch_inner(key,head,compar,&inserted,&nullme,&kcomparv); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search without insert. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry * const *phead = (struct ts_entry * const*)rootp; struct ts_entry *head = 0; struct ts_entry *p = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } p = head->rlink; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)(&(p->keyptr)); } p = getlink(p,kc); } return NULL; } /* Used for an array of records used in the deletion code. k == 0 for the special head node which is never matched by input. k == 1 etc. */ struct pkrecord { struct ts_entry *pk; int ak; /* Is -1 or +1 */ }; /* Here we rearrange the tree so the node p to be deleted is a node with a null left link. With that done we can fix pkarray and then we can use the pkarray to rebalance. It's a bit long, so we refactor out the code from where it is called. The rearrangement is Algorithm 6.2.2D in Knuth. PRECONDITION: p,p->rlink, pp non-null. RETURNS: new high index of pkarray. */ static unsigned rearrange_tree_so_p_llink_null( struct pkrecord * pkarray, unsigned k, UNUSEDARG struct ts_entry *head, struct ts_entry *r, struct ts_entry *p, UNUSEDARG int pak, UNUSEDARG struct ts_entry *pp, int ppak) { struct ts_entry *s = 0; unsigned k2 = 0; /* indexing pkarray */ int pbalance = p->balance; /* Step D3 */ /* Since we are going to modify the tree by movement of a node down the tree a ways, we need to build pkarray with the (not yet found) new next node, in pkarray[k], not p. The deletion will be of p, but by then p will be moved in the tree so it has a null left link. P's possibly-non-null right link */ k2 = k; k2++; r = p->rlink; pkarray[k2].pk = r; pkarray[k2].ak = -1; s = r->llink; /* Move down and left to get a null llink. */ while (s->llink) { k2++; r = s; s = r->llink; pkarray[k2].pk = r; pkarray[k2].ak = -1; } /* Now we move S up in place (in the tree) of the node P we will delete. and p replaces s. Finally winding up with a newly shaped balanced tree. */ { struct ts_entry *tmp = 0; int sbalance = s->balance; s->llink = p->llink; r->llink = p; p->llink = 0; tmp = p->rlink; p->rlink = s->rlink; s->rlink = tmp; setlink(pp,ppak,s); s->balance = pbalance; p->balance = sbalance; /* Now the tree is rearranged and still in balance. */ /* Replace the previous k position entry with S. We trace the right link off of the moved S node. */ pkarray[k].pk = s; pkarray[k].ak = 1; r->llink = p->rlink; /* Now p is out of the tree and we start the rebalance at r. pkarray Index k2. */ } /* Step D4 */ free(p); return k2; } /* Returns deleted node parent unless the head changed. Returns NULL if wanted node not found or the tree is now empty or the head node changed. Sets *did_delete if it found and deleted a node. Sets *tree_empty if there are no more user nodes present. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *head, int (*compar)(const void *, const void *), int *tree_empty, int *did_delete) { struct ts_entry *p = 0; struct ts_entry *pp = 0; struct pkrecord * pkarray = 0; size_t depth = head->llink - (struct ts_entry *)0; unsigned k = 0; /* Allocate extra, head is on the stack we create here and the depth might increase. */ depth = depth + 4; pkarray = calloc(sizeof(struct pkrecord),depth); if (!pkarray) { /* Malloc fails, we could abort... */ return NULL; } k = 0; pkarray[k].pk=head; pkarray[k].ak=1; p = head->rlink; while(p) { int kc = 0; k++; kc = compar(key,p->keyptr); pkarray[k].pk = p; pkarray[k].ak = kc; if (!kc) { break; } p = getlink(p,kc); } if (!p) { /* Node to delete never found. */ free(pkarray); return NULL; } { struct ts_entry *t = 0; struct ts_entry *r = 0; int pak = 0; int ppak = 0; p = pkarray[k].pk; pak = pkarray[k].ak; pp = pkarray[k-1].pk; ppak = pkarray[k-1].ak; /* Found a match. p to be deleted. */ t = p; *did_delete = 1; if (!t->rlink) { if (k == 1 && !t->llink) { *tree_empty = 1; /* upper level will fix up head node. */ free(t); free(pkarray); return NULL; } /* t->llink might be NULL. */ setlink(pp,ppak,t->llink); /* ASSERT: t->llink NULL or t->llink has no children, balance zero and balance of t->llink not changing. */ k--; /* Step D4. */ free(t); goto balance; } #ifdef IMPLEMENTD15 /* Step D1.5 */ if (!t->llink) { setlink(pp,ppak,t->rlink); /* we change the left link off ak */ k--; /* Step D4. */ free(t); goto balance; } #endif /* IMPLEMENTD15 */ /* Step D2 */ r = t->rlink; if (!r->llink) { /* We decrease the height of the right tree. */ r->llink = t->llink; setlink(pp,ppak,r); pkarray[k].pk = r; pkarray[k].ak = 1; /* The following essential line not mentioned in Knuth AFAICT. */ r->balance = t->balance; /* Step D4. */ free(t); goto balance; } /* Step D3, we rearrange the tree and pkarray so the balance step can work. step D2 is insufficient so not done. */ k = rearrange_tree_so_p_llink_null(pkarray,k, head,r, p,pak,pp,ppak); goto balance; } /* Now use pkarray decide if rebalancing needed and, if needed, to rebalance. k here matches l-1 in Knuth. */ balance: { unsigned k2 = k; /* We do not want a test in the for () itself. */ for ( ; 1 ; k2--) { struct ts_entry *pk = 0; int ak = 0; int bk = 0; if (k2 == 0) { /* decreased in height */ head->llink--; goto cleanup; } pk = pkarray[k2].pk; if (!pk) { /* Nothing here to work with. Move up. */ continue; } ak = pkarray[k2].ak; bk = pk->balance; if (bk == ak) { pk->balance = 0; continue; } if (bk == 0) { pk->balance = -ak; goto cleanup; } /* ASSERT: bk == -ak. We will use bk == adel here (just below). */ /* Rebalancing required. Here we use (1) and (2) in 6.2.3 to adjust the nodes */ { /* Rebalance. We use s for what is called A in Knuth Case 1, Case 2 page 461. r For what is called B. So the link movement logic looks similar to the tsearch insert case.*/ struct ts_entry *r = 0; struct ts_entry *s = 0; struct ts_entry *pa = 0; int pak = 0; int adel = -ak; s = pk; r = getlink(s,adel); pa = pkarray[k2-1].pk; pak = pkarray[k2-1].ak; if (r->balance == adel) { /* case 1. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,r); s->balance = 0; r->balance = 0; continue; } else if (r->balance == -adel) { /* case 2 */ /* x plays the role of p in step A9 */ struct ts_entry*x = getlink(r,-adel); setlink(r,-adel,getlink(x,adel)); setlink(x,adel,r); setlink(s,adel,getlink(x,-adel)); setlink(x,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,x); if (x->balance == adel) { s->balance = -adel; r->balance = 0; } else if (x->balance == 0) { s->balance = 0; r->balance = 0; } else if (x->balance == -adel) { s->balance = 0; r->balance = adel; } x->balance = 0; continue; } else { /* r->balance == 0 case 3 we do a single rotation and we are done. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); setlink(pa,pak,r); r->balance = -adel; /*s->balance = r->balance = 0; */ goto cleanup; } } } } cleanup: free(pkarray); #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return pp; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int tree_empty = 0; int did_delete = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } if (!head->rlink) { return NULL; } parentp = tdelete_inner(key,head,compar,&tree_empty,&did_delete); if (tree_empty) { head->rlink = 0; head->llink = 0; free(head); *phead = 0; return NULL; } /* ASSERT: head->rlink non-null. */ if (did_delete) { if (!parentp) { parentp = head->rlink; } return (void *)(&(parentp->keyptr)); } /* Not deleted */ return NULL; } static void dwarf_twalk_inner(struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if (p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if (p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { return; } /* Get to actual tree. */ dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if (p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if (p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (root) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } libdwarf-20210528/dwarfdump/helpertree_test.c0000664000175000017500000000461113764006205016034 00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "helpertree.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ struct Helpertree_Base_s testbase; int main() { struct Helpertree_Map_Entry_s *re = 0; int failcount = 0; /* Test 1 */ re = helpertree_add_entry(0x1000,0,&testbase); if (!re) { printf("FAIL test1\n"); failcount++; } re = helpertree_add_entry(0x2000,0,&testbase); if (!re) { printf("FAIL test2\n"); failcount++; } re = helpertree_find(0x1000,&testbase); if (!re) { printf("FAIL test3\n"); failcount++; } re = helpertree_find(0x2000,&testbase); if (!re) { printf("FAIL test4\n"); failcount++; } re = helpertree_find(0x2004,&testbase); if (re) { printf("FAIL test5\n"); failcount++; } helpertree_clear_statistics(&testbase); if (failcount) { return 1; } printf("PASS helpertree\n"); return 0; } libdwarf-20210528/dwarfdump/getopttest.c0000664000175000017500000005006714004637665015056 00000000000000/* This is for testing the local getopt. This test code is hereby placed into the public domain by David Anderson.*/ #ifdef GETOPT_FROM_SYSTEM #define dwgetopt getopt #define dwgetopt_long getopt_long #define dwopterr opterr #define dwoptind optind #define dwoptopt optopt #define dwopterr opterr #define dwoptarg optarg /* Leave dw_noargument etc to be defined as 0,1,2 as that matches system getopt.h */ #endif #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include "dwgetopt.h" /* for dwgetopt */ char *argv1[20]; /* Use for testing dwgetopt only. Not a standard function. */ static void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } static int turnprintable(int c) { if ( c >= 0x20 && c <= 0x7f) { return c; } return '.'; } static void printcheckargs( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, const char *testid, int testline) { printf("chkval entry ct %d test %s line %d\n",ct,testid,testline); printf(" rchar 0x%x('%c') xchar 0x%x('%c') roptarg " "%s xoptarg %s\n", rchar,turnprintable(rchar), xchar,turnprintable(xchar), roptarg?roptarg:"",xoptarg?xoptarg:""); printf(" roptind %d xoptind %d\n",roptind,xoptind); } /* for rchar read the real int/char returned. for xchar read the expected int/char. for roptarg, read dwoptarg (the real optarg val), for xoptarg read expected-optarg for roptind read dwoptind, for xoptind read expected-optind */ static void chkval( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, const char *testid, int testline) { int err = 0; if (rchar != xchar) { int pr = turnprintable(rchar); int px = turnprintable(xchar); err++; printf("Mismatch %d %s line %d: got char %c " "%d 0x%x; exp char %c %d 0x%x\n", ct,testid,testline,pr,rchar,rchar,px,xchar,xchar); } if (roptarg != xoptarg) { /* pointers non-match */ if (roptarg && xoptarg && (!strcmp(roptarg,xoptarg))) { /* strings match. */ } else { err++; printf("Mismatch %d %s line %d: got dwoptarg " "%s 0x%lx exp optarg %s 0x%lx\n", ct,testid,testline, roptarg?roptarg:"", (unsigned long)roptarg, xoptarg?xoptarg:"", (unsigned long)xoptarg); } } if (roptind != xoptind) { err++; printf("Mismatch %d %s line %d: got dwoptind %d " "0x%x exp optind %d 0x%x\n", ct,testid,testline, roptind,roptind,xoptind,xoptind); } if (err > 0) { printcheckargs(ct,rchar,xchar,roptarg,xoptarg, roptind,xoptind,testid,testline); printf("FAIL getopttest %s line %d\n",testid,testline); exit(1); } } static void chkval_long( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, int rlongindex, int xlongindex, const char *testid,int testline) { int err = 0; chkval(ct,rchar,xchar,roptarg,xoptarg,roptind,xoptind, testid,testline); if (rlongindex != xlongindex) { printf("chkval_long entry ct %d test %s line %d\n",ct, testid,testline); printf(" rlongindex %d xlongindex %d\n", rlongindex,xlongindex); ++err; printf("Mismatch %d %s line %d: on longopt longindex " "got %d expected %d\n", ct,testid,testline, rlongindex,xlongindex); } if (err > 0) { printf("FAIL getopttest %s line %d\n",testid,testline); exit(1); } } static int test3(void) { int ct = 1; int c = 0; int argct = 8; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#bx"; argv1[3]="-b"; argv1[4]="-c"; argv1[5]="-cfoo"; argv1[6]="-d"; argv1[7]="progtoread"; argv1[8]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::d")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test31",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"bx",dwoptind,3,"test32",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,4,"test33",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"test34",__LINE__); break; case 5: chkval(ct,c,'c',dwoptarg,"foo",dwoptind,6,"test35",__LINE__); break; case 6: chkval(ct,c,'d',dwoptarg,0,dwoptind,7,"test36",__LINE__); break; case 7: case 8: case 9: case 10: case 11: default: printf("FAIL test3 unexpected ct %d\n",ct); } } if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL test3 on non-dash dwoptind %d arg got " "%s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt test 3\n"); return 0; } static int test2(void) { int ct = 1; int c = 0; int argct = 5; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#pound"; argv1[3]="-b"; argv1[4]="-cfilename"; argv1[5]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test21",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"pound",dwoptind,3,"test22", __LINE__); break; break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,4,"test23",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,"filename",dwoptind,5,"test24", __LINE__); break; default: printf("FAIL test2 unexpected ct %d\n",ct); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test2 on non-dash arg dwoptind %d " "got 0x%lx exp NULL\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test 2\n"); return 0; } static int ltest1(void) { int ct = 1; int c = 0; int argct = 13; static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1000}, {"optarglong", dwoptional_argument,0,1001}, {"requireoptarglong",dwrequired_argument,0,1002}, {0,0,0,0} }; int longindex = 0; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2] = "--simplelong"; argv1[3] = "--optarglong"; argv1[4] = "--requireoptarglong=val"; argv1[5] = "-cd"; argv1[6]="progtoread"; argv1[7]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"ltest1.1",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"ltest1.2",__LINE__); break; case 3: chkval_long(ct,c,1000,dwoptarg,0,dwoptind,3,longindex,0, "ltest1.3",__LINE__); break; case 4: chkval_long(ct,c,1001,dwoptarg,0,dwoptind,4,longindex,1, "ltest1.4",__LINE__); break; case 5: chkval_long(ct,c,1002,dwoptarg,"val",dwoptind,5,longindex,2, "ltest1.5",__LINE__); break; case 6: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"ltest1.6",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,0,dwoptind,6,"ltest1.7",__LINE__); break; default: printf("FAIL ltest1 unexpected ct %d in ltest1\n",ct); exit(1); } } if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL ltest1 on non-dash arg dwoptind %d got " "%s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt ltest1\n"); return 0; } static int ltest2(void) { int ct = 1; int c = 0; int argct = 13; static struct dwoption longopts[] = { {"optarglong", dwoptional_argument,0,6}, {0,0,0,0} }; int longindex = 0; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2] = "--optarglong"; argv1[3] = "--optarglong="; argv1[4] = "--optarglong=val"; argv1[5] = "-cd"; argv1[6]="progtoread"; argv1[7]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"ltest21",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"ltest22",__LINE__); break; case 3: chkval_long(ct,c,6,dwoptarg,0,dwoptind,3,longindex,0, "ltest23",__LINE__); break; case 4: chkval_long(ct,c,6,dwoptarg,0,dwoptind,4,longindex,0, "ltest24",__LINE__); break; case 5: chkval_long(ct,c,6,dwoptarg,"val",dwoptind,5,longindex,0, "ltest25",__LINE__); break; case 6: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"ltest26",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,0,dwoptind,6,"ltest27",__LINE__); break; default: printf("FAIL ltest1 unexpected ct %d in ltest2\n",ct); exit(1); } } if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL ltest2 on non-dash arg dwoptind %d got " "%s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt ltest2\n"); return 0; } static int test1(void) { int ct = 1; int c = 0; int argct = 13; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#"; argv1[3]="6"; argv1[4]="-H1"; argv1[5]="-H"; argv1[6]="2"; argv1[7]="-ka"; argv1[8]="-l"; argv1[9]="-lv"; argv1[10]="-x"; argv1[11]="path=./foo"; argv1[12]="progtoread"; argv1[13]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::CdDeE::fFgGhH:iIk:l::mMnNo::O:pPqQrRsS:t:" "u:UvVwW::x:yz")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test11",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"6",dwoptind,4,"test12",__LINE__); break; case 3: chkval(ct,c,'H',dwoptarg,"1",dwoptind,5,"test13",__LINE__); break; case 4: chkval(ct,c,'H',dwoptarg,"2",dwoptind,7,"test14",__LINE__); break; case 5: chkval(ct,c,'k',dwoptarg,"a",dwoptind,8,"test15",__LINE__); break; case 6: chkval(ct,c,'l',dwoptarg,0,dwoptind,9,"test16",__LINE__); break; case 7: chkval(ct,c,'l',dwoptarg,"v",dwoptind,10,"test17",__LINE__); break; case 8: chkval(ct,c,'x',dwoptarg,"path=./foo",dwoptind,12,"test18", __LINE__); break; default: printf("FAIL test1 unexpected ct %d in test1\n",ct); exit(1); } } if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL test1 on non-dash arg dwoptind %d got " "%s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt test1\n"); return 0; } static int test5(void) { int ct = 1; int c = 0; int argct = 8; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2]="-a"; argv1[3]="-cx"; argv1[4]="-c"; argv1[5]="y"; argv1[6]="-d"; argv1[7]="-da"; argv1[8]=0; for ( ;(c = dwgetopt(argct, argv1, "abc:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"test51",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"test52",__LINE__); break; case 3: chkval(ct,c,'a',dwoptarg,0,dwoptind,3,"test53",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,"x",dwoptind,4,"test54",__LINE__); break; case 5: chkval(ct,c,'c',dwoptarg,"y",dwoptind,6,"test55",__LINE__); break; case 6: chkval(ct,c,'d',dwoptarg,0,dwoptind,7,"test56",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,"a",dwoptind,8,"test17",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char " "0x%x %c\n",ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test5 there is a non-dash arg dwoptind " "%d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test5\n"); return 0; } static int test6(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-H"; argv1[2]=0; for ( ;(c = dwgetopt(argct, argv1, "abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'?',dwoptarg,0,dwoptind,2,"test61",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char " "0x%x %c\n",ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test6 there is a non-dash arg dwoptind " "%d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test6\n"); return 0; } /* Leading : in opt string */ static int test7(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-H"; argv1[2]=0; for ( ;(c = dwgetopt(argct, argv1, ":abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,':',dwoptarg,0,dwoptind,2,"test7.1",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n", ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test7 there is a non-dash arg dwoptind " "%d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test7\n"); return 0; } static int test8(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-x"; argv1[2]=0; /* We expect a ? because the arg list is improper. */ for ( ;(c = dwgetopt(argct, argv1, "abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'?',dwoptarg,0,dwoptind,2,"test8.1",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n", ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test8 there is a non-dash arg " "dwoptind %d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test8\n"); return 0; } static int test9(void) { int ct = 1; int c = 0; int argct = 13; /* If an argument is required and there is no = in the input, the next argv is taken as the optarg. This was found by experiment. */ static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1}, {"optarglong", dwoptional_argument,0,2}, {"requireoptarglong",dwrequired_argument,0,3}, {0,0,0,0} }; int longindex = 0; int stop = 0; argv1[0]="a.out"; argv1[1]="-acb"; argv1[2] = "--bogusarg"; argv1[3] = "-cd"; argv1[4]="progtoread"; argv1[5]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1, "ltest9.1",__LINE__); break; case 2: chkval(ct,c,'c',dwoptarg,0,dwoptind,1, "ltest9.2",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,2, "ltest9.2",__LINE__); break; case 4: /* invalid long option */ chkval_long(ct,c,'?',dwoptarg,0,dwoptind,3, longindex,0, "ltest9.4",__LINE__); stop = 1; break; default: break; } if (stop) { break; } } printf("PASS getopt test9\n"); return 0; } static int test10(void) { int ct = 1; int c = 0; int argct = 13; /* If an argument is required and there is no = in the input, the next argv is taken as the optarg. This was found by experiment. */ static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1}, {"optarglong", dwoptional_argument,0,2}, {"requireoptarglong",dwrequired_argument,0,3}, {0,0,0,0} }; int longindex = 0; int done=0; argv1[0]="a.out"; argv1[1]="-acb"; argv1[2] = "--optarglong"; argv1[3] = "--simplelong=oops"; argv1[4] = "-cd"; argv1[5]="progtoread"; argv1[6]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1, "ltest10.1",__LINE__); break; case 2: chkval(ct,c,'c',dwoptarg,0,dwoptind,1, "ltest10.2",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,2, "ltest10.3",__LINE__); break; case 4: chkval_long(ct,c,2,dwoptarg,0,dwoptind,3, longindex,1, "ltest10.4",__LINE__); break; case 5: /* This one has error . =arg when none allowed */ chkval_long(ct,c,'?',dwoptarg,0, dwoptind,4, longindex,1, "ltest10.5",__LINE__); done=1; break; default: break; } if (done) { break; } } printf("PASS getopt test10\n"); return 0; } int main(int argc, const char **argv) { int ct = 0; int failct = 0; printf("argc: %d\n",argc); for (ct = 0; ct < argc ; ++ct) { printf("argv[%d] = %s\n",ct,argv[ct]); } if ( argc == 3) { int num = 0; if (strcmp(argv[1],"-c")) { printf("FAIL: invalid arg list\n"); exit(1); } num = atoi(argv[2]); printf("Run one test, number %d\n",num); switch(num) { case 1: failct = test1(); break; case 2: failct = test2(); break; case 3: failct = test3(); break; case 5: failct = test5(); break; case 6: failct = test6(); break; case 7: failct = test7(); break; case 8: failct = test8(); break; case 9: failct = test9(); break; case 10: failct = test10(); break; default: printf("FAIL: invalid test number %d\n",num); exit(1); } if ( failct) { printf("FAIL getopttest\n"); exit(1); } printf("PASS getopttest\n"); exit(0); } else if (argc != 1) { printf("FAIL: invalid arg list\n"); exit(1); } failct += ltest1(); dwgetoptresetfortestingonly(); failct += ltest2(); dwgetoptresetfortestingonly(); failct += test5(); dwgetoptresetfortestingonly(); failct += test1(); dwgetoptresetfortestingonly(); failct += test2(); dwgetoptresetfortestingonly(); failct += test3(); dwgetoptresetfortestingonly(); failct += test6(); dwgetoptresetfortestingonly(); failct += test7(); dwgetoptresetfortestingonly(); failct += test8(); dwgetoptresetfortestingonly(); failct += test9(); dwgetoptresetfortestingonly(); failct += test10(); if ( failct) { printf("FAIL getopttest\n"); exit(1); } printf("PASS getopttest\n"); return 0; } libdwarf-20210528/dwarfdump/makename.c0000664000175000017500000000671214003122254014406 00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright(C) David Anderson 2016-2019. All Rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. makename.c $Revision: 1.4 $ $Date: 2005/11/08 21:48:42 $ This used to be elaborate stuff. Now it is trivial, as duplicating names is unimportant in dwarfdump (in general). And in fact, this is only called for attributes and tags etc whose true name is unknown. Not for any normal case. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "makename.h" #include "globals.h" #if defined(__WIN32) && (!defined(__GNUC__) && !defined(__clang__)) #pragma warning(disable:4996) /* Warning when migrated to VS2010 */ #endif /* _WIN32 */ #define TRUE 1 #define FALSE 0 static void * makename_data; #define VALTYPE char * static int value_compare_func(const void *l, const void *r) { VALTYPE ml = (VALTYPE)l; VALTYPE mr = (VALTYPE)r; return strcmp(ml,mr); } /* Nothing to free for the 'value' example but the key itself. */ static void value_node_free(void *valp) { VALTYPE v = (VALTYPE)valp; free(v); } void makename_destructor(void) { /* Pass in root, not pointer to root */ dwarf_tdestroy(makename_data,value_node_free); makename_data = 0; } /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ char * makename(const char *s) { char *newstr = 0; VALTYPE re = 0; void *retval = 0; if (!s) { return ""; } newstr = (char *)strdup(s); retval = dwarf_tfind(newstr,&makename_data, value_compare_func); if (retval) { /* We found our string, it existed already. */ re = *(VALTYPE *)retval; free(newstr); return re; } retval = dwarf_tsearch(newstr,&makename_data, value_compare_func); if (!retval) { /* Out of memory, lets just use the string we dup'd and let it leak. Things will surely fail anyway. */ return newstr; } re = *(VALTYPE *)retval; return re; } libdwarf-20210528/dwarfdump/makename.h0000644000175000017500000000340413743575426014433 00000000000000#ifndef names_h #define names_h /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* makename.h $Revision: 1.3 $ $Date: 2004/10/28 22:26:58 $ This is for putting strings into stable storage. Effectively an strdup() wrapper. Rarely called. It leaks memory, (the memory is never freed) but that seems unimportant since use of this is very rare. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ char * makename(const char *); /* Makes a copy of the string in a malloc area. Can never return 0. */ /* Destroy all makename data. Do just before exit. */ void makename_destructor(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MAKENAME_H */ libdwarf-20210528/dwarfdump/esb_using_functions.h0000664000175000017500000000520513755067735016730 00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef ESB_USING_FUNCTIONS_H #define ESB_USING_FUNCTIONS_H #ifdef __cplusplus extern "C" { #endif /* Always returns DW_DLV_OK */ int print_ranges_list_to_extra(Dwarf_Debug dbg, Dwarf_Unsigned originaloff, Dwarf_Unsigned finaloff, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount, struct esb_s *stringbuf); int get_producer_name(Dwarf_Debug dbg,Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, struct esb_s *producername,Dwarf_Error *err); int get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, int die_indent_level, Dwarf_Off die_cu_offset, Dwarf_Attribute attrib, char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp, int show_form,int local_verbose, Dwarf_Error *err); void format_sig8_string(Dwarf_Sig8 *data,struct esb_s *out); int dwarfdump_print_location_operations(Dwarf_Debug dbg, Dwarf_Die die, int die_indent_level, Dwarf_Locdesc * llbuf, /* 2014 interface */ Dwarf_Locdesc_c locs, /* 2015 interface */ Dwarf_Unsigned llent, /* Which locdesc is this */ Dwarf_Unsigned entrycount, /* count of DW_OP operators */ Dwarf_Small lkind, int no_ending_newlines, Dwarf_Addr baseaddr, struct esb_s *string_out, Dwarf_Error *err); void get_true_section_name(Dwarf_Debug dbg, const char *standard_name, struct esb_s *name_out, Dwarf_Bool add_compr); #ifdef __cplusplus } #endif #endif /* ESi_USING_FUNCTIONS_H */ libdwarf-20210528/appveyor.yml0000664000175000017500000000254613644370703013102 00000000000000environment: global: LIBELF_INSTALL_PREFIX: "C:/libelf" matrix: - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "" - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "-DBUILD_SHARED=ON" - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "-DBUILD_SHARED=ON -DBUILD_NON_SHARED=OFF" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "-DBUILD_SHARED=ON" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "-DBUILD_SHARED=ON -DBUILD_NON_SHARED=OFF" configuration: Release install: - git clone https://github.com/dvirtz/libelf.git - cd libelf - git checkout cmake - cmake . -B_build -G "%CMAKE_GENERATOR_NAME%" -DCMAKE_INSTALL_PREFIX=%LIBELF_INSTALL_PREFIX% - cmake --build _build --config %CONFIGURATION% - cmake --build _build --config %CONFIGURATION% --target INSTALL - cd .. build_script: - cmake . -B_build -G "%CMAKE_GENERATOR_NAME%" -DLIBELF_ROOT=%LIBELF_INSTALL_PREFIX% %OPTIONS% - cmake --build _build --config %CONFIGURATION% test_script: - cmake --build _build --config %CONFIGURATION% --target RUN_TESTS libdwarf-20210528/COPYING0000644000175000017500000000117713743575426011553 00000000000000 COPYING June 23 2018 The source code in the libdwarf directory is LGPL version 2.1. See libdwarf/LIBDWARFCOPYRIGHT libdwarf/LGPL.txt A few portions use the two-clause BSD copyright ("FreeBSD License"). The source code in the dwarfdump directory is generally GPL version 2. See dwarfdump/COPYING dwarfdump/DWARFDUMPCOPYRIGHT dwarfdump/GPL.txt a The source code in the dwarfgen directory has the two-clause BSD copyright. See dwarfgen/COPYING The source code in the dwarfexample has the two-clause BSD copyright. The source code in the tsearch directory has the two-clause BSD copyright. libdwarf-20210528/config.guess0000755000175000017500000012637314054252020013020 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval "$set_cc_for_build" cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" # If ldd exists, use it to detect musl libc. if command -v ldd >/dev/null && \ ldd --version 2>&1 | grep -q ^musl then LIBC=musl fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ [ "$TARGET_BINARY_INTERFACE"x = x ] then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) if objdump -f /bin/sh | grep -q elf32-x86-64; then echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 else echo "$UNAME_MACHINE"-pc-linux-"$LIBC" fi exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libdwarf-20210528/config.h.in.cmake0000664000175000017500000001372314050561503013603 00000000000000 /* Define if building universal (internal helper macro) */ #cmakedefine AC_APPLE_UNIVERSAL_BUILD 1 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #cmakedefine CRAY_STACKSEG_END 1 /* Define to 1 if using `alloca.c'. */ #cmakedefine C_ALLOCA 1 /* Set to 1 as we are building with libelf */ #cmakedefine DWARF_WITH_LIBELF /* Define to 1 if you have `alloca', as a function or macro. */ #cmakedefine HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #cmakedefine HAVE_ALLOCA_H 1 /* Define 1 if including a custom libelf library */ #cmakedefine HAVE_CUSTOM_LIBELF 1 /* Define 1 if doing specific analasys of libdwarf allocations */ #cmakedefine HAVE_GLOBAL_ALLOC_SUMS 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H 1 /* Set to 1 if the elf64_getehdr function is in libelf. */ #cmakedefine HAVE_ELF64_GETEHDR 1 /* Set to 1 if the elf64_getshdr function is in libelf. */ #cmakedefine HAVE_ELF64_GETSHDR 1 /* Set to 1 if Elf64_Rela defined in elf.h. */ #cmakedefine HAVE_ELF64_RELA 1 /* Set to 1 if Elf64_Rel structure as r_info field. */ #cmakedefine HAVE_ELF64_R_INFO 1 /* Set to 1 if Elf64_Sym defined in elf.h. */ #cmakedefine HAVE_ELF64_SYM 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ELFACCESS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIBELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIBELF_LIBELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H 1 /* Define 1 if need nonstandard printf format for 64bit */ #cmakedefine HAVE_NONSTANDARD_PRINTF_64_FORMAT 1 /* Set to 1 if old frame columns are enabled. */ #cmakedefine HAVE_OLD_FRAME_CFA_COL 1 /* Set to 1 if regex is usable. */ #cmakedefine HAVE_REGEX 1 /* Set to 1 if big endian . */ #cmakedefine WORDS_BIGENDIAN 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_REGEX_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SGIDEFS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_386_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_AMD64_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_SPARC_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_IA64_ELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H 1 /* Define to HAVE_UINTPTR_T 1 if the system has the type `uintptr_t'. */ #cmakedefine HAVE_UINTPTR_T 1 /* Define to 1 if the system has the type `intptr_t'. */ #cmakedefine HAVE_INTPTR_T /* Define to the uintptr_t to the type of an unsigned integer type wide enough to hold a pointer if the system does not define it. */ #cmakedefine uintptr_t ${uintptr_t} #cmakedefine intptr_t ${intptr_t} /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H 1 /* Set to 1 if __attribute__ ((unused)) is available. */ #cmakedefine HAVE_UNUSED_ATTRIBUTE 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_WINDOWS_H 1 /* Define 1 if want to allow Windows full path detection */ #cmakedefine HAVE_WINDOWS_PATH 1 /* Set to 1 if zlib decompression is available. */ #cmakedefine HAVE_ZLIB 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ZLIB_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #cmakedefine LT_OBJDIR 1 /* Name of package */ #cmakedefine PACKAGE /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME libdwarf /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "${PACKAGE_NAME} ${VERSION}" /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME /* Define to the home page for this package. */ #cmakedefine PACKAGE_URL "${tarname}" ) /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #cmakedefine STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} /* Version number of package */ #cmakedefine VERSION ${VERSION} /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # cmakedefine WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to `unsigned int' if does not define. */ #undef size_t libdwarf-20210528/scripts/0000775000175000017500000000000014054271043012243 500000000000000libdwarf-20210528/scripts/ChangeLog20200000664000175000017500000000230313757502603014247 000000000000002020-11-24 David Anderson * buildandreleasetest.sh: Now does additional cmake builds to verify -DDWARF_WITH_LIBELF=OFF and -DBUILD_SHARED=ON work. 2020-10-21 David Anderson * run-all-tests.sh: getting directory right for modified regressiontests configre. 2020-10-21 David Anderson * buildandreleasetest.sh: Now uses temp files under /tmp/bart and if all passes removes that directory to clean up. 2020-10-20 David Anderson * ddbuild.sh: Changes to sanitized.c meant a bit of changing for tag_tree etc. * buildandreleasetest.sh: A major revision. Directory naming used in /tmp is now easier to follow, and using a couple script functions eliminated many busywork lines. 2020-02-25 David Anderson * run-all-tests.sh: Added echo statments to make it clearer were we are in the run. 2020-02-16 David Anderson * FIX-CONFIGURE-TIMES: alter the startup message so anyone seeing it will understand it is the code (libdwarf etc) fix script. 2020-01-14 David Anderson * buildandreleasetest.sh: The script element that finds the version in configure.ac now also allows for 202xmmdd versions, not just 201xmmdd libdwarf-20210528/scripts/ChangeLog20180000664000175000017500000000172213644370703014261 000000000000002018-09-21 David Anderson * buildandreleasetest.sh: Now uses the 2nd-generation release as source and does a cmake to verify cmake works. The new test lines added at the end (about line 129) but /tmp/cmakebld directory setup occurs early in this script. 2018-08-02 David Anderson * FIX-CONFIGURE-TIMES: Added another cautionary check before doing anything. 2018-08-01 David Anderson * FIX-CONFIGURE-TIMES: Was not cautious enough about whether it was in the right place and also was fussy about the top-level name being 'code'. Both issues fixed. 2018-07-16 David Anderson * CLEANUP: Now uses distclean so deleted a few lines here. * fixlibdwarfelf.sh: Used by configure to create libdwarf.h from libdwarf.h.in * generatedcasetext.c: A utility used to generate a ctype-like table for converting to uri-style. The table exists in dwarfdump so this C file likely will not be used again. libdwarf-20210528/scripts/fixlibdwarfelf.sh0000664000175000017500000000071214054014666015515 00000000000000#!/bin/sh # For cmake, this results in getting the correct # libdwarf.h if [ $# -ne 3 ] then echo "ERROR fixlibdwarfelf.sh wrong argument count: $#" exit 1 fi # Yes means use struct _Elf, no means use struct Elf yorn=$1 srcdir=$2/libdwarf builddir=$3/libdwarf #echo "FILES $yourn $srcdir $builddir" if [ x$yorn = "xno" ] then cp $srcdir/libdwarf.h.in $builddir/libdwarf.h else cp $srcdir/generated_libdwarf.h.in $builddir/libdwarf.h fi exit 0 libdwarf-20210528/scripts/UPD.awk0000664000175000017500000000037014054205525013321 00000000000000BEGIN { if (ARGC <= 2) { print "Bogus use of awk file, requires arg" exit 1 } else { v=ARGV[1] ARGV[1]="" } } $0 ~ /#define DW_VERSION_DATE_STR/ { print $1, $2, "\"",v,"\"" } $0 !~ /^#define DW_VERSION_DATE_STR/ { print $0 } libdwarf-20210528/scripts/buildandreleasetest.sh0000664000175000017500000002125014054013653016543 00000000000000#!/bin/sh # A script verifying the distribution gets all needed files # for building, including "make check" # First, get the current configure.ac version into v: # if stdint.h does not define uintptr_t and intptr_t # Then dwarfgen (being c++) will not build # Use --disable-libelf to disable reliance on libelf # and dwarfgen. # To just eliminate dwarfgen build/test/install use --disable-dwarfgen. genopta="--enable-dwarfgen" genoptb="-DBUILD_DWARFGEN=ON" libelfopt='' wd=`pwd` nonstdprintf= # If passes, remove the /tmp/bart working directory. # Useful to consider if all intended files actually present, # including any possibly not used. savebart=n while [ $# -ne 0 ] do case $1 in --savebart ) savebart=y ; shift ;; --disable-libelf ) genopta='' ; genoptb='' libelfopt=$1 ; shift ;; --enable-libelf ) shift ;; --disable-dwarfgen ) genopta='' ; genoptb='' ; shift ;; --enable-nonstandardprintf ) nonstdprintf=$1 ; shift ;; * ) echo "Unknown buildandreleasetest.sh option $1. Error." ; exit 1 ;; esac done echo "savebart flag about temp files:...: $savebart" if [ -f ./configure.ac ] then f=./configure.ac else if [ -f ../configure.ac ] then f=../configure.ac else echo "FAIL Running distribution test from the wrong place." exit fi fi v=`grep -o '20[1-2][0-9][0-9][0-9][0-9][0-9]'< $f | head -n 1` if [ x$v = "x" ] then echo FAIL did not get configure.ac version exit 1 fi chkres() { if [ $1 -ne 0 ] then echo "$2" exit 1 fi } mdirs() { while [ $# -ne 0 ] do f=$1 rm -rf $f mkdir $f chkres $? "mkdir $f failed!" shift done } safecd() { f=$1 cd $f chkres $? "cd $f failed $2" } safemv() { s=$1 t=$2 echo "mv $s $t" mv $s $t chkres $? "mv $f $t failed $3" } configloc=$wd/configure bart=/tmp/bart abld=$bart/a-dwbld ainstall=$bart/a-install binstrelp=$bart/a-installrelp binstrelbld=$bart/b-installrelbld blibsrc=$bart/b-libsrc crelbld=$bart/c-installrelbld cinstrelp=$bart/c-installrelp dbigend=$bart/d-bigendian ecmakebld=$bart/e-cmakebld fcmakebld=$bart/f-cmakebld gcmakebld=$bart/g-cmakebld hcmakebld=$bart/h-cmakebld mdirs $bart $abld $ainstall $binstrelp $binstrelbld $crelbld mdirs $cinstrelp $dbigend $ecmakebld $fcmakebld $gcmakebld mdirs $hcmakebld relset=$bart/a-gzfilelist atfout=$bart/a-tarftout btfout=$bart/b-tarftout arelgz=$bart/a-dwrelease.tar.gz brelgz=$bart/b-dwrelease.tar.gz rm -rf $bart/a-dwrelease rm -rf $blibsrc rm -rf $arelgz echo "dirs created empty" echo cd $abld safecd $abld "FAIL A cd failed" echo "now: $configloc --prefix=$ainstall $libelfopt $nonstdprintf" $configloc --prefix=$ainstall $libelfopt $nonstdprintf chkres $? "FAIL A4a configure fail" echo "TEST Section A: initial $ainstall make install" make install chkres $? "FAIL Secton A 4b make install" ls -lR $ainstall make dist chkres $? "FAIL make dist Section A" # We know there is just one tar.gz in $abld, that we just created ls -1 ./*tar.gz chkres $? "FAIL Section A ls ./*tar.gz" safemv ./*.tar.gz $arelgz "FAIL Section A moving gz" ls -l $arelgz tar -zxf $arelgz chkres $? "FAIL B2tar tar -zxf $arelgz" safemv libdwarf-$v $blibsrc "FAIL moving libdwarf srcdir" echo " End Section A $bart" ################ End Section A ################ Start Section B echo "TEST Section B: now cd $binstrelbld for second build install" safecd $binstrelbld "FAIL C cd" echo "TEST: now second install install, prefix $binstrelp" echo "TEST: Expecting src in $blibsrc" $blibsrc/configure --enable-wall --enable-dwarfgen --enable-dwarfexample --prefix=$binstrelp $libelfopt $nonstdprintf chkres $? "FAIL configure fail in Section B" echo "TEST: In $binstrelbld make install from $blibsrc/configure" make install chkres $? "FAIL Section B install fail" ls -lR $binstrelp echo "TEST: Now lets see if make check works" make check chkres $? "FAIL make check in Section B" make dist chkres $? "FAIL make dist Section B" # We know there is just one tar.gz in $abld, that we just created ls -1 ./*tar.gz safemv ./*.tar.gz $brelgz "FAIL Section B moving gz" ls -l $arelgz ls -l $brelgz # gzip does not build diffs quite identically to the byte. # Lots of diffs, So we do tar tf to get the file name list. echo "Now tar -tf on $arelgz and $brelgz " tar -tf $arelgz > $atfout tar -tf $brelgz > $btfout echo "Now diff the respective -tf output file lists" diff $atfout $btfout chkres $? "FAIL second gen tar gz file list does not match first gen" echo " End Section B $bart" ################ End section B ################ Start section C echo "TEST Section C: now cd $dbigend for big-endian build (not runnable) " safecd $dbigend "FAIL C be1 " echo "TEST: now second install install, prefix $crelbld" echo "TEST: Expecting src in $blibsrc" echo "TEST: $blibsrc/configure $genopta --enable-wall --enable-dwarfexample --prefix=$crelbld $libelfopt $nonstdprintf" $blibsrc/configure $genopta --enable-wall --enable-dwarfexample --prefix=$cinstrelp $libelfopt $nonstdprintf chkres $? "FAIL be2 configure fail" echo "#define WORDS_BIGENDIAN 1" >> config.h echo "TEST: Compile In $dbigend make from $blibsrc/configure" make chkres $? "FAIL be3 Build failed" echo " End Section C $bart" ################ End section C ################ Start section D safecd $crelbld "FAIL section D cd " echo "TEST: Now configure from source dir $blibsrc/ in build dir $crelbld" $blibsrc/configure --enable-wall --enable-dwarfexample $genopta $nonstdprintf chkres $? "FAIL C9 $blibsrc/configure" make chkres $? "FAIL C9 $blibsrc/configure make" echo " End Section D $bart" ################### End Section D ################### Cmake test E safecd $ecmakebld "FAIL C10 Section E cd" havecmake=n which cmake >/dev/null if [ $? -eq 0 ] then havecmake=y echo "We have cmake and can test it." fi if [ $havecmake = "y" ] then echo "TEST: Now cmake from source dir $blibsrc/ in build dir $ecmakebld" cmake $genoptb -DWALL=ON -DBUILD_DWARFEXAMPLE=ON -DDO_TESTING=ON $blibsrc chkres $? "FAIL C10b cmake in $ecmakdbld" make chkres $? "FAIL C10c cmake make in $ecmakebld" make test chkres $? "FAIL C10d cmake make test in $ecmakebld" ctest -R self chkres $? "FAIL C10e ctest -R self in $ecmakebld" else echo "cmake not installed so Test section E not tested." fi echo " End Section E $bart (ls output follows)" ls $bart ############ End Section E ################### Cmake test F safecd $fcmakebld "FAIL C11 Section F cd" havecmake=n which cmake >/dev/null if [ $? -eq 0 ] then havecmake=y echo "We have cmake and can test it." fi if [ $havecmake = "y" ] then echo "TEST: Now cmake from source dir $blibsrc/ in build dir $fcmakebld" cmake $genoptb -DWALL=ON -DDWARF_WITH_LIBELF=OFF -DBUILD_DWARFEXAMPLE=ON -DDO_TESTING=ON $blibsrc chkres $? "FAIL Sec F C11b cmake in $ecmakdbld" make chkres $? "FAIL Sec F C11c cmake make in $fcmakebld" make test chkres $? "FAIL Sec F C11d cmake make test in $fcmakebld" ctest -R self chkres $? "FAIL Sec F C11e ctest -R self in $fcmakebld" else echo "cmake not installed so -DDWARF_WITH_LIBELF=OFF (sec. F) not tested." fi echo " End Section F $bart (ls output follows)" ls $bart ############ End Section F ################### Cmake test G safecd $gcmakebld "FAIL C11 Section G cd" havecmake=n which cmake >/dev/null if [ $? -eq 0 ] then havecmake=y echo "We have cmake and can test it." fi if [ $havecmake = "y" ] then echo "TEST: Now cmake from source dir $blibsrc/ in build dir $gcmakebld" cmake $genoptb -DWALL=ON -DBUILD_NON_SHARED=OFF -DDO_TESTING=ON -DBUILD_SHARED=ON -DBUILD_DWARFGEN=ON -DBUILD_DWARFEXAMPLE=ON $blibsrc chkres $? "FAIL Sec F C11b cmake in $gcmakdbld" make chkres $? "FAIL Sec F C11d cmake make in $gcmakebld" ctest -R self chkres $? "FAIL Sec F C11e ctest -R self in $gcmakebld" else echo "cmake not installed so Section G not tested." fi echo " End Section G $bart (ls output follows)" ls $bart ############ End Section G ################### Cmake test H safecd $hcmakebld "FAIL C12 Section H cd" havecmake=n which cmake >/dev/null if [ $? -eq 0 ] then havecmake=y echo "We have cmake and can test it." else echo "We do NOT have cmake, cannot test it." fi if [ $havecmake = "y" ] then echo "TEST: Now cmake from source dir $blibsrc/ in build dir $gcmakebld" cmake -DDWARF_WITH_LIBELF=OFF -DWALL=ON -DBUILD_NON_SHARED=ON -DDO_TESTING=ON -DBUILD_SHARED=OFF -DBUILD_DWARFEXAMPLE=ON $blibsrc chkres $? "FAIL Sec H C12b cmake in $hcmakdbld" make chkres $? "FAIL Sec H C12d cmake make test in $hcmakebld" ctest -R self chkres $? "FAIL Sec H C12e ctest -R self in $hcmakebld" else echo "cmake not installed so Section H not tested." fi echo " End Section H $bart (ls output follows)" ls $bart ############ End Section H echo "PASS scripts/buildandreleasetest.sh" if [ "$savebart" = "n" ] then rm -rf $bart fi exit 0 libdwarf-20210528/scripts/ChangeLog0000664000175000017500000000547214054250503013743 000000000000002021-05-28 David Anderson * UPDATEDWARFDUMPVERSION.sh,baseconfig.h,ddbuild.sh, fixlibdwarfelf.sh,libbuild.sh: Comments added to explain the role each plays. 2021-05-28 David Anderson * BLDLIBDWARF,BLDLIBDWARFTAR,BLDTESTDIR,CPTARTOWEBDIR, CPTOPUBLIC,CREATINGARELEASE,GETTOTOP,REBLDLIBDWARF, RUNPY,SETUP_GZ_TREE,conddef.py,dateorder, extractrelocdefines.sh, find_pdfpages.py,funcfinderhdr.py,funcfindermm.py, funcfindersrcs.py,haveinclude.py,rebuildpdf.sh, scanconfig.py: None of these play any role in any part of the build, test, or update now. Deleting them. 2021-05-19 David Anderson * scanconfig.py: Reformatted with the 'black' formatter. 2021-05-16 David Anderson * buildandreleasetest.sh: Some comments referred to the wrong test name for F G and H, which caused confusion. Removed 'make test' for cmake, now using ctest -R self (and only that). 2021-05-16 David Anderson * scanconfig.py: A tool to make it simple to know if config.h.in and config.h.in.cmake match properly. Is to be run by hand on each file and the diff checked. Only config.h.in should have NO_MINUS_C_MINUS_O as that is a configure thing, not used by cmake. 2021-05-16 David Anderson * buildandreleasetest.sh. The cmake test H and G script sections were missing -DDO_TESTING=ON so ctest found nothing to run. Fixed. 2021-05-14 David Anderson * conddef.py,find_pdfpages.py,funcfinderhdr.py,funcfindermm.py, funcfindersrcs.py,scripts/haveinclude.py: Reformatted to standard pythoni3 style. 2021-05-12 David Anderson * buildandreleasetest.sh: Adds cmake test H (C12) so ctest -R done with -DDWARF_WITH_LIBELF=OFF, the H test adds another libelf off test. 2020-10-21 David Anderson * run-all-tests.sh: getting directory right for modified regressiontests configre. 2020-10-21 David Anderson * buildandreleasetest.sh: Now uses temp files under /tmp/bart and if all passes removes that directory to clean up. 2020-10-20 David Anderson * ddbuild.sh: Changes to sanitized.c meant a bit of changing for tag_tree etc. * buildandreleasetest.sh: A major revision. Directory naming used in /tmp is now easier to follow, and using a couple script functions eliminated many busywork lines. 2020-02-25 David Anderson * run-all-tests.sh: Added echo statments to make it clearer were we are in the run. 2020-02-16 David Anderson * FIX-CONFIGURE-TIMES: alter the startup message so anyone seeing it will understand it is the code (libdwarf etc) fix script. 2020-01-14 David Anderson * buildandreleasetest.sh: The script element that finds the version in configure.ac now also allows for 202xmmdd versions, not just 201xmmdd libdwarf-20210528/scripts/FIX-CONFIGURE-TIMES0000664000175000017500000000423514054015056014736 00000000000000#/bin/sh # After doing a copy of the source tree (as by 'cp -r') # the timestamps are not always # such that a build using configure will work. File timestamps matter # with the new configure. # If the 'configure ; make' ends in failure with a message about # aclocal-1.15 being missing then this script # will likely fix that problem. # With 'cp -rp' the problem should not arise. # Note that one user found the command: # touch aclocal.m4 Makefile.am configure Makefile.in # sufficient to avoid the problem. # Partly motivated by git clone because # git does not record timestamps so builds from # a cloned tree will not work unless this is run # to help configure. # cmake users can ignore this. l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` cdtarg=. sloc=$l/scripts rightplace() { for i in dwarfdump dwarfgen libdwarf dwarfexample m4 scripts do if [ ! -d $i ] then echo "$i is not a directory of $1." echo "we are not in the right place to touch configure etc" echo "to fix the missing aclocal-1.15 problem." echo "No action taken" exit 1 fi done } if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" echo "We appear to start in libdwarf scripts directory" echo "Change directory .." cd .. echo "Are we in the right directory now?" `pwd` rightplace `pwd` echo "Yes, we are in the right code (libdwarf) directory." else echo "Are we in the right directory?" rightplace `pwd` echo "Yes, we are in the right code (libdwarf) directory." fi l=`pwd` echo "Now touch files to get timestamps usable." for i in \ m4/ax_prog_cc_for_build.m4 \ m4/dw_compiler.m4 \ dwarfexample/Makefile.am \ dwarfdump/Makefile.am \ Makefile.am \ dwarfgen/Makefile.am \ libdwarf/Makefile.am \ configure.ac \ ltmain.sh \ m4/libtool.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/lt~obsolete.m4 \ aclocal.m4 \ configure \ config.h.in \ ar-lib \ compile \ config.guess \ config.sub \ install-sh \ missing \ INSTALL \ Makefile.in \ dwarfdump/Makefile.in \ dwarfexample/Makefile.in \ dwarfgen/Makefile.in \ depcomp \ test-driver \ libdwarf/Makefile.in do sleep 1 #echo "now touch $i" touch $i done libdwarf-20210528/scripts/libbuild.sh0000664000175000017500000000222514054015424014305 00000000000000# libbuild.sh # Build the .c .h needed for libdwarf. # Intended for simple non-elf builds on systems # This script is by David Anderson and hereby # put into the public domain # for anyone to use in any way. # This is used by scripts/buildstandardsource.sh # Requires a basic config.h at top level # Possibly cp scripts/baseconfig.h config.h # Run this from the libdwarf directory. d=`pwd` db=`basename $d` if [ x$db != "xlibdwarf" ] then echo FAIL Run this in the libdwarf directory. exit 1 fi set -x CC="gcc -g -I.." $CC gennames.c dwgetopt.c -o gennames rm -f dwarf_names.h dwarf_names.c dwarf_names_enum.h dwarf_names_new.h ./gennames -i . -o . if [ $? -ne 0 ] then echo gennames fail exit 1 fi $CC dwarf_test_errmsg_list.c -o errmsg_check if [ $? -ne 0 ] then echo build errmsgcheck fail exit 1 fi # This produces no output. # If it fails it indicates a problem with the DW_DLE names or strings. # If it passes there is no problem. grep DW_DLE libdwarf.h.in >errmsg_check_list ./errmsg_check -f errmsg_check_list if [ $? -ne 0 ] then echo errmsg check fail exit 1 fi rm -f gennames rm -f errmsg_check_list rm -f errmsg_check exit 0 libdwarf-20210528/scripts/buildstandardsource.sh0000664000175000017500000000333214012266121016554 00000000000000# # Use to build the .c and .h source based on static information # in libdwarf.h.in and dwarf_errmsg_list.h and the dwarfdump *.list files. # If you change any of those you should run this script # (which, for non-linux non-unix may mean some changes of this script # or of scripts/libbuild.sh or scripts/ddbuild.sh or baseconfig.h) # # This script is by David Anderson and hereby put into the public domain # for anyone to use in any way. # cp scripts/baseconfig.h config.h if [ $? -ne 0 ] then echo "FAIL getting base config.h for .c .h builing.Runningfrom wrong place?" exit 1 fi cd libdwarf if [ $? -ne 0 ] then echo "FAIL cd to libdwarf. Running buildstandardsource.sh from the wrong place" exit 1 fi cp libdwarf.h.in libdwarf.h sed 's/struct Elf/struct _Elf/g' ub_temp cmp ub_temp generated_libdwarf.h.in if [ $? -ne 0 ] then # Since cmake does not copy ; sensibly we will # provide a unique version for _Elf platforms. # libdwarf.h.in differs from generated_libdwarf.h.in: # update the latter. mv ub_temp generated_libdwarf.h.in fi rm ub_temp sh ../scripts/libbuild.sh if [ $? -ne 0 ] then echo "FAIL libbuild.sh. " exit 1 fi cd .. if [ $? -ne 0 ] then echo "FAIL cd back to top-level" exit 1 fi #Now build the source files needed by dwarfdump builds. cd dwarfdump if [ $? -ne 0 ] then echo "FAIL cd to dwarfdump. Running buildstandardsource.sh from the wrong place" exit 1 fi sh ../scripts/ddbuild.sh if [ $? -ne 0 ] then echo "FAIL building dwarfdump .c .h source" exit 1 fi cd .. if [ $? -ne 0 ] then echo "FAIL second cd back to top-level" exit 1 fi rm -f config.h rm -f libdwarf/libdwarf.h echo "PASS. The .c and .h files are built" exit 0 libdwarf-20210528/scripts/UPDATEDWARFDUMPVERSION.sh0000664000175000017500000000243114054016042016015 00000000000000#!/bin/bash # Do not turn on -x here. it will screw things up! # This puts the current date/time into # libdwarf/libdwarf_version.h # so libdwarf and dwarfdump can report the date time # applying currently to the source. # Sometimes only used. just before a release. l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" x=`date --rfc-3339=seconds |tr '\n' ' '` cat > $sloc/UPD.awk <<\EOF BEGIN { if (ARGC <= 2) { print "Bogus use of awk file, requires arg" exit 1 } else { v=ARGV[1] ARGV[1]="" } } $0 ~ /#define DW_VERSION_DATE_STR/ { print $1, $2, "\"",v,"\"" } $0 !~ /^#define DW_VERSION_DATE_STR/ { print $0 } EOF awk -f $sloc/UPD.awk "$x" $l/libdwarf/libdwarf_version.h >t mv t $l/libdwarf/libdwarf_version.h libdwarf-20210528/scripts/ddbuild.sh0000664000175000017500000001064514054014355014135 00000000000000# ddbuild.sh # A primitive build. # Intended for simple non-elf builds on systems # with no libelf, no elf.h, no libz. # This script is by David Anderson and hereby # put into the public domain # for anyone to use in any way. # This is used by scripts/buildstandardsource.sh # Requires a basic config.h at top level d=`pwd` db=`basename $d` if [ x$db != "xdwarfdump" ] then echo FAIL Run this in the dwarfdump directory. exit 1 fi # Following two lines needed for independent tests of # this script. Done by buildstandardsource.sh normally. # If added *must* be removed else dwarfdump builds will fail. #cp ../scripts/baseconfig.h config.h #cp ../libdwarf/libdwarf.h.in libdwarf.h set -x top_builddir=.. top_srcdir=.. CC="gcc -g -Wall -I.. -I../libdwarf -I../dwarfdump" EXEXT=.exe cp $top_builddir/libdwarf/dwarf_names.c . cp $top_builddir/libdwarf/dwarf_names.h . $CC -DTRIVIAL_NAMING dwarf_names.c common.c \ dwarf_tsearchbal.c \ $top_srcdir/libdwarf/dwarf_form_class_names.c \ dwgetopt.c \ esb.c \ makename.c \ naming.c \ sanitized.c \ tag_attr.c \ glflags.c \ tag_common.c -o tag_attr_build$EXEXT if [ $? -ne 0 ] then echo tag_attr_build compile fail exit 1 fi $CC -DTRIVIAL_NAMING dwarf_names.c common.c \ dwarf_tsearchbal.c \ $top_srcdir/libdwarf/dwarf_form_class_names.c \ dwgetopt.c \ esb.c \ makename.c \ naming.c \ glflags.c \ sanitized.c \ tag_common.c \ tag_tree.c -o tag_tree_build$EXEXT if [ $? -ne 0 ] then echo tag_tree_build compile fail exit 1 fi rm -f tmp-t1.c #======= echo BEGIN attr_form build taf=tempaftab rm $taf af=dwarfdump-af-table.h if [ ! -f $af ] then touch $af fi $CC -DTRIVIAL_NAMING -DSKIP_AF_CHECK dwarf_names.c common.c \ $top_srcdir/libdwarf/dwarf_form_class_names.c \ attr_form.c \ dwarf_tsearchbal.c \ dwgetopt.c \ esb.c \ makename.c \ naming.c \ glflags.c \ sanitized.c \ tag_common.c \ attr_form_build.c -o attr_form_build$EXEXT if [ $? -ne 0 ] then echo attr_form_build compile fail exit 1 fi rm -f tmp-t1.c cp $top_srcdir/dwarfdump/attr_formclass.list tmp-t1.c ls -l tmp-t1.c $CC -E tmp-t1.c >tmp-attr-formclass-build1.tmp ls -l tmp-attr-formclass-build1.tmp cp $top_srcdir/dwarfdump/attr_formclass_ext.list tmp-t2.c ls -l tmp-t2.c $CC -E tmp-t2.c >tmp-attr-formclass-build2.tmp ls -l tmp-attr-formclass-build2.tmp # Both of the next two add to the same array used by # dwarfdump itself. ./attr_form_build$EXEXT -s -i tmp-attr-formclass-build1.tmp -o $taf if [ $? -ne 0 ] then echo attr_formclass_build 1 FAIL exit 1 fi ./attr_form_build$EXEXT -e -i tmp-attr-formclass-build2.tmp -o $taf if [ $? -ne 0 ] then echo attr_formclass_build 2 FAIL exit 1 fi mv $taf $af rm -f tmp-attr-formclass-build1.tmp rm -f tmp-attr-formclass-build2.tmp rm -f ./attr_form_build$EXEXT cp $top_srcdir/dwarfdump/tag_tree.list tmp-t1.c $CC -E tmp-t1.c >tmp-tag-tree-build1.tmp ./tag_tree_build$EXEXT -s -i tmp-tag-tree-build1.tmp -o dwarfdump-tt-table.h if [ $? -ne 0 ] then echo tag_tree_build 1 FAIL exit 1 fi rm -f tmp-tag-tree-build1.tmp rm -f tmp-t1.c rm -f tmp-t2.c cp $top_srcdir/dwarfdump/tag_attr.list tmp-t2.c $CC -DTRIVIAL_NAMING -I$top_srcdir/libdwarf -E tmp-t2.c >tmp-tag-attr-build2.tmp ./tag_attr_build$EXEXT -s -i tmp-tag-attr-build2.tmp -o dwarfdump-ta-table.h if [ $? -ne 0 ] then echo tag_attr_build 2 FAIL exit 1 fi rm -f tmp-tag-attr-build2.tmp rm -f tmp-t2.c rm -f tmp-t3.c cp $top_srcdir/dwarfdump/tag_attr_ext.list tmp-t3.c $CC -I$top_srcdir/libdwarf -DTRIVIAL_NAMING -E tmp-t3.c > tmp-tag-attr-build3.tmp ./tag_attr_build$EXEXT -e -i tmp-tag-attr-build3.tmp -o dwarfdump-ta-ext-table.h if [ $? -ne 0 ] then echo tag_attr_build 3 FAIL exit 1 fi rm -f tmp-tag-attr-build3.tmp rm -f tmp-t3.c rm -f tmp-t4.c cp $top_srcdir/dwarfdump/tag_tree_ext.list tmp-t4.c $CC -I$top_srcdir/libdwarf -DTRIVIAL_NAMING -E tmp-t4.c > tmp-tag-tree-build4.tmp ./tag_tree_build$EXEXT -e -i tmp-tag-tree-build4.tmp -o dwarfdump-tt-ext-table.h if [ $? -ne 0 ] then echo tag_tree_build 4 compile fail exit 1 fi $CC -I $top_srcdir/libdwarf \ $top_srcdir/dwarfdump/buildopscounttab.c \ $top_srcdir/dwarfdump/dwarf_names.c -o buildop if [ $? -ne 0 ] then echo "FAIL compiling buildop and building opstabcount.c source" exit 1 fi ./buildop >opscounttab.c if [ $? -ne 0 ] then echo "FAIL building opstabcount.c source" exit 1 fi rm -f ./buildop rm -f tmp-tag-tree-build4.tmp rm -f tmp-t4.c rm -f tag_attr_build$EXEXT rm -f tag_tree_build$EXEXT rm -f attr_form_build$EXEXT exit 0 libdwarf-20210528/scripts/baseconfig.h0000664000175000017500000000570114054023103014427 00000000000000/* baseconfig.h. Maintained by hand for buildstandardsource.sh This avoids the necessity for running configure but makes assumptions (such as the existence of libz) that are not tested. So you may need to alter this to make buildstandardsource.sh work if your environment is sufficiently different. Assuming you have a reason to run scripts/buildstandardsource.sh (you most likely have no reason) . */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Only defined here, done for the benefit if buildstandardsource.sh */ #define BUILD_STANDARD_SOURCE 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Fake. For buildstandardsource.sh */ #define PACKAGE_VERSION "20190101" /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define 1 if need nonstandard printf format for 64bit */ /* #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT */ /* Set to 1 if old frame columns are enabled. */ /* #undef HAVE_OLD_FRAME_CFA_COL */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SGIDEFS_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Set to 1 if __attribute__ ((unused)) is available. */ #define HAVE_UNUSED_ATTRIBUTE 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* Define 1 if want to allow Windows full path detection */ /* #undef HAVE_WINDOWS_PATH */ /* Set to 1 if zlib decompression is available. */ #define HAVE_ZLIB 1 /* Define to 1 if you have the header file. */ #define HAVE_ZLIB_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ libdwarf-20210528/scripts/CLEANUP0000664000175000017500000000153514054013121013170 00000000000000#!/bin/bash # CLEANUP l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" # Won't work unless configure was done. make distclean # Some unlikely but possible files no one wants: rm -f libdwarf/BLD rm -f dwarfdump/BLD rm -f dwarfgen/configure.lineno rm -f ALLd* rm -f junk* */junk* rm -f *~ */*~ libdwarf-20210528/scripts/ChangeLog20190000664000175000017500000000432413644370703014263 000000000000002019-11-07 David Anderson * run-all-tests.sh,buildandreleasetest.sh: Now handle --enable-nonstandardprintf though that's not sufficient to let these work everywhere. 2019-11-04 David Anderson * buildandreleasetest.sh: Now handles --disable-libelf so we can run this test successfully in more environments. A few fixes to silly indentations. If cmake is not available skip the cmake test. * run-all-tests.sh: Now handles --disable-libelf and --enable-nonstandardprintf and when libelf missing avoids checks that could not possibly pass. 2019-10-29 David Anderson * buildandreleasetest.sh: If cmake is not installed do not attempt to run it. 2019-10-28 David Anderson * FIX-CONFIGURE-TIMES: No longer does echo on every file name, that was silly. Answers the 'are we in the right place?' now. 2019-10-24 David Anderson * run-all-tests.sh: Improving the precision of (meaning adding words to) the status messages so it's easier to interpret the output text. 2019-10-23 David Anderson * buildandreleasetest.sh: Do --enable-wall or cmake equivalent for every build. 2019-10-22 David Anderson * baseconfig.h: Now has a fake PACKAGE_VERSION and defines BUILD_STANDARD_SOURCE, both for use by buildstandardsource.sh * ddbuild.sh: One comment line was long for no good reason. Made it into two lines. * buildandreleasetest.sh: now the cmake is with -DWALL 2019-10-18 David Anderson * buildandreleasetest.sh: Reference $HOME, not a hard coded home dir. 2019-10-18 David Anderson * run-all-tests.sh: using a small function to check for failure reduces the file size by more than 40 lines and improves readability. 2019-10-17 David Anderson * buildandreleasetest.sh: The cmake test had misspellings in the cmake command options. * run-all-tests.sh: Renamed from run-bld-tests-readelfobj.sh and with small corrections. It now works in one environment! 2019-10-16 David Anderson * run-bld-tests-readelfobj.sh: New runs all the make check and the overall tests. * buildandreleasetest.sh: Added a ctest -R self to the test. libdwarf-20210528/m4/0000775000175000017500000000000014054271043011074 500000000000000libdwarf-20210528/m4/ltversion.m40000644000175000017500000000127314054252014013301 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libdwarf-20210528/m4/libtool.m40000644000175000017500000112676314054252014012735 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cr} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libdwarf-20210528/m4/lt~obsolete.m40000644000175000017500000001377414054252014013637 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libdwarf-20210528/m4/ltsugar.m40000644000175000017500000001044014054252014012731 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libdwarf-20210528/m4/ltoptions.m40000644000175000017500000003426214054252014013313 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libdwarf-20210528/m4/dw_compiler.m40000664000175000017500000000466713653364306013610 00000000000000dnl Copyright (C) 2018 Vincent Torri dnl This code is public domain and can be freely used or copied. dnl Macro that check if compiler flags are available dnl Macro that checks for a C compiler flag availability dnl dnl _DWARF_CHECK_C_COMPILER_FLAG(FLAGS) dnl AC_SUBST : DWARF_CFLAGS_WARN dnl have_flag: yes or no. AC_DEFUN([_DWARF_CHECK_C_COMPILER_FLAG], [dnl dnl store in options -Wfoo if -Wno-foo is passed option="m4_bpatsubst([[$1]], [-Wno-], [-W])" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" AC_LANG_PUSH([C]) AC_MSG_CHECKING([whether the C compiler supports $1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]])], [have_flag="yes"], [have_flag="no"]) AC_MSG_RESULT([${have_flag}]) AC_LANG_POP([C]) CFLAGS="${CFLAGS_save}" AS_IF( [test "x${have_flag}" = "xyes"], [DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} [$1]"]) AC_SUBST(DWARF_CFLAGS_WARN)dnl ]) dnl DWARF_CHECK_C_COMPILER_FLAGS(FLAGS) dnl Checks if FLAGS are supported and add to DWARF_CLFAGS. dnl dnl It will first try every flag at once, if one fails we will try dnl them one by one. AC_DEFUN([DWARF_CHECK_C_COMPILER_FLAGS], [dnl _DWARF_CHECK_C_COMPILER_FLAG([$1]) AS_IF( [test "${have_flag}" != "yes"], [m4_foreach_w([flag], [$1], [_DWARF_CHECK_C_COMPILER_FLAG(m4_defn([flag]))])]) ]) dnl Macro that checks for a C++ compiler flag availability dnl dnl _DWARF_CHECK_CXX_COMPILER_FLAG(FLAGS) dnl AC_SUBST : DWARF_CXXFLAGS_WARN dnl have_flag: yes or no. AC_DEFUN([_DWARF_CHECK_CXX_COMPILER_FLAG], [dnl dnl store in options -Wfoo if -Wno-foo is passed option="m4_bpatsubst([[$1]], [-Wno-], [-W])" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" AC_LANG_PUSH([C++]) AC_MSG_CHECKING([whether the C++ compiler supports $1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]])], [have_flag="yes"], [have_flag="no"]) AC_MSG_RESULT([${have_flag}]) AC_LANG_POP([C++]) CXXFLAGS="${CXXFLAGS_save}" AS_IF( [test "x${have_flag}" = "xyes"], [DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} [$1]"]) AC_SUBST(DWARF_CXXFLAGS_WARN)dnl ]) dnl DWARF_CHECK_CXX_COMPILER_FLAGS(FLAGS) dnl Checks if FLAGS are supported and add to DWARF_CXXLFAGS. dnl dnl It will first try every flag at once, if one fails we will try dnl them one by one. AC_DEFUN([DWARF_CHECK_CXX_COMPILER_FLAGS], [dnl _DWARF_CHECK_CXX_COMPILER_FLAG([$1]) AS_IF( [test "${have_flag}" != "yes"], [m4_foreach_w([flag], [$1], [_DWARF_CHECK_CXX_COMPILER_FLAG(m4_defn([flag]))])]) ]) libdwarf-20210528/CMakeLists.txt0000664000175000017500000003235514054031563013245 00000000000000cmake_minimum_required(VERSION 3.2) project(libdwarf C CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include_directories( ${CMAKE_BINARY_DIR} ) # used to compile on MSVC upto 2013 where snprintf is not available macro(msvc_posix target) if(MSVC AND ("${MSVC_VERSION}" LESS 1900)) # under VS 2015 target_compile_definitions(${target} PUBLIC snprintf=_snprintf) endif() endmacro() # set target folder on IDE macro(set_folder target folder) set_target_properties(${target} PROPERTIES FOLDER ${folder}) endmacro() # set source groups on IDE macro(set_source_group list_name group_name) set(${list_name} ${ARGN}) source_group(${group_name} FILES ${ARGN}) endmacro() # view folders on supported IDEs set_property(GLOBAL PROPERTY USE_FOLDERS ON) # used when finding libelf # tells cmake to look in 64bit first (cmake # would probably do this anyway). set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) enable_testing() # always include project's folder to includes set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) ### begin what was configure.cmake # cmake macros include(TestBigEndian) include(CheckIncludeFile) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckSymbolExists) ### Version also appears in configure.ac set(VERSION 20210528) set(PACKAGE_VERSION "\"${VERSION}\"") set(PACKAGE_NAME "libdwarf" ) ###set(VERSION ${PACKAGE_VERSION} ) set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"") string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" ) string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${tarname1}" ) set(PACKAGE_TARNAME "\"${tarname}\"" ) ###set(PACKAGE_VERSION "\"${PACKAGE_VERSION}\"") test_big_endian(isBigEndian) if (${isBigEndian}) set ( WORDS_BIGENDIAN 1 ) endif() check_include_file( "sys/types.h" HAVE_SYS_TYPES_H) check_include_file( "sys/stat.h" HAVE_SYS_STAT_H ) check_include_file( "inttypes.h" HAVE_INTTYPES_H ) check_include_file( "stddef.h" HAVE_STDDEF_H ) check_include_file( "stdlib.h" HAVE_STDLIB_H ) check_include_file( "string.h" HAVE_STRING_H ) check_include_file( "memory.h" HAVE_MEMORY_H ) check_include_file( "strings.h" HAVE_STRINGS_H ) check_include_file( "stdint.h" HAVE_STDINT_H ) check_include_file( "unistd.h" HAVE_UNISTD_H ) check_include_file( "sgidefs.h" HAVE_SGIDEFS_H ) check_include_file( "stdafx.h" HAVE_STDAFX_H ) check_include_file( "Windows.h" HAVE_WINDOWS_H ) check_include_file( "elf.h" HAVE_ELF_H ) check_include_file( "libelf.h" HAVE_LIBELF_H ) check_include_file( "libelf/libelf.h" HAVE_LIBELF_LIBELF_H) check_include_file( "alloca.h" HAVE_ALLOCA_H ) check_include_file( "elfaccess.h" HAVE_ELFACCESS_H) check_include_file( "sys/elf_386.h" HAVE_SYS_ELF_386_H ) check_include_file( "sys/elf_amd64.h" HAVE_SYS_ELF_AMD64_H) check_include_file( "sys/elf_sparc.h" HAVE_SYS_ELF_SPARC_H) check_include_file( "sys/ia64/elf.h" HAVE_SYS_IA64_ELF_H ) if(HAVE_STDINT_H) check_c_source_compiles(" #include int main() { uintptr_t i; i = 12; return (int)i; }" HAVE_UINTPTR_T) check_c_source_compiles(" #include int main() { intptr_t i; i = 12; return (int)i; }" HAVE_INTPTR_T) endif() if (HAVE_UINTPTR_T) message(STATUS "HAVE_UINTPTR_T 1: uintptr_t defined in stdint.h... YES") else() message(STATUS "uintptr_t defined in stdint.h... NO") set(uintptr_t "unsigned long long int" ) message(STATUS "Setting #define uintptr_t " ${uintptr_t}) endif() if (uintptr_t) message(STATUS "uintptr_t value considered YES ") else() message(STATUS "uintptr_t value considered NO ") endif() if (HAVE_INTPTR_T) message(STATUS "HAVE_INTPTR_T 1: intptr_t defined in stdint.h... YES") else() message(STATUS "intptr_t defined in stdint.h... NO") set(uintptr_t "long long int" ) message(STATUS "Setting #define intptr_t " ${intptr_t}) endif() if (intptr_t) message(STATUS "intptr_t value considered YES ") else() message(STATUS "intptr_t value considered NO ") endif() # It's not really setting the location of libelfheader, # it is really # either elf.h, or if that is missing # it is assuming elf.h data is in the supplied libelf. if(HAVE_ELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") elseif(HAVE_LIBELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") elseif(HAVE_LIBELF_LIBELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") endif() if(HAVE_LIBELF_H) set(JUST_LIBELF "") set(PLAIN_JUST_LIBELF "libelf.h") elseif(HAVE_LIBELF_LIBELF_H) set(JUST_LIBELF "") set(PLAIN_JUST_LIBELF "libelf/libelf.h") endif() if (HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H) set (CMAKE_REQUIRED_LIBRARIES elf) message(STATUS "libelf header ${PLAIN_JUST_LIBELF} checking for elf64_getehdr") check_symbol_exists( elf64_getehdr ${PLAIN_JUST_LIBELF} HAVE_ELF64_GETEHDR) message(STATUS "libelf header ${PLAIN_JUST_LIBELF} checking for elf64_getshdr") check_symbol_exists( elf64_getshdr ${PLAIN_JUST_LIBELF} HAVE_ELF64_GETSHDR) set (CMAKE_REQUIRED_LIBRARIES) endif() option(DWARF_WITH_LIBELF "Use libelf (default is YES)" TRUE) message(STATUS "Building using libelf... ${DWARF_WITH_LIBELF}") if (DWARF_WITH_LIBELF AND NOT HAVE_LIBELF_H AND NOT HAVE_LIBELF_LIBELF_H) set(DWARF_WITH_LIBELF OFF) set(HAVE_ELF_H OFF) elseif (NOT DWARF_WITH_LIBELF) set(HAVE_ELF_H OFF) set(HAVE_LIBELF_LIBELF_H OFF) set(HAVE_LIBELF_H OFF) set(HAVE_ELF64_GETSHDR OFF) set(HAVE_ELF64_GETEHDR OFF) endif () if (DWARF_WITH_LIBELF) message(STATUS "checking using HAVE_ELF_H ... ${HAVE_ELF_H}") message(STATUS "checking using elf header ... ${HAVE_LOCATION_OF_LIBELFHEADER}") message(STATUS "checking using libelf header ... ${JUST_LIBELF}") check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Rel *p; int i; i = p->r_info; return 0; }" HAVE_ELF64_R_INFO) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Rela p; p.r_offset = 1; return 0; }" HAVE_ELF64_RELA) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Sym p; p.st_info = 1; return 0; }" HAVE_ELF64_SYM) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { int p; p = 0; return 0; }" HAVE_RAW_LIBELF_OK) # This is attempting do determine that with GNU_SOURCE # we have off64_t. The autoconf version is not attemping # to set HAVE_LIBELF_OFF64_OK at present. check_c_source_compiles(" #define _GNU_SOURCE 1 #include ${JUST_LIBELF} int main() { off64_t p; p = 0; return 0; }" HAVE_LIBELF_OFF64_OK) check_c_source_compiles(" #include ${JUST_LIBELF} /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; struct _Elf *a = 0; int main() { int i = 12; return 0; }" HAVE_STRUCT_UNDERSCORE_ELF) else() endif() message(STATUS "Assuming struct Elf for the default libdwarf.h") # Because cmake treats ; in an interesting way attempting # to read/update/write Elf to _Elf fails badly: semicolons vanish. # So for _Elf use a pre-prepared version. if(HAVE_STRUCT_UNDERSCORE_ELF AND DWARF_WITH_LIBELF) message(STATUS "Found struct _Elf in ${JUST_LIBELF}") message(STATUS "Using struct _Elf in libdwarf.h") configure_file(libdwarf/generated_libdwarf.h.in libdwarf/libdwarf.h COPYONLY) else() configure_file(libdwarf/libdwarf.h.in libdwarf/libdwarf.h COPYONLY) message(STATUS "${JUST_LIBELF} does not have struct _Elf") message(STATUS "Using struct Elf in libdwarf.h, no actual elf.h used") endif() check_c_source_runs(" static unsigned foo( unsigned x, __attribute__ ((unused)) int y) { unsigned x2 = x + 1; return x2; } int main(void) { unsigned y = 0; y = foo(12,y); return 0; }" HAVE_UNUSED_ATTRIBUTE) message(STATUS "Checking compiler supports __attribute__ unused... ${HAVE_UNUSED_ATTRIBUTE}") check_c_source_compiles([=[ #include "stdafx.h" int main() { int p; p = 27; return 0; }]=] HAVE_STDAFX_H) #message(STATUS "Checking have windows stdafx.h... ${HAVE_STDAFX_H}") check_c_source_compiles([=[ #include #include int main() { int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); return 0; } ]=] HAVE_REGEX) set(CMAKE_REQUIRED_LIBRARIES z) check_c_source_compiles( [=[ #include "zlib.h" int main() { Bytef dest[100]; uLongf destlen = 100; Bytef *src = 0; uLong srclen = 3; int res = uncompress(dest,&destlen,src,srclen); if (res == Z_OK) { /* ALL IS WELL */ } return 0; } ]=] HAVE_ZLIB ) check_c_source_compiles( [=[ #include "zlib.h" int main() { Bytef dest[100]; uLongf destlen = 100; Bytef *src = 0; uLong srclen = 3; int res = uncompress(dest,&destlen,src,srclen); if (res == Z_OK) { /* ALL IS WELL */ } return 0; } ]=] HAVE_ZLIB_H ) set(CMAKE_REQUIRED_LIBRARIES) if (HAVE_ZLIB) # For linking in libz set(DW_FZLIB "z") endif() check_c_source_compiles([=[ #include int main() { intptr_t p; p = 27; return 0; }]=] HAVE_INTPTR_T) message(STATUS "CMAKE_SIZEOF_VOID_P ... " ${CMAKE_SIZEOF_VOID_P} ) # libdwarf default-disabled shared option(BUILD_SHARED "build shared library libdwarf.so and use it if present" FALSE) option(BUILD_NON_SHARED "build archive library libdwarf.a" TRUE) # This adds compiler option -Wall (gcc compiler warnings) option(WALL "Add -Wall" FALSE) # DW_FWALLXX are gnu C++ options. if (WALL) set(DW_FWALLXX -Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror) set(DW_FWALL ${DW_FWALLXX} -Wpointer-arith -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wextra -Wcomment -Wformat -Wpedantic -Wuninitialized -Wno-long-long -Wshadow -Werror ) message(STATUS "Compiler warning options... YES ${DW_FWALL}") else() unset(DW_FWALL ) message(STATUS "Compiler warning options... NO") endif() option(HAVE_CUSTOM_LIBELF "Have a custom libelf library (default is NO)" FALSE) message(STATUS "Including a custom libelf library... ${HAVE_CUSTOM_LIBELF}") option(HAVE_NONSTANDARD_PRINTF_64_FORMAT "Use a special printf format for 64bit (default is NO)" FALSE) message(STATUS "Checking enable non standard printf... ${HAVE_NONSTANDARD_PRINTF_64_FORMAT}") option(BUILD_DWARFGEN "Build dwarfgen (default is NO)" FALSE) message(STATUS "Building dwarfgen ... ${BUILD_DWARFGEN}") option(BUILD_DWARFEXAMPLE "Build dwarfexample (default is NO)" FALSE) message(STATUS "Building dwarfexample... ${BUILD_DWARFEXAMPLE}") option(DO_TESTING "Do certain api tests (default is NO)" FALSE) message(STATUS "Building api tests ... ${DOTESTS}") ### end what was configure.cmake # This changes the gennames option from -s to -t # though in 2019 builds we no longer run gennames. option(NAMES_TABLE "string functions implemented as binary search (default is with C switch)" TRUE) if(NAMES_TABLE) set(dwarf_namestable "-s") else() set(dwarf_namestable "-t") endif() option(HAVE_WINDOWS_PATH "Detect certain Windows paths as full paths (default is NO)" FALSE) message(STATUS "Checking enable windows path... ${HAVE_WINDOWS_PATH}") option(HAVE_OLD_FRAME_CFA_COL "Use HAVE_OLD_FRAME_CFA_COL (default is to use new DW_FRAME_CFA_COL3)" FALSE) message(STATUS "Checking enable old frame columns... ${HAVE_OLD_FRAME_CFA_COL}") # See pro_init(), HAVE_DWARF2_99_EXTENSION also generates # 32bit offset dwarf unless DW_DLC_OFFSET_SIZE_64 flag passed to # pro_init. option(HAVE_SGI_IRIX_OFFSETS "Force producer to SGI IRIX offset dwarf" FALSE) message(STATUS "Checking producer generates SGI IRIX output... ${HAVE_SGI_IRIX_OFFSETS}") option(HAVE_STRICT_DWARF2_32BIT_OFFSET "Force producer to generate only DWARF format 32bit" FALSE) set(HAVE_DWARF2_99_EXTENSION NOT ${HAVE_STRICT_DWARF2_32BIT_OFFSET}) message(STATUS "Checking producer generates only 32bit... ${HAVE_STRICT_DWARF2_32BIT_OFFSET}") # This references cmake/FindLibElf.cmake. See cmake documentation. find_package(LibElf REQUIRED) list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBELF_INCLUDE_DIRS}) configure_file(config.h.in.cmake config.h) if(BUILD_NON_SHARED) set(DWARF_TARGETS dwarf-static) set(DWARF_TYPES STATIC) set(dwarf-target dwarf-static) endif() if(BUILD_SHARED) list(APPEND DWARF_TARGETS dwarf-shared) list(APPEND DWARF_TYPES SHARED) set(dwarf-target dwarf-shared) endif() add_subdirectory(libdwarf) add_subdirectory(dwarfdump) if ( BUILD_DWARFGEN ) if ( DWARF_WITH_LIBELF ) add_subdirectory(dwarfgen) else () message(STATUS "Not building dwarfgen because libelf is not available" ) endif () endif() if ( BUILD_DWARFEXAMPLE ) add_subdirectory(dwarfexample) endif() message(STATUS "Install prefix ... ${CMAKE_INSTALL_PREFIX}" ) # add_custom_target(dd DEPENDS ${DWARF_TARGETS} dwarfdump) # installation of libdwarf has to be in libdwarf/CMakeLists.txt # so that it works properly for cmake before cmake 3.13. libdwarf-20210528/depcomp0000755000175000017500000005602014054252021012045 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libdwarf-20210528/cmake/0000775000175000017500000000000013653056466011652 500000000000000libdwarf-20210528/cmake/FindLibElf.cmake0000664000175000017500000000345113644370703014526 00000000000000# - Try to find libelf # Referenced by the find_package() command from the top-level # CMakeLists.txt. # Once done this will define # # LIBELF_FOUND - system has libelf # LIBELF_INCLUDE_DIRS - the libelf include directory # LIBELF_LIBRARIES - Link these to use libelf # LIBELF_DEFINITIONS - Compiler switches required for using libelf # # This module reads hints about search locations from variables: # # LIBELF_ROOT - Preferred installation prefix # # Copyright (c) 2008 Bernhard Walle # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # if (NOT DWARF_WITH_LIBELF) return() endif () if (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS) set (LibElf_FIND_QUIETLY TRUE) endif (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS) find_path (LIBELF_INCLUDE_DIRS NAMES libelf/libelf.h libelf.h HINTS ${LIBELF_ROOT} PATH_SUFFIXES include libelf/include ) if (NOT LIBELF_INCLUDE_DIRS) set (DWARF_WITH_LIBELF OFF) return () endif() find_library (LIBELF_LIBRARIES NAMES elf libelf HINTS ${LIBELF_ROOT} PATH_SUFFIXES lib libelf/lib ) if (NOT LIBELF_LIBRARIES) set (DWARF_WITH_LIBELF OFF) return () endif() include (FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG LIBELF_LIBRARIES LIBELF_INCLUDE_DIRS) set(CMAKE_REQUIRED_LIBRARIES elf) include(CheckCSourceCompiles) check_c_source_compiles("#include int main() { Elf *e = (Elf*)0; size_t sz; elf_getshdrstrndx(e, &sz); return 0; }" ELF_GETSHDRSTRNDX) unset(CMAKE_REQUIRED_LIBRARIES) mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX) libdwarf-20210528/ChangeLog20180000664000175000017500000000744513644370703012602 000000000000002018-12-19 David Anderson * configure.ac: Updated version to 20181218. 2018-11-29 David Anderson * configure.ac: Updated version to 20181129. 2018-11-04 David Anderson * configure.ac: Updated version to 20181123. 2018-11-05 David Anderson * configure.ac: Updated version to 20181105. Fixing magic-number dectection for mach-o and pe. 2018-10-23 David Anderson * configure.ac: Updated version to 20181022. 2018-10-20 David Anderson * configure.ac: Updated version to 20181020. 2018-10-15 David Anderson * configure.ac: Updated version to 20181015. * configure: Regenerated. 2018-10-14 David Anderson * configure.ac: Updated version to 20181014. * configure: Regenerated. 2018-09-21 David Anderson * configure.ac: Updated version to 20180920 * Makefile.am: Added tsearch (directory) and configure.cmake to the files put in a 'make dist' distribution so cmake works with a released tar.gz. 2018-09-12 David Anderson * configure.ac: Updated version to 20180912 * configure. Regenerated. Version now 20180912 2018-09-11 David Anderson * configure.ac: Restored the configure option --enable-nonstandardprintf which sets the config.h HAVE_NONSTANDARD_PRINTF_64_FORMAT variable for those needing it. See libdwarf/libdwarf.h.in for its use. * configure. Regenerated. Version now 20180910 2018-09-02 David Anderson * README: noted the example install commands for libelf and zlib work on 18.04 Ubuntu as well as 16.04. * configure.ac: Updated version to 20180901. Corrected a couple of typos in the summary output of configure. * configure: Regenerated. 2018-08-24 David Anderson * README: Moved comments about common build problems to the beginning of the text. Removed trailing whitespace. 2018-08-23 David Anderson * README: Added mention of the aclocal-missing configure/ build problem and the simple action to fix it. 2018-08-21 David Anderson * configure.ac: Version 20180821. --enable-wall did not show up in the output and wound up ignored. * configure: Regenerated. 2018-08-14 David Anderson * configure.ac: Version 20180814. Fixed small Makefile.am omissions in dwarfdump and libdwarf. * configure: Regenerated. 2018-08-09 David Anderson * configure.ac: Version 20180809 * configure: Regenerated. 2018-08-06 David Anderson * configure.ac: Version now 20180808. * Makefile.am: Corrected references to runtest.sh * configure: Regenerated. 2018-08-06 David Anderson * configure.ac: Version now 20180806. 2018-08-05 David Anderson * configure.ac: Version now 20180805. * configure: Regenerated. 2018-08-02 David Anderson * configure.ac: Deleted unneeded variables. Now env vars like CFLAGS work in standard fashion. Updated version to 20180801 * configure: Regenerated 2018-08-02 David Anderson * README: Added and corrected some details of the new configure. 2018-07-31 David Anderson * configure.ac: Fix the .so version number fields to be 1 0 0, not 1 5 0 version is now hand typed in, not generated by current date * Makefile.am: Now reflects renaming of CPLIBDWARFTAR to CPTARTOWEBDIR add runtests.sh to files in distribution * configure: regenerated 2018-07-23 David Anderson * configure.ac: Reintroduced CXX -wno-long-long to avoid spurious warnings from C++ when using --enable-wall. * configure: Regenerated. 2018-07-22 David Anderson * configure.ac: Complete the handling of --enable-sanitize. 2018-07-19 David Anderson * NEWS, README: Updated to match the new configure code. * configure.ac: Now configure is created by autoreconf -vif and the only configure.ac is here in the same directory as this ChangeLog. libdwarf-20210528/INSTALL0000644000175000017500000003661414054252020011527 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. libdwarf-20210528/aclocal.m40000664000175000017500000012603214054252017012340 00000000000000# generated automatically by aclocal 1.16.1 -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/dw_compiler.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) libdwarf-20210528/dwarfexample/0000775000175000017500000000000014054271043013233 500000000000000libdwarf-20210528/dwarfexample/dummyexecutable.c0000664000175000017500000000056613737716107016537 00000000000000/* This is a dummy to create a tiny executable we will use in make check on debuglink Compiled by cc -g dummyexecutable.c -o dummyexecutable On Ubuntu 18.04 10 November 2019 */ #include int myfunc(unsigned x) { int z = x +3; return z; } int main(int argc, char **argv) { int zed = 0; zed = myfunc(zed +2); return zed; } libdwarf-20210528/dwarfexample/dwdebuglink.c0000644000175000017500000003352313744143355015633 00000000000000/* David Anderson. 2019-2020. This small program is hereby placed into the public domain to be copied or used by anyone for any purpose. See https://sourceware.org/gdb/onlinedocs/\ gdb/Separate-Debug-Files.html An emerging GNU pattern seems to be: If a path found from debuglink or build-id matches an elf object then both the objects may bave a build-id and if it is the right object the build-ids will match. This pattern does not refer to the crc from the executable debuglink. To build a separate debug file x.debug with DWARF and an executable with just debugid and debuglink data using the pattern seen in Ubuntu 20.04: first compile and link, creating x then: objcopy --only-keep-debug x x.debug objcopy --strip-debug x objcopy --add-gnu-debuglink=x.debug x See 'man objcopy' or https://sourceware.org/binutils/docs/binutils/objcopy.html for more information. */ #include "config.h" #include /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_UNISTD_H #include /* for close */ #endif /* HAVE_UNISTD_H */ #ifdef HAVE_SYS_TYPES_H #include /* for off_t ssize_t */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include /* for memset */ #endif /* HAVE_STRING_H */ #include "dwarf.h" #include "libdwarf.h" #define TRUE 1 #define FALSE 0 char trueoutpath[2000]; static const char *dlname = ".gnu_debuglink"; static const char *buildidname = ".note.gnu.buildid"; static int doprintbuildid = 1; static int doprintdebuglink = 1; #define Dwarf_Small unsigned char static void dump_bytes(const char *prefix, char *msg, unsigned char *start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; if (!start) { printf("%s ptr null, ignore. \n",msg); return; } printf("%s%s ",prefix,msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } static int blockmatch(unsigned char *l, unsigned char* r, unsigned length) { unsigned int i = 0; for( ; i < length; ++i) { if (l[i] != r[i]) { return FALSE; } } return TRUE; } static void print_debuglink(const char *prefix, char *debuglinkpath, unsigned char *crc, char *debuglinkfullpath, unsigned int debuglinkfullpath_strlen) { unsigned char *crcx = 0; unsigned char *end = 0; printf("%s Section : %s\n",prefix,dlname); printf("%s Debuglink name : %s\n",prefix,debuglinkpath); crcx = crc; end = crcx + 4; printf("%s crc 0X: ",prefix); for (; crcx < end; crcx++) { printf("%02x ", *crcx); } printf("\n"); if (debuglinkfullpath_strlen) { printf("%s Debuglink target : %s\n", prefix,debuglinkfullpath); } } static void print_buildid(const char *prefix, unsigned int buildid_type, char *buildidownername, unsigned int buildid_length, unsigned char *buildid) { printf("%s Section : %s\n",prefix,buildidname); printf("%s Build-id type : %u\n",prefix, buildid_type); printf("%s Build-id ownername: %s\n",prefix, buildidownername); printf("%s Build-id length : %u\n",prefix,buildid_length); printf("%s Build-id : ",prefix); { const unsigned char *cur = 0; const unsigned char *end = 0; cur = buildid; end = cur + buildid_length; for (; cur < end; cur++) { printf("%02x", (unsigned char)*cur); } } printf("\n"); } /* Returns TRUE if its a real file of some interest. */ static int print_ftype_message(const char * prefix, unsigned int ftype) { switch(ftype) { case DW_FTYPE_ELF: printf("%s file above is an Elf object\n",prefix); return TRUE; case DW_FTYPE_MACH_O: printf("%s file above is a Mach-O object\n",prefix); return TRUE; case DW_FTYPE_PE: printf("%s file above is a PE object",prefix); return TRUE; case DW_FTYPE_CUSTOM_ELF: printf("%s file above is a custom elf object",prefix); return TRUE; case DW_FTYPE_ARCHIVE: printf("%s file above is an archive so ignore it.", prefix); return FALSE; default: printf("%s file above is not an object type" " we recognize\n",prefix); } return FALSE; } /* The debug version we expect not to have debuglink, checking here if buildid matches. Never returns DW_DLV_ERROR. */ static int match_buildid(const char *prefix, unsigned char *crc_base, unsigned buildid_length_base, unsigned char * buildid_base, /* *_base is executable info while *_debug is the debug object. */ unsigned char * crc_debug, unsigned buildid_length_debug, unsigned char *buildid_debug) { if (crc_debug && crc_base) { /* crc available for both */ if (!blockmatch(crc_debug,crc_base,4)) { dump_bytes(prefix," crc base ",crc_base,4); dump_bytes(prefix," crc target",crc_debug,4); printf("%s===crc does not match\n",prefix); return DW_DLV_NO_ENTRY; } } else { } if(buildid_length_base != buildid_length_debug) { printf("%s===buildid length does not match",prefix); return DW_DLV_NO_ENTRY; } if (!blockmatch(buildid_base,buildid_debug, buildid_length_base)) { printf("%s===buildid does not match\n",prefix); return DW_DLV_NO_ENTRY; } return DW_DLV_OK; } static int one_file_debuglink_internal(int is_outer,const char *prefix, char **gl_pathnames, unsigned gl_pathcount, int no_follow_debuglink, char *path_in, unsigned char *crc_in, unsigned buildid_len_in, unsigned char *buildid_in, char *debug_path_in) { int res = 0; Dwarf_Debug dbg = 0; unsigned i = 0; char *debuglinkpath = 0; /* must be freed */ unsigned char *crc = 0; char *debuglinkfullpath = 0; unsigned debuglinkfullpath_strlen = 0; unsigned buildid_type = 0; char * buildidownername = 0; unsigned char *buildid = 0; unsigned buildid_length = 0; char ** paths = 0; /* must be freed */ unsigned paths_count = 0; char * path = 0; char * basepath = 0; Dwarf_Error error = 0; Dwarf_Unsigned laccess = DW_DLC_READ; unsigned int p = 0; /* Don't let dwarf_init_path find the debuglink, we want to do it here so we can show it all. */ path = basepath = path_in; if (!is_outer) { path = debug_path_in; printf("%s===Referred-path : %s\n",prefix,debug_path_in); } else { printf("%s===Exec-path : %s\n",prefix,basepath); } res = dwarf_init_path(path, 0,0, laccess, DW_GROUPNUMBER_ANY, 0,0, &dbg, 0,0,0,&error); if (res == DW_DLV_ERROR) { printf("%sError from libdwarf opening \"%s\": %s\n", prefix, path, dwarf_errmsg(error)); dwarf_dealloc_error(dbg,error); error = 0; return res; } if (res == DW_DLV_NO_ENTRY) { printf("%sThere is no such file as \"%s\"\n", prefix, path); return DW_DLV_NO_ENTRY; } if (is_outer && no_follow_debuglink) { printf("%s no follow debuglink: TRUE\n",prefix); } for (p = 0; p < gl_pathcount; ++p) { const char *lpath = 0; lpath = (const char *)gl_pathnames[p]; res = dwarf_add_debuglink_global_path(dbg, lpath, &error); if (res != DW_DLV_OK){ printf("Failed add global path. result %d line %d\n", res,__LINE__); exit(1); } printf("%s global path : %s\n",prefix,lpath); } res = dwarf_gnu_debuglink(dbg, &debuglinkpath, &crc, &debuglinkfullpath, &debuglinkfullpath_strlen, &buildid_type, &buildidownername, &buildid, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { printf("%sError from libdwarf accessing debuglink " "related sections in \"%s\": %s\n", prefix, path, dwarf_errmsg(error)); dwarf_dealloc_error(dbg,error); error = 0; dwarf_finish(dbg,&error); return res; } else if (res == DW_DLV_NO_ENTRY) { printf("%sThere is no %s or %s section in \"%s\"\n", prefix,dlname,buildidname,path); res = dwarf_finish(dbg,&error); return DW_DLV_NO_ENTRY; } if (doprintdebuglink && crc) { print_debuglink(prefix,debuglinkpath,crc, debuglinkfullpath,debuglinkfullpath_strlen); } if (doprintbuildid && buildid) { print_buildid(prefix, buildid_type, buildidownername, buildid_length, buildid); } if (!is_outer) { unsigned char lcrc[4]; /* dbg might be the correct .debug object */ memset(&lcrc[0],0,sizeof(lcrc)); if (crc_in && !crc) { res = dwarf_crc32(dbg,lcrc,&error); if (res == DW_DLV_ERROR) { dwarf_dealloc_error(dbg,error); error = 0; } else if (res == DW_DLV_OK) { crc = &lcrc[0]; } } res = match_buildid(prefix, /* This is the executable */ crc_in,buildid_len_in,buildid_in, /* pass in dbg so we can calculate the missing crc */ /* following is the target, ie, debug */ crc,buildid_length,buildid); if (res == DW_DLV_OK) { printf("%s===executable and debug buildid match\n", prefix); } return DW_DLV_NO_ENTRY; } /* If debug_path_in then this list does not mean anything. */ for (i =0; is_outer && i < paths_count; ++i) { char *pa = paths[i]; unsigned int ftype = 0; unsigned int endian = 0; unsigned int offsetsize = 0; Dwarf_Unsigned filesize = 0; int errcode = 0; int realobj = TRUE; static char lprefix[50]; snprintf(lprefix,sizeof(lprefix), " [%2u]",i); printf("%s Path [%2u] %s\n",lprefix,i,pa); /* First, open the file to determine if it exists. If not, loop again */ res = dwarf_object_detector_path(pa, 0,0,&ftype,&endian,&offsetsize, &filesize, &errcode); if (res == DW_DLV_NO_ENTRY) { printf("%s file above does not match/exist.\n",lprefix); continue; } if (res == DW_DLV_ERROR) { printf("%s file above access attempt " "lead to error %s\n", dwarf_errmsg_by_number(errcode),lprefix); continue; } realobj = print_ftype_message(lprefix, ftype); if (!realobj) { continue; } /* Now see if the debug has buildid matching the executable. */ if (is_outer && !no_follow_debuglink) { /* read the executable, now look to the debug (ie pa) to see if it matches. Do not pass in globals paths*/ res = one_file_debuglink_internal( FALSE,lprefix,0,0,0, pa,crc,buildid_length, buildid,pa); if (res == DW_DLV_OK) { printf("%s =====File %s is a correct" " .debug object\n\n", lprefix,pa); } } } free(paths); free(debuglinkfullpath); dwarf_finish(dbg,&error); return DW_DLV_OK; } static void one_file_debuglink(char *path,char **dlpaths,unsigned int dlcount, int no_follow_debuglink) { one_file_debuglink_internal(TRUE,"",dlpaths,dlcount, no_follow_debuglink, path,0,0,0,0); } static char **gl_pathnames; static unsigned int gl_pathcount; static void add_a_path(char *path) { unsigned count; char ** newpathnames = 0; unsigned int newslen = 0; unsigned int i = 0; if (!path) { printf("Null debuglink path error\n"); exit(1); } newslen = strlen(path); if (!newslen){ printf("Empty debuglink path ignored\n"); return; } count = gl_pathcount + 1; newpathnames = (char **)malloc(sizeof(char *) *count); if (!newpathnames) { printf("Out of malloc space? giving up.\n"); exit(1); } for (i = 0; i < gl_pathcount; ++i) { newpathnames[i] = gl_pathnames[i]; } newpathnames[i] = strdup(path); if (!newpathnames[i]) { printf("Out of malloc space? giving up.\n"); exit(1); } free(gl_pathnames); gl_pathcount = count; gl_pathnames = newpathnames; } static void free_paths(void) { unsigned i = 0; if (!gl_pathcount) { return; } for(i = 0; i < gl_pathcount; ++i) { free(gl_pathnames[i]); gl_pathnames[i] = 0; } free(gl_pathnames); gl_pathnames = 0; } int main(int argc, char **argv) { int i = 1; char *filenamein = 0; int no_follow_debuglink = FALSE; for ( ; i < argc; ++i) { char *arg = argv[i]; if (!strncmp(arg,"--no-follow-debuglink",21)) { no_follow_debuglink = TRUE; continue; } if (!strncmp(arg,"--add-debuglink-path=",21)){ add_a_path(arg+21); continue; } filenamein = arg; one_file_debuglink(filenamein,gl_pathnames,gl_pathcount, no_follow_debuglink); printf("=======done with %s\n",filenamein); } free_paths(); } libdwarf-20210528/dwarfexample/ChangeLog20130000664000175000017500000000064313737716107015252 000000000000002013-11-24 David Anderson * Makefile: Some compilers (FreeBSD gcc, for example) do not support -gdwarf-4, so changed the compile to -g. 2013-08-13 David Anderson * Add the --check option to verify that dwarf_highpc() and the new dwarf_highpc_b() work properly with both form address and form constant instances of attributes DW_AT_high_pc. libdwarf-20210528/dwarfexample/ChangeLog20090000664000175000017500000000071713737716107015261 00000000000000August 7, 2009 David Anderson * frame1.c: This is a new example that uses frame functions. July 21, 2009 David Anderson * simplereader.c: After cur_die = sib_die; nothing was printing cur_die, so added a print call after the assignment. July 8, 2009 David Anderson * Makefile: New trivial Makefile to build the example. * simplereader.c: New trivial example using libdwarf. libdwarf-20210528/dwarfexample/ChangeLog20140000664000175000017500000000043013737716107015245 000000000000002014-01-30 David Anderson * simplereader.c: Removed dwarf_dealloc from call of string returned by dwarf_diename(). The dwarf_diename() call was incorrectly documented. 2014-01-29 David Anderson * frame1.c,simplereader.c: Remove trailing whitespace. libdwarf-20210528/dwarfexample/CMakeLists.txt0000644000175000017500000000336713743575426015742 00000000000000set_source_group(SIMPLE_READER_SOURCES "Source Files" simplereader.c) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(simplereader ${SIMPLE_READER_SOURCES} ${SIMPLE_READER_HEADERS} ${CONFIGURATION_FILES}) set_folder(simplereader dwarfexample) target_compile_definitions(simplereader PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(simplereader PRIVATE ${DW_FWALL}) target_link_libraries(simplereader PRIVATE ${dwarf-target} ${DW_FZLIB}) set_source_group(FRAME1_SOURCES "Source Files" frame1.c) add_executable(frame1 ${FRAME1_SOURCES} ${FRAME1_HEADERS} ${CONFIGURATION_FILES}) set_folder(frame1 dwarfexample) target_compile_definitions(frame1 PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(frame1 PRIVATE ${DW_FWALL}) target_link_libraries(frame1 PRIVATE ${dwarf-target} ${DW_FZLIB}) set_source_group(FINDFUNCBYPC_SOURCES "Source Files" findfuncbypc.c) add_executable(findfuncbypc ${FINDFUNCBYPC_SOURCES} ${FINDFUNCBYPC_HEADERS} ${CONFIGURATION_FILES}) set_folder(findfuncbypc dwarfexample) target_compile_definitions(findfuncbypc PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(findfuncbypc PRIVATE ${DW_FWALL}) target_link_libraries(findfuncbypc PRIVATE ${dwarf-target} ${DW_FZLIB}) set_source_group(GETDEBUGLINK_SOURCES "Source Files" dwdebuglink.c) add_executable(dwdebuglink ${GETDEBUGLINK_SOURCES} ${GETDEBUGLINK_HEADERS} ${CONFIGURATION_FILES}) set_folder(dwdebuglink dwarfexample) target_compile_definitions(dwdebuglink PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(dwdebuglink PRIVATE ${DW_FWALL}) target_link_libraries(dwdebuglink PRIVATE ${dwarf-target} ${DW_FZLIB}) libdwarf-20210528/dwarfexample/ChangeLog20180000664000175000017500000000256213737716107015261 000000000000002018-09-21 David Anderson * Makefile.am: Now config.h.in.cmake gets into releases. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Moves ChangeLog and other files to the distribution, and out of the set of installed files. 2018-07-16 David Anderson * simplereader.c: Refines the ifdef of HAVE_STDAFX_H 2018-07-16 David Anderson * simplereader.c: Changed // comments to /* */ * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-14 David Anderson * Makefile.in,config.h.in,configure,configure.ac: Removed unnecessary configure lines, regenerated configure. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * simplereader.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-05 David Anderson * simplereader.c: Remove erroneous _MSC_VER per Carlos Alberto Enciso. Change WIN32 to _WIN32. 2018-05-12 David Anderson * frame1.c: Adding new code (select with option --just-print-selected-regs) to test a new frame access function. libdwarf-20210528/dwarfexample/frame1.c0000644000175000017500000005415613744143544014514 00000000000000/* Copyright (c) 2009-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3)The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* simplereader.c This is an example of code reading dwarf .debug_frame. It is kept as simple as possible to expose essential features. It does not do all possible error reporting or error handling. It specifically calls dwarf_expand_frame_instructions() to verify that works without crashing! To use, try make ./frame1 frame1 gcc/clang may produce .eh_frame without .debug_frame. To read .eh_frame call dwarf_get_fde_list_eh() below instead of dwarf_get_fde_list() . */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ #include /* For strcmp* */ #include #include #include "dwarf.h" #include "libdwarf.h" static void read_frame_data(Dwarf_Debug dbg,const char *sec); static void print_fde_instrs(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Error *error); static void print_regtable(Dwarf_Regtable3 *tab3); static void print_cie_instrs(Dwarf_Cie cie,Dwarf_Error *error); static void print_fde_selected_regs( Dwarf_Fde fde); static void print_reg(int r); static int just_print_selected_regs = 0; /* Depending on the ABI we set INITIAL_VAL differently. For ia64 initial value is UNDEF_VAL, for MIPS and others initial value is SAME_VAL. Here we'll set it UNDEF_VAL as that way we'll see when first set. */ #define UNDEF_VAL 2000 #define SAME_VAL 2001 #define CFA_VAL 2002 #define INITIAL_VAL UNDEF_VAL /* Don't really want getopt here. yet. so hand do options. */ int main(int argc, char **argv) { Dwarf_Debug dbg = 0; int fd = -1; const char *filepath = ""; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; int regtabrulecount = 0; int curopt = 0; for(curopt = 1;curopt < argc; ++curopt) { if (strncmp(argv[curopt],"--",2)) { break; } if (!strcmp(argv[curopt],"--just-print-selected-regs")) { just_print_selected_regs++; } } if(curopt == argc ) { fd = 0; /* stdin */ } else if (curopt == (argc-1)) { filepath = argv[curopt]; fd = open(filepath,O_RDONLY|O_BINARY); } else { printf("Too many args, giving up. \n"); exit(1); } if(fd < 0) { printf("Failure attempting to open %s\n",filepath); } res = dwarf_init_b(fd,DW_DLC_READ,DW_GROUPNUMBER_ANY, errhand,errarg, &dbg,&error); if(res != DW_DLV_OK) { printf("Giving up, dwarf_init failed, " "cannot do DWARF processing\n"); if (res == DW_DLV_ERROR) { printf("Error code %s\n",dwarf_errmsg(error)); } exit(1); } /* Do this setting after init before any real operations. These return the old values, but here we do not need to know the old values. The sizes and values here are higher than most ABIs and entirely arbitrary. The setting of initial_value to the same as undefined-value (the other possible choice being same-value) is arbitrary, different ABIs do differ, and you have to know which is right. In dwarfdump we get the SAME_VAL, UNDEF_VAL, INITIAL_VAL CFA_VAL from dwconf_s struct. */ regtabrulecount=1999; dwarf_set_frame_undefined_value(dbg, UNDEF_VAL); dwarf_set_frame_rule_initial_value(dbg, INITIAL_VAL); dwarf_set_frame_same_value(dbg,SAME_VAL); dwarf_set_frame_cfa_value(dbg,CFA_VAL); dwarf_set_frame_rule_table_size(dbg,regtabrulecount); read_frame_data(dbg,".debug_frame"); read_frame_data(dbg,".eh_frame"); res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } close(fd); return 0; } static void read_frame_data(Dwarf_Debug dbg,const char *sect) { Dwarf_Error error; Dwarf_Signed cie_element_count = 0; Dwarf_Signed fde_element_count = 0; Dwarf_Cie *cie_data = 0; Dwarf_Fde *fde_data = 0; int res = DW_DLV_ERROR; Dwarf_Signed fdenum = 0; /* If you wish to read .eh_frame data, use dwarf_get_fde_list_eh() instead. Get debug_frame with dwarf_get_fde_list. */ printf(" Print %s\n",sect); if (!strcmp(sect,".eh_frame")) { res = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_element_count, &fde_data,&fde_element_count,&error); } else { res = dwarf_get_fde_list(dbg,&cie_data,&cie_element_count, &fde_data,&fde_element_count,&error); } if(res == DW_DLV_NO_ENTRY) { printf("No %s data present\n",sect); return; } if( res == DW_DLV_ERROR) { printf("Error reading frame data "); exit(1); } printf( "%" DW_PR_DSd " cies present. " "%" DW_PR_DSd " fdes present. \n", cie_element_count,fde_element_count); /*if(fdenum >= fde_element_count) { printf("Want fde %d but only %" DW_PR_DSd " present\n",fdenum, fde_element_count); exit(1); }*/ for(fdenum = 0; fdenum < fde_element_count; ++fdenum) { Dwarf_Cie cie = 0; res = dwarf_get_cie_of_fde(fde_data[fdenum],&cie,&error); if(res != DW_DLV_OK) { printf("Error accessing cie of fdenum %" DW_PR_DSd " to get its cie\n",fdenum); exit(1); } printf("Print cie of fde %" DW_PR_DSd "\n",fdenum); print_cie_instrs(cie,&error); printf("Print fde %" DW_PR_DSd "\n",fdenum); if (just_print_selected_regs) { print_fde_selected_regs(fde_data[fdenum]); } else { print_fde_instrs(dbg,fde_data[fdenum],&error); } } /* Done with the data. */ dwarf_fde_cie_list_dealloc(dbg,cie_data,cie_element_count, fde_data, fde_element_count); return; } /* Simply shows the instructions at hand for this fde. */ static void print_cie_instrs(Dwarf_Cie cie,Dwarf_Error *error) { int res = DW_DLV_ERROR; Dwarf_Unsigned bytes_in_cie = 0; Dwarf_Small version = 0; char *augmentation = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr instrp = 0; Dwarf_Unsigned instr_len = 0; res = dwarf_get_cie_info(cie,&bytes_in_cie, &version, &augmentation, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &instrp,&instr_len,error); if(res != DW_DLV_OK) { printf("Unable to get cie info!\n"); exit(1); } } /* This was written with DWARF2 Dwarf_Frame_Op! FIXME need dwarf_expand_frame_instructions_b() */ static void print_frame_instrs(Dwarf_Frame_Op *frame_op_array, Dwarf_Signed frame_op_count) { Dwarf_Signed i = 0; printf("Base op. Ext op. Reg. Offset. Instr-offset.\n"); for(i = 0; i < frame_op_count; ++i) { Dwarf_Frame_Op *fo = frame_op_array +i; printf("[%2" DW_PR_DSd "]", i); printf(" %2d. ", fo->fp_base_op); printf(" 0x%02x. ", fo->fp_extended_op); printf(" %3d. ", fo->fp_register); /* DWARF3 and later: for DW_CFA_def_cfa_expression, DW_CFA_val_expression, and DW_CFA_expression the fp_offset is a pointer into runtime memory. Printing it is not helpful in a diff. */ if (fo->fp_extended_op == DW_CFA_def_cfa || fo->fp_extended_op == DW_CFA_val_expression || fo->fp_extended_op == DW_CFA_def_cfa_expression ) { /* The offset is really a pointer. */ printf(" (pointer-value) "); } else { /* The offset is a real offset /value of some sort. */ printf(" %6" DW_PR_DSd ". ", fo->fp_offset); } printf(" 0x%08" DW_PR_DUx ". ", fo->fp_instr_offset); printf("\n"); } } static void print_fde_col(Dwarf_Signed k, Dwarf_Addr jsave, Dwarf_Small value_type, Dwarf_Signed offset_relevant, Dwarf_Signed reg_used, Dwarf_Signed offset_or_block_len, Dwarf_Ptr block_ptr, Dwarf_Addr row_pc, Dwarf_Bool has_more_rows, Dwarf_Addr subsequent_pc) { char *type_title = ""; Dwarf_Unsigned rule_id = k; printf(" pc=0x%" DW_PR_DUx ,jsave); if (row_pc != jsave) { printf(" row_pc=0x%" DW_PR_DUx ,row_pc); } printf(" col=%" DW_PR_DSd " ",k); switch(value_type) { case DW_EXPR_OFFSET: type_title = "off"; goto preg2; case DW_EXPR_VAL_OFFSET: type_title = "valoff"; preg2: printf("<%s ", type_title); if (reg_used == SAME_VAL) { printf(" SAME_VAL"); break; } else if (reg_used == INITIAL_VAL) { printf(" INITIAL_VAL"); break; } print_reg(rule_id); printf("="); if (offset_relevant == 0) { print_reg(reg_used); printf(" "); } else { printf("%02" DW_PR_DSd , offset_or_block_len); printf("("); print_reg(reg_used); printf(") "); } break; case DW_EXPR_EXPRESSION: type_title = "expr"; goto pexp2; case DW_EXPR_VAL_EXPRESSION: type_title = "valexpr"; pexp2: printf("<%s ", type_title); print_reg(rule_id); printf("="); printf("expr-block-len=%" DW_PR_DSd , offset_or_block_len); printf(" block-ptr=%" DW_PR_DUx, (Dwarf_Unsigned)(uintptr_t)block_ptr); #if 0 { char pref[40]; strcpy(pref, "<"); strcat(pref, type_title); strcat(pref, "bytes:"); /* The data being dumped comes direct from libdwarf so libdwarf validated it. */ dump_block(pref, block_ptr, offset_or_block_len); printf("%s", "> "); if (glflags.verbose) { struct esb_s exprstring; esb_constructor(&exprstring); get_string_from_locs(dbg, block_ptr,offset,addr_size, offset_size,version,&exprstring); printf("",esb_get_string(&exprstring)); esb_destructor(&exprstring); } } #endif break; default: printf("Internal error in libdwarf, value type %d\n", value_type); exit(1); } printf(" more=%d",has_more_rows); printf(" next=0x%" DW_PR_DUx,subsequent_pc); printf("%s", "> "); printf("\n"); } /* In dwarfdump we use dwarf_get_fde_info_for_cfa_reg3_b() to get subsequent pc and avoid incrementing pc by for the next cfa, using has_more_rows and subsequent_pc passed back. Here, to verify function added in May 2018, we instead use dwarf_get_fde_info_for_reg3_b() which has the has_more_rows and subsequent_pc functions for the case where one is tracking a particular register and not closely watching the CFA value itself. */ static void print_fde_selected_regs( Dwarf_Fde fde) { Dwarf_Error oneferr = 0; /* Arbitrary column numbers for testing. */ static int selected_cols[] = {1,3,5}; static int selected_cols_count = sizeof(selected_cols)/sizeof(selected_cols[0]); Dwarf_Signed k = 0; int fres = 0; Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes = NULL; Dwarf_Unsigned fde_bytes_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Fde curfde = fde; Dwarf_Cie cie = 0; Dwarf_Addr jsave = 0; Dwarf_Addr high_addr = 0; Dwarf_Addr next_jsave = 0; Dwarf_Bool has_more_rows = 0; Dwarf_Addr subsequent_pc = 0; Dwarf_Error error = 0; int res = 0; fres = dwarf_get_fde_range(curfde, &low_pc, &func_length, &fde_bytes, &fde_bytes_length, &cie_offset, &cie_index, &fde_offset, &oneferr); if (fres == DW_DLV_ERROR) { printf("FAIL: dwarf_get_fde_range err %" DW_PR_DUu " line %d\n", dwarf_errno(oneferr),__LINE__); exit(1); } if (fres == DW_DLV_NO_ENTRY) { printf("No fde range data available\n"); return; } res = dwarf_get_cie_of_fde(fde,&cie,&error); if(res != DW_DLV_OK) { printf("Error getting cie from fde\n"); exit(1); } high_addr = low_pc + func_length; /* Could check has_more_rows here instead of high_addr, If we initialized has_more_rows to 1 above. */ for(jsave = low_pc ; next_jsave < high_addr; jsave = next_jsave) { next_jsave = jsave+1; printf("\n"); for(k = 0; k < selected_cols_count ; ++k ) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; int fires = 0; Dwarf_Small value_type = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Addr row_pc = 0; fires = dwarf_get_fde_info_for_reg3_b(curfde, selected_cols[k], jsave, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, &has_more_rows, &subsequent_pc, &oneferr); if (fires == DW_DLV_ERROR) { printf("FAIL: reading reg err %" DW_PR_DUu " line %d", dwarf_errno(oneferr),__LINE__); exit(1); } if (fires == DW_DLV_NO_ENTRY) { continue; } print_fde_col( selected_cols[k],jsave, value_type,offset_relevant, reg,offset_or_block_len,block_ptr,row_pc, has_more_rows, subsequent_pc); if (has_more_rows) { next_jsave = subsequent_pc; } else { next_jsave = high_addr; } } } } /* Just prints the instructions in the fde. */ static void print_fde_instrs(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Error *error) { int res; Dwarf_Addr lowpc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes; Dwarf_Unsigned fde_byte_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Addr arbitrary_addr = 0; Dwarf_Addr actual_pc = 0; Dwarf_Regtable3 tab3; int oldrulecount = 0; Dwarf_Ptr outinstrs = 0; Dwarf_Unsigned instrslen = 0; Dwarf_Frame_Op * frame_op_array = 0; Dwarf_Signed frame_op_count = 0; Dwarf_Cie cie = 0; res = dwarf_get_fde_range(fde,&lowpc,&func_length,&fde_bytes, &fde_byte_length,&cie_offset,&cie_index,&fde_offset,error); if(res != DW_DLV_OK) { printf("Problem getting fde range \n"); exit(1); } arbitrary_addr = lowpc + (func_length/2); printf("function low pc 0x%" DW_PR_DUx " and length 0x%" DW_PR_DUx " and midpoint addr we choose 0x%" DW_PR_DUx "\n", lowpc,func_length,arbitrary_addr); /* 1 is arbitrary. We are winding up getting the rule count here while leaving things unchanged. */ oldrulecount = dwarf_set_frame_rule_table_size(dbg,1); dwarf_set_frame_rule_table_size(dbg,oldrulecount); tab3.rt3_reg_table_size = oldrulecount; tab3.rt3_rules = (struct Dwarf_Regtable_Entry3_s *) malloc( sizeof(struct Dwarf_Regtable_Entry3_s)* oldrulecount); if (!tab3.rt3_rules) { printf("Unable to malloc for %d rules\n",oldrulecount); exit(1); } res = dwarf_get_fde_info_for_all_regs3(fde,arbitrary_addr , &tab3,&actual_pc,error); printf("function actual addr of row 0x%" DW_PR_DUx "\n", actual_pc); if(res != DW_DLV_OK) { printf("dwarf_get_fde_info_for_all_regs3 failed!\n"); exit(1); } print_regtable(&tab3); res = dwarf_get_fde_instr_bytes(fde,&outinstrs,&instrslen,error); if(res != DW_DLV_OK) { printf("dwarf_get_fde_instr_bytes failed!\n"); exit(1); } res = dwarf_get_cie_of_fde(fde,&cie,error); if(res != DW_DLV_OK) { printf("Error getting cie from fde\n"); exit(1); } res = dwarf_expand_frame_instructions(cie, outinstrs,instrslen,&frame_op_array, &frame_op_count,error); if(res != DW_DLV_OK) { printf("dwarf_expand_frame_instructions failed!\n"); exit(1); } printf("Frame op count: %" DW_PR_DUu "\n",frame_op_count); print_frame_instrs(frame_op_array,frame_op_count); dwarf_dealloc(dbg,frame_op_array, DW_DLA_FRAME_BLOCK); free(tab3.rt3_rules); } static void print_reg(int r) { switch(r) { case SAME_VAL: printf(" %d SAME_VAL ",r); break; case UNDEF_VAL: printf(" %d UNDEF_VAL ",r); break; case CFA_VAL: printf(" %d (CFA) ",r); break; default: printf(" r%d ",r); break; } } static void print_one_regentry(const char *prefix, struct Dwarf_Regtable_Entry3_s *entry) { int is_cfa = !strcmp("cfa",prefix); printf("%s ",prefix); printf("type: %d %s ", entry->dw_value_type, (entry->dw_value_type == DW_EXPR_OFFSET)? "DW_EXPR_OFFSET": (entry->dw_value_type == DW_EXPR_VAL_OFFSET)? "DW_EXPR_VAL_OFFSET": (entry->dw_value_type == DW_EXPR_EXPRESSION)? "DW_EXPR_EXPRESSION": (entry->dw_value_type == DW_EXPR_VAL_EXPRESSION)? "DW_EXPR_VAL_EXPRESSION": "Unknown"); switch(entry->dw_value_type) { case DW_EXPR_OFFSET: print_reg(entry->dw_regnum); printf(" offset_rel? %d ",entry->dw_offset_relevant); if(entry->dw_offset_relevant) { printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); if(is_cfa) { printf("defines cfa value"); } else { printf("address of value is CFA plus signed offset"); } if(!is_cfa && entry->dw_regnum != CFA_VAL) { printf(" compiler botch, regnum != CFA_VAL"); } } else { printf("value in register"); } break; case DW_EXPR_VAL_OFFSET: print_reg(entry->dw_regnum); printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); if(is_cfa) { printf("does this make sense? No?"); } else { printf("value at CFA plus signed offset"); } if(!is_cfa && entry->dw_regnum != CFA_VAL) { printf(" compiler botch, regnum != CFA_VAL"); } break; case DW_EXPR_EXPRESSION: print_reg(entry->dw_regnum); printf(" offset_rel? %d ",entry->dw_offset_relevant); printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); printf("Block ptr set? %s ",entry->dw_block_ptr?"yes":"no"); printf(" Value is at address given by expr val "); /* printf(" block-ptr 0x%" DW_PR_DUx " ", (Dwarf_Unsigned)entry->dw_block_ptr); */ break; case DW_EXPR_VAL_EXPRESSION: printf(" expression byte len %" DW_PR_DSd " " , entry->dw_offset_or_block_len); printf("Block ptr set? %s ",entry->dw_block_ptr?"yes":"no"); printf(" Value is expr val "); if(!entry->dw_block_ptr) { printf("Compiler botch. "); } /* printf(" block-ptr 0x%" DW_PR_DUx " ", (Dwarf_Unsigned)entry->dw_block_ptr); */ break; } printf("\n"); } static void print_regtable(Dwarf_Regtable3 *tab3) { int r; /* We won't print too much. A bit arbitrary. */ int max = 10; if(max > tab3->rt3_reg_table_size) { max = tab3->rt3_reg_table_size; } print_one_regentry("cfa",&tab3->rt3_cfa_rule); for(r = 0; r < max; r++) { char rn[30]; snprintf(rn,sizeof(rn),"reg %d",r); print_one_regentry(rn,tab3->rt3_rules+r); } } libdwarf-20210528/dwarfexample/simplereader.c0000644000175000017500000010523713745334567016022 00000000000000/* Copyright (c) 2009-2020 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3)The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* simplereader.c This is an example of code reading dwarf .debug_info. It is kept simple to expose essential features. Though it now has a bunch of special options to enable testing of specific libdwarf features so it's no longer all that simple... It does not do all possible error reporting or error handling. It does to a bit of error checking as a help in ensuring that some code works properly... for error checks. The --names option adds some extra printing. The --check option does some interface and error checking. Option new September 2016: --dumpallnames=filepath This causes all the strings from the .debug_info and .debug_types sections to be written to 'filepath'. Any previous contents of the file are wiped out. This could be handy if you want to use the set of strings to investigate ways to improve the density of strings in some way. Options new 03 May 2015: These options do something different. They use specific DWARF5 package file libdwarf operations as a way to ensure libdwarf works properly (these specials used by the libdwarf regresson test suite). Examples given assuming dwp object fissionb-ld-new.dwp from the regressiontests --tuhash=hashvalue example: --tuhash=b0dd19898e8aa823 It prints a DIE. --cuhash=hashvalue example: --cuhash=1e9983f631642b1a It prints a DIE. --cufissionhash=hashvalue example: --tufissionhash=1e9983f631642b1a It prints the fission data for this hash. --tufissionhash=hashvalue example: --tufissionhash=b0dd19898e8aa823 It prints the fission data for this hash. --fissionfordie=cunumber example: --fissionfordie=5 For CU number 5 (0 is the initial CU/TU) it accesses the CU/TU DIE and then uses that DIE to get the fission data. New January 2019: --use-init-fd Instead of using dwarf_init_path(), use dwarf_init_fd() to make particular tests of that interface. To use, try make ./simplereader simplereader */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf.h" #include "libdwarf.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ struct srcfilesdata { char ** srcfiles; Dwarf_Signed srcfilescount; int srcfilesres; }; #define TRUE 1 #define FALSE 0 static void read_cu_list(Dwarf_Debug dbg); static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf); static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info, int in_level, struct srcfilesdata *sf); static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf); /* Use a generic call to open the file, due to issues with Windows */ static int namesoptionon = 0; static int checkoptionon = 0; static int dumpallnames = 0; FILE *dumpallnamesfile = 0; static const char * dumpallnamespath = 0; #if 0 DW_UT_compile 0x01 /* DWARF5 */ DW_UT_type 0x02 /* DWARF5 */ DW_UT_partial 0x03 /* DWARF5 */ #endif static int stdrun = TRUE; static int unittype = DW_UT_compile; static Dwarf_Bool g_is_info = TRUE; int cu_version_stamp = 0; int cu_offset_size = 0; /* dienumberr is used to count DIEs. The point is to match fissionfordie. */ static int dienumber = 0; static int fissionfordie = -1; static int passnullerror = 0; /* These hash representations have to be converted to Dwarf_Sig8 before use. */ static const char * cuhash = 0; static const char * tuhash = 0; static const char * cufissionhash = 0; static const char * tufissionhash = 0; /* So we get clean reports from valgrind and other tools we clean up strdup strings. With a primitive technique as we need nothing fancy. */ #define DUPSTRARRAYSIZE 100 static const char *dupstrarray[DUPSTRARRAYSIZE]; static unsigned dupstrused; static void cleanupstr(void) { unsigned i = 0; for (i = 0; i < dupstrused; ++i) { free((char *)dupstrarray[i]); dupstrarray[i] = 0; } dupstrused = 0; } static unsigned char_to_uns4bit(unsigned char c) { unsigned v; if( c >= '0' && c <= '9') { v = c - '0'; } else if( c >= 'a' && c <= 'f') { v = c - 'a' + 10; } else if( c >= 'A' && c <= 'F') { v = c - 'A' + 10; } else { printf("Garbage hex char in %c 0x%x\n",c,c); exit(1); } return v; } static void xfrm_to_sig8(const char *cuhash_in, Dwarf_Sig8 *hash_out) { char localhash[16]; unsigned hashin_len = strlen(cuhash_in); unsigned fixed_size = sizeof(localhash); unsigned init_byte = 0; unsigned i; memset(localhash,0,fixed_size); if (hashin_len > fixed_size) { printf("FAIL: argument hash too long, len %u val:\"%s\"\n", hashin_len, cuhash_in); exit(1); } if (hashin_len < fixed_size) { unsigned add_zeros = fixed_size - hashin_len; for ( ; add_zeros > 0; add_zeros--) { localhash[init_byte] = '0'; init_byte++; } } for (i = 0; i < hashin_len; ++i,++init_byte) { localhash[init_byte] = cuhash_in[i]; } /* So now local hash as a full 16 bytes of hex characters with any needed leading zeros. transform it to 8 byte hex signature */ for (i = 0; i < sizeof(Dwarf_Sig8) ; ++i) { unsigned char hichar = localhash[2*i]; unsigned char lochar = localhash[2*i+1]; hash_out->signature[i] = (char_to_uns4bit(hichar) << 4) | char_to_uns4bit(lochar); } printf("Hex key = 0x"); for (i = 0; i < sizeof(Dwarf_Sig8) ; ++i) { unsigned char c = hash_out->signature[i]; printf("%02x",c); } printf("\n"); } static int startswithextractnum(const char *arg,const char *lookfor, int *numout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); int v = 0; if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; /* We are not making any attempt to deal with garbage. Pass in good data... */ v = atoi(s); *numout = v; return TRUE; } static int startswithextractstring(const char *arg,const char *lookfor, const char ** ptrout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; *ptrout = strdup(s); dupstrarray[dupstrused] = *ptrout; dupstrused++; if (dupstrused >= DUPSTRARRAYSIZE) { printf("FAIL: increase the value DUPSTRARRAYSIZE" " for test purposes\n"); exit(1); } return TRUE; } static void format_sig8_string(Dwarf_Sig8*data, char* str_buf,unsigned buf_size) { unsigned i = 0; char *cp = str_buf; if (buf_size < 19) { printf("FAIL: internal coding error in test.\n"); exit(1); } strcpy(cp,"0x"); cp += 2; buf_size -= 2; for (; i < sizeof(data->signature); ++i,cp+=2,buf_size--) { snprintf(cp, buf_size, "%02x", (unsigned char)(data->signature[i])); } return; } static void print_debug_fission_header(struct Dwarf_Debug_Fission_Per_CU_s *fsd) { const char * fissionsec = ".debug_cu_index"; unsigned i = 0; char str_buf[30]; if (!fsd || !fsd->pcu_type) { /* No fission data. */ return; } printf("\n"); if (!strcmp(fsd->pcu_type,"tu")) { fissionsec = ".debug_tu_index"; } printf(" %-19s = %s\n","Fission section",fissionsec); printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx "\n","Fission index ", fsd->pcu_index); format_sig8_string(&fsd->pcu_hash,str_buf,sizeof(str_buf)); printf(" %-19s = %s\n","Fission hash",str_buf); /* 0 is always unused. Skip it. */ printf(" %-19s = %s\n","Fission entries","offset size DW_SECTn"); for( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int res = 0; if (size == 0) { continue; } res = dwarf_get_SECT_name(i,&nstring); if (res != DW_DLV_OK) { nstring = "Unknown SECT"; } off = fsd->pcu_offset[i]; printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %2u\n", nstring, off, size,i); } } /* If there is no 'error' passed into a dwarf function and there is an error, and an error-handler like this is passed. This example simply returns so we test how well that action works. */ static void simple_error_handler(Dwarf_Error error, Dwarf_Ptr errarg) { Dwarf_Unsigned unused = (Dwarf_Unsigned)(uintptr_t)errarg; printf("\nlibdwarf error detected: 0x%" DW_PR_DUx " %s\n", dwarf_errno(error),dwarf_errmsg(error)); printf("libdwarf errarg. Not really used here %" DW_PR_DUu "\n", unused); return; } int main(int argc, char **argv) { Dwarf_Debug dbg = 0; const char *filepath = 0; int use_init_fd = FALSE; int my_init_fd = 0; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; Dwarf_Sig8 hash8; Dwarf_Error *errp = 0; int simpleerrhand = 0; int i = 0; #define MACHO_PATH_LEN 2000 char macho_real_path[MACHO_PATH_LEN]; macho_real_path[0] = 0; for(i = 1; i < (argc-1) ; ++i) { if(strcmp(argv[i],"--names") == 0) { namesoptionon=1; } else if(startswithextractstring(argv[1],"--dumpallnames=", &dumpallnamespath)) { dumpallnames=1; } else if(strcmp(argv[i],"--check") == 0) { checkoptionon=1; } else if(startswithextractstring(argv[i],"--tuhash=",&tuhash)) { /* done */ } else if(startswithextractstring(argv[i],"--cuhash=",&cuhash)) { /* done */ } else if(startswithextractstring(argv[i],"--tufissionhash=", &tufissionhash)) { /* done */ } else if(startswithextractstring(argv[i],"--cufissionhash=", &cufissionhash)) { /* done */ } else if(strcmp(argv[i],"--passnullerror") == 0) { passnullerror=1; } else if(strcmp(argv[i],"--simpleerrhand") == 0) { simpleerrhand=1; } else if(startswithextractnum(argv[i],"--isinfo=",&g_is_info)) { /* done */ } else if(startswithextractnum(argv[i],"--type=",&unittype)) { /* done */ } else if(startswithextractnum(argv[i],"--fissionfordie=", &fissionfordie)) { /* done */ } else if(!strcmp(argv[i],"--use-init-fd")) { use_init_fd = TRUE; /* done */ } else { printf("Unknown argument \"%s\", give up \n",argv[i]); exit(1); } } if (i >= argc) { printf("simplereader not given file to open\n"); printf("simplereader exits\n"); exit(1); } filepath = argv[i]; if (dumpallnames) { if (!strcmp(dumpallnamespath,filepath)) { printf("Using --dumpallnames with the same path " "(%s) " "as the file to read is not allowed. giving up.\n", filepath); exit(1); } dumpallnamesfile = fopen(dumpallnamespath,"w"); if(!dumpallnamesfile) { printf("Cannot open %s. Giving up.\n", dumpallnamespath); exit(1); } } if(passnullerror) { errp = 0; } else { errp = &error; } if (simpleerrhand) { errhand = simple_error_handler; /* Not a very useful errarg... */ errarg = (Dwarf_Ptr)1; } if (use_init_fd) { /* For testing a libdwarf init function. We are not finding the true dSYM Macho-object here if that applies, so it's up to the user of simplereader to pass in the correct dSYM object in the dSYM case. dwarf_object_detector_path() could do the dSYM object finding, but to keep this simple we leave that to the reader. */ my_init_fd = open(filepath,O_RDONLY|O_BINARY); if (my_init_fd == -1) { printf("Giving up, cannot open %s\n",filepath); exit(1); } res = dwarf_init(my_init_fd,DW_DLC_READ, errhand,errarg,&dbg,errp); } else { res = dwarf_init_path(filepath, macho_real_path, MACHO_PATH_LEN, DW_DLC_READ, DW_GROUPNUMBER_ANY,errhand,errarg,&dbg, 0,0,0,errp); } if(res != DW_DLV_OK) { printf("Giving up, cannot do DWARF processing\n"); cleanupstr(); exit(1); } if(cuhash) { Dwarf_Die die; stdrun = FALSE; xfrm_to_sig8(cuhash,&hash8); printf("\n"); printf("Getting die for CU key %s\n",cuhash); res = dwarf_die_from_hash_signature(dbg, &hash8,"cu", &die,errp); if (res == DW_DLV_OK) { struct srcfilesdata sf; printf("Hash found.\n"); sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; print_die_data(dbg,die,0,&sf); dwarf_dealloc(dbg,die, DW_DLA_DIE); } else if (res == DW_DLV_NO_ENTRY) { printf("cuhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("cuhash DW_DLV_ERROR %s\n", errp? dwarf_errmsg(error):"an error"); } } if(tuhash) { Dwarf_Die die; stdrun = FALSE; xfrm_to_sig8(tuhash,&hash8); printf("\n"); printf("Getting die for TU key %s\n",tuhash); res = dwarf_die_from_hash_signature(dbg, &hash8,"tu", &die,errp); if (res == DW_DLV_OK) { struct srcfilesdata sf; printf("Hash found.\n"); sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; print_die_data(dbg,die,0,&sf); dwarf_dealloc(dbg,die, DW_DLA_DIE); } else if (res == DW_DLV_NO_ENTRY) { printf("tuhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("tuhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):"error!"); } } if(cufissionhash) { Dwarf_Debug_Fission_Per_CU fisdata; stdrun = FALSE; memset(&fisdata,0,sizeof(fisdata)); xfrm_to_sig8(cufissionhash,&hash8); printf("\n"); printf("Getting fission data for CU key %s\n",cufissionhash); res = dwarf_get_debugfission_for_key(dbg, &hash8,"cu", &fisdata,errp); if (res == DW_DLV_OK) { printf("Hash found.\n"); print_debug_fission_header(&fisdata); } else if (res == DW_DLV_NO_ENTRY) { printf("cufissionhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("cufissionhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):"error..."); } } if(tufissionhash) { Dwarf_Debug_Fission_Per_CU fisdata; stdrun = FALSE; memset(&fisdata,0,sizeof(fisdata)); xfrm_to_sig8(tufissionhash,&hash8); printf("\n"); printf("Getting fission data for TU key %s\n",tufissionhash); res = dwarf_get_debugfission_for_key(dbg, &hash8,"tu", &fisdata,errp); if (res == DW_DLV_OK) { printf("Hash found.\n"); print_debug_fission_header(&fisdata); } else if (res == DW_DLV_NO_ENTRY) { printf("tufissionhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("tufissionhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):" Some error"); } } if (stdrun) { read_cu_list(dbg); } res = dwarf_finish(dbg,errp); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } if (use_init_fd) { close(my_init_fd); } if (dumpallnamesfile) { fclose(dumpallnamesfile); } cleanupstr(); return 0; } static void read_cu_list(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Half version_stamp = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Sig8 signature; Dwarf_Unsigned typeoffset = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Half header_cu_type = unittype; Dwarf_Bool is_info = g_is_info; Dwarf_Error error; int cu_number = 0; Dwarf_Error *errp = 0; for(;;++cu_number) { Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; struct srcfilesdata sf; sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; memset(&signature,0, sizeof(signature)); if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_next_cu_header_d(dbg,is_info,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size,&signature, &typeoffset, &next_cu_header, &header_cu_type,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"An error next cu her"; printf("Error in dwarf_next_cu_header: %s\n",em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ return; } cu_version_stamp = version_stamp; cu_offset_size = offset_size; /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof_b(dbg,no_die,is_info, &cu_die,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"An error"; printf("Error in dwarf_siblingof_b on CU die: %s\n",em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ printf("no entry! in dwarf_siblingof on CU die \n"); exit(1); } get_die_and_siblings(dbg,cu_die,is_info,0,&sf); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); resetsrcfiles(dbg,&sf); } } static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info,int in_level, struct srcfilesdata *sf) { int res = DW_DLV_ERROR; Dwarf_Die cur_die=in_die; Dwarf_Die child = 0; Dwarf_Error error = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } print_die_data(dbg,in_die,in_level,sf); for(;;) { Dwarf_Die sib_die = 0; res = dwarf_child(cur_die,&child,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_child , level %d \n",in_level); exit(1); } if(res == DW_DLV_OK) { get_die_and_siblings(dbg,child,is_info, in_level+1,sf); /* No longer need 'child' die. */ dwarf_dealloc(dbg,child,DW_DLA_DIE); child = 0; } /* res == DW_DLV_NO_ENTRY or DW_DLV_OK */ res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"Error siblingof_b"; printf("Error in dwarf_siblingof_b , level %d :%s \n", in_level,em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if(cur_die != in_die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); cur_die = 0; } cur_die = sib_die; print_die_data(dbg,cur_die,in_level,sf); } return; } static void get_addr(Dwarf_Attribute attr,Dwarf_Addr *val) { Dwarf_Error error = 0; int res; Dwarf_Addr uval = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_formaddr(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } return; } static void get_number(Dwarf_Attribute attr,Dwarf_Unsigned *val) { Dwarf_Error error = 0; int res; Dwarf_Signed sval = 0; Dwarf_Unsigned uval = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_formudata(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } res = dwarf_formsdata(attr,&sval,errp); if(res == DW_DLV_OK) { *val = sval; return; } return; } static void print_subprog(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf, const char *name) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed attrcount = 0; Dwarf_Signed i; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned linenum = 0; char *filename = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_attrlist(die,&attrbuf,&attrcount,errp); if(res != DW_DLV_OK) { return; } for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,errp); if(res == DW_DLV_OK) { if(aform == DW_AT_decl_file) { Dwarf_Signed filenum_s = 0; get_number(attrbuf[i],&filenum); filenum_s = filenum; /* Would be good to evaluate filenum_s sanity here, ensuring filenum_s-1 is sensible. */ if((filenum > 0) && (sf->srcfilescount > (filenum_s-1))) { filename = sf->srcfiles[filenum_s-1]; } } if(aform == DW_AT_decl_line) { get_number(attrbuf[i],&linenum); } if(aform == DW_AT_low_pc) { get_addr(attrbuf[i],&lowpc); } if(aform == DW_AT_high_pc) { /* This will FAIL with DWARF4 highpc form of 'class constant'. */ get_addr(attrbuf[i],&highpc); } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } /* Here let's test some alternative interfaces for high and low pc. We only do both dwarf_highpc and dwarf_highpcb_b as an error check. Do not do both yourself. */ if(checkoptionon){ int hres = 0; int hresb = 0; int lres = 0; Dwarf_Addr althipc = 0; Dwarf_Addr hipcoffset = 0; Dwarf_Addr althipcb = 0; Dwarf_Addr altlopc = 0; Dwarf_Half highform = 0; enum Dwarf_Form_Class highclass = 0; /* Reusing errp before checking for err here is bogus. FIXME. */ /* Should work for DWARF 2/3 DW_AT_high_pc, and all high_pc where the FORM is DW_FORM_addr Avoid using this interface as of 2013. */ hres = dwarf_highpc(die,&althipc,errp); /* Should work for all DWARF DW_AT_high_pc. */ hresb = dwarf_highpc_b(die,&althipcb,&highform,&highclass,errp); lres = dwarf_lowpc(die,&altlopc,errp); printf("high_pc checking %s ",name); if (hres == DW_DLV_OK) { /* present, FORM addr */ printf("highpc 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipc); } else if (hres == DW_DLV_ERROR) { printf("dwarf_highpc() error not class address "); } else { /* absent */ } if(hresb == DW_DLV_OK) { /* present, FORM addr or const. */ if(highform == DW_FORM_addr) { printf("highpcb 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb); } else { if(lres == DW_DLV_OK) { hipcoffset = althipcb; althipcb = altlopc + hipcoffset; printf("highpcb 0x%" DW_PR_XZEROS DW_PR_DUx " " "highoff 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb,hipcoffset); } else { printf("highoff 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb); } } } else if (hresb == DW_DLV_ERROR) { printf("dwarf_highpc_b() error!"); } else { /* absent */ } /* Should work for all DWARF DW_AT_low_pc */ if (lres == DW_DLV_OK) { /* present, FORM addr. */ printf("lowpc 0x%" DW_PR_XZEROS DW_PR_DUx " ", altlopc); } else if (lres == DW_DLV_ERROR) { printf("dwarf_lowpc() error!"); } else { /* absent. */ } printf("\n"); } if(namesoptionon && (filenum || linenum)) { printf("<%3d> file: %" DW_PR_DUu " %s line %" DW_PR_DUu "\n",level,filenum,filename?filename:"",linenum); } if(namesoptionon && lowpc) { printf("<%3d> low_pc : 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)lowpc); } if(namesoptionon && highpc) { printf("<%3d> high_pc: 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)highpc); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); } static void print_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Signed attrcount = 0; Dwarf_Signed i; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_attrlist(die,&attrbuf,&attrcount,errp); if(res != DW_DLV_OK) { return; } sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles,&sf->srcfilescount, &error); for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,errp); if(res == DW_DLV_OK) { if(aform == DW_AT_comp_dir) { char *name = 0; res = dwarf_formstring(attrbuf[i],&name,errp); if(res == DW_DLV_OK) { printf( "<%3d> compilation directory : \"%s\"\n", level,name); } } if(aform == DW_AT_stmt_list) { /* Offset of stmt list for this CU in .debug_line */ } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); } static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf) { Dwarf_Signed sri = 0; if (sf->srcfiles) { for (sri = 0; sri < sf->srcfilescount; ++sri) { dwarf_dealloc(dbg, sf->srcfiles[sri], DW_DLA_STRING); } dwarf_dealloc(dbg, sf->srcfiles, DW_DLA_LIST); } sf->srcfilesres = DW_DLV_ERROR; sf->srcfiles = 0; sf->srcfilescount = 0; } static void print_single_string(Dwarf_Debug dbg, Dwarf_Die die,Dwarf_Half attrnum) { int res = 0; Dwarf_Error error = 0; char * stringval = 0; res = dwarf_die_text(die,attrnum, &stringval,&error); if (res == DW_DLV_OK) { fprintf(dumpallnamesfile,"%s\n",stringval); dwarf_dealloc(dbg,stringval, DW_DLA_STRING); } return; } static void print_name_strings_attr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr) { int res = 0; Dwarf_Half attrnum = 0; Dwarf_Half finalform = 0; enum Dwarf_Form_Class cl = DW_FORM_CLASS_UNKNOWN; Dwarf_Error error = 0; res = dwarf_whatattr(attr,&attrnum,&error); if(res != DW_DLV_OK) { printf("Unable to get attr number"); exit(1); } res = dwarf_whatform(attr,&finalform,&error); if(res != DW_DLV_OK) { printf("Unable to get attr form"); exit(1); } cl = dwarf_get_form_class(cu_version_stamp, attrnum,cu_offset_size,finalform); if (cl != DW_FORM_CLASS_STRING) { return; } print_single_string(dbg,die,attrnum); } static void printnamestrings(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_Error error =0; Dwarf_Attribute *atlist = 0; Dwarf_Signed atcount = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_attrlist(die,&atlist, &atcount,&error); if (res != DW_DLV_OK) { return; } for (i = 0; i < atcount; ++i) { Dwarf_Attribute attr = atlist[i]; /* Use an empty attr to get a placeholder on the attr list for this IRDie. */ print_name_strings_attr(dbg,die,attr); } dwarf_dealloc(dbg,atlist, DW_DLA_LIST); } static void print_die_data_i(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf) { char *name = 0; Dwarf_Error error = 0; Dwarf_Half tag = 0; const char *tagname = 0; int res = 0; Dwarf_Error *errp = 0; Dwarf_Attribute attr = 0; Dwarf_Half formnum = 0; const char *formname = 0; if (passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_diename(print_me,&name,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_diename , level %d \n",level); exit(1); } if(res == DW_DLV_NO_ENTRY) { name = ""; } res = dwarf_tag(print_me,&tag,errp); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } res = dwarf_get_TAG_name(tag,&tagname); if(res != DW_DLV_OK) { printf("Error in dwarf_get_TAG_name , level %d \n",level); exit(1); } if (dumpallnames) { printnamestrings(dbg,print_me); } res = dwarf_attr(print_me,DW_AT_name,&attr, errp); if (res != DW_DLV_OK) { /* do nothing */ } else { res = dwarf_whatform(attr,&formnum,errp); if (res != DW_DLV_OK) { printf("Error in dwarf_whatform , level %d \n",level); exit(1); } formname = "form-name-unavailable"; res = dwarf_get_FORM_name(formnum,&formname); if (res != DW_DLV_OK) { formname = "UNKNoWn FORM!"; } dwarf_dealloc(dbg,attr,DW_DLA_ATTR); } if(namesoptionon ||checkoptionon) { if( tag == DW_TAG_subprogram) { if(namesoptionon) { printf( "<%3d> subprogram : \"%s\"\n",level,name); } print_subprog(dbg,print_me,level,sf,name); } if( (namesoptionon) && (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_type_unit)) { resetsrcfiles(dbg,sf); printf( "<%3d> source file : \"%s\"\n",level,name); print_comp_dir(dbg,print_me,level,sf); } } else { printf("<%d> tag: %d %s name: \"%s\"",level,tag,tagname,name); if (formname) { printf(" FORM 0x%x \"%s\"",formnum, formname); } printf("\n"); } /* This dwarf_dealloc was always wrong but before March 14, 2020 the documentation said the dwarf_dealloc was necessary. dwarf_dealloc(dbg,name,DW_DLA_STRING); */ } static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf) { if (fissionfordie != -1) { Dwarf_Debug_Fission_Per_CU percu; memset(&percu,0,sizeof(percu)); if (fissionfordie == dienumber) { int res = 0; Dwarf_Error error = 0; Dwarf_Error *errp = 0; if (passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_get_debugfission_for_die(print_me, &percu,errp); if(res == DW_DLV_ERROR) { printf("FAIL: Error in dwarf_get_debugfission_for_die %d\n", fissionfordie); exit(1); } if(res == DW_DLV_NO_ENTRY) { printf("FAIL: no-entry in dwarf_get_debugfission_for_die %d\n", fissionfordie); exit(1); } print_die_data_i(dbg,print_me,level,sf); print_debug_fission_header(&percu); exit(0); } dienumber++; return; } print_die_data_i(dbg,print_me,level,sf); dienumber++; } libdwarf-20210528/dwarfexample/runtests.sh0000755000175000017500000000764614047057513015422 00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run only after config.h created in a configure # in the source directory # Assumes env vars DWTOPSRCDIR set to the path to source. # Assumes CFLAGS warning stuff set in env var DWCOMPILERFLAGS # Assumes we run the script in the dwarfexample directory. blddir=`pwd` top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi # So we know the build. Because of debuglink. echo "DWARF_BIGENDIAN=$DWARF_BIGENDIAN" srcdir=$top_srcdir/dwarfexample if [ x"$DWCOMPILERFLAGS" = 'x' ] then CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra" echo "CFLAGS basic default default $CFLAGS" else CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf $DWCOMPILERFLAGS" echo "CFLAGS via configure $CFLAGS" fi goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status for the test $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } which cc if [ $? -eq 0 ] then CC=cc else which gcc if [ $? -eq 0 ] then CC=gcc else # we will fail CC=cc fi fi # echo "y" or "n" srcrelativepath () { p="$1" rm -f /tmp/srcrel.$$ echo "$p" >/tmp/srcrel.$$ grep '^/' /dev/null 2>/dev/null if [ $? -eq 0 ] then echo "n" else echo "y" fi rm /tmp/srcrel.$$ } #lsiok=y #ls -i $blddir >/dev/null 2>/dev/null #r=$? #if [ $r -ne 0 ] #then # echo "SKIP dwdebuglink tests cannot work when ls -i does not work" # lsiok=n #fi rel=`srcrelativepath "$srcdir"` if [ $rel = "y" ] then echo "dwdebuglink tests: $srcdir is a relative path" echo "so we are building in the source tree. Use $blddir " srcdir="$blddir" #This depends on perhaps-incorrect belief that #only srcdir can be a relative path (if #the test is run out-of-source-tree srcdir will #be a full path too). # For both srcdir and blddir the final directory component will # be 'dwarfexample' fi if [ $DWARF_BIGENDIAN = "yes" ] then echo "SKIP dwdebuglink test1, cannot work on bigendian build " else echo "dwdebuglink test1" o=junk.debuglink1 p="--add-debuglink-path=/exam/ple" p2="--add-debuglink-path=/tmp/phony" $blddir/dwdebuglink $p $p2 $srcdir/dummyexecutable > $blddir/$o chkres $? "running dwdebuglink test1" # we strip out the actual srcdir and blddir for the obvious # reason: We want the baseline data to be meaningful no matter # where one's source/build directories are. echo $srcdir | sed "s:[.]:\[.\]:g" >$blddir/${o}sed1 sedv1=`head -n 1 $blddir/${o}sed1` sed "s:$sedv1:..src..:" <$blddir/$o >$blddir/${o}a echo $blddir | sed "s:[.]:\[.\]:g" >$blddir/${o}sed2 sedv2=`head -n 1 $blddir/${o}sed2` sed "s:$sedv2:..bld..:" <$blddir/${o}a >$blddir/${o}b diff $srcdir/debuglink.base $blddir/${o}b r=$? if [ $r -ne 0 ] then echo "To update dwdebuglink baseline:" echo "mv $blddir/${o}b $srcdir/debuglink.base" fi chkres $r "running dwdebuglink test1 diff against baseline" fi echo "dwdebuglink test2" o=junk.debuglink2 p=" --no-follow-debuglink --add-debuglink-path=/exam/ple" p2="--add-debuglink-path=/tmp/phony" $blddir/dwdebuglink $p $p2 $srcdir/dummyexecutable > $blddir/$o chkres $? "running dwdebuglink test2" # we strip out the actual srcdir and blddir for the obvious # reason: We want the baseline data to be meaningful no matter # where one's source/build directories are. sed "s:$srcdir:..src..:" <$blddir/$o >$blddir/${o}a sed "s:$blddir:..bld..:" <$blddir/${o}a >$blddir/${o}b diff $srcdir/debuglink2.base $blddir/${o}b r=$? if [ $r -ne 0 ] then echo "To update dwdebuglink test2 baseline: mv $blddir/${o}b $srcdir/debuglink2.base" fi chkres $r "running dwdebuglink test2 diff against baseline" if [ $failcount -gt 0 ] then echo "FAIL $failcount dwarfexample/runtests.sh" exit 1 fi exit 0 libdwarf-20210528/dwarfexample/dummyexecutable0000755000175000017500000004016013743575426016315 00000000000000ELF>@@ð8@8 @@@@ØØÈÈ XXð-ð=ð= (.>>ÀÀ888 XXXDDSåtd888 Påtd   DDQåtdRåtdð-ð=ð=/lib64/ld-linux-x86-64.so.2GNUÀGNU´v¹*–|Âug±×ÿÂÇwâ¿|GNUÑeÎm8 T c "libc.so.6__cxa_finalize__libc_start_mainGLIBC_2.2.5_ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTableui ,ð= ø=à@@Ø?à?è?ð?ø?óúHƒìH‹Ù/H…ÀtÿÐHƒÄÃÿ5¢/òÿ%£/óúòÿ%½/Dóú1íI‰Ñ^H‰âHƒäðPTL–H H=Úÿr/ôH=™/H’/H9øtH‹N/H…Àt ÿà€Ã€H=i/H5b/H)þH‰ðHÁî?HÁøHÆHÑþtH‹%/H…ÀtÿàfDÀóú€=%/u+UHƒ=/H‰åt H‹=/è)ÿÿÿèdÿÿÿÆý.]ÃÀóúéwÿÿÿóúUH‰å‰}ì‹EìƒÀ‰Eü‹Eü]ÃóúUH‰åHƒì ‰}ìH‰uàÇEü‹EüƒÀ‰ÇèÀÿÿÿ‰Eü‹EüÉÃf.„DóúAWL=c,AVI‰ÖAUI‰õATA‰üUH-T,SL)ýHƒìèOþÿÿHÁýt1Û€L‰òL‰îD‰çAÿßHƒÃH9ÝuêHƒÄ[]A\A]A^A_Ãff.„óúÃóúHƒìHƒÄÃ;@ðÿÿt,ðÿÿœ<ðÿÿ\%ñÿÿ´>ñÿÿÔ|ñÿÿôìñÿÿ<zRx Øïÿÿ/D$4 ïÿÿFJ w€?:*3$"\ˆïÿÿtiðÿÿE†C P ”bðÿÿ/E†C f D´€ðÿÿeFIŽE E(ŒD0†H8ƒG@n8A0A(B BBBü¨ðÿÿ à  øð=ø=õþÿo XÈ } À?À ûÿÿoþÿÿoèÿÿÿoðÿÿoÖùÿÿo>@GCC: (Ubuntu 9.3.0-10ubuntu2) 9.3.0dummyexecutable.debugȺ´p à,@;ø=b nð=T!›ø=¬>µð=È ÛÀ?Œ 8X| ÈXÖ è    0@ø  H ð=ø=>À?@@ñð L @@ûø$)+J@W f@s ‚€e§@P@/’@žB/£@¯ É"deregister_tm_clones__do_global_dtors_auxcompleted.8059__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entry__FRAME_END____init_array_end_DYNAMIC__init_array_start__GNU_EH_FRAME_HDR_GLOBAL_OFFSET_TABLE___libc_csu_fini_ITM_deregisterTMCloneTable_edatamyfunc__libc_start_main@@GLIBC_2.2.5__data_start__gmon_start____dso_handle_IO_stdin_used__libc_csu_init__bss_startmain__TMC_END___ITM_registerTMCloneTable__cxa_finalize@@GLIBC_2.2.5.symtab.strtab.shstrtab.interp.note.gnu.property.note.gnu.build-id.note.ABI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.init.plt.plt.got.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.dynamic.data.bss.comment.gnu_debuglink#88 6XX$I|| Wöÿÿo  $a ÈÈiXX}qÿÿÿoÖÖ ~þÿÿoèè À—  ¢00«@@µ±øø · ¿  DÍH H ×ð=ð-ãø=ø-ï>.À¦À?À/@ø@0þ@000$ 40P0 ) ð5åÕ7libdwarf-20210528/dwarfexample/debuglink2.base0000644000175000017500000000260014047042676016043 00000000000000===Exec-path : ..src../dummyexecutable no follow debuglink: TRUE global path : /exam/ple global path : /tmp/phony Section : .gnu_debuglink Debuglink name : dummyexecutable.debug crc 0X: c8 ba b4 1c Debuglink target : ..src../dummyexecutable.debug Section : .note.gnu.buildid Build-id type : 3 Build-id ownername: GNU Build-id length : 20 Build-id : b476b92a967c17c27567b1d7ffc2c7771fe2bf7c [ 0] Path [ 0] /usr/lib/debug/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 0] file above does not match/exist. [ 1] Path [ 1] /exam/ple/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 1] file above does not match/exist. [ 2] Path [ 2] /tmp/phony/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 2] file above does not match/exist. [ 3] Path [ 3] ..src../dummyexecutable.debug [ 3] file above is an Elf object [ 4] Path [ 4] ..src../.debug/dummyexecutable.debug [ 4] file above does not match/exist. [ 5] Path [ 5] /usr/lib/debug..src../dummyexecutable.debug [ 5] file above does not match/exist. [ 6] Path [ 6] /exam/ple..src../dummyexecutable.debug [ 6] file above does not match/exist. [ 7] Path [ 7] /tmp/phony..src../dummyexecutable.debug [ 7] file above does not match/exist. =======done with ..src../dummyexecutable libdwarf-20210528/dwarfexample/debuglink.base0000644000175000017500000000325114047042705015755 00000000000000===Exec-path : ..src../dummyexecutable global path : /exam/ple global path : /tmp/phony Section : .gnu_debuglink Debuglink name : dummyexecutable.debug crc 0X: c8 ba b4 1c Debuglink target : ..src../dummyexecutable.debug Section : .note.gnu.buildid Build-id type : 3 Build-id ownername: GNU Build-id length : 20 Build-id : b476b92a967c17c27567b1d7ffc2c7771fe2bf7c [ 0] Path [ 0] /usr/lib/debug/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 0] file above does not match/exist. [ 1] Path [ 1] /exam/ple/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 1] file above does not match/exist. [ 2] Path [ 2] /tmp/phony/.build-id/b4/76b92a967c17c27567b1d7ffc2c7771fe2bf7c.debug [ 2] file above does not match/exist. [ 3] Path [ 3] ..src../dummyexecutable.debug [ 3] file above is an Elf object [ 3]===Referred-path : ..src../dummyexecutable.debug [ 3] Section : .note.gnu.buildid [ 3] Build-id type : 3 [ 3] Build-id ownername: GNU [ 3] Build-id length : 20 [ 3] Build-id : b476b92a967c17c27567b1d7ffc2c7771fe2bf7c [ 3]===executable and debug buildid match [ 4] Path [ 4] ..src../.debug/dummyexecutable.debug [ 4] file above does not match/exist. [ 5] Path [ 5] /usr/lib/debug..src../dummyexecutable.debug [ 5] file above does not match/exist. [ 6] Path [ 6] /exam/ple..src../dummyexecutable.debug [ 6] file above does not match/exist. [ 7] Path [ 7] /tmp/phony..src../dummyexecutable.debug [ 7] file above does not match/exist. =======done with ..src../dummyexecutable libdwarf-20210528/dwarfexample/NEWS0000644000175000017500000000171213743575426013671 00000000000000September 30, 2020 Renamed getdebuglink to dwdebuglink and added the ability fo find the debuglink target properly. November 11, 2019 Added getdebuglink.c to show how to use libdwarf to find a GNU alternate DWARF file. Add dummyexample.c as a trivial C test case, compiled into the file dummyexample. Compiled as cc -g dummyexample.c -o dummyexample This dummyexample (the executable) is a static, unchanging, file that getdebuglink can use in runtests.sh to verify getdebuglink works. September 05, 2016 simplereader.c: Added the --dumpallnames option so one can get all the strings from debug_info,_types into a file. A simple way to enable further examination of the strings. July 21, 2009 Roni Simonian noticed a call to print_die_data(dbg,cur_die,in_level); was missing so not all DIEs would print. Good Catch! July 8, 2009 Created a sample libdwarf consumer. Using BSD license so anyone can use it. And a trivial Makefile. libdwarf-20210528/dwarfexample/ChangeLog0000664000175000017500000000017614047060220014724 000000000000002021-05-12: David Anderson * runtests.sh: Now make check works whether the build done in- or out-of-build tree. libdwarf-20210528/dwarfexample/ChangeLog20170000664000175000017500000000102513737716107015251 000000000000002017-12-21 David Anderson * simplereader.c: A DIE was not getting deallocated, now it is deallocated, avoiding a memory leak. 2017-12-17 David Anderson * Makefile.in: Add CPPFLAGS, helpful for one user build, harmless to others. 2017-08-21 David Anderson * configure.in: Add unistd.h to AC_CHECK_HEADERS. * configure: Regenerated. * frame1.c: Add #ifdef and include config.h to make windows builds easier. * simplereader.c: Change #ifdef to make windows builds easier. libdwarf-20210528/dwarfexample/Makefile.am0000644000175000017500000000341313757551040015215 00000000000000###Copyright (C) 2018 Vincent Torri @@(@8 @"!@@@ØØœÈ Xð ð=ð=(ð >>À888 XXXDDSåtd888 Påtd  DQåtdRåtdð ð=ð=GNUÀGNU´v¹*–|Âug±×ÿÂÇwâ¿|GNUGCC: (Ubuntu 9.3.0-10ubuntu2) 9.3.0,)HnÓ ()HDÑ9ÚßÀšÂ:int˜l™l‘É‘·Ø1$ Y3e 6 ‹ v7 ‹ o8 ‹ u9 ‹ K: ‹( ù; ‹0 `< ‹8 = ‹@ Œ@ ‹H KA ‹P ìB ‹X mD=` FCh ¦Hep aIet J sx ¦MP€ }NW‚ kOIƒ —QYˆ Y  Ñ[d˜ @\o  ¹]C¨ ƒ^ G° Ç_ -¸ i`eÀ „buÄ» µ+ `8 ‘Y 90 Î_ =j ‘… 9[‰‘$®Š‘‹‘ e ÑÆ»˜ËšÆ­eB/œ2Îe‘\²2‘Pzed e‘l‹² e)œx @‘\z e‘l% : ; 9 I$ >  $ >  I&I : ; 9  : ; 9 I8 : ; 9 < I !I/ 4: ; 9 I?<!.?: ; 9 'I@–B: ; 9 I4: ; 9 I.?: ; 9 'I@—B: ; 9 I/÷û /usr/lib/gcc/x86_64-linux-gnu/9/include/usr/include/x86_64-linux-gnu/bits/usr/include/x86_64-linux-gnu/bits/types/usr/includedummyexecutable.cstddef.htypes.hstruct_FILE.hFILE.hstdio.hsys_errlist.h ) ­ f ==1 /v f Ÿ=_IO_buf_end_chain_old_offsetsys_nerrdummyexecutable.cshort intsize_t_IO_write_ptr_flags_IO_buf_base_markers_IO_read_end_freeres_bufstderr_locklong int_cur_columnargv_IO_FILEunsigned charargcGNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection_IO_marker_shortbuf_IO_write_base_unused2_IO_read_ptrshort unsigned intmainmyfunc_freeres_list__pad5_IO_codecvtlong unsigned int_IO_save_end_IO_write_end__off64_t__off_t/home/davea/dwarf/code/dwarfexample_IO_wide_data_IO_backup_basestdin_flags2_mode_IO_read_base_vtable_offset_IO_save_basesys_errlist_filenostdout_IO_lock_t8X| ÈXÖ è    0@ø  H ð=ø=>À?@@ñÿ p !à7@Fø=m yð=˜ñÿñÿªT!ñÿ¸ø=É>Òð=å øÀ?© ð i @:@øA)Hg@t ƒ@ Ÿ€eÄ@m@/¯@»B/À@Ì æ"crtstuff.cderegister_tm_clones__do_global_dtors_auxcompleted.8059__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrydummyexecutable.c__FRAME_END____init_array_end_DYNAMIC__init_array_start__GNU_EH_FRAME_HDR_GLOBAL_OFFSET_TABLE___libc_csu_fini_ITM_deregisterTMCloneTable_edatamyfunc__libc_start_main@@GLIBC_2.2.5__data_start__gmon_start____dso_handle_IO_stdin_used__libc_csu_init__bss_startmain__TMC_END___ITM_registerTMCloneTable__cxa_finalize@@GLIBC_2.2.5.symtab.strtab.shstrtab.interp.note.gnu.property.note.gnu.build-id.note.ABI-tag.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.init.plt.plt.got.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.dynamic.data.bss.comment.debug_aranges.debug_info.debug_abbrev.debug_line.debug_str#88 6XX$I|| W œ$aÈœiXœ}qÖœ ~èœ œÀ— ¢0«@µ±ø · ¿ DÍH ×ð=ð ãø=ð ï>ð À¦À?ð @ø@ð þ@ð 0œ$ À0ðr'b53A0´ Àx ` 1 ØÚLlibdwarf-20210528/dwarfexample/simplecrc.c0000644000175000017500000000555613743575426015331 00000000000000/* Copyright (C) 2020 David Anderson. 2020. This small program is hereby placed into the public domain to be copied or used by anyone for any purpose. It is not tested nor normally built, it is just in case one wants to redo a crc calculation on a file. In a build directory compile something like this: cc -Ilibdwarf $HOME/dwarf/code/dwarfexample/simplecrc.c \ libdwarf/.libs/libdwarf.a -lelf -lz */ #include #include /* for exit(), C89 malloc */ #include /* for close */ #include /* for off_t ssize_t */ #include #include #include #include /* for memset */ #include "dwarf.h" #include "libdwarf.h" static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; if (!start) { printf("%s ptr null, ignore. \n",msg); return; } printf("%s ",msg); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } static void simple_test(const char *fname) { int fd = 0; off_t size_left = 0; off_t fsize = 0; off_t lsval = 0; ssize_t readlen = 1000; unsigned char *readbuf = 0; ssize_t readval = 0; unsigned int tcrc = 0; unsigned int init = 0; printf("File: %s\n",fname); fd = open(fname,O_RDONLY); if (fd < 0) { printf("no such file\n"); return; } { fsize = size_left = lseek(fd,0L,SEEK_END); printf("file size %lu (0x%lx)\n",(unsigned long)fsize, (unsigned long)fsize); if(fsize == (off_t)-1) { printf("Fail 22\n"); exit(1); } } if (fsize <= (off_t)500) { /* Not a real object file. A random length check. */ printf("Fail 21\n"); exit(1); } lsval = lseek(fd,0L,SEEK_SET); if(lsval < 0) { printf("Fail 1\n"); exit(1); } readbuf = (unsigned char *)malloc(readlen); if (!readbuf) { printf("Fail 2\n"); exit(1); } while (size_left > 0) { if (size_left < readlen) { readlen = size_left; } readval = read(fd,readbuf,readlen); if (readval != (ssize_t)readlen) { printf("Fail 3\n"); exit(1); } size_left -= readlen; tcrc = dwarf_basic_crc32(readbuf,readlen,init); init = tcrc; } /* endianness issues? */ dump_bytes("crc: ",(unsigned char *)&tcrc,4); } int main(int argc, char **argv) { const char *fname = 0; fname = "/usr/lib/debug/.build-id/1c/" "2d642ffb01d1894d3c7dba050fcd160580a3e1.debug"; simple_test(fname); fname = "/usr/bin/gdb"; simple_test(fname); fname = "/home/davea/dwarf/code/dwarfexample" "/dummyexecutable.debug"; simple_test(fname); } libdwarf-20210528/dwarfexample/ChangeLog20160000664000175000017500000000344013737716107015253 000000000000002016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-04 David Anderson * simplereader.c(printnamestrings): Remove C99-ism in favor of C90 style. 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize * configure: Regenerated. 2016-09-21 David Anderson * Makefile.in: Added dwfsanitize when -fsanitize=address desired. * configure.in: Added --enable-sanitize option. * configure: Regenerated. * simplereader.c: Added trivial static array for string pointers so such can be freed at normal exit to avoid having malloc space problem reports from valgrind. 2016-09-05 David Anderson * simplereader.c: Adding --dumpallnames option so it becomes easy to analyze string usage in objects. (The analysys to be carried out be other code, not part of the libdwarf distribution.) 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-14 DavidAnderson * frame1.c: Fixing various compiler warnings. * simplereader.c: In case a badly spelled argument given, exit with message, do not ignore the mistake. 2016-03-14 DavidAnderson * simplereader.c: --simpleerrhand flag lets us test an error handler when combined with --passnullerror. Fixed various warnings exposed by configure --enable-wall. 2016-03-13 DavidAnderson * simplereader.c: --passnullerror flag lets us test for libdwarf mistakes in handling a NULL error argument. * configure.in: Handle --enable-wall configure choice. * configure: Regenerated. * Makefile.in: Handle --enable-wall. libdwarf-20210528/dwarfexample/ChangeLog20100000664000175000017500000000106713737716107015250 00000000000000April 26, 2010 David Anderson * simplereader.c: Now prints all TAGs regardless of whether a DIE has a DW_AT_name attribute. All names print an "" pair so it's easy to recognize empty names and names with embedded spaces. March 31, 2010 David Anderson * simplereader.c: Added a new option --names which shows additional detail on getting attributes and source file information. January 3, 2010 David Anderson * frame1.c, simplereader.c: Update copyright year. libdwarf-20210528/dwarfexample/buildingdummy.sh0000644000175000017500000000142613743575426016401 00000000000000#!/bin/sh # This is a script used to create # dummyexecutable and dummyexecutable.debug # Just doing what objcopy provides. # It's currently not useable for automated regression testing # without more work to make it independent of source/build # location. d=dummyexecutable cc -g $d.c -o $d objcopy --only-keep-debug $d $d.debug objcopy --strip-debug $d objcopy --add-gnu-debuglink=$d.debug $d # by moving the $d.debug we ensure that # it can only be found if the proper path is provided # to dwdebuglink rm -rf dummydir mkdir -p dummydir/home/davea/dwarf/code/dwarfexample/ cp $d.debug dummydir/home/davea/dwarf/code/dwarfexample/ echo "Test1 " /tmp/dwdebuglink $d echo "Test2 " /tmp/dwdebuglink --add-debuglink-path=/globala/ax --add-debuglink-path=./dummydir $d rm -rf dummydir libdwarf-20210528/dwarfexample/ChangeLog20150000664000175000017500000000216613737716107015256 000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. 2015-11-15 David Anderson * configure.in, Makefile.in: So we now use configure to build. * configure: Generated 2015-09-22 David Anderson * simplereader.c: Removed trailing whitespace. 2015-09-15 Carlos Alberto Enciso * simplereader.c: Fix some C99 issues with local variables declaration in main() and read_cu_list(). Include the 'config.h' and 'stdafx.h' headers for Windows port. Include the Dwarfdump generic open_a_file() and close_a_file() calls. 2015-06-19 David Anderson * frame1.c: Add printf and comments suggesting use of dwarf_get_fde_list_eh() if dwarf_get_fde_list() gets DW_DLV_NO_ENTRY. 2015-05-05 David Anderson * simplereader.c: Added code to help testing in libdwarf DebugFission Package File interfaces. 2015-01-01 David Anderson * A new year begins. libdwarf-20210528/dwarfexample/ChangeLog20120000664000175000017500000000002413737716107015242 00000000000000No changes in 2012. libdwarf-20210528/dwarfexample/Makefile.in0000664000175000017500000013306214054252021015220 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = simplereader$(EXEEXT) frame1$(EXEEXT) \ findfuncbypc$(EXEEXT) dwdebuglink$(EXEEXT) subdir = dwarfexample ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_dwdebuglink_OBJECTS = dwdebuglink-dwdebuglink.$(OBJEXT) dwdebuglink_OBJECTS = $(am_dwdebuglink_OBJECTS) am__DEPENDENCIES_1 = dwdebuglink_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dwdebuglink_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dwdebuglink_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_findfuncbypc_OBJECTS = findfuncbypc-findfuncbypc.$(OBJEXT) findfuncbypc_OBJECTS = $(am_findfuncbypc_OBJECTS) findfuncbypc_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) findfuncbypc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(findfuncbypc_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_frame1_OBJECTS = frame1-frame1.$(OBJEXT) frame1_OBJECTS = $(am_frame1_OBJECTS) frame1_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) frame1_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(frame1_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_simplereader_OBJECTS = simplereader-simplereader.$(OBJEXT) simplereader_OBJECTS = $(am_simplereader_OBJECTS) simplereader_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) simplereader_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simplereader_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dwdebuglink-dwdebuglink.Po \ ./$(DEPDIR)/findfuncbypc-findfuncbypc.Po \ ./$(DEPDIR)/frame1-frame1.Po \ ./$(DEPDIR)/simplereader-simplereader.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dwdebuglink_SOURCES) $(findfuncbypc_SOURCES) \ $(frame1_SOURCES) $(simplereader_SOURCES) DIST_SOURCES = $(dwdebuglink_SOURCES) $(findfuncbypc_SOURCES) \ $(frame1_SOURCES) $(simplereader_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver ChangeLog NEWS DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_BIGENDIAN = @DWARF_BIGENDIAN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects dwarfbigend = @DWARF_BIGENDIAN@ simplereader_SOURCES = simplereader.c simplereader_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf simplereader_CFLAGS = $(DWARF_CFLAGS_WARN) simplereader_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) frame1_SOURCES = frame1.c frame1_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf frame1_CFLAGS = $(DWARF_CFLAGS_WARN) frame1_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) findfuncbypc_SOURCES = findfuncbypc.c findfuncbypc_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf findfuncbypc_CFLAGS = $(DWARF_CFLAGS_WARN) findfuncbypc_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) dwdebuglink_SOURCES = dwdebuglink.c dwdebuglink_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf dwdebuglink_CFLAGS = $(DWARF_CFLAGS_WARN) dwdebuglink_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) TESTS = runtests.sh AM_TESTS_ENVIRONMENT = DWARF_BIGENDIAN='$(dwarfbigend)'; export DWARF_BIGENDIAN ; DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR ; DWCOMPILERFLAGS='$(DWARF_CFLAGS_WARN)'; export DWCOMPILERFLAGS ; EXTRA_DIST = \ ChangeLog \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ runtests.sh \ buildingdummy.sh \ debuglink.base \ debuglink2.base \ dummyexecutable \ dummyexecutable.debug \ dummyexecutable.c \ simplecrc.c \ NEWS \ $(dwarfexample_DATA) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfexample/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfexample/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dwdebuglink$(EXEEXT): $(dwdebuglink_OBJECTS) $(dwdebuglink_DEPENDENCIES) $(EXTRA_dwdebuglink_DEPENDENCIES) @rm -f dwdebuglink$(EXEEXT) $(AM_V_CCLD)$(dwdebuglink_LINK) $(dwdebuglink_OBJECTS) $(dwdebuglink_LDADD) $(LIBS) findfuncbypc$(EXEEXT): $(findfuncbypc_OBJECTS) $(findfuncbypc_DEPENDENCIES) $(EXTRA_findfuncbypc_DEPENDENCIES) @rm -f findfuncbypc$(EXEEXT) $(AM_V_CCLD)$(findfuncbypc_LINK) $(findfuncbypc_OBJECTS) $(findfuncbypc_LDADD) $(LIBS) frame1$(EXEEXT): $(frame1_OBJECTS) $(frame1_DEPENDENCIES) $(EXTRA_frame1_DEPENDENCIES) @rm -f frame1$(EXEEXT) $(AM_V_CCLD)$(frame1_LINK) $(frame1_OBJECTS) $(frame1_LDADD) $(LIBS) simplereader$(EXEEXT): $(simplereader_OBJECTS) $(simplereader_DEPENDENCIES) $(EXTRA_simplereader_DEPENDENCIES) @rm -f simplereader$(EXEEXT) $(AM_V_CCLD)$(simplereader_LINK) $(simplereader_OBJECTS) $(simplereader_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwdebuglink-dwdebuglink.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findfuncbypc-findfuncbypc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame1-frame1.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simplereader-simplereader.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< dwdebuglink-dwdebuglink.o: dwdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwdebuglink_CPPFLAGS) $(CPPFLAGS) $(dwdebuglink_CFLAGS) $(CFLAGS) -MT dwdebuglink-dwdebuglink.o -MD -MP -MF $(DEPDIR)/dwdebuglink-dwdebuglink.Tpo -c -o dwdebuglink-dwdebuglink.o `test -f 'dwdebuglink.c' || echo '$(srcdir)/'`dwdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwdebuglink-dwdebuglink.Tpo $(DEPDIR)/dwdebuglink-dwdebuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwdebuglink.c' object='dwdebuglink-dwdebuglink.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwdebuglink_CPPFLAGS) $(CPPFLAGS) $(dwdebuglink_CFLAGS) $(CFLAGS) -c -o dwdebuglink-dwdebuglink.o `test -f 'dwdebuglink.c' || echo '$(srcdir)/'`dwdebuglink.c dwdebuglink-dwdebuglink.obj: dwdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwdebuglink_CPPFLAGS) $(CPPFLAGS) $(dwdebuglink_CFLAGS) $(CFLAGS) -MT dwdebuglink-dwdebuglink.obj -MD -MP -MF $(DEPDIR)/dwdebuglink-dwdebuglink.Tpo -c -o dwdebuglink-dwdebuglink.obj `if test -f 'dwdebuglink.c'; then $(CYGPATH_W) 'dwdebuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwdebuglink.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwdebuglink-dwdebuglink.Tpo $(DEPDIR)/dwdebuglink-dwdebuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwdebuglink.c' object='dwdebuglink-dwdebuglink.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwdebuglink_CPPFLAGS) $(CPPFLAGS) $(dwdebuglink_CFLAGS) $(CFLAGS) -c -o dwdebuglink-dwdebuglink.obj `if test -f 'dwdebuglink.c'; then $(CYGPATH_W) 'dwdebuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwdebuglink.c'; fi` findfuncbypc-findfuncbypc.o: findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -MT findfuncbypc-findfuncbypc.o -MD -MP -MF $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo -c -o findfuncbypc-findfuncbypc.o `test -f 'findfuncbypc.c' || echo '$(srcdir)/'`findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo $(DEPDIR)/findfuncbypc-findfuncbypc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findfuncbypc.c' object='findfuncbypc-findfuncbypc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -c -o findfuncbypc-findfuncbypc.o `test -f 'findfuncbypc.c' || echo '$(srcdir)/'`findfuncbypc.c findfuncbypc-findfuncbypc.obj: findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -MT findfuncbypc-findfuncbypc.obj -MD -MP -MF $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo -c -o findfuncbypc-findfuncbypc.obj `if test -f 'findfuncbypc.c'; then $(CYGPATH_W) 'findfuncbypc.c'; else $(CYGPATH_W) '$(srcdir)/findfuncbypc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo $(DEPDIR)/findfuncbypc-findfuncbypc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findfuncbypc.c' object='findfuncbypc-findfuncbypc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -c -o findfuncbypc-findfuncbypc.obj `if test -f 'findfuncbypc.c'; then $(CYGPATH_W) 'findfuncbypc.c'; else $(CYGPATH_W) '$(srcdir)/findfuncbypc.c'; fi` frame1-frame1.o: frame1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -MT frame1-frame1.o -MD -MP -MF $(DEPDIR)/frame1-frame1.Tpo -c -o frame1-frame1.o `test -f 'frame1.c' || echo '$(srcdir)/'`frame1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/frame1-frame1.Tpo $(DEPDIR)/frame1-frame1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame1.c' object='frame1-frame1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -c -o frame1-frame1.o `test -f 'frame1.c' || echo '$(srcdir)/'`frame1.c frame1-frame1.obj: frame1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -MT frame1-frame1.obj -MD -MP -MF $(DEPDIR)/frame1-frame1.Tpo -c -o frame1-frame1.obj `if test -f 'frame1.c'; then $(CYGPATH_W) 'frame1.c'; else $(CYGPATH_W) '$(srcdir)/frame1.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/frame1-frame1.Tpo $(DEPDIR)/frame1-frame1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame1.c' object='frame1-frame1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -c -o frame1-frame1.obj `if test -f 'frame1.c'; then $(CYGPATH_W) 'frame1.c'; else $(CYGPATH_W) '$(srcdir)/frame1.c'; fi` simplereader-simplereader.o: simplereader.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -MT simplereader-simplereader.o -MD -MP -MF $(DEPDIR)/simplereader-simplereader.Tpo -c -o simplereader-simplereader.o `test -f 'simplereader.c' || echo '$(srcdir)/'`simplereader.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simplereader-simplereader.Tpo $(DEPDIR)/simplereader-simplereader.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simplereader.c' object='simplereader-simplereader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -c -o simplereader-simplereader.o `test -f 'simplereader.c' || echo '$(srcdir)/'`simplereader.c simplereader-simplereader.obj: simplereader.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -MT simplereader-simplereader.obj -MD -MP -MF $(DEPDIR)/simplereader-simplereader.Tpo -c -o simplereader-simplereader.obj `if test -f 'simplereader.c'; then $(CYGPATH_W) 'simplereader.c'; else $(CYGPATH_W) '$(srcdir)/simplereader.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simplereader-simplereader.Tpo $(DEPDIR)/simplereader-simplereader.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simplereader.c' object='simplereader-simplereader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -c -o simplereader-simplereader.obj `if test -f 'simplereader.c'; then $(CYGPATH_W) 'simplereader.c'; else $(CYGPATH_W) '$(srcdir)/simplereader.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? runtests.sh.log: runtests.sh @p='runtests.sh'; \ b='runtests.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dwdebuglink-dwdebuglink.Po -rm -f ./$(DEPDIR)/findfuncbypc-findfuncbypc.Po -rm -f ./$(DEPDIR)/frame1-frame1.Po -rm -f ./$(DEPDIR)/simplereader-simplereader.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dwdebuglink-dwdebuglink.Po -rm -f ./$(DEPDIR)/findfuncbypc-findfuncbypc.Po -rm -f ./$(DEPDIR)/frame1-frame1.Po -rm -f ./$(DEPDIR)/simplereader-simplereader.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-binPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am recheck tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libdwarf-20210528/dwarfexample/ChangeLog20110000664000175000017500000000036513737716107015251 000000000000002011-06-04 DavidAnderson * frame1.c, simplereader.c: Altered indentation to multiples of 4 spaces, no tabs. No substantive change. 2011-01-13 DavidAnderson * New year starts. libdwarf-20210528/dwarfexample/findfuncbypc.c0000644000175000017500000011544013744143636016007 00000000000000/* Copyright (c) 2019 David Anderson. This source code is placed in the Public Domain. It may be copied or used in any way without restriction. */ /* findfuncbypc.c This is an example of code reading dwarf .debug_info. It is kept simple to expose essential features. It does not do all possible error reporting or error handling. It does to a bit of error checking as a help in ensuring that some code works properly... for error checks. To use, try make ./findfuncbypc --pc=0x10000 ./findfuncbypc */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf.h" #include "libdwarf.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ struct srcfilesdata { char ** srcfiles; Dwarf_Signed srcfilescount; int srcfilesres; }; struct target_data_s { Dwarf_Debug td_dbg; Dwarf_Unsigned td_target_pc; /* from argv */ int td_print_details; /* from argv */ int td_reportallfound; /* from argv */ /* cu die data. */ Dwarf_Unsigned td_cu_lowpc; Dwarf_Unsigned td_cu_highpc; int td_cu_haslowhighpc; Dwarf_Die td_cu_die; char * td_cu_name; char * td_cu_comp_dir; Dwarf_Unsigned td_cu_number; struct srcfilesdata td_cu_srcfiles; /* Help deal with DW_AT_ranges */ /* This is base offset of ranges, the value from DW_AT_rnglists_base. */ Dwarf_Unsigned td_cu_ranges_base; /* Following subprog related. Offset has tc_cu_ranges_base added in. */ Dwarf_Off td_ranges_offset; /* DIE data of appropriate DIE */ /* From DW_AT_name */ char * td_subprog_name; Dwarf_Unsigned td_subprog_fileindex; Dwarf_Die td_subprog_die; Dwarf_Unsigned td_subprog_lowpc; Dwarf_Unsigned td_subprog_highpc; int td_subprog_haslowhighpc; Dwarf_Unsigned td_subprog_lineaddr; Dwarf_Unsigned td_subprog_lineno; char * td_subprog_srcfile; /* dealloc */ }; /* Adding return codes to DW_DLV, relevant to our purposes here. */ #define NOT_THIS_CU 10 #define IN_THIS_CU 11 #define FOUND_SUBPROG 12 #define TRUE 1 #define FALSE 0 static int look_for_our_target(Dwarf_Debug dbg, struct target_data_s *target_data, Dwarf_Error *errp); static int examine_die_data(Dwarf_Debug dbg, int is_info,Dwarf_Die die, int level, struct target_data_s *td, Dwarf_Error *errp); static int check_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct target_data_s *td,Dwarf_Error *errp); static int get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info, int in_level,int cu_number, struct target_data_s *td, Dwarf_Error *errp); #if 0 DW_UT_compile 0x01 /* DWARF5 */ DW_UT_type 0x02 /* DWARF5 */ DW_UT_partial 0x03 /* DWARF5 */ #endif static int unittype = DW_UT_compile; static Dwarf_Bool g_is_info = TRUE; int cu_version_stamp = 0; int cu_offset_size = 0; static void printusage(void) { printf("Usage example: " "./findfuncbypc --pc=0x10000 ./findfuncbypc\n"); printf(" options list:\n"); printf(" --pc=(hex or decimal pc address)\n"); printf(" --printdetails \n"); printf(" prints some details of the discovery process\n"); printf(" --allinstances\n"); printf(" reports but does does not stop processing\n"); printf(" on finding pc address\n"); printf(" --help or -h prints this usage message an stops.\n"); } static void target_data_destructor( struct target_data_s *td); static int startswithextractnum(const char *arg, const char *lookfor, Dwarf_Unsigned *numout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); Dwarf_Unsigned v = 0; char *endptr = 0; if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; /* We are not making any attempt to deal with garbage. Pass in good data... */ v = strtoul(s,&endptr,0); if (!*s || *endptr) { printf("Incoming argument in error: \"%s\"\n",arg); return FALSE; } *numout = v; return TRUE; } int main(int argc, char **argv) { Dwarf_Debug dbg = 0; const char *filepath = 0; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; int i = 0; Dwarf_Unsigned target_pc = 0; #define PATH_LEN 2000 char real_path[PATH_LEN]; struct target_data_s target_data; real_path[0] = 0; memset(&target_data,0, sizeof(target_data)); for(i = 1; i < (argc-1) ; ++i) { if(startswithextractnum(argv[i],"--pc=", &target_pc)) { /* done */ target_data.td_target_pc = target_pc; } else if (!strcmp(argv[i],"--printdetails")){ target_data.td_print_details = TRUE; } else if (!strcmp(argv[i],"--allinstances")){ target_data.td_reportallfound = TRUE; } else if (!strcmp(argv[i],"-h")){ printusage(); exit(0); } else if (!strcmp(argv[i],"--help")){ printusage(); exit(0); } else { printf("Unknown argument \"%s\", give up \n",argv[i]); exit(1); } } if (i >= (argc-1)) { printusage(); exit(1); } filepath = argv[i]; res = dwarf_init_path(filepath, real_path, PATH_LEN, DW_DLC_READ, DW_GROUPNUMBER_ANY,errhand,errarg,&dbg, 0,0,0,&error); if(res == DW_DLV_ERROR) { printf("Giving up, cannot do DWARF processing of %s " "dwarf err %" DW_PR_DUu " %s\n", filepath, dwarf_errno(error), dwarf_errmsg(error)); exit(1); } if(res == DW_DLV_NO_ENTRY) { printf("Giving up, file %s not found\n",filepath); exit(1); } res = look_for_our_target(dbg,&target_data,&error); target_data_destructor(&target_data); res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } return 0; } static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf) { Dwarf_Signed sri = 0; for (sri = 0; sri < sf->srcfilescount; ++sri) { dwarf_dealloc(dbg, sf->srcfiles[sri], DW_DLA_STRING); } dwarf_dealloc(dbg, sf->srcfiles, DW_DLA_LIST); sf->srcfilesres = DW_DLV_ERROR; sf->srcfiles = 0; sf->srcfilescount = 0; } static void resetsubprog(Dwarf_Debug dbg,struct target_data_s *td) { td->td_subprog_haslowhighpc = FALSE; if (td->td_subprog_die) { dwarf_dealloc(dbg,td->td_subprog_die,DW_DLA_DIE); td->td_subprog_die = 0; } } static void reset_target_data(Dwarf_Debug dbg,struct target_data_s *td) { if (td->td_cu_die) { dwarf_dealloc(dbg,td->td_cu_die,DW_DLA_DIE); td->td_cu_die = 0; } if (td->td_subprog_die) { dwarf_dealloc(dbg,td->td_subprog_die,DW_DLA_DIE); td->td_subprog_die = 0; } td->td_cu_haslowhighpc = FALSE; resetsrcfiles(dbg,&td->td_cu_srcfiles); resetsubprog(dbg,td); } static void target_data_destructor( struct target_data_s *td) { Dwarf_Debug dbg = 0; if (!td || !td->td_dbg) { return; } dbg = td->td_dbg; reset_target_data(dbg,td); if (td->td_subprog_srcfile) { dwarf_dealloc(dbg,td->td_subprog_srcfile,DW_DLA_STRING); td->td_subprog_srcfile = 0; } } static void print_target_info( UNUSEDARG Dwarf_Debug dbg, struct target_data_s *td) { printf("FOUND function \"%s\", requested pc 0x%" DW_PR_DUx "\n", td->td_subprog_name?td->td_subprog_name:"", td->td_target_pc); printf(" function lowpc 0x%" DW_PR_DUx " highpc 0x%" DW_PR_DUx "\n", td->td_subprog_lowpc, td->td_subprog_highpc); printf(" file name index 0x%" DW_PR_DUx "\n", td->td_subprog_fileindex); printf(" in:\n"); printf(" CU %" DW_PR_DUu " %s\n", td->td_cu_number, td->td_cu_name?td->td_cu_name:""); printf(" comp-dir %s\n", td->td_cu_comp_dir?td->td_cu_comp_dir:""); printf(" Src line address 0x%" DW_PR_DUx " lineno %" DW_PR_DUu " %s\n", td->td_subprog_lineaddr, td->td_subprog_lineno, td->td_subprog_srcfile); printf("\n"); } static int read_line_data(UNUSEDARG Dwarf_Debug dbg, struct target_data_s *td, Dwarf_Error *errp) { int res = 0; Dwarf_Unsigned line_version = 0; Dwarf_Small table_type = 0; Dwarf_Line_Context line_context = 0; Dwarf_Signed i = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed endindex = 0; Dwarf_Signed file_count = 0; Dwarf_Unsigned dirindex = 0; res = dwarf_srclines_b(td->td_cu_die,&line_version, &table_type,&line_context,errp); if (res != DW_DLV_OK) { return res; } if (td->td_print_details) { printf(" Srclines: linetable version %" DW_PR_DUu " table count %d\n",line_version,table_type); } if (table_type == 0) { /* There are no lines here, just table header and names. */ int sres = 0; sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Filenames base index %" DW_PR_DSd " file count %" DW_PR_DSd " endindex %" DW_PR_DSd "\n", baseindex,file_count,endindex); } for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,errp); if (vres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; /* something very wrong. */ return vres; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " directory index %" DW_PR_DUu " %s \n",i,dirindex,name); } } dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } else if (table_type == 1) { const char * dir_name = 0; int sres = 0; Dwarf_Line *linebuf = 0; Dwarf_Signed linecount = 0; Dwarf_Signed dir_count = 0; Dwarf_Addr prev_lineaddr = 0; Dwarf_Unsigned prev_lineno = 0; char * prev_linesrcfile = 0; sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Filenames base index %" DW_PR_DSd " file count %" DW_PR_DSd " endindex %" DW_PR_DSd "\n", baseindex,file_count,endindex); } for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned dirindexb = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindexb, &modtime,&flength, &md5data,errp); if (vres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; /* something very wrong. */ return vres; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " directory index %" DW_PR_DUu " file: %s \n",i,dirindexb,name); } } sres = dwarf_srclines_include_dir_count(line_context, &dir_count,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Directories count: %" DW_PR_DSd "\n", dir_count); } for (i =1; i <= dir_count; ++i) { dir_name = 0; sres = dwarf_srclines_include_dir_data(line_context, i,&dir_name,errp); if (sres == DW_DLV_ERROR) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (sres == DW_DLV_NO_ENTRY) { printf("Something wrong in dir tables line %d %s\n", __LINE__,__FILE__); break; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] directory: " " %s \n",i,dir_name); } } /* For this case where we have a line table we will likely wish to get the line details: */ sres = dwarf_srclines_from_linecontext(line_context, &linebuf,&linecount, errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } /* The lines are normal line table lines. */ for (i = 0; i < linecount; ++i) { Dwarf_Addr lineaddr = 0; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned lineno = 0; char * linesrcfile = 0; sres = dwarf_lineno(linebuf[i],&lineno,errp); if (sres == DW_DLV_ERROR) { return sres; } sres = dwarf_line_srcfileno(linebuf[i],&filenum,errp); if (sres == DW_DLV_ERROR) { return sres; } if (filenum) { filenum -= 1; } sres = dwarf_lineaddr(linebuf[i],&lineaddr,errp); if (sres == DW_DLV_ERROR) { return sres; } sres = dwarf_linesrc(linebuf[i],&linesrcfile,errp); if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " address 0x%" DW_PR_DUx " filenum %" DW_PR_DUu " lineno %" DW_PR_DUu " %s \n",i,lineaddr,filenum,lineno,linesrcfile); } if (lineaddr > td->td_target_pc) { /* Here we detect the right source and line */ td->td_subprog_lineaddr = prev_lineaddr; td->td_subprog_lineno = prev_lineno; td->td_subprog_srcfile = prev_linesrcfile; return DW_DLV_OK; } prev_lineaddr = lineaddr; prev_lineno = lineno; if (prev_linesrcfile) { dwarf_dealloc(dbg,prev_linesrcfile,DW_DLA_STRING); } prev_linesrcfile = linesrcfile; } /* Here we detect the right source and line (last such in this subprogram) */ td->td_subprog_lineaddr = prev_lineaddr; td->td_subprog_lineno = prev_lineno; td->td_subprog_srcfile = prev_linesrcfile; dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } return DW_DLV_ERROR; #if 0 /* ASSERT: table_type == 2, Experimental two-level line table. Version 0xf006 We do not define the meaning of this non-standard set of tables here. */ /* For ’something C’ (two-level line tables) one codes something like this Note that we do not define the meaning or use of two-level li tables as these are experimental, not standard DWARF. */ sres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf,&linecount, &linebuf_actuals,&linecount_actuals, &err); if (sres == DW_DLV_OK) { for (i = 0; i < linecount; ++i) { /* use linebuf[i], these are the ’logicals’ entries. */ } for (i = 0; i < linecount_actuals; ++i) { /* use linebuf_actuals[i], these are the actuals entries */ } dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else if (sres == DW_DLV_NO_ENTRY) { dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; return sres; } else { /*DW_DLV_ERROR */ return sres; } #endif /* 0 */ } static int look_for_our_target(Dwarf_Debug dbg, struct target_data_s *td, Dwarf_Error *errp) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Half version_stamp = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Unsigned typeoffset = 0; Dwarf_Half header_cu_type = unittype; Dwarf_Bool is_info = g_is_info; int cu_number = 0; for(;;++cu_number) { Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; Dwarf_Sig8 signature; memset(&signature,0, sizeof(signature)); reset_target_data(dbg,td); res = dwarf_next_cu_header_d(dbg,is_info,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size,&signature, &typeoffset, 0, &header_cu_type,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_next_cu_header: %s\n",em); target_data_destructor(td); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ target_data_destructor(td); return DW_DLV_NO_ENTRY; } cu_version_stamp = version_stamp; cu_offset_size = offset_size; /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof_b(dbg,no_die,is_info, &cu_die,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_siblingof_b on CU die: %s\n",em); target_data_destructor(td); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ printf("no entry! in dwarf_siblingof on CU die \n"); target_data_destructor(td); exit(1); } td->td_cu_die = cu_die; res = get_die_and_siblings(dbg,cu_die,is_info,0,cu_number, td,errp); if (res == FOUND_SUBPROG) { read_line_data(dbg,td,errp); print_target_info(dbg,td); if (td->td_reportallfound) { target_data_destructor(td); return res; } reset_target_data(dbg,td); } else if (res == IN_THIS_CU) { char *em = dwarf_errmsg(*errp); printf("Impossible return code in reading DIEs: %s\n",em); target_data_destructor(td); exit(1); } else if (res == NOT_THIS_CU) { /* This is normal. Keep looking */ } else if (res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in reading DIEs: %s\n",em); target_data_destructor(td); exit(1); } else if (res == DW_DLV_NO_ENTRY) { /* This is odd. Assume normal. */ } else { /* DW_DLV_OK. normal. */ } reset_target_data(dbg,td); } return DW_DLV_NO_ENTRY; } /* Recursion, following DIE tree. On initial call in_die is a cu_die (in_level 0 ) */ static int get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info,int in_level,int cu_number, struct target_data_s *td, Dwarf_Error *errp) { int res = DW_DLV_ERROR; Dwarf_Die cur_die=in_die; Dwarf_Die child = 0; td->td_cu_number = cu_number; res = examine_die_data(dbg,is_info,in_die,in_level,td,errp); if (res == DW_DLV_ERROR) { printf("Error in die access , level %d \n",in_level); exit(1); } else if (res == DW_DLV_NO_ENTRY) { return res; } else if ( res == NOT_THIS_CU) { return res; } else if ( res == IN_THIS_CU) { /* Fall through to examine details. */ } else if ( res == FOUND_SUBPROG) { return res; } else { /* DW_DLV_OK */ /* Fall through to examine details. */ } /* Now look at the children of the incoming DIE */ for(;;) { Dwarf_Die sib_die = 0; res = dwarf_child(cur_die,&child,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_child , level %d \n",in_level); exit(1); } if(res == DW_DLV_OK) { int res2 = 0; res2 = get_die_and_siblings(dbg,child,is_info, in_level+1,cu_number,td,errp); if (child != td->td_cu_die && child != td->td_subprog_die) { /* No longer need 'child' die. */ dwarf_dealloc(dbg,child,DW_DLA_DIE); } if (res2 == FOUND_SUBPROG) { return res2; } else if (res2 == IN_THIS_CU) { /* fall thru */ } else if (res2 == NOT_THIS_CU) { return res2; } else if (res2 == DW_DLV_ERROR) { return res2; } else if (res2 == DW_DLV_NO_ENTRY) { /* fall thru */ } else { /* DW_DLV_OK */ /* fall thru */ } child = 0; } res = dwarf_siblingof_b(dbg,cur_die,is_info, &sib_die,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_siblingof_b , level %d :%s \n", in_level,em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if(cur_die != in_die) { if (child != td->td_cu_die && child != td->td_subprog_die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } cur_die = 0; } cur_die = sib_die; res = examine_die_data(dbg,is_info,cur_die,in_level,td,errp); if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_OK) { /* fall through */ } else if (res == FOUND_SUBPROG) { return res; } else if (res == NOT_THIS_CU) { /* impossible */ } else if (res == IN_THIS_CU) { /* impossible */ } else {/* res == DW_DLV_NO_ENTRY */ /* impossible */ /* fall through */ } } return DW_DLV_OK; } #if 0 static void get_addr(Dwarf_Attribute attr,Dwarf_Addr *val) { Dwarf_Error error = 0; int res; Dwarf_Addr uval = 0; Dwarf_Error *errp = 0; errp = &error; res = dwarf_formaddr(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } return; } static void get_number(Dwarf_Attribute attr,Dwarf_Unsigned *val) { Dwarf_Error error = 0; int res; Dwarf_Signed sval = 0; Dwarf_Unsigned uval = 0; Dwarf_Error *errp = 0; errp = &error; res = dwarf_formudata(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } res = dwarf_formsdata(attr,&sval,errp); if(res == DW_DLV_OK) { *val = sval; return; } return; } #endif static int getlowhighpc(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG struct target_data_s *td, Dwarf_Die die, UNUSEDARG int level, int *have_pc_range, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error*error) { Dwarf_Addr hipc = 0; int res = 0; Dwarf_Half form = 0; enum Dwarf_Form_Class formclass = 0; *have_pc_range = FALSE; res = dwarf_lowpc(die,lowpc_out,error); if (res == DW_DLV_OK) { res = dwarf_highpc_b(die,&hipc,&form,&formclass,error); if (res == DW_DLV_OK) { if (formclass == DW_FORM_CLASS_CONSTANT) { hipc += *lowpc_out; } *highpc_out = hipc; *have_pc_range = TRUE; return DW_DLV_OK; } } /* Cannot check ranges yet, we don't know the ranges base offset yet. */ return DW_DLV_NO_ENTRY; } static int check_subprog_ranges_for_match(Dwarf_Debug dbg, UNUSEDARG int is_info, Dwarf_Die die, UNUSEDARG int level, struct target_data_s *td, int *have_pc_range, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error *errp) { int res = 0; Dwarf_Ranges *ranges; Dwarf_Signed ranges_count; Dwarf_Unsigned byte_count; Dwarf_Signed i = 0; Dwarf_Addr baseaddr = 0; int done = FALSE; /* Check libdwarf to ensure ranges_base not added again. FIXME */ res = dwarf_get_ranges_a(dbg,td->td_ranges_offset, die, &ranges, &ranges_count, &byte_count, errp); if (res != DW_DLV_OK) { return res; } for (i=0; i < ranges_count && !done; ++i) { Dwarf_Ranges *cur = ranges+i; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; switch(cur->dwr_type) { case DW_RANGES_ENTRY: lowpc = cur->dwr_addr1 +baseaddr; highpc = cur->dwr_addr2 +baseaddr; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ break; } *lowpc_out = lowpc; *highpc_out = highpc; *have_pc_range = TRUE; done = TRUE; res = FOUND_SUBPROG; break; case DW_RANGES_ADDRESS_SELECTION: baseaddr = cur->dwr_addr2; break; case DW_RANGES_END: break; default: printf("Impossible debug_ranges content!" " enum val %d \n",(int)cur->dwr_type); exit(1); } } dwarf_ranges_dealloc(dbg,ranges,ranges_count); return res; } /* The return value is not interesting. Getting the name is interesting. */ static int get_name_from_abstract_origin(Dwarf_Debug dbg, int is_info, Dwarf_Die die, char ** name, Dwarf_Error *errp) { int res = 0; Dwarf_Die abrootdie = 0; Dwarf_Attribute ab_attr = 0; Dwarf_Off ab_offset = 0; res = dwarf_attr(die,DW_AT_abstract_origin,&ab_attr,errp); if (res != DW_DLV_OK) { return res; } res = dwarf_global_formref(ab_attr,&ab_offset,errp); if (res != DW_DLV_OK) { return res; } res = dwarf_offdie_b(dbg,ab_offset,is_info,&abrootdie,errp) ; if (res != DW_DLV_OK) { return res; } res = dwarf_diename(abrootdie,name,errp); if (res == DW_DLV_OK) { } return res; } static int check_subprog_details(Dwarf_Debug dbg, int is_info, Dwarf_Die die, UNUSEDARG int level, struct target_data_s *td, int *have_pc_range_out, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error *errp) { int res = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; int finalres = 0; int have_pc_range = FALSE; res = getlowhighpc(dbg,td,die,level, &have_pc_range,&lowpc,&highpc,errp); if (res == DW_DLV_OK) { if (have_pc_range) { int res2 = DW_DLV_OK; char *name = 0; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this subprogram */ finalres = DW_DLV_OK; } else { td->td_subprog_die = die; td->td_subprog_lowpc = lowpc; *lowpc_out = lowpc; *highpc_out = highpc; *have_pc_range_out = have_pc_range; td->td_subprog_highpc = highpc; td->td_subprog_haslowhighpc = have_pc_range; res2 = dwarf_diename(die,&name,errp); if (res2 == DW_DLV_OK) { td->td_subprog_name = name; } else { get_name_from_abstract_origin(dbg,is_info, die, &name, errp); } td->td_subprog_name = name; name = 0; /* Means this is an address match */ finalres = FOUND_SUBPROG; } } } { Dwarf_Signed i = 0; Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; res = dwarf_attrlist(die,&atlist,&atcount,errp); if(res != DW_DLV_OK) { return res; } for(i = 0; i < atcount ; ++i) { Dwarf_Half atr = 0; Dwarf_Attribute attrib = atlist[i]; res = dwarf_whatattr(attrib,&atr,errp); if(res != DW_DLV_OK) { /* Something is very wrong here.*/ if (td->td_print_details) { printf("dwarf_whatattr returns bad errcode %d\n", res); } return res; } if (atr == DW_AT_ranges) { int res2 = 0; Dwarf_Off ret_offset = 0; int has_low_hi = FALSE; Dwarf_Addr low = 0; Dwarf_Addr high = 0; res2 = dwarf_global_formref(attrib, &ret_offset,errp); if (res2 != DW_DLV_OK) { return res2; } td->td_ranges_offset = ret_offset + td->td_cu_ranges_base; res = check_subprog_ranges_for_match(dbg, is_info, die, level, td, &has_low_hi, &low, &high, errp); if (res == DW_DLV_OK) { continue; } else if (res == DW_DLV_OK) { continue; } else if (res == DW_DLV_NO_ENTRY) { continue; } else if (res == FOUND_SUBPROG) { td->td_subprog_lowpc = lowpc; td->td_subprog_highpc = highpc; td->td_subprog_haslowhighpc = has_low_hi; finalres = FOUND_SUBPROG; continue; } else { return res; } } else if(atr == DW_AT_decl_file ) { int res3 = 0; Dwarf_Unsigned file_index = 0; res3 = dwarf_formudata(attrib,&file_index,errp); if (res3 != DW_DLV_OK) { return res3; } td->td_subprog_fileindex = file_index; } dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); } dwarf_dealloc(dbg,atlist,DW_DLA_LIST); } return finalres; } static int check_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct target_data_s *td,Dwarf_Error *errp) { int res = 0; int resb = 0; int finalres = 0; int have_pc_range = FALSE; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Off real_ranges_offset = 0; int rdone = FALSE; res = getlowhighpc(dbg,td,die, level, &have_pc_range, &lowpc,&highpc,errp); if (res == DW_DLV_OK) { if (have_pc_range) { if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ res = NOT_THIS_CU; } else { td->td_cu_lowpc = lowpc; td->td_cu_highpc = highpc; /* td->td_cu_haslowhighpc = have_pc_range; */ res = IN_THIS_CU; } } } finalres = IN_THIS_CU; { Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; Dwarf_Signed j = 0; res = dwarf_attrlist(die,&atlist,&atcount,errp); if(res != DW_DLV_OK) { return res; } for(j = 0; j < atcount ; ++j) { Dwarf_Half atr = 0; Dwarf_Attribute attrib = atlist[j]; resb = dwarf_whatattr(attrib,&atr,errp); if(resb != DW_DLV_OK) { /* Something is very wrong here.*/ printf("dwarf_whatattr returns bad errcode %d, " "serious error somewhere.\n", res); return resb; } if(atr == DW_AT_name) { char *name = 0; resb = dwarf_formstring(attrib,&name,errp); if (resb == DW_DLV_OK) { td->td_cu_name = name; } } else if (atr == DW_AT_comp_dir) { char *name = 0; resb = dwarf_formstring(attrib,&name,errp); if (resb == DW_DLV_OK) { td->td_cu_comp_dir = name; } } else if(atr == DW_AT_rnglists_base || atr == DW_AT_GNU_ranges_base) { Dwarf_Off rbase = 0; resb = dwarf_global_formref(attrib,&rbase,errp); if (resb != DW_DLV_OK) { return resb; } td->td_cu_ranges_base = rbase; } else if (atr == DW_AT_ranges) { /* we have actual ranges. */ Dwarf_Off rbase = 0; resb = dwarf_global_formref(attrib,&rbase,errp); if (resb != DW_DLV_OK) { return resb; } real_ranges_offset = rbase; rdone = TRUE; } dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); } dwarf_dealloc(dbg,atlist,DW_DLA_LIST); } if (rdone) { /* We can do get ranges now as we already saw ranges base above (if any). */ int resr = 0; Dwarf_Ranges *ranges; Dwarf_Signed ranges_count; Dwarf_Unsigned byte_count; Dwarf_Signed k = 0; int done = FALSE; resr = dwarf_get_ranges_a(dbg,real_ranges_offset, die, &ranges, &ranges_count, &byte_count, errp); if (resr != DW_DLV_OK) { /* Something badly wrong here. */ return res; } for (k=0; k < ranges_count && !done; ++k) { Dwarf_Ranges *cur = ranges+k; Dwarf_Addr lowpcr = 0; Dwarf_Addr highpcr = 0; Dwarf_Addr baseaddr = td->td_cu_ranges_base; switch(cur->dwr_type) { case DW_RANGES_ENTRY: lowpc = cur->dwr_addr1 +baseaddr; highpc = cur->dwr_addr2 +baseaddr; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ break; } td->td_cu_lowpc = lowpcr; td->td_cu_highpc = highpcr; td->td_cu_haslowhighpc = TRUE; done = TRUE; res = IN_THIS_CU; break; case DW_RANGES_ADDRESS_SELECTION: baseaddr = cur->dwr_addr2; break; case DW_RANGES_END: break; default: printf("Impossible debug_ranges content!" " enum val %d \n",(int)cur->dwr_type); exit(1); } } dwarf_ranges_dealloc(dbg,ranges,ranges_count); } return finalres; #if 0 /* dwarf pdf page 101 */ sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles, &sf->srcfilescount, errp); if (sf->srcfilesres == DW_DLV_ERROR) { } /* see pdf, page 95 */ res2 = dwarf_srclines_comp_dir(linecontext, /* see pdf, page 92 */ res2 = dwarf_srclines_b(die,&version,&table_count, &linecontext,errp); /* see dwarf_srclines_dealloc_b() page 91*/ res2 = dwarf_srclines_from_linecontext(linecontext, &linebuf,&linecount,errp); /* files_indexes are page 96 */ int dwarf_srclines_files_indexes(linecontext, &baseindex, &filescount,&endindex,errp); #endif /* 0 */ } static int examine_die_data(Dwarf_Debug dbg, int is_info, Dwarf_Die die, int level, struct target_data_s *td, Dwarf_Error *errp) { Dwarf_Half tag = 0; int res = 0; res = dwarf_tag(die,&tag,errp); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } if( tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { int have_pc_range = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; res = check_subprog_details(dbg,is_info,die,level,td, &have_pc_range, &lowpc, &highpc, errp); if (res == FOUND_SUBPROG) { td->td_subprog_die = die; return res; } else if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_NO_ENTRY) { /* impossible? */ return res; } else if (res == NOT_THIS_CU) { /* impossible */ return res; } else if (res == IN_THIS_CU) { /* impossible */ return res; } else { /* DW_DLV_OK */ } return DW_DLV_OK; } else if(tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_type_unit) { if (level) { /* Something badly wrong, CU DIEs are only at level 0. */ return NOT_THIS_CU; } res = check_comp_dir(dbg,die,level,td,errp); return res; } /* Keep looking */ return DW_DLV_OK; } libdwarf-20210528/dwarfgen/0000775000175000017500000000000014054271043012351 500000000000000libdwarf-20210528/dwarfgen/strtabdata.h0000664000175000017500000000575113644370703014612 00000000000000#ifndef STRTABDATA_H #define STRTABDATA_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // strtabdata.h // Creates a string table in a way consistent with // elf string tables. The zero index is a null byte always. class strtabdata { public: strtabdata(): data_(new char[1000]), datalen_(1000), nexttouse_(0) { data_[0] = 0; nexttouse_ = 1;}; ~strtabdata() { delete[]data_; }; unsigned addString(const std::string & newstr) { // The 1 is for the terminating null byte. unsigned nsz = newstr.size() +1; unsigned needed = nexttouse_ + nsz; if (needed >= datalen_) { unsigned baseincr = nsz; unsigned altincr = datalen_*2; if(altincr> baseincr) { baseincr = altincr; } unsigned newsize = datalen_ + baseincr; char *newdata = new char [newsize]; memcpy(newdata, data_, nexttouse_); delete [] data_; data_ = newdata; datalen_ = newsize; } memcpy(data_ + nexttouse_, newstr.c_str(),nsz); unsigned newstrindex = nexttouse_; nexttouse_ += nsz; return newstrindex; }; void *exposedata() {return (void *)data_;}; unsigned exposelen() const {return nexttouse_;}; private: char * data_; // datalen_ is the size in bytes pointed to by data_ . unsigned datalen_; // nexttouse_ is the index of the next (unused) byte in // data_ , so it is also the amount of space in data_ that // is in use. unsigned nexttouse_; }; #endif /* STRTABDATA_H */ libdwarf-20210528/dwarfgen/dwarf-generator.txt0000775000175000017500000000171013644370703016132 00000000000000Speculative thoughts on using a script to define what DWARF? to write out in an elf file: Syntax for dw tab entry # is comment levels by indentation like python attrs. indent to the tag they apply to. ;section x ;endsection x :label: [] tag attr [form name] value any attr or tag may have a label. Various forms require specific value formats. values sometims require offsets such as a sibling ref or a fwd/rev ref or a ref to the debug_loc sec DW_FORM_data 1,2 integer DW_FORM_data 4,8 integer or offset depends on context DW_FORM_sdata, udata integer DW_FORM_string "string value" DW_FORM_strp "string value" DW_FORM_block 1,2,4,8 blk-fmt this is blk_fmt hex number decimal number [ dw-expr] sythetic forms: DW_FORM_loclist [label | loclist-itself] loclist-itself offset offset DW_FORM_block [blk_fmt] ... DW_FORM_maclist label DW_FORM_? Line table entries CIE entries FDE entries mac sec entries libdwarf-20210528/dwarfgen/ireppubnames.h0000664000175000017500000000571513644370703015153 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // ireppubnames.h // // class IRPub{ public: IRPub():dieoffset_(0),cudieoffset_(0) { }; IRPub(const std::string &name, Dwarf_Unsigned dieoffset,Dwarf_Unsigned cudieoffset): name_(name),dieoffset_(dieoffset),cudieoffset_(cudieoffset) { }; IRPub(const IRPub&r) { name_ = r.name_; dieoffset_ = r.dieoffset_; cudieoffset_ = r.cudieoffset_; }; IRPub& operator=( const IRPub&r) { if(this == &r) { return *this; } name_ = r.name_; dieoffset_ = r.dieoffset_; cudieoffset_ = r.cudieoffset_; return *this; }; void setBaseData(const std::string &name, Dwarf_Unsigned dieoffset, Dwarf_Unsigned cudieoffset){ name_ = name; dieoffset_ = dieoffset; cudieoffset_ = cudieoffset; }; const std::string& getName() {return name_;}; Dwarf_Unsigned getDieOffset() {return dieoffset_;}; Dwarf_Unsigned getCUdieOffset() {return cudieoffset_;} private: std::string name_; Dwarf_Unsigned dieoffset_; Dwarf_Unsigned cudieoffset_; }; // For .debug_pubnames and .debug_pubtypes. // By the Dwarf Std sec 6.1.1 "Lookup by Name" // these names and offsets refer to the .debug_info section. class IRPubsData { public: IRPubsData() {}; ~IRPubsData() {}; std::list& getPubnames() {return pubnames_; }; std::list& getPubtypes() {return pubtypes_; }; private: std::list pubnames_; std::list pubtypes_; }; libdwarf-20210528/dwarfgen/ChangeLog20130000664000175000017500000000621113644370703014360 000000000000002013-10-31 David Anderson * createirepformfrombinary.cc: Adding support for some CLASS REFERENCE forms. * createirepformfrombinary.cc, creatirepfrombinary.cc: Adding support for some CLASS REFERENCE forms. Fixed dealloc for dwarf_get_pubtypes to avoid duplicate free. * dwarfgen.cc: Added #include so it compiles. * irepattrtodbg.cc,irepattrtodbg.h: Added support for some CLASS REFERENCE forms. * irepdie.h,irepform.h: Added support for some CLASS REFERENCE forms. * irepframe.h: Added 3 comment lines about fde_instrs_ * ireptodbg.cc: Added support for some CLASS REFERENCE forms. 2013-10-17 David Anderson 2013-10-17 David Anderson * ireppubnames.h: deals with debug_pubnames and debug_pubtypes data. * irepdie.h: Remember the producer DIE offset so we can access it for pubnames/pubtypes. * createirepfrombinary.cc: Read in pubnames and pubtypes data. * irepresentation.h: Add in pubnames and pubtypes data. * ireptodbg.cc: Write out applicable pubnames/pubtype data. 2013-10-14 David Anderson * dwarfgen.cc: The declaration of CallbackFunc() now has const char *name to match the corrected declaration in libdwarf.h 2013-08-13 David Anderson * createirepformfrombinary.cc: IRFormReference now allows DW_FORM_data4/8 as reference forms (applies to DWARF2). Made two error outputs look just enough different to tell which test cause the error string. * dwarfgen.cc: Added the -h option to specify transformation of DW_AT_high_pc from form address to form const to create a specific regression test case . * general.h: Added the -h global flag variable transformHighpcToConst as an extern. * irepattrtodbg.cc: Now emits class constant attributes and values. * irepform.h: Now has a new IRFormConstant constructor so we can easily create an attribute on-the-fly internally. Added accessor functions for IRFormConstant values. * ireptodbg.cc: specialAttrTransformations() does the transformation that -h requests: making DW_AT_high_pc be of form constant instead of form address. 2013-02-01 David Anderson * createirepfrombinary.cc,createirepfrombinary.h,dwarfgen.cc, general.h,irepattrtodbg.cc,irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepline.h,irepmacro.h,irepresentation.h, ireptodbg.cc,strtabdata.h: updated copyright year to 2013. * createirepformfrombinary.cc: Added missing implemenation detals for all FORMs and FormFlag. * createirepfrombinary.cc: Rename some local variables for readability based on the realization that dwarf_whatform and dwarf_whatform_direct() are misnamed. * irepattrtodbg.cc: Fixed instances of << cerr when << endl was what was wanted. * ireptodbg.cc: Fixed cast from pointer to int as int is too small, causes build to error off. * irepdie.h,irepform.h: Rename form fields from indirectform_ directform_ to initialform_ and finalform_ based on the realization that dwarf_whatform and dwarf_whatform were misnamed. libdwarf-20210528/dwarfgen/COPYING0000644000175000017500000000342213743575426013343 00000000000000Files here are copyrighted by David Anderson (and possibly others, see the copyright notices in individual files) by the two-clause BSD (FreeBSD) copyright. A typical notice is: Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. David Anderson is at libdwarf-list -at- linuxmail =dot= org 280 Bella Vista Drive Hillsborough, California 94010 USA. libdwarf-20210528/dwarfgen/irepline.h0000664000175000017500000000767213644370703014274 00000000000000#ifndef IREPLINE_H #define IREPLINE_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepline.h // class IRCULine { public: IRCULine(Dwarf_Addr addr,Dwarf_Bool isset, Dwarf_Unsigned fileno, Dwarf_Unsigned lineno, Dwarf_Unsigned linecol, const std::string & linename, Dwarf_Bool is_stmt, Dwarf_Bool bb, Dwarf_Bool endseq, Dwarf_Bool prol_end, Dwarf_Bool epil_beg, Dwarf_Unsigned isa, Dwarf_Unsigned discrim): address_(addr), isaddrset_(isset), srcfileno_(fileno), lineno_(lineno), linecol_(linecol), linesrc_(linename), is_stmt_(is_stmt), basic_block_(bb), end_sequence_(endseq), prologue_end_(prol_end), epilogue_begin_(epil_beg), isa_(isa), discriminator_(discrim) {}; const std::string &getpath() { return linesrc_; }; Dwarf_Addr getaddr() { return address_;}; bool getaddrset() { return isaddrset_;}; bool getendsequence() { return end_sequence_; }; Dwarf_Unsigned getlineno() { return lineno_; }; Dwarf_Unsigned getlinecol() { return linecol_; }; bool getisstmt() { return is_stmt_; }; bool getisblock() { return basic_block_; }; bool getepiloguebegin() { return epilogue_begin_; }; bool getprologueend() { return prologue_end_; }; Dwarf_Unsigned getisa() { return isa_; }; Dwarf_Unsigned getdiscriminator() { return discriminator_; }; ~IRCULine() {}; private: // Names taken from the DWARF4 std. document, sec 6.2.2. Dwarf_Addr address_; bool isaddrset_; Dwarf_Unsigned srcfileno_; Dwarf_Unsigned lineno_; Dwarf_Signed linecol_; // aka lineoff std::string linesrc_; // Name for the file, constructed by libdwarf. bool is_stmt_; bool basic_block_; bool end_sequence_; bool prologue_end_; bool epilogue_begin_; int isa_; int discriminator_; }; class IRCUSrcfile { public: IRCUSrcfile(std::string file): cusrcfile_(file) {}; ~IRCUSrcfile() {}; std::string &getfilepath() {return cusrcfile_;}; private: std::string cusrcfile_; }; class IRCULineData { public: IRCULineData() {}; ~IRCULineData() {}; std::vector &get_cu_lines() { return culinedata_; }; std::vector &get_cu_srcfiles() { return cusrcfiledata_; }; private: std::vector cusrcfiledata_; std::vector culinedata_; }; #endif // IREPLINE_H libdwarf-20210528/dwarfgen/createirepfrombinary.h0000664000175000017500000000310113644370703016660 00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepfrombinary.h void createIrepFromBinary(const std::string &infile, IRepresentation & irep); libdwarf-20210528/dwarfgen/ChangeLog20140000664000175000017500000000316213644370703014363 000000000000002014-12-28 David Anderson * fakemalloc.c: Renamed to fakemalloc.in . 2014-12-28 David Anderson * fakemalloc.c,TESTmallocfail: This makes possible a simple test that we handle malloc failure as sensible as possible. The test requires hand modification of the dwarfgen Makefile. * createirepfrombinary.cc: Now prints the libdwarf error number for better error reporting when there is a libdwarf error (running out of malloc space, for example). 2014-12-09 David Anderson * dwarfgen.cc: Add try/catch for bad malloc and any other disasters.. Add dwarfgen in the string for all the errors leading to exit * dwarf_tsearchhash.c: Add check for NULL return in tsearch_inner() so we don't just core dump when malloc fails. 2014-05-08 David Anderson * dwarfgen.cc: Now uses the newest form of dwarf_producer_init(). The old forms no longer are supported. 2014-02-08 David Anderson * dwarfgen.cc: Added commentary about the callback function setting sect_name_index. 2014-01-29 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc,createirepfrombinary.h, dwarfgen.cc,general.h,irepattrtodbg.cc,irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepline.h,irepmacro.h,ireppubnames.h, irepresentation.h,ireptodbg.cc,ireptodbg.h,strtabdata.h: Remove trailing whitespace. 2014-01-10 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc,dwarfgen.cc, irepattrtodbg.cc,ireptodbg.cc: Removed include of elf.h as it is not needed given the include of gelf.h. libdwarf-20210528/dwarfgen/CMakeLists.txt0000664000175000017500000000215413644370703015042 00000000000000set_source_group(SOURCES "Source Files" createirepformfrombinary.cc createirepfrombinary.cc dwarfgen.cc irepattrtodbg.cc ireptodbg.cc ../libdwarf/dwgetopt.c) set_source_group(HEADERS "Header Files" createirepfrombinary.h general.h irepattrtodbg.h irepdie.h irepform.h irepframe.h irepline.h irepmacro.h ireppubnames.h irepresentation.h ireptodbg.h strtabdata.h ../libdwarf/dwgetopt.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(dwarfgen ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) set_folder(dwarfgen dwarfgen) target_compile_options(dwarfgen PRIVATE ${DW_FWALLXX}) target_link_libraries(dwarfgen PRIVATE ${dwarf-target} ${DW_FZLIB}) set(SUFFIX $<$:64>) set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS dwarfgen DESTINATION RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) #install(FILES dwarfgen.conf DESTINATION lib) install(FILES dwarfgen.1 DESTINATION share/man/man1) libdwarf-20210528/dwarfgen/irepform.h0000664000175000017500000006067414003633317014302 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepform.h // // class IRCUdata; class IRDie; class IRAttr; class IRFormInterface; // An Abstract class. class IRForm { public: //virtual void emitvalue() = 0; //IRForm & operator=(const IRForm &r); virtual IRForm * clone() const =0; virtual ~IRForm() {}; IRForm() {}; virtual enum Dwarf_Form_Class getFormClass() const = 0; private: }; class IRFormUnknown : public IRForm { public: IRFormUnknown(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_UNKNOWN) {} ~IRFormUnknown() {}; IRFormUnknown(IRFormInterface *); IRFormUnknown(const IRFormUnknown &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; } virtual IRFormUnknown * clone() const { return new IRFormUnknown(*this); } IRFormUnknown & operator=(const IRFormUnknown &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; return *this; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; }; // An address class entry refers to some part // (normally a loadable) section of the object file. // Not to DWARF info. Typically into .text or .data for example. // We therefore want a section number and offset (generally useless for us) // or preferably an elf symbol as that has a value // and an elf section number. // We often/usually know neither here so we do not even try. // Later we will make one up if we have to. class IRFormAddress : public IRForm { public: IRFormAddress(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_ADDRESS), address_(0) {}; IRFormAddress(IRFormInterface *); ~IRFormAddress() {}; IRFormAddress & operator=(const IRFormAddress &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; address_ = r.address_; return *this; }; IRFormAddress(const IRFormAddress &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; address_ = r.address_; } virtual IRFormAddress * clone() const { return new IRFormAddress(*this); }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Addr getAddress() { return address_;}; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: void setAddress(Dwarf_Addr addr) { address_ = addr; }; Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Addr address_; }; class IRFormBlock : public IRForm { public: IRFormBlock(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_BLOCK), fromloclist_(0),sectionoffset_(0) {} IRFormBlock(IRFormInterface *); ~IRFormBlock() {}; IRFormBlock & operator=(const IRFormBlock &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; blockdata_ = r.blockdata_; fromloclist_ = r.fromloclist_; sectionoffset_ = r.sectionoffset_; return *this; }; IRFormBlock(const IRFormBlock &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; blockdata_ = r.blockdata_; fromloclist_ = r.fromloclist_; sectionoffset_ = r.sectionoffset_; } virtual IRFormBlock * clone() const { return new IRFormBlock(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Unsigned getBlockLen() {return blockdata_.size();} Dwarf_Small* getBlockBytes() { // Standard guarantees vector content is simply array. return &blockdata_[0]; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; void insertBlock(Dwarf_Block *bl) { Dwarf_Small *d = static_cast(bl->bl_data); Dwarf_Unsigned len = bl->bl_len; blockdata_.clear(); blockdata_.insert(blockdata_.end(),d+0,d+len); fromloclist_ = bl->bl_from_loclist; sectionoffset_ = bl->bl_section_offset; }; std::vector getBlockData(){ return blockdata_;}; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::vector blockdata_; Dwarf_Small fromloclist_; Dwarf_Unsigned sectionoffset_; }; class IRFormConstant : public IRForm { public: enum Signedness {SIGN_NOT_SET,SIGN_UNKNOWN,UNSIGNED, SIGNED }; IRFormConstant(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_CONSTANT), signedness_(SIGN_NOT_SET), uval_(0), sval_(0) { memset(&data16_,0,sizeof(data16_)); }; IRFormConstant(IRFormInterface *); ~IRFormConstant() {}; IRFormConstant(Dwarf_Half finalform, Dwarf_Half initialform, enum Dwarf_Form_Class formclass, IRFormConstant::Signedness signedness, Dwarf_Unsigned uval, Dwarf_Signed sval) { finalform_ = finalform; initialform_ = initialform; formclass_ = formclass; signedness_ = signedness; uval_ = uval; sval_ = sval; }; IRFormConstant(Dwarf_Half finalform, Dwarf_Half initialform, enum Dwarf_Form_Class formclass UNUSEDARG, Dwarf_Form_Data16 & data16) { finalform_ = finalform; initialform_ = initialform; formclass_ = DW_FORM_CLASS_CONSTANT; signedness_ = SIGN_UNKNOWN; uval_ = 0; sval_ = 0; data16_ = data16; }; IRFormConstant & operator=(const IRFormConstant &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; signedness_ = r.signedness_; uval_ = r.uval_; sval_ = r.sval_; data16_ = r.data16_; return *this; }; IRFormConstant(const IRFormConstant &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; signedness_ = r.signedness_; uval_ = r.uval_; sval_ = r.sval_; data16_ = r.data16_; } virtual IRFormConstant * clone() const { return new IRFormConstant(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Form_Class getFormClass() const { return formclass_; }; Signedness getSignedness() const {return signedness_; }; Dwarf_Signed getSignedVal() const {return sval_;}; Dwarf_Unsigned getUnsignedVal() const {return uval_;}; Dwarf_Form_Data16 getData16Val() const {return data16_;}; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; // Starts at SIGN_NOT_SET. // SIGN_UNKNOWN means it was a DW_FORM_data* of some // kind so we do not really know. Signedness signedness_; // Both uval_ and sval_ are always set to the same bits. Dwarf_Unsigned uval_; Dwarf_Signed sval_; Dwarf_Form_Data16 data16_; void setValues16(Dwarf_Form_Data16 *v, enum Signedness s UNUSEDARG) { uval_ = 0; sval_ = 0; data16_ = *v; } void setValues(Dwarf_Signed sval, Dwarf_Unsigned uval, enum Signedness s) { signedness_ = s; uval_ = uval; sval_ = sval; } }; class IRFormExprloc : public IRForm { public: IRFormExprloc(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_EXPRLOC) {}; IRFormExprloc(IRFormInterface *); ~IRFormExprloc() {}; IRFormExprloc & operator=(const IRFormExprloc &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; exprlocdata_ = r.exprlocdata_; return *this; }; IRFormExprloc(const IRFormExprloc &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; exprlocdata_ = r.exprlocdata_; } virtual IRFormExprloc * clone() const { return new IRFormExprloc(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; std::vector getexprlocdata() const {return exprlocdata_; }; void insertBlock(Dwarf_Unsigned len, Dwarf_Ptr data) { char *d = static_cast(data); exprlocdata_.clear(); exprlocdata_.insert(exprlocdata_.end(),d+0,d+len); }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::vector exprlocdata_; }; class IRFormFlag : public IRForm { public: IRFormFlag(): initialform_(0), finalform_(0), formclass_(DW_FORM_CLASS_FLAG), flagval_(0) {}; IRFormFlag(IRFormInterface*); ~IRFormFlag() {}; IRFormFlag & operator=(const IRFormFlag &r) { if(this == &r) return *this; initialform_ = r.initialform_; finalform_ = r.finalform_; formclass_ = r.formclass_; flagval_ = r.flagval_; return *this; }; IRFormFlag(const IRFormFlag &r) { initialform_ = r.initialform_; finalform_ = r.finalform_; formclass_ = r.formclass_; flagval_ = r.flagval_; } virtual IRFormFlag * clone() const { return new IRFormFlag(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setFlagVal(Dwarf_Bool v) { flagval_ = v;} Dwarf_Bool getFlagVal() { return flagval_; } private: Dwarf_Half initialform_; // In most cases initialform_ == finalform_. // Otherwise, initialform == DW_FORM_indirect. Dwarf_Half finalform_; enum Dwarf_Form_Class formclass_; Dwarf_Bool flagval_; }; class IRFormLinePtr : public IRForm { public: IRFormLinePtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_LINEPTR), debug_line_offset_(0) {}; IRFormLinePtr(IRFormInterface *); ~IRFormLinePtr() {}; IRFormLinePtr & operator=(const IRFormLinePtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; debug_line_offset_ = r.debug_line_offset_; return *this; }; IRFormLinePtr(const IRFormLinePtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; debug_line_offset_ = r.debug_line_offset_; } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm(void) {return finalform_; } virtual IRFormLinePtr * clone() const { return new IRFormLinePtr(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off debug_line_offset_; void setOffset(Dwarf_Unsigned uval) { debug_line_offset_ = uval; }; }; class IRFormLoclistPtr : public IRForm { public: IRFormLoclistPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_LOCLISTPTR), loclist_offset_(0) {}; IRFormLoclistPtr(IRFormInterface *); ~IRFormLoclistPtr() {}; IRFormLoclistPtr & operator=(const IRFormLoclistPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; loclist_offset_ = r.loclist_offset_; return *this; }; IRFormLoclistPtr(const IRFormLoclistPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; loclist_offset_ = r.loclist_offset_; } virtual IRFormLoclistPtr * clone() const { return new IRFormLoclistPtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off loclist_offset_; void setOffset(Dwarf_Unsigned uval) { loclist_offset_ = uval; }; }; class IRFormMacPtr : public IRForm { public: IRFormMacPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_MACPTR), macro_offset_(0) {}; IRFormMacPtr(IRFormInterface *); ~IRFormMacPtr() {}; IRFormMacPtr & operator=(const IRFormMacPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; macro_offset_ = r.macro_offset_; return *this; }; IRFormMacPtr(const IRFormMacPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; macro_offset_ = r.macro_offset_; } virtual IRFormMacPtr * clone() const { return new IRFormMacPtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off macro_offset_; void setOffset(Dwarf_Unsigned uval) { macro_offset_ = uval; }; }; class IRFormRangelistPtr : public IRForm { public: IRFormRangelistPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_RANGELISTPTR), rangelist_offset_(0) {}; IRFormRangelistPtr(IRFormInterface *); ~IRFormRangelistPtr() {}; IRFormRangelistPtr & operator=(const IRFormRangelistPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; rangelist_offset_ = r.rangelist_offset_; return *this; }; IRFormRangelistPtr(const IRFormRangelistPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; rangelist_offset_ = r.rangelist_offset_; } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} virtual IRFormRangelistPtr * clone() const { return new IRFormRangelistPtr(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off rangelist_offset_; void setOffset(Dwarf_Unsigned uval) { rangelist_offset_ = uval; }; }; class IRFormFramePtr : public IRForm { public: IRFormFramePtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_FRAMEPTR), frame_offset_(0) {}; IRFormFramePtr(IRFormInterface *); ~IRFormFramePtr() {}; IRFormFramePtr & operator=(const IRFormFramePtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; frame_offset_ = r.frame_offset_; return *this; }; IRFormFramePtr(const IRFormFramePtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; frame_offset_ = r.frame_offset_; } virtual IRFormFramePtr * clone() const { return new IRFormFramePtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off frame_offset_; void setOffset(Dwarf_Unsigned uval) { frame_offset_ = uval; }; }; class IRFormReference : public IRForm { public: IRFormReference(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_REFERENCE), reftype_(RT_NONE), globalOffset_(0),cuRelativeOffset_(0), targetInputDie_(0), target_die_(0) {initSig8();}; IRFormReference(IRFormInterface *); ~IRFormReference() {}; IRFormReference & operator=(const IRFormReference &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; reftype_ = r.reftype_; globalOffset_ = r.globalOffset_; cuRelativeOffset_ = r.cuRelativeOffset_; typeSig8_ = r.typeSig8_; targetInputDie_ = r.targetInputDie_; target_die_ = r.target_die_; return *this; }; IRFormReference(const IRFormReference &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; reftype_ = r.reftype_; globalOffset_ = r.globalOffset_; cuRelativeOffset_ = r.cuRelativeOffset_; typeSig8_ = r.typeSig8_; targetInputDie_ = r.targetInputDie_; target_die_ = r.target_die_; } virtual IRFormReference * clone() const { return new IRFormReference(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setOffset(Dwarf_Off off) { globalOffset_ = off; reftype_ = RT_GLOBAL;}; void setCUOffset(Dwarf_Off off) { cuRelativeOffset_= off; reftype_ = RT_CUREL;}; void setSignature(Dwarf_Sig8 * sig) { typeSig8_ = *sig; reftype_ = RT_SIG;}; const Dwarf_Sig8 *getSignature() { return &typeSig8_;}; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; enum RefType { RT_NONE,RT_GLOBAL, RT_CUREL,RT_SIG }; enum RefType getReferenceType() { return reftype_;}; Dwarf_P_Die getTargetGenDie() { return target_die_;}; IRDie * getTargetInDie() { return targetInputDie_;}; void setTargetGenDie(Dwarf_P_Die targ) { target_die_ = targ; }; void setTargetInDie(IRDie* targ) { targetInputDie_ = targ; }; private: void initSig8(); Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; enum RefType reftype_; // gobalOffset_ on input target set if and only if RT_GLOBAL Dwarf_Off globalOffset_; // cuRelativeOffset_ on input targetset if and only if RT_CUREL Dwarf_Off cuRelativeOffset_; // typeSig8_ on input target set if and only if RT_SIG Dwarf_Sig8 typeSig8_; // For RT_SIG we do not need extra data. // For RT_CUREL and RT_GLOBAL we do. // For RT_CUREL. Points at the target input DIE // after all input DIEs set up for a CU . IRDie * targetInputDie_; // FIXME Dwarf_P_Die target_die_; //for RT_CUREL, this is known // for sure only after all target DIEs generated! // RT_GLOBAL. FIXME }; class IRFormString: public IRForm { public: IRFormString(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_STRING), strpoffset_(0) {}; ~IRFormString() {}; IRFormString(IRFormInterface *); IRFormString(const IRFormString &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; formdata_= r.formdata_; strpoffset_= r.strpoffset_; } virtual IRFormString * clone() const { return new IRFormString(*this); } IRFormString & operator=(const IRFormString &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; formdata_ = r.formdata_; strpoffset_ = r.strpoffset_; return *this; }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setString(const char *s) {formdata_ = s; }; const std::string & getString() const {return formdata_; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::string formdata_; Dwarf_Unsigned strpoffset_; }; // Factory Method. IRForm *formFactory(Dwarf_Debug dbg, Dwarf_Attribute attr, IRCUdata &cudata,IRAttr & irattr); libdwarf-20210528/dwarfgen/ChangeLog20180000664000175000017500000001340013644370703014363 000000000000002018-11-29 David Anderson * createirepfrombinary.cc: Removed trailing whitespace. * dwarfgen.cc: Added option --add-implicit-const to create an object with DW_FORM_implicit_const. * general.h: Added bool addimplicitconst flag for the new option. * irepattrtodbg.cc: For DW_FORM_implicit_const add a call to new libdwarf function dwarf_add_AT_implicit_const(). * ireptodbg.cc: New static function addImplicitConstItem() deals with replacing parts of existing variables with DW_FORM_implicit_const when the new option used. 2018-10-03 David Anderson * dwarfgen.cc: Now uses dwarf_init_b() instead of the original dwarf_init(). 2018-09-21 David Anderson * dwarfgen.cc: S_IRUSR was defined incorrectly (when not provided by system headers). Fixed. * CMakeLists.txt: Updated headers list to include all the local headers. * Makefile.am: Ensured config.h.in.cmake and dwarfgen.1 get into releases. 2018-09-11 David Anderson * ireptodbg.cc: Removed pointless comment. 2018-08-02 David Anderson * irepattrtodbg.cc: Fixed a typo and removed/#if 0 some debugging code * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Moved ChangeLog etc out of /usr/share but have them in the distribution. Now make install puts nothing of dwarfgen in /usr/local/share. 2018-07-31 David Anderson * createirepfrombinary.cc: Delete blank line. * dwarfgen.cc: Adding new option --force-empty-dnames to force out .debug_names section (even if empty). Added dwarf_transform_to_disk_form_a() which does the same as dwarf_transform_to_disk_form() but has a status as the return value and returns its value via a pointer arg. * irepattrtodbg.cc: Removing some useless whitespace. 2018-07-24 David Anderson * dwarfgen.cc: CallbackFunc() was awkwardly declared (now more sensibly declared as static function, still extern "C" as it is called from C (libdwarf)) ErrorHandler() was unused (now deleted). 2018-07-23 David Anderson * createirepformfrombinary.cc: Removed unused local variable. #define UNUSEDARG appropriately * createirepfrombinary.cc: Removed extra ';'. #define UNUSEDARG appropriately mark static functions as such to avoid warnings. Mark arguments UNUSEDARG where appropriate. Test the correct libdwarf return value. Delete unused local variables. * dwarfgen.cc: Declared functions for C callbacks as extern C. #define UNUSEDARG appropriately * general.h: Reformat the header comments to avoid too-long lines. Delete duplicative comments. * irepattrtodbg.cc: Fixed reinterpret casts to be the correct type which made the typedef myintptrt unused (and now deleted). #define UNUSEDARG appropriately Mark arguments UNUSEDARG where appropriate. * irepdie.h, irepform.h: Mark arguments UNUSEDARG where appropriate. * ireptodbg.cc:Fixed reinterpret casts to be the correct type, fixing signed/unsigned comparison warnings. Removed some unused local variables. Fixed a couple declarations to avoid signed/unsigned comparison warnings. #define UNUSEDARG appropriately Mark arguments UNUSEDARG where appropriate. 2018-07-22 David Anderson * dwarfgen.cc: The relocations processing was assuming alignment of 32bit and 64bit values. Now no longer makes that incorrect assumption. 2018-07-16 David Anderson * createirepformfrombinary.cc: Refines ifdef of HAVE_STDAFX_H * createirepfrombinary.cc: Refines ifdef of HAVE_STDAFX_H Delete unused local variable. * dwarfgen.cc: Refines ifdef of HAVE_STDAFX_H. Changes certain function_argument names to avoid shadowing a global. For example, elf -> elf_w * general.h: Remove pointless trailing ; ending IToHex() * irepattrtodbg.cc: Refines ifdef of HAVE_STDAFX_H. Rename local vars to avoid shadowing. Example: form -> form_a * ireptodbg.cc: Refines ifdef of HAVE_STDAFX_H. Rename local vars to avoid shadowing. Example: error -> lerror 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-19 David Anderson * dwarfgen.cc: Now it's intended to build for Linux or Windows and get usable file open modes automatically. 2018-06-14 David Anderson * Makefile.in * config.h.in,configure.ac Removed unnecessary defines and checks. * configure: Regenerated * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc,ireptodbg.cc: Removed unnecessary #includes * dwarfgen.cc: Removed unnecessary #includes. Switch from gelf.h (GNU only) to libelf.h. 2018-06-14 David Anderson * Added #ifdef for Windows environment builds. _O_WRONLY etc for creating a file. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * dwarfgen.cc.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-05 David Anderson * dwarfdump.c: Change WIN32 to _WIN32. 2018-06-05 David Anderson * configure.ac: Now configure.in gone, using configure.ac. * configure: regenerated. * config.h.in: Regenerated, HAVE_LIBELF_LIBELF gone. 2018-06-05 David Anderson * dwarfgen.cc: Remove erroneous _MSC_VER per Carlos Alberto Enciso. 2018-05-28 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc, general.h,irepattrtodbg.cc,irepdie.h, irepform.h,ireppubnames.h: Removed trailing blank lines and updated copyright year. libdwarf-20210528/dwarfgen/createirepfrombinary.cc0000664000175000017500000006145313644370703017034 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepfrombinary.cc // Reads an object and inserts its dwarf data into // an object intended to hold all the dwarf data. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include //open #include //open #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "createirepfrombinary.h" #include "general.h" // For IToHex() using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; using std::map; static void readFrameDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readCUDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readGlobals(Dwarf_Debug dbg, IRepresentation & irep); /* Use a generic call to open the file, due to issues with Windows */ extern int open_a_file(const char * name); extern int create_a_file(const char * name); extern void close_a_file(int f); static void errprint(Dwarf_Error err) { cerr << "Error num: " << dwarf_errno(err) << " " << dwarf_errmsg(err) << endl; } class DbgInAutoCloser { public: DbgInAutoCloser(Dwarf_Debug dbg,int fd): dbg_(dbg),fd_(fd) {}; ~DbgInAutoCloser() { Dwarf_Error err = 0; dwarf_finish(dbg_,&err); close(fd_); }; private: Dwarf_Debug dbg_; int fd_; }; void createIrepFromBinary(const std::string &infile, IRepresentation & irep) { Dwarf_Debug dbg = 0; Dwarf_Error err; int fd = open_a_file(infile.c_str()); if(fd < 0 ) { cerr << "Unable to open " << infile << " for reading." << endl; exit(1); } // All reader error handling is via the err argument. int res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, DW_DLC_READ, 0, 0, &dbg, &err); if(res == DW_DLV_NO_ENTRY) { close_a_file(fd); cerr << "Error init-ing " << infile << " for reading. dwarf_init_b(). Not object file." << endl; exit(1); } else if(res == DW_DLV_ERROR) { close_a_file(fd); cerr << "Error init-ing " << infile << " for reading. dwarf_init_b() failed. " << dwarf_errmsg(err) << endl; exit(1); } DbgInAutoCloser closer(dbg,fd); readFrameDataFromBinary(dbg,irep); readCUDataFromBinary(dbg,irep); readMacroDataFromBinary(dbg,irep); readGlobals(dbg,irep); return; } static void readFrameDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error err = 0; Dwarf_Cie * cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde * fde_data = 0; Dwarf_Signed fde_count = 0; bool have_standard_frame = true; int res = dwarf_get_fde_list(dbg, &cie_data, &cie_count, &fde_data, &fde_count, &err); if(res == DW_DLV_NO_ENTRY) { // No frame data we are dealing with. #if 0 res = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_count, &fde_data, &fde_count, &err); if(res == DW_DLV_NO_ENTRY) { // No frame data. return; } have_standard_frame = false; #endif /* 0 */ return; } if(res == DW_DLV_ERROR) { cerr << "Error reading frame data " << endl; exit(1); } for(Dwarf_Signed i =0; i < cie_count; ++i) { Dwarf_Unsigned bytes_in_cie = 0; Dwarf_Small version = 0; char * augmentation = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; res = dwarf_get_cie_info(cie_data[i], &bytes_in_cie, &version,&augmentation, &code_alignment_factor, &data_alignment_factor,&return_address_register_rule, &initial_instructions,&initial_instructions_length, &err); if(res != DW_DLV_OK) { errprint(err); cerr << "Error reading frame data cie index " << i << endl; exit(1); } // Index in cie_data must match index in ciedata_, here // correct by construction. IRCie cie(bytes_in_cie,version,augmentation, code_alignment_factor, data_alignment_factor,return_address_register_rule, initial_instructions,initial_instructions_length); if (have_standard_frame) { irep.framedata().insert_cie(cie); } else { irep.ehframedata().insert_cie(cie); } } for(Dwarf_Signed i =0; i < fde_count; ++i) { Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes = 0; Dwarf_Unsigned fde_byte_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; res = dwarf_get_fde_range(fde_data[i], &low_pc, &func_length,&fde_bytes, &fde_byte_length, &cie_offset,&cie_index, &fde_offset, &err); if(res != DW_DLV_OK) { cerr << "Error reading frame data fde index " << i << endl; exit(1); } IRFde fde(low_pc,func_length,fde_bytes,fde_byte_length, cie_offset, cie_index,fde_offset); Dwarf_Ptr instr_in = 0; Dwarf_Unsigned instr_len = 0; res = dwarf_get_fde_instr_bytes(fde_data[i], &instr_in, &instr_len, &err); if(res != DW_DLV_OK) { cerr << "Error reading frame data fde instructions " << i << endl; exit(1); } fde.get_fde_instrs_into_ir(instr_in,instr_len); if (have_standard_frame) { irep.framedata().insert_fde(fde); } else { irep.ehframedata().insert_fde(fde); } } dwarf_fde_cie_list_dealloc(dbg,cie_data,cie_count, fde_data,fde_count); } static void readCUMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep, Dwarf_Unsigned macrodataoffset,IRCUdata &cu) { // Arbitrary, but way too high to be real! // Probably should be lower. Dwarf_Unsigned maxcount = 1000000000; Dwarf_Error error; Dwarf_Signed mcount=0; Dwarf_Macro_Details *md = 0; int res = dwarf_get_macro_details(dbg,macrodataoffset, maxcount, &mcount, &md, &error); if(res == DW_DLV_OK) { IRMacro ¯odata = irep.macrodata(); vector mvec = macrodata.getMacroVec(); mvec.reserve(mcount); Dwarf_Unsigned dieoffset = cu.baseDie().getGlobalOffset(); Dwarf_Macro_Details *mdp = md; for(int i = 0; i < mcount; ++i, mdp++ ) { IRMacroRecord ir(dieoffset,mdp->dmd_offset, mdp->dmd_type, mdp->dmd_lineno, mdp->dmd_fileindex, mdp->dmd_macro?mdp->dmd_macro:""); mvec.push_back(ir); } } dwarf_dealloc(dbg, md, DW_DLA_STRING); } static void get_basic_attr_data_one_attr(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr) { Dwarf_Error error; Dwarf_Half attrnum = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; int res = dwarf_whatattr(attr,&attrnum,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr number " << endl; exit(1); } res = dwarf_whatform(attr,&finalform,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr form " << endl; exit(1); } res = dwarf_whatform_direct(attr,&initialform,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr direct form " << endl; exit(1); } irattr.setBaseData(attrnum,finalform,initialform); enum Dwarf_Form_Class cl = dwarf_get_form_class( cudata.getVersionStamp(), attrnum, cudata.getOffsetSize(), finalform); irattr.setFormClass(cl); if (cl == DW_FORM_CLASS_UNKNOWN) { cerr << "Unable to figure out form class. ver " << cudata.getVersionStamp() << " attrnum " << attrnum << " offsetsize " << cudata.getOffsetSize() << " formnum " << finalform << endl; return; } irattr.setFormData(formFactory(dbg,attr,cudata,irattr)); } static void get_basic_die_data(Dwarf_Debug dbg UNUSEDARG, Dwarf_Die indie,IRDie &irdie) { Dwarf_Half tagval = 0; Dwarf_Error error = 0; int res = dwarf_tag(indie,&tagval,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get die tag "<< endl; exit(1); } Dwarf_Off goff = 0; res = dwarf_dieoffset(indie,&goff,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get die offset "<< endl; exit(1); } Dwarf_Off localoff = 0; res = dwarf_die_CU_offset(indie,&localoff,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get cu die offset "<< endl; exit(1); } irdie.setBaseData(tagval,goff,localoff); } static void get_attrs_of_die(Dwarf_Die in_die,IRDie &irdie, IRCUdata &cudata, IRepresentation &irep UNUSEDARG, Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Attribute *atlist = 0; Dwarf_Signed atcnt = 0; std::list &attrlist = irdie.getAttributes(); int res = dwarf_attrlist(in_die, &atlist,&atcnt,&error); std::map attrmap; if(res == DW_DLV_NO_ENTRY) { return; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_attrlist failed " << endl; exit(1); } for (Dwarf_Signed i = 0; i < atcnt; ++i) { Dwarf_Attribute attr = atlist[i]; Dwarf_Half attrnum = 0; res = dwarf_whatattr(attr,&attrnum,&error); if (res != DW_DLV_OK) { cout << "ERROR FAIL: unable to get attrnum from attr!" <::iterator m = attrmap.find(attrnum); if (m != attrmap.end()) { // A duplicate! ignore. Compiler bug // in some gcc versions. continue; } attrmap[attrnum] = i; // Use an empty attr to get a placeholder on // the attr list for this IRDie. IRAttr irattr; attrlist.push_back(irattr); // We want a pointer to the final attr to be // recorded for references, not a local temp IRAttr. IRAttr & lastirattr = attrlist.back(); get_basic_attr_data_one_attr(dbg,attr,cudata,lastirattr); } dwarf_dealloc(dbg,atlist, DW_DLA_LIST); } // Invariant: IRDie and IRCUdata are in the irep tree, // not local record references to local scopes. static void get_children_of_die(Dwarf_Die in_die,IRDie&irdie, IRCUdata &ircudata, IRepresentation &irep, Dwarf_Debug dbg) { Dwarf_Die curchilddie = 0; Dwarf_Error error = 0; int res = dwarf_child(in_die,&curchilddie,&error); if(res == DW_DLV_NO_ENTRY) { return; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_child failed " << endl; exit(1); } //std::list & childlist = irdie.getChildren(); int childcount = 0; for(;;) { IRDie child; get_basic_die_data(dbg,curchilddie,child); irdie.addChild(child); IRDie &lastchild = irdie.lastChild(); get_attrs_of_die(curchilddie,lastchild,ircudata,irep,dbg); ircudata.insertLocalDieOffset(lastchild.getCURelativeOffset(), &lastchild); get_children_of_die(curchilddie,lastchild,ircudata,irep,dbg); ++childcount; Dwarf_Die tchild = 0; res = dwarf_siblingof(dbg,curchilddie,&tchild,&error); if(res == DW_DLV_NO_ENTRY) { break; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_siblingof failed " << endl; exit(1); } dwarf_dealloc(dbg,curchilddie,DW_DLA_DIE); curchilddie = tchild; } dwarf_dealloc(dbg,curchilddie,DW_DLA_DIE); } static void get_linedata_of_cu_die(Dwarf_Die in_die,IRDie&irdie UNUSEDARG, IRCUdata &ircudata, IRepresentation &irep UNUSEDARG, Dwarf_Debug dbg) { Dwarf_Error error = 0; char **srcfiles = 0; Dwarf_Signed srccount = 0; IRCULineData&culinesdata = ircudata.getCULines(); int res = dwarf_srcfiles(in_die,&srcfiles, &srccount,&error); if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_srcfiles failed " << endl; exit(1); } else if (res == DW_DLV_NO_ENTRY) { // No data. return; } std::vector &srcs = culinesdata.get_cu_srcfiles(); for (Dwarf_Signed i = 0; i < srccount; ++i) { IRCUSrcfile S(srcfiles[i]); srcs.push_back(S); /* use srcfiles[i] */ dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); Dwarf_Line * linebuf = 0; Dwarf_Signed linecnt = 0; int res2 = dwarf_srclines(in_die,&linebuf,&linecnt, &error); if(res2 == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_srclines failed " << endl; exit(1); } else if (res2 == DW_DLV_NO_ENTRY) { // No data. cerr << "dwarf_srclines failed NO_ENTRY, crazy " "since srcfiles worked" << endl; exit(1); } std::vector &lines = culinesdata.get_cu_lines(); for(Dwarf_Signed j = 0; j < linecnt ; ++j ) { Dwarf_Line li = linebuf[j]; int lres; Dwarf_Addr address = 0; lres = dwarf_lineaddr(li,&address,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineaddr failed. " << endl; exit(1); } Dwarf_Bool is_addr_set = 0; lres = dwarf_line_is_addr_set(li,&is_addr_set,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_line_is_addr_set failed. " << endl; exit(1); } Dwarf_Unsigned fileno = 0; lres = dwarf_line_srcfileno(li,&fileno,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_srcfileno failed. " << endl; exit(1); } Dwarf_Unsigned lineno = 0; lres = dwarf_lineno(li,&lineno,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineno failed. " << endl; exit(1); } Dwarf_Unsigned lineoff = 0; lres = dwarf_lineoff_b(li,&lineoff,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineoff failed. " << endl; exit(1); } char *linesrctmp = 0; lres = dwarf_linesrc(li,&linesrctmp,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_linesrc failed. " << endl; exit(1); } // libdwarf is trying to generate a full path, // the string here is that generated data, not // simply the 'file' path represented by the // file number (fileno). std::string linesrc(linesrctmp); Dwarf_Bool is_stmt = 0; lres = dwarf_linebeginstatement(li,&is_stmt,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_linebeginstatement failed. " << endl; exit(1); } Dwarf_Bool basic_block = 0; lres = dwarf_lineblock(li,&basic_block,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineblock failed. " << endl; exit(1); } Dwarf_Bool end_sequence = 0; lres = dwarf_lineendsequence(li,&end_sequence,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineendsequence failed. " << endl; exit(1); } Dwarf_Bool prologue_end = 0; Dwarf_Bool epilogue_begin = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; lres = dwarf_prologue_end_etc(li,&prologue_end, &epilogue_begin,&isa,&discriminator,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_prologue_end_etc failed. " << endl; exit(1); } IRCULine L(address, is_addr_set, fileno, lineno, lineoff, linesrc, is_stmt, basic_block, end_sequence, prologue_end,epilogue_begin, isa,discriminator); lines.push_back(L); } dwarf_srclines_dealloc(dbg, linebuf, linecnt); } static bool getToplevelOffsetAttr(Dwarf_Die cu_die,Dwarf_Half attrnumber, Dwarf_Unsigned &offset_out) { Dwarf_Error error = 0; Dwarf_Off offset = 0; Dwarf_Attribute attr = 0; int res = dwarf_attr(cu_die,attrnumber,&attr, &error); bool foundit = false; if(res == DW_DLV_OK) { res = dwarf_global_formref(attr,&offset,&error); if(res == DW_DLV_OK) { foundit = true; offset_out = offset; } } return foundit; } // We record the .debug_info info for each CU found // To start with we restrict attention to very few DIEs and // attributes, but intend to get all eventually. static void readCUDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error error; int cu_number = 0; std::list &culist = irep.infodata().getCUData(); for(;;++cu_number) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Half version_stamp = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; res = dwarf_next_cu_header_b(dbg,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size, &next_cu_header, &error); if(res == DW_DLV_ERROR) { errprint(error); cerr <<"Error in dwarf_next_cu_header"<< endl; exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ return; } IRCUdata cudata(cu_header_length,version_stamp, abbrev_offset,address_size, offset_size, extension_size,next_cu_header); // The CU will have a single sibling (well, it is // not exactly a sibling, but close enough), a cu_die. res = dwarf_siblingof(dbg,no_die,&cu_die,&error); if(res == DW_DLV_ERROR) { errprint(error); cerr <<"Error in dwarf_siblingof on CU die "<< endl; exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ cerr <<"no Entry! in dwarf_siblingof on CU die "<< endl; exit(1); } Dwarf_Off macrooffset = 0; bool foundmsect = getToplevelOffsetAttr(cu_die,DW_AT_macro_info, macrooffset); Dwarf_Off linesoffset = 0; bool foundlines = getToplevelOffsetAttr(cu_die,DW_AT_stmt_list, linesoffset); Dwarf_Off dieoff = 0; res = dwarf_dieoffset(cu_die,&dieoff,&error); if(res != DW_DLV_OK) { cerr << "Unable to get cu die offset for macro infomation "<< endl; exit(1); } if(foundmsect) { cudata.setMacroData(macrooffset,dieoff); } if(foundlines) { cudata.setLineData(linesoffset,dieoff); } culist.push_back(cudata); IRCUdata & treecu = irep.infodata().lastCU(); IRDie &cuirdie = treecu.baseDie(); get_basic_die_data(dbg,cu_die,cuirdie); treecu.insertLocalDieOffset(cuirdie.getCURelativeOffset(), &cuirdie); get_attrs_of_die(cu_die,cuirdie,treecu,irep,dbg); get_children_of_die(cu_die,cuirdie,treecu,irep,dbg); get_linedata_of_cu_die(cu_die,cuirdie,treecu,irep,dbg); // Now we have all local DIEs in the CU so we // can identify all targets of local CLASS_REFERENCE // and insert the IRDie * into the IRFormReference treecu.updateReferenceAttrDieTargets(); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); } // If we want pointers from child to parent now is the time // we can construct them. } // We read thru the CU headers and the CU die to find // the macro info for each CU (if any). // We record the CU macro info for each CU found (using // the value of the DW_AT_macro_info attribute, if any). static void readMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { list &cudata = irep.infodata().getCUData(); list::iterator it = cudata.begin(); int ct = 0; for( ; it != cudata.end(); ++it,++ct) { Dwarf_Unsigned macrooffset = 0; Dwarf_Unsigned cudieoffset = 0; bool foundmsect = it->hasMacroData(¯ooffset,&cudieoffset); if(foundmsect) { readCUMacroDataFromBinary(dbg, irep, macrooffset,*it); } } } // Offsets refer to .debug_info, nothing else. static void readGlobals(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error error; Dwarf_Global *globs = 0; Dwarf_Type *types = 0; Dwarf_Signed cnt = 0; int res = 0; IRPubsData &pubdata = irep.pubnamedata(); res = dwarf_get_globals(dbg, &globs,&cnt, &error); if(res == DW_DLV_OK) { std::list &pubnames = pubdata.getPubnames(); for (Dwarf_Signed i = 0; i < cnt; ++i) { Dwarf_Global g = globs[i]; char *name = 0; // dieoff and cuoff may be in .debug_info // or .debug_types Dwarf_Off dieoff = 0; Dwarf_Off cuoff = 0; res = dwarf_global_name_offsets(g,&name, &dieoff,&cuoff,&error); if( res == DW_DLV_OK) { IRPub p(name,dieoff,cuoff); dwarf_dealloc(dbg,name,DW_DLA_STRING); pubnames.push_back(p); } } dwarf_globals_dealloc(dbg, globs, cnt); } else if (res == DW_DLV_ERROR) { cerr << "dwarf_get_globals failed" << endl; exit(1); } res = dwarf_get_pubtypes(dbg, &types,&cnt, &error); if(res == DW_DLV_OK) { std::list &pubtypes = pubdata.getPubtypes(); for (Dwarf_Signed i = 0; i < cnt; ++i) { Dwarf_Type g = types[i]; char *name = 0; // dieoff and cuoff may be in .debug_info // or .debug_types Dwarf_Off dieoff = 0; Dwarf_Off cuoff = 0; res = dwarf_pubtype_name_offsets(g,&name, &dieoff,&cuoff,&error); if( res == DW_DLV_OK) { IRPub p(name,dieoff,cuoff); dwarf_dealloc(dbg,name,DW_DLA_STRING); pubtypes.push_back(p); } } dwarf_types_dealloc(dbg, types, cnt); } else if (res == DW_DLV_ERROR) { cerr << "dwarf_get_globals failed" << endl; exit(1); } } libdwarf-20210528/dwarfgen/irepresentation.h0000664000175000017500000001311413644370703015664 00000000000000/* Copyright (C) 2010-2016 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepresentation.h // The internal (to dwarfgen) representation of debug information. // All the various components (info, frame, etc) // will be stored here in an internal-to-dwarfgen form. // // #include "irepform.h" #include "irepline.h" #include "irepdie.h" #include "irepmacro.h" #include "irepframe.h" #include "ireppubnames.h" #include "strtabdata.h" // The elf symbols are used to tie relocations to values. // We do relocations ourselves in dwarfgen so the data is not needed // once the dwarf .debug_* sections created in elf. // We don't write the symbols out as an elf section. // The position in the vector of symbols is the 'elf symbol index' // we create. // Symbol 0 is 'no symbol'. // Symbol 1 is .text class ElfSymbol { public: ElfSymbol():symbolValue_(0), nameIndex_(0) {}; ElfSymbol(Dwarf_Unsigned val, const std::string&name, strtabdata&stab): symbolValue_(val),name_(name) { nameIndex_ = stab.addString(name); }; ~ElfSymbol() {}; Dwarf_Unsigned getSymbolValue() const { return symbolValue_;} private: Dwarf_Unsigned symbolValue_; std::string name_; // The offset in the string table. unsigned nameIndex_; }; // It's very easy to confuse the section number in an elf file // with an array index in dwarfgen. // So this class hold an elf section number // and gives those a recognizable type. class ElfSectIndex { public: ElfSectIndex():elfsect_(0) {}; ~ElfSectIndex() {}; ElfSectIndex(unsigned v):elfsect_(v) {}; unsigned getSectIndex() const { return elfsect_; } void setSectIndex(unsigned v) { elfsect_ = v; } private: unsigned elfsect_; }; // It's very easy to confuse the symbol number in an elf file // with a symbol number in dwarfgen. // So this class hold an elf symbol number number // and gives those a recognizable type. class ElfSymIndex { public: ElfSymIndex():elfsym_(0) {}; ~ElfSymIndex() {}; ElfSymIndex(unsigned v):elfsym_(v) {}; unsigned getSymIndex() const { return elfsym_; } void setSymIndex(unsigned v) { elfsym_ = v; } private: unsigned elfsym_; }; class ElfSymbols { public: ElfSymbols() { // The initial symbol is 'no symbol'. std::string emptyname(""); elfSymbols_.push_back(ElfSymbol(0,emptyname,symstrtab_)); // We arbitrarily make this symbol .text now, though // not needed yet. std::string textname(".text"); elfSymbols_.push_back(ElfSymbol(0,textname,symstrtab_)); baseTextAddressSymbol_.setSymIndex(elfSymbols_.size()-1); } ~ElfSymbols() {}; ElfSymIndex getBaseTextSymbol() const {return baseTextAddressSymbol_;}; ElfSymIndex addElfSymbol(Dwarf_Unsigned val, const std::string&name) { elfSymbols_.push_back(ElfSymbol(val,name,symstrtab_)); ElfSymIndex indx(elfSymbols_.size()-1); return indx; }; ElfSymbol & getElfSymbol(ElfSymIndex symi) { size_t i = symi.getSymIndex(); if (i >= elfSymbols_.size()) { std::cerr << "Error, sym index " << i << " to big for symtab size " << elfSymbols_.size() << std::endl; exit(1); } return elfSymbols_[i]; } private: std::vector elfSymbols_; strtabdata symstrtab_; ElfSymIndex baseTextAddressSymbol_; }; class IRepresentation { public: IRepresentation() {}; ~IRepresentation(){}; IRFrame &framedata() { return framedata_; }; IRFrame &ehframedata() { return ehframedata_; }; IRMacro ¯odata() { return macrodata_; }; IRDInfo &infodata() { return debuginfodata_; }; IRPubsData &pubnamedata() {return pubnamedata_;}; ElfSymbols &getElfSymbols() { return elfSymbols_;}; unsigned getBaseTextSymbol() { return elfSymbols_.getBaseTextSymbol().getSymIndex();}; private: // The Elf symbols data to use for relocations ElfSymbols elfSymbols_; IRFrame framedata_; IRFrame ehframedata_; IRMacro macrodata_; IRPubsData pubnamedata_; // .debug_info and its line data are inside debuginfodata_; IRDInfo debuginfodata_; // .debug_types and its line data are in debugtypesdata_. IRDInfo debugtypesdata_; }; libdwarf-20210528/dwarfgen/irepmacro.h0000664000175000017500000000430113644370703014430 00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepmacro.h // class IRMacroRecord { public: IRMacroRecord() {}; ~IRMacroRecord() {}; IRMacroRecord(Dwarf_Off cuDieOffset,Dwarf_Off offset,Dwarf_Small type, Dwarf_Signed lineno, Dwarf_Signed lineindex, const std::string ¯o):cuDieOffset_(cuDieOffset), offset_(offset), type_(type),lineno_(lineno),lineindex_(lineindex), macro_(macro) {}; private: Dwarf_Off cuDieOffset_; Dwarf_Off offset_; Dwarf_Small type_; Dwarf_Signed lineno_; Dwarf_Signed lineindex_; std::string macro_; }; class IRMacro { public: IRMacro() {}; ~IRMacro() {}; std::vector &getMacroVec() { return macrorec_; }; private: std::vector macrorec_; }; libdwarf-20210528/dwarfgen/README0000664000175000017500000000274513644370703013170 00000000000000 David Anderson, September 20, 2010 Updated July 22, 2018 The dwarfgen application is intended as both a vehicle for testing dwarf-generation by libdwarf and as an example of how one uses libdwarf to generate DWARF. In addition, it should be useful as a test vehicle for evaluating future changes to the DWARF standard. It is necessary as a test-vehicle so that the libdwarf producer code can be updated to allow more recent features of DWARF to be supported while trying to guarantee current producer code users are correctly supported. By default dwarfgen produces a fake a.out. By that we mean that no relocation sections are written. Instead, relocations are processed directly by dwarfgen. Perhaps at some point a more a.out-like output will be optionally supported. In its 2018 form the code calling producer functions leaks memory as the return values usually need to be dealloc'd, but only after the code is generated. An example from -fsanitize= is Direct leak of 2688 byte(s) in 28 object(s) allocated from: #0 0x7f51fb2f9602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x5873d9 in _dwarf_p_get_alloc /home/davea/dwarf/regressiontests/../code/libdwarf/pro_alloc.c:76 #2 0x55cdaa in dwarf_add_AT_any_value_uleb /home/davea/dwarf/regressiontests/../code/libdwarf/pro_forms.c:1277 #3 0x495d4a in AddAttrToDie(Dwarf_P_Debug_s*, IRepresentation&, IRCUdata&, Dwarf_P_Die_s*, IRDie&, IRAttr&) /home/davea/dwarf/regressiontests/../code/dwarfgen/irepattrtodbg.cc:176 libdwarf-20210528/dwarfgen/NEWS0000664000175000017500000000036613644370703013004 0000000000000026 February, 2015 Now uses dwgetopt() instead of getopt() so all environments have a getopt-like functionality. It reaches around to libdwarf for the source to dwgetopt, but it could equally well reach into dwarfdump for that source. libdwarf-20210528/dwarfgen/general.h0000664000175000017500000000513214003360753014061 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // general.h // The following needed in code using this. #ifndef GENERAL_H #define GENERAL_H #include #include // iomanip for setw etc // Run time flags from command line. extern struct CmdOptions { bool transformHighpcToConst; int defaultInfoStringForm; bool showrelocdetails; bool adddata16; bool addimplicitconst; bool addframeadvanceloc; bool addSUNfuncoffsets; bool adddebugsup; bool addskipbranch; } cmdoptions; template std::string IToHex(T v,unsigned l=0) { if(v == 0) { // For a zero value, ostringstream does not insert 0x. // So we do zeroes here. std::string out = "0x0"; if(l > 3) { out.append(l-3,'0'); } return out; } std::ostringstream s; s.setf(std::ios::hex,std::ios::basefield); s.setf(std::ios::showbase); if (l > 0) { s << std::setw(l); } s << v ; return s.str(); } template std::string BldName(const std::string & prefix, T v) { std::ostringstream s; s << prefix; s << v; return s.str(); } #endif /* GENERAL_H */ libdwarf-20210528/dwarfgen/ChangeLog0000664000175000017500000000177714004605416014057 000000000000002021-01-28 David Anderson * createirepformfrombinary.cc: Now adds DW_FORM_CLASS_EXPERLOC as a uniform way to handle dwarf expressions across all DWARF2 and later versions. libdwarf changed a little to support this as the old way just did not work. * dwarfdump.cc: Added option --add-skip-branch-ops to create special DW_OP_skip and DW_OP_bra entries to verify dwarfdump error checking works properly. * general.h: Added bool addskipbranch for the --add-skip-branch-ops option. * irepattrtodbg.c: Corrected EXPRLOC handling to actually emit expressions. * irepdie.h: Reformatted the copyright to fit properly within libdwarf line lengths. * irepform.h: Reformatted copyright. Added new methods so block and EXPRLOC can emit proper expr byte blobs. * ireptodbg.cc: When --add-skip-branch-ops present this emits some special crafted expressions that emit DW_OP_bra and skip with errors so dwarfdump can report on them. libdwarf-20210528/dwarfgen/fakemalloc.in0000664000175000017500000000375313644370703014736 00000000000000/* This file is a simple way (on Linux) to do a certain kind of test. "Code Testing Through Fault Injection" in ":login;" magazine (December, 2014. Usenix.org) by Peter Gutmann offered a simple example by an unnamed friend: instrument malloc() so on call N it returns NULL. Try with N from 0 to some higher number (I used 0 to 100). Run your chosen executable and see how it fares. This test exposed a couple bugs in libdwarf. Here are some of the example core dumps (running dwarfgen): 2000: Could not allocate Dwarf_Error structure, abort() in libdwarf. 1000: FAIL:bad alloc caughtstd::bad_alloc 500: FAIL:bad alloc caughtstd::bad_alloc 250: FAIL:bad alloc caughtstd::bad_alloc 125: Could not allocate Dwarf_Error structure, abort() in libdwarf. Aborted (core dumped) 100: FAIL:bad alloc caughtstd::bad_alloc 46-60: FAIL:bad alloc caughtstd::bad_alloc 45- Could not allocate Dwarf_Error structure, abort() in libdwarf. Aborted (core dumped) 42-44: FAIL:bad alloc caughtstd::bad_alloc 30- 41: Could not allocate Dwarf_Error structure, abort() in libdwarf. Aborted (core dumped) 28-29 :FAIL:bad alloc caught std::bad_alloc Aborted (core dumped) 8,9,10,11-27: Could not allocate Dwarf_Error structure, abort() in libdwarf. Aborted (core dumped) 7: 6: FAIL:bad alloc caught std::bad_alloc 0,1,2,3,4,5: terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped) -------HOW TO USE: Configure generates the following for Makefile. $(CXX) $(CXXFLAGS) -o $@ $(DGOBJECTS) $(LDFLAGS) In the generated Makefile, replace the above line with these two lines. $(CC) $(CFLAGS) -c fakemalloc.o $(CXX) $(CXXFLAGS) -o $@ $(DGOBJECTS) $(LDFLAGS) fakemalloc.o Run tests using the script TESTmallocfail ------- */ static unsigned count; extern void * __libc_malloc(); void *malloc(unsigned len) { /* Perhaps the test should be count >= FAILCOUNT ??? */ if (count == FAILCOUNT) { return 0; } count++; return __libc_malloc(len); } libdwarf-20210528/dwarfgen/createirepformfrombinary.cc0000664000175000017500000003757014003620515017710 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepformfrombinary.cc // Reads an object and inserts its dwarf data into // an object intended to hold all the dwarf data. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_UNITSTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "createirepfrombinary.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; // THis should instantiated only locally, not with 'new'. // It should not be copied. class IRFormInterface { public: IRFormInterface(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr): dbg_(dbg),attr_(attr),cudata_(cudata),irattr_(irattr) {}; // Do not free anything we did not create here. ~IRFormInterface() {}; Dwarf_Debug dbg_; Dwarf_Attribute attr_; IRCUdata &cudata_; IRAttr &irattr_; private: // Do not instantiate. IRFormInterface(); IRFormInterface& operator= (const IRFormInterface &ir); }; IRForm *formFactory(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr) { IRFormInterface interface(dbg,attr,cudata,irattr); enum Dwarf_Form_Class cl = irattr.getFormClass(); switch(cl) { case DW_FORM_CLASS_UNKNOWN: break; case DW_FORM_CLASS_ADDRESS: { IRFormAddress *f = new IRFormAddress(&interface); // FIXME: do we need to do anything about symbol here? // Yes, if it has a relocation. return f; } break; case DW_FORM_CLASS_EXPRLOC: case DW_FORM_CLASS_BLOCK: { IRFormBlock *f = new IRFormBlock(&interface); return f; } break; case DW_FORM_CLASS_CONSTANT: { IRFormConstant *f = new IRFormConstant(&interface); return f; } break; case DW_FORM_CLASS_FLAG: { IRFormFlag *f = new IRFormFlag(&interface); return f; } break; case DW_FORM_CLASS_LINEPTR: { IRFormLinePtr *f = new IRFormLinePtr(&interface); return f; } break; case DW_FORM_CLASS_LOCLISTPTR: { IRFormLoclistPtr *f = new IRFormLoclistPtr(&interface); return f; } break; case DW_FORM_CLASS_MACPTR: { IRFormMacPtr *f = new IRFormMacPtr(&interface); return f; } break; case DW_FORM_CLASS_RANGELISTPTR: { IRFormRangelistPtr *f = new IRFormRangelistPtr(&interface); return f; } break; case DW_FORM_CLASS_REFERENCE: { IRFormReference *f = new IRFormReference(&interface); return f; } break; case DW_FORM_CLASS_STRING: { IRFormString *f = new IRFormString(&interface); return f; } break; case DW_FORM_CLASS_FRAMEPTR: /* SGI/IRIX extension. */ { IRFormFramePtr *f = new IRFormFramePtr(&interface); return f; } break; default: break; } return new IRFormUnknown(); } static void extractInterafaceForms(IRFormInterface *interface, Dwarf_Half *finalform, Dwarf_Half *initialform) { Dwarf_Error error = 0; int res = dwarf_whatform(interface->attr_,finalform,&error); if(res != DW_DLV_OK) { cerr << "Unable to get attr form " << endl; exit(1); } res = dwarf_whatform_direct(interface->attr_,initialform,&error); if(res != DW_DLV_OK) { cerr << "Unable to get attr direct form " << endl; exit(1); } } IRFormAddress::IRFormAddress(IRFormInterface * interface) { Dwarf_Addr val = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_ = DW_FORM_CLASS_ADDRESS; address_ = 0; int res = dwarf_formaddr(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << " line " << __LINE__ << " file " << __FILE__ << endl; exit(1); } // FIXME do we need to do anything about the symbol here? // It might have a relocation and we should determine that. address_ = val; } IRFormBlock::IRFormBlock(IRFormInterface * interface) { Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_BLOCK; fromloclist_= 0; sectionoffset_=0; Dwarf_Block *blockptr = 0; Dwarf_Error error = 0; int res = dwarf_formblock(interface->attr_,&blockptr, &error); if(res != DW_DLV_OK) { cerr << "Unable to read block . Impossible error.\n" << " line " << __LINE__ << " file " << __FILE__ << endl; exit(1); } insertBlock(blockptr); dwarf_dealloc(interface->dbg_,blockptr,DW_DLA_BLOCK); } IRFormConstant::IRFormConstant(IRFormInterface * interface) { Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_CONSTANT; signedness_=SIGN_NOT_SET; uval_=0; sval_=0; Dwarf_Error error = 0; if (finalform == DW_FORM_data16) { Dwarf_Form_Data16 data16; int rd16 = dwarf_formdata16(interface->attr_,&data16, &error); if (rd16 != DW_DLV_OK) { cerr << "Unable to read constant data16 value. " "Impossible error.\n" << endl; exit(1); } setValues16(&data16, SIGN_UNKNOWN); return; } enum Signedness oursign = SIGN_NOT_SET; Dwarf_Unsigned uval = 0; Dwarf_Signed sval = 0; int ress = dwarf_formsdata(interface->attr_, &sval,&error); int resu = dwarf_formudata(interface->attr_, &uval,&error); if(resu == DW_DLV_OK ) { if(ress == DW_DLV_OK) { oursign = SIGN_UNKNOWN; } else { oursign = UNSIGNED; sval = static_cast(uval); } } else { if(ress == DW_DLV_OK) { oursign = SIGNED; uval = static_cast(sval); } else { cerr << "Unable to read constant value. Impossible error.\n" << endl; exit(1); } } setValues(sval, uval, oursign); } IRFormExprloc::IRFormExprloc(IRFormInterface * interface) { Dwarf_Unsigned len = 0; Dwarf_Ptr data = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_EXPRLOC; int res = dwarf_formexprloc(interface->attr_,&len, &data, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << " line " << __LINE__ << " file " << __FILE__ << endl; exit(1); } // FIXME: Would be nice to expand to the expression details // instead of just a block of bytes. insertBlock(len,data); } IRFormFlag::IRFormFlag(IRFormInterface * interface) { Dwarf_Bool flagval = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_FLAG; flagval_=0; Dwarf_Error error = 0; int res = dwarf_formflag(interface->attr_,&flagval, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << " line " << __LINE__ << " file " << __FILE__ << endl; exit(1); } setFlagVal(flagval); setFinalForm(finalform); setInitialForm(initialform); } // We are simply assuming (here) that the value is a global offset // to some section or other. // Calling code ensures that is true. // static Dwarf_Unsigned get_section_offset(IRFormInterface * interface) { Dwarf_Unsigned uval = 0; Dwarf_Signed sval = 0; Dwarf_Error error = 0; Dwarf_Off sectionoffset = 0; int resu = 0; // The following allows more sorts of value than // we really want to allow here, but that is // harmless, we believe. int resgf = dwarf_global_formref(interface->attr_, §ionoffset, &error); if(resgf == DW_DLV_OK ) { return sectionoffset; } resu = dwarf_formudata(interface->attr_, &uval,&error); if(resu != DW_DLV_OK ) { int ress = dwarf_formsdata(interface->attr_, &sval,&error); if(ress == DW_DLV_OK) { uval = static_cast(sval); } else { cerr << "Unable to read constant offset value. Impossible error.\n" << endl; exit(1); } } return uval; } IRFormLoclistPtr::IRFormLoclistPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_LOCLISTPTR; loclist_offset_=0; } // When emitting line data from the producer, this // attribute is automatically emitted by the transform_to_disk // function if there is line data in the generated CU, // not created by interpreting this input attribute. IRFormLinePtr::IRFormLinePtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); } IRFormMacPtr::IRFormMacPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_MACPTR; macro_offset_=0; } IRFormRangelistPtr::IRFormRangelistPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_RANGELISTPTR; rangelist_offset_=0; } IRFormFramePtr::IRFormFramePtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_FRAMEPTR; frame_offset_=0; } // This is a .debug_info to .debug_info (or .debug_types to .debug_types) // reference. // Since local/global reference target values are not known // till the DIEs are actually emitted, // we eventually use libdwarf (dwarf_get_die_markers) to fix up // the new target value. Here we just record the input value. // IRFormReference::IRFormReference(IRFormInterface * interface) { Dwarf_Off val = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; formclass_ = DW_FORM_CLASS_REFERENCE; reftype_ = RT_NONE; globalOffset_ = 0; cuRelativeOffset_ = 0; targetInputDie_= 0; target_die_= 0; initSig8(); extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); IRCUdata &cudata = interface->cudata_; if(finalform == DW_FORM_ref_sig8) { Dwarf_Sig8 val8; int res = dwarf_formsig8(interface->attr_,&val8, &error); if(res != DW_DLV_OK) { cerr << "Unable to read sig8 reference. Impossible error.\n" << endl; exit(1); } setSignature(&val8); return; } if(finalform == DW_FORM_ref_addr || finalform == DW_FORM_data4 || finalform == DW_FORM_data8) { // FIXME there might be a relocation record. int res = dwarf_global_formref(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read reference. Impossible error.\n" << endl; exit(1); } setOffset(val); return; } // Otherwise it is (if a correct FORM for a .debug_info reference) // a local CU offset, and we record it as such.. int res = dwarf_formref(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read reference.. Impossible error. finalform " << finalform << endl; exit(1); } setCUOffset(val); cudata.insertLocalReferenceAttrTargetRef(val,this); IRDie *targdie = cudata.getLocalDie(val); if (targdie) { // Record local offset's IRDie when it is already known. setTargetInDie(targdie); } } // Global static data used to initialized a sig8 reliably. static Dwarf_Sig8 zero_sig8; // Initialization helper function. void IRFormReference::initSig8() { typeSig8_ = zero_sig8; } IRFormString::IRFormString(IRFormInterface * interface) { char *str = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_STRING; strpoffset_=0; int res = dwarf_formstring(interface->attr_,&str, &error); if(res != DW_DLV_OK) { cerr << "Unable to read string. Impossible error.\n" << endl; exit(1); } setString(str); } libdwarf-20210528/dwarfgen/ChangeLog20170000664000175000017500000000206713644370703014371 000000000000002017-12-17 David Anderson * dwarfgen.1: The options to dwarfgen are now documented. 2017-10-20 David Anderson * createirepformfrombinary.cc,irepattrtodbg.cc, irepform.h, ireptodbg.cc: Added support for DW_FORM_data16. 2017-10-15 David Anderson * dwarfgen.cc,general.h,ireptodbg.cc: Moved global command-line options into a single global struct to clarify their use for a reader of the code. See 'cmdoptions'. 2017-08-21 David Anderson * config.h.in: Adding HAVE_LIBELF_LIBELF for consistency. * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc,ireptodbg.cc: Add ifdef HAVE_UNISTD_H. * dwarfgen.cc: Add ifdef HAVE_UNISTD_H, HAVE_LIBELF_LIBELF_H. Improve #ifdefs for Windows builds. 2017-04-21 David Anderson * dwarfgen.cc: Now supports -v with 2,3,4, or 5. 2017-04-20 David Anderson * dwarfgen.cc: Use dwoptarg. Not optarg. oops. 2017-04-20 David Anderson * dwarfgen.cc: Added new options allowing specification of the desired dwarf version. libdwarf-20210528/dwarfgen/dwarfgen.10000664000175000017500000000412013644370703014154 00000000000000.Dd $Mdocdate$ .Dt DWARFGEN \&1 "dwarfdump and libdwarf" .Os .Sh NAME .Nm dwarfgen .Nd generate example DWARF data. .Sh SYNOPSIS .Nm .Op Fl t Ar type .Op Fl o Ar outpath .Op Fl c cunum .Ar pathname . .Sh DESCRIPTION The .Nm creates DWARF sections as requested by specific options. .Pp Using some information source, create a tree of dwarf information (speaking of a DIE tree). Turn the die tree into dwarfdata using libdwarf producer and write the resulting data in an object file. It is a bit inconsistent in error handling just to demonstrate the various possibilities using the producer library. .Pp Main options: .Bl -tag -compact .It Fl t Ar type what sort of input to read. May be one of: .Bl -tag -compact .It Ar def means predefined (no input is read, the output is based on some canned setups built into dwarfgen). .Ar path is ignored in this case. This is the default, and does not work. .It Ar obj means .Ar path is the object file to read (The dwarf sections are duplicated in the output file.) Requires .Ar path . .It Ar txt .Ar path contains plain text (in a form rather like output by dwarfdump) that defines the dwarf that is to be output. Requires .Ar path . .El . .It Fl o Ar outpath specifies the pathname of the output object. If not supplied, .Pa testout.o is used as the default output path. . .It Fl c Ar cunum supplies a CU number of the .Ql obj .Ar type input to read . .\" not "output" ??? jkl because the dwarf producer wants just one CU. Default is -1 which won't match anything. .El .Pp Other options: .Bl -tag -compact .It Fl h transform high PC to const. .It Fl s output as text. .It Fl r show relocation details. .It Fl v Ar version DWARF version 2, 3, 4, or 5. .It Fl p Ar size pointer size, 4 or 8. .It Fl f Ar offset offset size, 4 or 8. .El . .\" .Sh ENVIRONMENT .\" For sections 1, 6, 7, and 8 only. .\" .Sh FILES .\" .Sh EXIT STATUS .\" For sections 1, 6, and 8 only. .\" .Sh EXAMPLES .\" .Sh DIAGNOSTICS .\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. .\" .Sh SEE ALSO .\" .Xr foobar 1 .\" .Sh STANDARDS .\" .Sh HISTORY .\" .Sh AUTHORS .\" .Sh CAVEATS .\" .Sh BUGS libdwarf-20210528/dwarfgen/Makefile.am0000664000175000017500000000215513653364312014336 00000000000000###Copyright (C) 2018 Vincent Torri clone(); } else { formdata_ = 0; } }; ~IRAttr() { delete formdata_; }; IRAttr & operator=( const IRAttr &r) { if(this == &r) { return *this; } attr_ = r.attr_; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; if(formdata_) { delete formdata_; formdata_ = r.formdata_->clone(); } else { formdata_ = r.formdata_->clone(); } return *this; } void setBaseData(Dwarf_Half attr, Dwarf_Half finalform, Dwarf_Half initialform){ attr_ = attr; finalform_ = finalform; initialform_ = initialform; }; void setFormClass(enum Dwarf_Form_Class cl) { formclass_ = cl; }; enum Dwarf_Form_Class getFormClass() const {return formclass_; }; void dropFormData() { if(formdata_) {delete formdata_; formdata_ = 0; }; } void setFormData(IRForm *f) { if (formdata_) { delete formdata_; formdata_ = 0; } formdata_ = f; }; Dwarf_Half getFinalForm() const { return initialform_; }; Dwarf_Half getDirectForm() const { return finalform_; }; Dwarf_Half getAttrNum() const { return attr_; }; IRForm * getFormData() { return formdata_;}; private: Dwarf_Half attr_; Dwarf_Half finalform_; // In most cases finalform == initialform form. // Otherwise, initialform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; IRForm *formdata_; }; class IRDie { public: IRDie():tag_(0),globalOffset_(0), cuRelativeOffset_(0), generatedDie_(0) {}; ~IRDie() {}; void addChild(const IRDie & newdie ) { children_.push_back(newdie); }; std::string getName() { std::list::iterator it = attrs_.begin(); for( ; it != attrs_.end() ; ++it) { if (it->getAttrNum() == DW_AT_name) { IRForm *f = it->getFormData(); const IRFormString * isv = dynamic_cast(f); if(isv) { return isv->getString(); } } } return ""; }; std::list & getAttributes() {return attrs_; }; std::list & getChildren() {return children_; }; bool hasNewestChild(IRDie **lastch) { size_t N = children_.size(); if(N < 1) { return false; } *lastch = &children_.back(); return true; }; // lastChild and lastAttr will throw if no entry exists. IRDie &lastChild() { return children_.back(); }; IRAttr &lastAttr() { return attrs_.back(); }; void setBaseData(Dwarf_Half tag,Dwarf_Unsigned goff, Dwarf_Unsigned cuoff) { tag_ = tag; globalOffset_=goff; cuRelativeOffset_ = cuoff; }; Dwarf_Unsigned getGlobalOffset() const { return globalOffset_;}; Dwarf_Unsigned getCURelativeOffset() const { return cuRelativeOffset_;}; void setGeneratedDie(Dwarf_P_Die p_die) { generatedDie_ = p_die;}; Dwarf_P_Die getGeneratedDie() const { return generatedDie_;}; unsigned getTag() {return tag_; } private: // We rely on the IRDie container being one which does not // invalidate pointers with addition/deletion. std::list children_; std::list attrs_; unsigned tag_; // The following are data from input. Dwarf_Unsigned globalOffset_; Dwarf_Unsigned cuRelativeOffset_; // the following is generated during output. Dwarf_P_Die generatedDie_; }; struct OffsetFormEntry { OffsetFormEntry(): off_(0),form_(0){}; OffsetFormEntry(Dwarf_Unsigned o, IRFormReference* f): off_(o),form_(f){}; ~OffsetFormEntry(){}; Dwarf_Unsigned off_; IRFormReference *form_; }; struct ClassReferenceFixupData { ClassReferenceFixupData(): dbg_(0), attrnum_(0), sourcedie_(0), target_(0) {} ~ClassReferenceFixupData(){}; ClassReferenceFixupData( Dwarf_P_Debug dbg, Dwarf_Half attrnum, Dwarf_P_Die sourcedie, IRDie *d): dbg_(dbg), attrnum_(attrnum), sourcedie_(sourcedie), target_(d) {}; Dwarf_P_Debug dbg_; // The source die and attrnum suffice because the definition of // DWARF guarantees only one attribute of any given attribute number // can exist on a given DIE. Dwarf_Half attrnum_; Dwarf_P_Die sourcedie_; IRDie *target_; }; class IRCUdata { public: IRCUdata(): cu_header_length_(0), abbrev_offset_(0), next_cu_header_offset_(0), version_stamp_(0), address_size_(0), length_size_(0), extension_size_(0), has_macrodata_(false), macrodata_offset_(0), has_linedata_(false), linedata_offset_(0), cudie_offset_(0) {}; IRCUdata(Dwarf_Unsigned len,Dwarf_Half version, Dwarf_Unsigned abbrev_offset, Dwarf_Half addr_size, Dwarf_Half length_size, Dwarf_Half extension_size, Dwarf_Unsigned next_cu_header UNUSEDARG): cu_header_length_(len), abbrev_offset_(abbrev_offset), next_cu_header_offset_(addr_size), version_stamp_(version), address_size_(addr_size), length_size_(length_size), extension_size_(extension_size), has_macrodata_(false), macrodata_offset_(0), has_linedata_(false), linedata_offset_(0), cudie_offset_(0) {}; ~IRCUdata() { }; bool hasMacroData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) { *offset_out = macrodata_offset_; *cudie_off = cudie_offset_; return has_macrodata_; } bool hasLineData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) { *offset_out = linedata_offset_; *cudie_off = cudie_offset_; return has_linedata_; } void setMacroData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) { has_macrodata_ = true; macrodata_offset_ = offset; cudie_offset_ = cudieoff; }; void setLineData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) { has_linedata_ = true; linedata_offset_ = offset; cudie_offset_ = cudieoff; }; IRDie & baseDie() { return cudie_; }; Dwarf_Half getVersionStamp() { return version_stamp_; }; Dwarf_Half getOffsetSize() { return length_size_; }; Dwarf_Unsigned getCUdieOffset() { return cudie_offset_; }; IRCULineData & getCULines() { return cu_lines_; }; void insertLocalDieOffset(Dwarf_Unsigned localoff,IRDie* dieptr) { cuOffInLocalToIRDie_[localoff] = dieptr; }; void insertLocalReferenceAttrTargetRef(Dwarf_Unsigned localoff, IRFormReference* attrptr) { cuOffInLocalToIRFormRef_.push_back(OffsetFormEntry(localoff, attrptr)); }; IRDie * getLocalDie(Dwarf_Unsigned localoff) { std::map::iterator pos; pos = cuOffInLocalToIRDie_.find(localoff); if(pos != cuOffInLocalToIRDie_.end()) { return pos->second; } return NULL; }; void insertClassReferenceFixupData(ClassReferenceFixupData &c) { classReferenceFixupList_.push_back(c); } void updateClassReferenceTargets(); std::string getCUName() { return cudie_.getName(); }; // Use cuOffInLocalToIRDie_ and // cuOffInLocalToIRAttr_ to update attr targets. void updateReferenceAttrDieTargets() { for(std::list::iterator it = cuOffInLocalToIRFormRef_.begin(); it != cuOffInLocalToIRFormRef_.end(); ++it) { IRFormReference* r = it->form_; IRDie * tdie = getLocalDie(it->off_); if(tdie) { r->setTargetInDie(tdie); } else { // Missing die in r // Should be impossible. } } } private: Dwarf_Unsigned cu_header_length_; Dwarf_Unsigned abbrev_offset_; Dwarf_Unsigned next_cu_header_offset_; Dwarf_Half version_stamp_; Dwarf_Half address_size_; Dwarf_Half length_size_; Dwarf_Half extension_size_; bool has_macrodata_; Dwarf_Unsigned macrodata_offset_; bool has_linedata_; Dwarf_Unsigned linedata_offset_; Dwarf_Unsigned cudie_offset_; IRCULineData cu_lines_; // If true, is 32bit dwarf,else 64bit. Gives the size of a reference. bool dwarf32bit_; IRDie cudie_; // Refers to cu-local offsets in the input CU and which DIE // in the input they target for this CU. // Used to find the target DIE for the IRAttrs // referenced by cuOffInLocalToIRAttr_ std::map cuOffInLocalToIRDie_; // Refers to IRAttrs which make a CU local reference // meaning CLASS_REFERENCE IRFormReference to a cu-local die // Once Input dies read in this and cuOffInLocalToIRDie_ // are used to update the IRAttr itself. std::list cuOffInLocalToIRFormRef_; // The data needed to get the Dwarf_P_Die set for // some class reference instances. std::list classReferenceFixupList_; }; class IRDInfo { public: IRDInfo() {}; ~IRDInfo() {}; IRCUdata &lastCU() { return cudata_.back(); } std::list& getCUData() {return cudata_; }; private: std::list cudata_; }; libdwarf-20210528/dwarfgen/irepframe.h0000664000175000017500000001431713644370703014431 00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepframe.h // class IRCie { public: IRCie(): cie_byte_length_(0), version_(0), code_alignment_factor_(1), data_alignment_factor_(1), return_address_register_rule_(0) {}; IRCie(Dwarf_Unsigned length, Dwarf_Unsigned version, const std::string &augmentation, Dwarf_Unsigned code_align, Dwarf_Signed data_align, Dwarf_Half return_reg_rule, const void * init_instrs, Dwarf_Unsigned instrs_len): cie_byte_length_(length), version_(version), augmentation_(augmentation), code_alignment_factor_(code_align), data_alignment_factor_(data_align), return_address_register_rule_(return_reg_rule) { const Dwarf_Small *x = reinterpret_cast(init_instrs); for(Dwarf_Unsigned i = 0; i < instrs_len; ++i) { initial_instructions_.push_back(x[i]); } } void insert_fde_index(unsigned i) { fde_index_.push_back(i); }; ~IRCie() {}; void get_basic_cie_data(Dwarf_Unsigned * version, std::string * aug, Dwarf_Unsigned * code_align, Dwarf_Signed * data_align, Dwarf_Half * ret_addr_reg) { *version = version_; *aug = augmentation_; *code_align = code_alignment_factor_; *data_align = data_alignment_factor_; *ret_addr_reg = return_address_register_rule_; } void get_init_instructions(Dwarf_Unsigned *len, void **bytes) { *len = initial_instructions_.size(); *bytes = reinterpret_cast(&initial_instructions_[0]); }; private: // Byte length 0 if not known yet. Dwarf_Unsigned cie_byte_length_; Dwarf_Unsigned version_; std::string augmentation_; Dwarf_Unsigned code_alignment_factor_; Dwarf_Signed data_alignment_factor_; Dwarf_Half return_address_register_rule_; std::vector initial_instructions_; // fde_index is the array of indexes into fdedata_ // that are fdes used by this cie. std::vector fde_index_; }; class IRFde { public: IRFde(): low_pc_(0), func_length_(0), cie_offset_(0), cie_index_(-1), fde_offset_(0) {}; IRFde(Dwarf_Addr low_pc,Dwarf_Unsigned func_length, Dwarf_Ptr fde_bytes, Dwarf_Unsigned fde_length, Dwarf_Off cie_offset,Dwarf_Signed cie_index_in, Dwarf_Off fde_offset): low_pc_(low_pc), func_length_(func_length), cie_offset_(cie_offset), cie_index_(cie_index_in), fde_offset_(fde_offset) { const Dwarf_Small *x = reinterpret_cast(fde_bytes); for(Dwarf_Unsigned i = 0; i < fde_length; ++i) { fde_bytes_.push_back(x[i]); } }; ~IRFde() {}; Dwarf_Unsigned cie_index() { return cie_index_; }; void get_fde_base_data(Dwarf_Addr *lowpc, Dwarf_Unsigned * funclen, Dwarf_Unsigned *cie_index_input) { *lowpc = low_pc_; *funclen = func_length_; *cie_index_input = cie_index_; }; void get_fde_instrs_into_ir(Dwarf_Ptr ip,Dwarf_Unsigned len ) { const Dwarf_Small *x = reinterpret_cast(ip); for(Dwarf_Unsigned i = 0; i < len; ++i) { fde_instrs_.push_back(x[i]); } }; void get_fde_instructions(Dwarf_Unsigned *len, void **bytes) { *len = fde_instrs_.size(); *bytes = reinterpret_cast(&fde_instrs_[0]); }; void fde_instrs () { }; private: Dwarf_Addr low_pc_; Dwarf_Unsigned func_length_; // fde_bytes_ may be empty if content bytes not yet created. std::vector fde_bytes_; // fde_instrs_ is simply a vector of bytes. // it might be good to actually parse the // instructions. std::vector fde_instrs_; // cie_offset may be 0 if not known yet. Dwarf_Off cie_offset_; // cie_index is the index in ciedata_ of // the applicable CIE. Begins with index 0. Dwarf_Signed cie_index_; // fde_offset may be 0 if not yet known. Dwarf_Off fde_offset_; }; class IRFrame { public: IRFrame() {}; ~IRFrame() {}; void insert_cie(IRCie &cie) { ciedata_.push_back(cie); } void insert_fde(IRFde &fdedata) { fdedata_.push_back(fdedata); unsigned findex = fdedata_.size() -1; Dwarf_Signed cindex = fdedata.cie_index(); if( cindex != -1) { IRCie & mycie = ciedata_[cindex]; mycie.insert_fde_index(findex); } } std::vector &get_cie_vec() { return ciedata_; }; std::vector &get_fde_vec() { return fdedata_; }; private: std::vector ciedata_; std::vector fdedata_; }; libdwarf-20210528/dwarfgen/irepattrtodbg.cc0000664000175000017500000003562414004054231015455 00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // irepattrtodbg.cc #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include // For BldName #include // iomanp for setw etc #include #include #include #include #include // For memset etc #include "general.h" #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "irepattrtodbg.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; using std::map; static Dwarf_Error error; static unsigned fakeaddrnum; // We are not going to 'validate' the FORM for this Attribute. // or this Die. We just assume that what we are handed is // what we are to produce. We do test the attribute // at times, partly to ensure we use as many of the dwarf_add_AT* // functions as possible. // Correctness/appropriateness must be evaluated elsewhere. void AddAttrToDie(Dwarf_P_Debug dbg, IRepresentation & Irep, IRCUdata &cu, Dwarf_P_Die outdie, UNUSEDARG IRDie & irdie, IRAttr &irattr) { int attrnum = irattr.getAttrNum(); enum Dwarf_Form_Class formclass = irattr.getFormClass(); // IRForm is an abstract base class. IRForm *form_a = irattr.getFormData(); int res = 0; switch(formclass) { case DW_FORM_CLASS_UNKNOWN: cerr << "ERROR AddAttrToDie: Impossible " "DW_FORM_CLASS_UNKNOWN, attrnum " <(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_ADDRESS " "cast fails, attrnum " <getAddress(); string symname = BldName("addrsym",fakeaddrnum++); Dwarf_Addr pcval = addr; ElfSymbols& es = Irep.getElfSymbols(); ElfSymIndex esi = es.addElfSymbol(pcval,symname); Dwarf_Unsigned sym_index = esi.getSymIndex(); // FIXME: we should allow for DW_FORM_indirect here. // Relocation later will fix value. Dwarf_P_Attribute a = 0; res = dwarf_add_AT_targ_address_c(dbg, outdie,attrnum,0,sym_index,&a,&error); if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_targ_address fails, attrnum " <(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_BLOCK/EXPRLOC " "cast fails, attrnum " <getBlockLen(); Dwarf_Small * block_data = f->getBlockBytes(); Dwarf_P_Attribute attrb =0; /* Always generates uleb followed by block, sets form based on output dwarf version. */ res = dwarf_add_AT_block_a(dbg,outdie,attrnum, block_data, block_len, &attrb, &error); if (res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_block_a: " " fails," " attrnum " << attrnum << " res "<< res << endl; } } break; case DW_FORM_CLASS_CONSTANT: { IRFormConstant *f = dynamic_cast(form_a); Dwarf_Half formv = f->getFinalForm(); // FIXME: Handle form indirect IRFormConstant::Signedness sn = f->getSignedness(); Dwarf_P_Attribute a = 0; if (formv == DW_FORM_data16) { Dwarf_Form_Data16 val = f->getData16Val(); res = dwarf_add_AT_data16(outdie, attrnum,&val,&a,&error); if (res != DW_DLV_OK) { cerr << "ERROR AddAttrToDie: " "dwarf_add_AT_ data16 class constant fails," " attrnum " << attrnum << " res "<getSignedVal(); res = dwarf_add_AT_implicit_const(outdie,attrnum, sval,&a,&error); if (res != DW_DLV_OK) { cerr << "ERROR AddAttrToDie: " "dwarf_add_AT_implicit_const fails," " attrnum " << attrnum << " res "<getSignedVal(); if (formv == DW_FORM_sdata) { res = dwarf_add_AT_any_value_sleb_a( outdie,attrnum, sval,&a,&error); } else { //cerr << "ERROR how can we know " // "a non-sdata const is signed?, attrnum " << // attrnum <getUnsignedVal(); if (formv == DW_FORM_udata) { res = dwarf_add_AT_any_value_uleb_a( outdie,attrnum, uval_i,&a,&error); } else { res = dwarf_add_AT_unsigned_const_a(dbg, outdie,attrnum, uval_i,&a,&error); } } if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_ class constant fails," << dwarf_errmsg(error) << " attrnum " << attrnum << " Continuing" << endl; } } break; case DW_FORM_CLASS_FLAG: { IRFormFlag *f = dynamic_cast(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_FLAG cast fails" ", attrnum " <getFlagVal(),&a,&error); if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_flag fails, attrnum " <(form_a); if (!r) { cerr << "ERROR Impossible DW_FORM_CLASS_REFERENCE cast fails, attrnum " <getReferenceType(); switch (reftype) { case IRFormReference::RT_NONE: cerr << "ERROR CLASS REFERENCE unknown reftype " <getTargetInDie(); Dwarf_P_Die targetoutdie = 0; if(targetofref) { targetoutdie = targetofref->getGeneratedDie(); } if(!targetoutdie) { if(!targetofref) { cerr << "ERROR CLASS REFERENCE targetdie of reference unknown" <getSignature(),&a,&error); if( res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_ref_sig8 fails, attrnum " << IToHex(attrnum) << endl; } } } } break; case DW_FORM_CLASS_STRING: { IRFormString *f = dynamic_cast(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_STRING cast fails, attrnum " <(f->getString().c_str()); switch(attrnum) { case DW_AT_name: res = dwarf_add_AT_name_a(outdie,mystr,&a,&error); break; case DW_AT_producer: res = dwarf_add_AT_producer_a(outdie,mystr,&a,&error); break; case DW_AT_comp_dir: res = dwarf_add_AT_comp_dir_a(outdie,mystr,&a,&error); break; default: res = dwarf_add_AT_string_a(dbg,outdie,attrnum,mystr, &a,&error); break; } if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_string fails, attrnum " <(formclass) <::iterator it = classReferenceFixupList_.begin(); it != classReferenceFixupList_.end(); ++it) { IRDie* d = it->target_; Dwarf_P_Die sourcedie = it->sourcedie_; Dwarf_P_Die targetdie = d->getGeneratedDie(); Dwarf_Error lerror = 0; int res = dwarf_fixup_AT_reference_die(it->dbg_, it->attrnum_,sourcedie,targetdie,&lerror); if(res != DW_DLV_OK) { cerr << "Improper dwarf_fixup_AT_reference_die call" << endl; } } } libdwarf-20210528/dwarfgen/dwarfgen.cc0000664000175000017500000013202614003360673014403 00000000000000/* Copyright (C) 2010-2019 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // dwarfgen.cc // // Using some information source, create a tree of dwarf // information (speaking of a DIE tree). // Turn the die tree into dwarfdata using libdwarf producer // and write the resulting data in an object file. // It is a bit inconsistent in error handling just to // demonstrate the various possibilities using the producer // library. // // dwarfgen [-t def|obj|txt] [-o outpath] [-c cunum] path // where -t means what sort of input to read // def means predefined (no input is read, the output // is based on some canned setups built into dwarfgen). // 'path' is ignored in this case. This is the default. // // obj means 'path' is required, it is the object file to // read (the dwarf sections are duplicated in the output file) // // txt means 'path' is required, path must contain plain text // (in a form rather like output by dwarfdump) // that defines the dwarf that is to be output. // // where -o means specify the pathname of the output object. If not // supplied testout.o is used as the default output path. // where -c supplies a CU number of the obj input to output // because the dwarf producer wants just one CU. // Default is -1 which won't match anything. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include //open #include "general.h" #include "dwgetopt.h" #ifdef HAVE_LIBELF_H // gelf.h is a GNU-only elf header, so not using it. #include "libelf.h" #elif HAVE_LIBELF_LIBELF_H #include "libelf/libelf.h" #endif #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "createirepfrombinary.h" #ifdef _WIN32 #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #endif /* _WIN32 */ #ifdef _WIN32 #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #endif #else /* !_WIN32 */ # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* !_WIN32 */ /* These are for a Windows environment */ #ifdef _WIN32 #ifdef _O_WRONLY #define O_WRONLY _O_WRONLY #endif #ifdef _O_CREAT #define O_CREAT _O_CREAT #endif #ifdef _O_TRUNC #define O_TRUNC _O_TRUNC #endif #ifdef _S_IREAD #define S_IREAD _S_IREAD #endif #ifdef _S_IWRITE #define S_IWRITE _S_IWRITE #endif /* open modes S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH */ #ifndef S_IRUSR #define S_IRUSR _S_IREAD #endif // S_IRUSR #ifndef S_IWUSR #define S_IWUSR _S_IWRITE #endif #ifndef S_IRGRP #define S_IRGRP 0 #endif #ifndef S_IROTH #define S_IROTH 0 #endif #endif /* _WIN32 */ using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; extern "C" { static int CallbackFunc( const char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_symbol_index, void * user_data, int* error); } // End extern "C" static void create_debug_sup_content(Dwarf_P_Debug dbg); // FIXME. This is incomplete. See FIXME just below here. #ifdef WORDS_BIGENDIAN static void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len) { unsigned char *targ = (unsigned char *) s1; const unsigned char *src = (const unsigned char *) s2; if (len == 4) { targ[3] = src[0]; targ[2] = src[1]; targ[1] = src[2]; targ[0] = src[3]; } else if (len == 8) { targ[7] = src[0]; targ[6] = src[1]; targ[5] = src[2]; targ[4] = src[3]; targ[3] = src[4]; targ[2] = src[5]; targ[1] = src[6]; targ[0] = src[7]; } else if (len == 2) { targ[1] = src[0]; targ[0] = src[1]; } /* should NOT get below here: is not the intended use */ else if (len == 1) { targ[0] = src[0]; } else { memcpy(s1, s2, (size_t)len); } return; } #endif /* WORDS_BIGENDIAN */ // There are issues 32/64 here, and endianness. // We are asserting here in dwarfgen that the target // object created is to be DW_DLC_TARGET_LITTLEENDIAN. // FIXME. not general. // op and ol aread MUST NOT overlap. // ip and il should be 2,4,or 8. Nothing else. // These could perfectly well be functions. #ifdef WORDS_BIGENDIAN #define ASNX(op,ol,ip,il) \ do { \ if( ol > il) { \ unsigned sbyte = 0; \ memset(op,0,ol); \ sbyte = ol - il; \ _dwarf_memcpy_swap_bytes(((char *)(op))+sbyte,\ (const void *)(ip),il);\ } else { \ unsigned sbyte = 0; \ sbyte = il - ol; \ _dwarf_memcpy_swap_bytes((char *)(op), \ (const void *)(((const char *)(ip))+sbyte),ol);\ } \ } while (0) #else // LITTLEENDIAN #define ASNX(op,ol,ip,il) \ do { \ if( ol > il) { \ memset(op,0,ol); \ memcpy(((char *)(op)),(const void *)(ip),il);\ } else { \ memcpy((char *)(op), \ (const void *)(((const char *)(ip))),ol);\ } \ } while (0) #endif // ENDIANNESS static void write_object_file(Dwarf_P_Debug dbg, IRepresentation &irep, unsigned machine, unsigned endian, unsigned long dwbitflags, void * user_data); static void write_text_section(Elf * elf,unsigned elfclass); static void write_generated_dbg(Dwarf_P_Debug dbg,Elf * elf, IRepresentation &irep); static string outfile("testout.o"); static string infile; static enum WhichInputSource { OptNone, OptReadText,OptReadBin,OptPredefined} whichinput(OptPredefined); /* Use a generic call to open the file, due to issues with Windows */ int open_a_file(const char * name); int create_a_file(const char * name); void close_a_file(int f); // This is a global so thet CallbackFunc can get to it // If we used the dwarf_producer_init_c() user_data pointer // creatively we would not need a global. static IRepresentation Irep; static Elf * elf = 0; static strtabdata secstrtab; CmdOptions cmdoptions = { false, //transformHighpcToConst DW_FORM_string, // defaultInfoStringForm false, //showrelocdetails false, //adddata16 false, //addimplicitconst false, //addframeadvanceloc false, //addSUNfuncoffsets false, //add_debug_sup false //addskipbranch }; // loff_t is signed for some reason (strange) but we make offsets unsigned. #define LOFFTODWUNS(x) ( (Dwarf_Unsigned)(x)) /* See the Elf ABI for further definitions of these fields. */ class SectionFromDwarf { public: std::string name_; Dwarf_Unsigned section_name_itself_; ElfSymIndex section_name_symidx_; int size_; Dwarf_Unsigned type_; Dwarf_Unsigned flags_; /* type: SHT_REL, RELA: Section header index of the section relocation applies to. SHT_SYMTAB: Section header index of the associated string table. */ Dwarf_Unsigned link_; /* type: SHT_REL, RELA: Section header index of the section relocation applies to. SHT_SYMTAB: One greater than index of the last local symbol.. */ Dwarf_Unsigned info_; private: ElfSectIndex elf_sect_index_; Dwarf_Unsigned lengthWrittenToElf_; public: Dwarf_Unsigned getNextOffset() { return lengthWrittenToElf_; } void setNextOffset(Dwarf_Unsigned v) { lengthWrittenToElf_ = v; } unsigned getSectionNameSymidx() { return section_name_symidx_.getSymIndex(); }; SectionFromDwarf():section_name_itself_(0), section_name_symidx_(0), size_(0),type_(0),flags_(0), link_(0), info_(0), elf_sect_index_(0), lengthWrittenToElf_(0) {} ; ~SectionFromDwarf() {}; void setSectIndex(ElfSectIndex v) { elf_sect_index_ = v;} ElfSectIndex getSectIndex() const { return elf_sect_index_;} SectionFromDwarf(const std::string&name, int size,Dwarf_Unsigned type,Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info): name_(name), size_(size),type_(type),flags_(flags), link_(link), info_(info), elf_sect_index_(0), lengthWrittenToElf_(0) { // Now create section name string section. section_name_itself_ = secstrtab.addString(name.c_str()); ElfSymbols& es = Irep.getElfSymbols(); // Now creat a symbol for the section name. // (which has its own string table) section_name_symidx_ = es.addElfSymbol(0,name); } ; }; vector dwsectab; static ElfSectIndex create_dw_elf(SectionFromDwarf &ds,unsigned elfclass); static SectionFromDwarf & FindMySection(const ElfSectIndex & elf_section_index) { for(unsigned i =0; i < dwsectab.size(); ++i) { if(elf_section_index.getSectIndex() != dwsectab[i].getSectIndex().getSectIndex()) { continue; } return dwsectab[i]; } cerr << "dwarfgen: Unable to find my dw sec data for elf section " << elf_section_index.getSectIndex() << endl; exit(1); } static int FindMySectionNum(const ElfSectIndex & elf_section_index) { for(unsigned i =0; i < dwsectab.size(); ++i) { if(elf_section_index.getSectIndex() != dwsectab[i].getSectIndex().getSectIndex()) { continue; } return i; } cerr << "dwarfgen: Unable to find my dw sec index for elf section " << elf_section_index.getSectIndex() << endl; exit(1); } static unsigned createnamestr(unsigned strtabstroff,unsigned elfclass) { Elf_Scn * strscn =elf_newscn(elf); if(!strscn) { cerr << "dwarfgen: Unable to elf_newscn() on " << outfile << endl; exit(1); } Elf_Data* shstr =elf_newdata(strscn); if(!shstr) { cerr << "dwarfgen: Unable to elf_newdata() on " << outfile << endl; exit(1); } shstr->d_buf = secstrtab.exposedata(); shstr->d_type = ELF_T_BYTE; shstr->d_size = secstrtab.exposelen(); shstr->d_off = 0; shstr->d_align = 1; shstr->d_version = EV_CURRENT; if (elfclass == ELFCLASS32) { Elf32_Shdr * strshdr = elf32_getshdr(strscn); if(!strshdr) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } strshdr->sh_name = strtabstroff; strshdr->sh_type= SHT_STRTAB; strshdr->sh_flags = SHF_STRINGS; strshdr->sh_addr = 0; strshdr->sh_offset = 0; strshdr->sh_size = 0; strshdr->sh_link = 0; strshdr->sh_info = 0; strshdr->sh_addralign = 1; strshdr->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * strshdr = elf64_getshdr(strscn); if(!strshdr) { cerr << "dwarfgen: Unable to elf64_getshdr() on " << outfile << endl; exit(1); } strshdr->sh_name = strtabstroff; strshdr->sh_type= SHT_STRTAB; strshdr->sh_flags = SHF_STRINGS; strshdr->sh_addr = 0; strshdr->sh_offset = 0; strshdr->sh_size = 0; strshdr->sh_link = 0; strshdr->sh_info = 0; strshdr->sh_addralign = 1; strshdr->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } return elf_ndxscn(strscn); } // This functional interface is defined by libdwarf. // Please see the comments in libdwarf2p.1.pdf // (libdwarf2p.1.mm) on this callback interface. // Returns (to libdwarf) an Elf section number, so // since 0 is always empty and dwarfgen sets 1 to be a fake // text section on the first call this returns 2, second 3, etc. static int CallbackFunc( const char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_symbol_index, void * user_data, int* error UNUSEDARG) { // Create an elf section. // If the data is relocations, we suppress the generation // of a section when we intend to do the relocations // ourself (fine for dwarfgen but would // be really surprising for a normal compiler // back end using the producer code). // The section name appears both in the section strings // .shstrtab and // in the elf symtab .symtab and its strings .strtab. unsigned elfclass = 0; if (user_data) { elfclass = *(unsigned *)user_data; } else { cerr << "We created an internal-to-dwarfgen bug here. " << " line " << __LINE__ << " " <<__FILE__ << endl; exit(1); } if (0 == strncmp(name,".rel",4)) { // It is relocation, create no section! return 0; } SectionFromDwarf ds(name,size,type,flags,link,info) ; // It is up to you to provide (to libdwarf, // to generate relocation records) // a symbol index for the section. // In Elf, each section gets an elf symbol table entry. // So that relocations have an address to refer to. // You will create the Elf symbol table, so you have to tell // libdwarf the index to put into relocation records for the // section newly defined here. *sect_name_symbol_index = ds.getSectionNameSymidx(); ElfSectIndex createdsec = create_dw_elf(ds,elfclass); // Do all the data creation before pushing // (copying) ds onto dwsectab! dwsectab.push_back(ds); // The number returned is elf section, not dwsectab[] index return createdsec.getSectIndex(); } // Here we create a new Elf section // This never happens for relocations in dwarfgen, // only a few sections are created by dwarfgen. static ElfSectIndex create_dw_elf(SectionFromDwarf &ds,unsigned elfclass) { Elf_Scn * scn =elf_newscn(elf); if(!scn) { cerr << "dwarfgen: Unable to elf_newscn() on " << ds.name_ << endl; exit(1); } if (elfclass == ELFCLASS32) { Elf32_Shdr * shdr = elf32_getshdr(scn); if(!shdr) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << ds.name_ << endl; exit(1); } shdr->sh_name = ds.section_name_itself_; shdr->sh_type = ds.type_; shdr->sh_flags = ds.flags_; shdr->sh_addr = 0; shdr->sh_offset = 0; shdr->sh_size = ds.size_; shdr->sh_link = ds.link_; shdr->sh_info = ds.info_; shdr->sh_addralign = 1; shdr->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * shdr = elf64_getshdr(scn); if(!shdr) { cerr << "dwarfgen: Unable to elf64_getshdr() on " << ds.name_ << endl; exit(1); } shdr->sh_name = ds.section_name_itself_; shdr->sh_type = ds.type_; shdr->sh_flags = ds.flags_; shdr->sh_addr = 0; shdr->sh_offset = 0; shdr->sh_size = ds.size_; shdr->sh_link = ds.link_; shdr->sh_info = ds.info_; shdr->sh_addralign = 1; shdr->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } ElfSectIndex si(elf_ndxscn(scn)); ds.setSectIndex(si); cout << "New Elf section: "<< ds.name_ << " Type="<< ds.type_ << " Flags="<< ds.flags_ << " Elf secnum="<< si.getSectIndex() << " link section=" << ds.link_<< " info=" << ds.info_ << endl ; return si; } static void setinput(enum WhichInputSource *src, const string &type, bool *pathreq) { if(type == "txt") { *src = OptReadText; *pathreq = true; return; } else if (type == "obj") { *src = OptReadBin; *pathreq = true; return; } else if (type == "def") { *src = OptPredefined; *pathreq = false; return; } cout << "dwarfgen: Giving up, only txt obj or def accepted after -t" << endl; exit(1); } int main(int argc, char **argv) { try { int opt; bool pathrequired(false); long cu_of_input_we_output = -1; bool force_empty_dnames = false; // Overriding macro constants from pro_line.h // so we can choose at runtime // and avoid modifying header files. // This is the original set of constants // used for testing. // see also output_v4_test (--output-v4-test // longopt). const char *dwarf_extras ="opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4"; int endian = DW_DLC_TARGET_LITTLEENDIAN; const char *dwarf_version = "V2"; const char * isa_name = "x86"; unsigned long ptrsizeflagbit = DW_DLC_POINTER32; unsigned long dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; /* DW_DLC_ELF_OFFSET_SIZE 32/64 winds up determining the ELFCLASS 32/64 in write_object_file() */ unsigned long elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_32; unsigned machine = EM_386; /* from elf.h */ int output_v4_test = 0; unsigned global_elfclass = 0; int longindex; static struct dwoption longopts[] = { {"adddata16",dwno_argument,0,1000}, {"force-empty-dnames",dwno_argument,0,1001}, {"add-implicit-const",dwno_argument,0,1002}, {"add-frame-advance-loc",dwno_argument,0,1003}, {"add-sun-func-offsets",dwno_argument,0,1004}, {"add-debug-sup",dwno_argument,0,1006}, {"output-pointer-size",dwrequired_argument,0,'p'}, {"output-offset-size",dwrequired_argument,0,'f'}, {"output-dwarf-version",dwrequired_argument,0,'v'}, {"output-v4-test",dwno_argument,0,1005}, {"default-form-strp",dwno_argument,0,'s'}, {"show-reloc-details",dwno_argument,0,'r'}, {"high-pc-as-const",dwno_argument,0,'h'}, {"add-skip-branch-ops",dwno_argument,0,1007}, {0,0,0,0}, }; // -p is pointer size // -f is offset size, overriding the above // -v is version number for dwarf output while((opt=dwgetopt_long(argc,argv, "o:t:c:hsrv:p:f:", longopts,&longindex)) != -1) { switch(opt) { case 1000: if(longindex == 0) { // To test adding the DWARF5 // DW_FORM_data16 // libdwarf reading is thus testable. cmdoptions.adddata16 = true; } else { cerr << "dwarfgen: Invalid lnogoption input " << longindex << endl; exit(1); } break; case 1001: // To test having an empty .debug_dnames // section. // libdwarf reading is thus testable. force_empty_dnames = true; break; case 1002: // To test creating DWARF5 // DW_FORM_implicit_const. // libdwarf reading is thus testable. cmdoptions.addimplicitconst = true; break; case 1003: // To test dwarf_add_fde_inst_a(). // libdwarf reading is thus testable. cmdoptions.addframeadvanceloc = true; break; case 1004: //{"add-sun-func-offsets",dwno_argument,0,1004}, // To test creating DWARF5 // DW_AT_SUN_func_offsets. // libdwarf reading is thus testable. cmdoptions.addSUNfuncoffsets = true; break; case 1005: //{"output-v4-test",dwno_argument,0,1005} output_v4_test = 1; break; case 1006: //{"add-debug-sup",dwno_argument,0,1006} cmdoptions.adddebugsup = true; break; case 1007: //{"add-skip-branch-ops",dwno_argument,0,1007}, cmdoptions.addskipbranch = true; break; case 'c': // At present we can only create a single // cu in the output of the libdwarf producer. cu_of_input_we_output = atoi(dwoptarg); break; case 'r': cmdoptions.showrelocdetails=true; break; case 's': // --default-form-strp cmdoptions.defaultInfoStringForm = DW_FORM_strp; break; case 'p': /* pointer size: value 4 or 8. */ if (!strcmp("4",dwoptarg)) { ptrsizeflagbit = DW_DLC_POINTER32; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_32; } else if (!strcmp("8",dwoptarg)) { ptrsizeflagbit = DW_DLC_POINTER64; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_64; } else { cerr << "dwarfgen: Invalid p option input " << dwoptarg << endl; exit(1); } break; case 'f': /* offset size for DWARF: value 4 or 8. */ if (!strcmp("4",dwoptarg)) { dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; } else if (!strcmp("8",dwoptarg)) { dwarfoffsetsizeflagbit = DW_DLC_OFFSET64; } else { cerr << "dwarfgen: Invalid f option input " << dwoptarg << endl; exit(1); } break; case 'v': /* Version 2 3 4 or 5 */ if (!strcmp("5",dwoptarg)) { dwarf_version = "V5"; } else if (!strcmp("4",dwoptarg)) { dwarf_version = "V4"; } else if (!strcmp("3",dwoptarg)) { dwarf_version = "V3"; } else if (!strcmp("2",dwoptarg)) { dwarf_version = "V2"; } else { cerr << "dwarfgen: Invalid v option input " << dwoptarg << endl; exit(1); } break; case 't': setinput(&whichinput,dwoptarg,&pathrequired); break; case 'h': cmdoptions.transformHighpcToConst = true; break; case 'o': outfile = dwoptarg; break; case '?': cerr << "dwarfgen: Invalid quest? option input " << endl; exit(1); default: cerr << "dwarfgen: Invalid option input " << endl; exit(1); } } if ( (dwoptind >= argc) && pathrequired) { cerr << "dwarfgen: Expected argument after options!" " Giving up." << endl; exit(EXIT_FAILURE); } if(pathrequired) { infile = argv[dwoptind]; } if (output_v4_test) { dwarf_extras ="opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4"; endian = DW_DLC_TARGET_LITTLEENDIAN; dwarf_version = "V4"; isa_name = "x86_64"; ptrsizeflagbit = DW_DLC_POINTER64; dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_64; machine = EM_X86_64; /* from elf.h */ } if(whichinput == OptReadBin) { createIrepFromBinary(infile,Irep); } else if (whichinput == OptReadText) { cerr << "dwarfgen: dwarfgen: text read not supported yet" << endl; exit(EXIT_FAILURE); } else if (whichinput == OptPredefined) { cerr << "dwarfgen: predefined not supported yet" << endl; exit(EXIT_FAILURE); } else { cerr << "dwarfgen: Impossible: unknown input style." << endl; exit(EXIT_FAILURE); } // We no longer use the libdwarf interfaces returning // DW_DLV_BADADDR (though they still exist in libdwarf) // as that sort of return (mixing returned-pointer with // an error value) was ugly. // We use the latest calls instead, returning // DW_DLV_OK, DW_DLV_NO_ENTRY, or DW_DLV_ERROR // as an int. Dwarf_Ptr errarg = 0; Dwarf_Error err = 0; // The point of user_data is, as here, to // have crucial data available to the callback // function implementation. void *user_data = &global_elfclass; Dwarf_P_Debug dbg = 0; unsigned long dwbitflags = DW_DLC_WRITE| endian | ptrsizeflagbit| elfoffsetsizeflagbit| dwarfoffsetsizeflagbit| DW_DLC_SYMBOLIC_RELOCATIONS; // We use DW_DLC_SYMBOLIC_RELOCATIONS so we can // read the relocations and do our own relocating. // See calls of dwarf_get_relocation_info(). int res = dwarf_producer_init( dwbitflags, CallbackFunc, 0, // errhand errarg, user_data, isa_name, dwarf_version, dwarf_extras, &dbg, &err); if(res == DW_DLV_NO_ENTRY) { cerr << "dwarfgen: Failed dwarf_producer_init() NO_ENTRY" << endl; exit(EXIT_FAILURE); } if(res == DW_DLV_ERROR) { cerr << "dwarfgen: Failed dwarf_producer_init() ERROR" << endl; cerr << "dwarfgen errmsg " << dwarf_errmsg(err)<e_ident[EI_MAG0] = ELFMAG0; ehp->e_ident[EI_MAG1] = ELFMAG1; ehp->e_ident[EI_MAG2] = ELFMAG2; ehp->e_ident[EI_MAG3] = ELFMAG3; ehp->e_ident[EI_CLASS] = elfclass; ehp->e_ident[EI_DATA] = elfendian; ehp->e_ident[EI_VERSION] = EV_CURRENT; ehp->e_machine = machine; // We do not bother to create program headers, so // mark this as ET_REL. ehp->e_type = ET_REL; ehp->e_version = EV_CURRENT; unsigned strtabstroff = secstrtab.addString(".shstrtab"); // an object section with fake .text data (just as an example). write_text_section(elf,elfclass); write_generated_dbg(dbg,elf,irep); // Create the section name string section. unsigned shstrindex = createnamestr(strtabstroff,elfclass); ehp->e_shstrndx = shstrindex; } else { #ifdef HAVE_ELF64_GETEHDR static Elf64_Ehdr * ehp = 0; ehp = elf64_newehdr(elf); if(!ehp) { cerr << "dwarfgen: Unable to elf64_newehdr() on " << outfile << endl; exit(1); } ehp->e_ident[EI_MAG0] = ELFMAG0; ehp->e_ident[EI_MAG1] = ELFMAG1; ehp->e_ident[EI_MAG2] = ELFMAG2; ehp->e_ident[EI_MAG3] = ELFMAG3; ehp->e_ident[EI_CLASS] = elfclass; ehp->e_ident[EI_DATA] = elfendian; ehp->e_ident[EI_VERSION] = EV_CURRENT; ehp->e_machine = machine; // We do not bother to create program headers, so // mark this as ET_REL. ehp->e_type = ET_REL; ehp->e_version = EV_CURRENT; unsigned strtabstroff = secstrtab.addString(".shstrtab"); // an object section with fake .text data (just as an example). write_text_section(elf,elfclass); write_generated_dbg(dbg,elf,irep); // Create the section name string section. unsigned shstrindex = createnamestr(strtabstroff,elfclass); ehp->e_shstrndx = shstrindex; #endif // HAVE_ELF64_GETEHDR } // Get it all written to the output file. off_t ures = elf_update(elf,cmd); if(ures == (off_t)(-1LL)) { cerr << "dwarfgen: Unable to elf_update() on " << outfile << endl; int eer = elf_errno(); cerr << "Error is " << eer << " " << elf_errmsg(eer) << endl; exit(1); } cout << " output image size in bytes " << ures << endl; elf_end(elf); close_a_file(fd); } // an object section with fake .text data (just as an example). static void write_text_section(Elf * elf_w,unsigned elfclass) { unsigned osecnameoff = secstrtab.addString(".text"); Elf_Scn * scn1 =elf_newscn(elf_w); if(!scn1) { cerr << "dwarfgen: Unable to elf_newscn() on " << outfile << endl; exit(1); } Elf_Data* ed1 =elf_newdata(scn1); if(!ed1) { cerr << "dwarfgen: Unable to elf_newdata() on " << outfile << endl; exit(1); } const char *d = "data in section"; ed1->d_buf = (void *)d; ed1->d_type = ELF_T_BYTE; ed1->d_size = strlen(d) +1; ed1->d_off = 0; ed1->d_align = 4; ed1->d_version = EV_CURRENT; if (elfclass == ELFCLASS32) { Elf32_Shdr * shdr1 = elf32_getshdr(scn1); if(!shdr1) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } shdr1->sh_name = osecnameoff; shdr1->sh_type= SHT_PROGBITS; shdr1->sh_flags = 0; shdr1->sh_addr = 0; shdr1->sh_offset = 0; shdr1->sh_size = 0; shdr1->sh_link = 0; shdr1->sh_info = 0; shdr1->sh_addralign = 1; shdr1->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * shdr1 = elf64_getshdr(scn1); if(!shdr1) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } shdr1->sh_name = osecnameoff; shdr1->sh_type= SHT_PROGBITS; shdr1->sh_flags = 0; shdr1->sh_addr = 0; shdr1->sh_offset = 0; shdr1->sh_size = 0; shdr1->sh_link = 0; shdr1->sh_info = 0; shdr1->sh_addralign = 1; shdr1->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } } static void InsertDataIntoElf(Dwarf_Signed d,Dwarf_P_Debug dbg,Elf *elf_i) { Dwarf_Signed elf_section_index = 0; Dwarf_Unsigned length = 0; Dwarf_Ptr bytes = dwarf_get_section_bytes(dbg,d, &elf_section_index,&length,0); Elf_Scn *scn = elf_getscn(elf_i,elf_section_index); if(!scn) { cerr << "dwarfgen: Unable to elf_getscn on disk transform # " << d << endl; exit(1); } ElfSectIndex si(elf_section_index); SectionFromDwarf & sfd = FindMySection(si); Elf_Data* ed =elf_newdata(scn); if(!ed) { cerr << "dwarfgen: elf_newdata died on transformed index " << d << endl; exit(1); } ed->d_buf = bytes; ed->d_type = ELF_T_BYTE; ed->d_size = length; ed->d_off = sfd.getNextOffset(); sfd.setNextOffset(ed->d_off + length); ed->d_align = 1; ed->d_version = EV_CURRENT; cout << "Inserted " << length << " bytes into elf section index " << elf_section_index << endl; } #if 0 static string printable_rel_type(unsigned char reltype) { enum Dwarf_Rel_Type t = (enum Dwarf_Rel_Type)reltype; switch(t) { case dwarf_drt_none: return "dwarf_drt_none"; case dwarf_drt_data_reloc: return "dwarf_drt_data_reloc"; case dwarf_drt_segment_rel: return "dwarf_drt_segment_rel"; case dwarf_drt_first_of_length_pair: return "dwarf_drt_first_of_length_pair"; case dwarf_drt_second_of_length_pair: return "dwarf_drt_second_of_length_pair"; default: break; } return "drt-unknown (impossible case)"; } #endif static Dwarf_Unsigned FindSymbolValue(ElfSymIndex symi,IRepresentation &irep) { ElfSymbols & syms = irep.getElfSymbols(); ElfSymbol & es = syms.getElfSymbol(symi); Dwarf_Unsigned symv = es.getSymbolValue(); return symv; } #if 0 static int dump_bytes(const char *msg,void *val,int len) { char *p = (char *)val; int i = 0; cout << msg << " "; for (; i < len; ++i) { char x = *(p+i); cout << IToHex(x,2) <<" "; } cout << endl; } #endif /* Lets not assume that the quantities are aligned. */ static void bitreplace(char *buf, Dwarf_Unsigned newval, size_t newvalsize UNUSEDARG, int length) { if(length == 4) { Dwarf_Unsigned my4 = newval; Dwarf_Unsigned oldval = 0; ASNX(&oldval,sizeof(oldval),buf,(unsigned)length); oldval += my4; ASNX(buf,(unsigned)length,&oldval,sizeof(oldval)); } else if (length == 8) { Dwarf_Unsigned my8 = newval; Dwarf_Unsigned oldval = 0; memcpy(&oldval,buf,length); oldval += my8; memcpy(buf,&oldval,length); } else { cerr << "dwarfgen: Relocation is length " << length << " which we do not yet handle." << endl; exit(1); } } // This remembers nothing, so is dreadfully slow. static char * findelfbuf(Elf *elf_f UNUSEDARG ,Elf_Scn *scn, Dwarf_Unsigned offset, unsigned length) { Elf_Data * edbase = 0; Elf_Data * ed = elf_getdata(scn,edbase); unsigned bct = 0; for (;ed; ed = elf_getdata(scn,ed)) { bct++; if(offset >= LOFFTODWUNS(ed->d_off + ed->d_size) ) { continue; } if(offset < LOFFTODWUNS(ed->d_off)) { cerr << "dwarfgen: Relocation at offset " << offset << " cannot be accomplished, no buffer. " << endl; exit(1); } Dwarf_Unsigned localoff = offset - ed->d_off; if((localoff + length) > ed->d_size) { cerr << "dwarfgen: Relocation at offset " << offset << " cannot be accomplished, size mismatch. " << endl; exit(1); } char *lclptr = reinterpret_cast(ed->d_buf) + localoff; return lclptr; } cerr << " Relocation at offset " << offset << " cannot be accomplished, past end of buffers" << endl; return 0; } static void write_generated_dbg(Dwarf_P_Debug dbg,Elf * elf_w, IRepresentation &irep) { Dwarf_Error err = 0; Dwarf_Signed sectioncount = 0; int res = dwarf_transform_to_disk_form_a(dbg,§ioncount,&err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { string msg(dwarf_errmsg(err)); cerr << "Dwarfgen fails: " << msg << endl; exit(1); } /* ASSERT: rex == DW_DLV_NO_ENTRY */ cerr << "Dwarfgen fails, some internal error " << endl; exit(1); } Dwarf_Signed d = 0; for(d = 0; d < sectioncount ; ++d) { InsertDataIntoElf(d,dbg,elf_w); } // Since we are emitting in final form sometimes, we may // do relocation processing here or we could (but do not) // emit relocation records into the object file. // The following is for DW_DLC_SYMBOLIC_RELOCATIONS. Dwarf_Unsigned reloc_sections_count = 0; int drd_version = 0; res = dwarf_get_relocation_info_count(dbg,&reloc_sections_count, &drd_version,&err); if( res != DW_DLV_OK) { cerr << "dwarfgen: Error getting relocation info count." << endl; exit(1); } cout << "Relocations sections count= " << reloc_sections_count << " relversion=" << drd_version << endl; for( Dwarf_Unsigned ct = 0; ct < reloc_sections_count ; ++ct) { // elf_section_index is the elf index of the // section to be relocated, and the section number // in the object file which we are creating. // In dwarfgen we do not use this as we do not create // relocation sections. Here it is always zero. Dwarf_Signed elf_section_index = 0; // elf_section_index_link is the elf index of the // section the relocations apply to, such as .debug_info. // An elf index, not dwsectab[] index. Dwarf_Signed elf_section_index_link = 0; // relocation_buffer_count is the number of relocations // of this section. Dwarf_Unsigned relocation_buffer_count = 0; Dwarf_Relocation_Data reld; res = dwarf_get_relocation_info(dbg,&elf_section_index, &elf_section_index_link, &relocation_buffer_count, &reld,&err); // elf_section_index_link // refers to the output section numbers, not to dwsectab. if (res != DW_DLV_OK) { cerr << "dwarfgen: Error getting relocation record " << ct << "." << endl; exit(1); } int dwseclink = FindMySectionNum(elf_section_index_link); ElfSectIndex sitarg = dwsectab[dwseclink].getSectIndex(); string linktarg= dwsectab[dwseclink].name_; long int targsec = sitarg.getSectIndex(); cout << "Relocs for sec=" << ct << " ourlinkto=" << elf_section_index_link << " linktoobjsecnum=" << targsec << " name=" << linktarg << " reloc-count=" << relocation_buffer_count << endl; Elf_Scn *scn = elf_getscn(elf_w,elf_section_index_link); if(!scn) { cerr << "dwarfgen: Unable to elf_getscn # " << elf_section_index_link << endl; exit(1); } for (Dwarf_Unsigned r = 0; r < relocation_buffer_count; ++r) { Dwarf_Relocation_Data rec = reld+r; ElfSymIndex symi(rec->drd_symbol_index); Dwarf_Unsigned newval = FindSymbolValue(symi,irep); char *buf_to_update = findelfbuf(elf_w,scn, rec->drd_offset,rec->drd_length); if(buf_to_update) { if(cmdoptions.showrelocdetails) { cout << "Reloc "<< r << " symindex=" << rec->drd_symbol_index << " targoffset= " << IToHex(rec->drd_offset) << " newval = " << IToHex(newval) << endl; } bitreplace(buf_to_update, newval,sizeof(newval), rec->drd_length); } else { if(cmdoptions.showrelocdetails) { cout << "Reloc "<< r << "does nothing"< #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "irepattrtodbg.h" #include "general.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::map; using std::list; using std::map; static Dwarf_Error error; typedef std::map pathToUnsignedType; // This set of operations is meaningless. const int skipscount = 10; struct Skips { Dwarf_Small opcode; Dwarf_Signed sval1; Dwarf_Unsigned uval2; } skips[10] = { { DW_OP_breg3,-4,0}, { DW_OP_dup,0,0}, { DW_OP_const4s,-1000,0}, { DW_OP_dup,0,0}, { DW_OP_const4s,4000,0}, { DW_OP_swap,0,0}, { DW_OP_skip,-1,0}, //This will be an error for dwarfdump to note, //not usable offset. { DW_OP_bra,2,0}, //This will be an error for dwarfdump to note, // not usable offset. { DW_OP_const4s,-6000,0}, { DW_OP_const4s,8000,0}, }; static int createskipbranchblock( Dwarf_P_Debug dbg, Dwarf_Block &bl) { Dwarf_P_Expr ex = 0; int res = 0; Dwarf_Unsigned stream_len = 0; error = 0; res = dwarf_new_expr_a(dbg,&ex, &error); if (res != DW_DLV_OK) { cout << "FAIL dwarf_new_expr_a createskipbranchblock " <opcode, sp->sval1,sp->uval2,&stream_len,&error); if (res != DW_DLV_OK) { cout << "FAIL dwarf_add_expr_gen_a createskipbranchblock " << dwarf_errmsg(error) << endl; error = 0; return res; } } Dwarf_Unsigned exlen = 0; Dwarf_Small * exptr = 0; res = dwarf_expr_into_block_a(ex, &exlen,&exptr,&error); if (res != DW_DLV_OK) { cout << "FAIL dwarf_expr_into_block_a createskipbranchblock" <& attrs, unsigned level UNUSEDARG) { static int done = false; if (!cmdoptions.addskipbranch) { // No transformation of this sort requested. return; } if (done) { return; } Dwarf_Half dietag = inDie.getTag(); if (dietag != DW_TAG_variable) { return; } for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); Dwarf_Form_Class formclass = attr.getFormClass(); if (attrnum == DW_AT_location) { // Before DW5 there was no DW_FORM_CLASS_EXPRLOC, // so we would have done this with a different // test. if (formclass != DW_FORM_CLASS_EXPRLOC) { // Ignore this. return; } IRForm*f = attr.getFormData(); IRFormBlock *f2 = dynamic_cast(f); std::vector vec= f2->getBlockData(); Dwarf_Block bl; int res = createskipbranchblock(dbg,bl); if (res != DW_DLV_OK) { return; } f2->insertBlock(&bl); done = true; break; } } } // The first special transformation is converting DW_AT_high_pc // from FORM_addr to an offset and we choose FORM_uleb // The attrs ref passed in is (sometimes) used to generate // a new attrs list for the caller. static void specialAttrTransformations(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, list& attrs, unsigned level UNUSEDARG) { if(!cmdoptions.transformHighpcToConst) { // No transformation of this sort requested. return; } Dwarf_Half dietag = inDie.getTag(); if(dietag != DW_TAG_subprogram) { return; } bool foundhipc= false; bool foundlopc= false; Dwarf_Addr lopcval = 0; Dwarf_Addr hipcval = 0; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); Dwarf_Half attrform = attr.getFinalForm(); Dwarf_Form_Class formclass = attr.getFormClass(); if(attrnum == DW_AT_high_pc) { if (attrform == DW_FORM_udata) { // Already the right form for the test. // Nothing to do. return; } if (formclass != DW_FORM_CLASS_ADDRESS) { return; } IRForm*f = attr.getFormData(); IRFormAddress *f2 = dynamic_cast(f); hipcval = f2->getAddress(); foundhipc = true; continue; } if(attrnum == DW_AT_low_pc) { if (formclass != DW_FORM_CLASS_ADDRESS) { return; } IRForm*f = attr.getFormData(); IRFormAddress *f2 = dynamic_cast(f); lopcval = f2->getAddress(); foundlopc = true; continue; } continue; } if(!foundlopc || !foundhipc) { return; } Dwarf_Addr hipcoffset = hipcval - lopcval; // Now we create a revised attribute. list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_high_pc) { // Here we want to create a constant form // to test that a const high_pc works. // This is new in DWARF5. IRAttr attr2(attrnum, DW_FORM_udata, DW_FORM_udata); attr2.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *f = new IRFormConstant( DW_FORM_udata, DW_FORM_udata, DW_FORM_CLASS_CONSTANT, IRFormConstant::UNSIGNED, hipcoffset, 0); attr2.setFormData(f); revisedattrs.push_back(attr2); // Avoid memoryleak attr.dropFormData(); continue; } revisedattrs.push_back(attr); continue; } attrs = revisedattrs; } /* Create a data16 data item out of nothing... */ static void addData16DataItem(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, IRDie &inParent, list& attrs, unsigned level) { static bool alreadydone = false; if (alreadydone) { return; } if(!cmdoptions.adddata16) { // No transformation of this sort requested. return; } if (level < 2) { return; } Dwarf_Half dietag = inDie.getTag(); Dwarf_Half parenttag = inParent.getTag(); if(dietag != DW_TAG_variable || parenttag != DW_TAG_subprogram) { return; } list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_name){ // Avoid memoryleak attr.dropFormData(); continue; } if(attrnum == DW_AT_const_value){ // Avoid memoryleak attr.dropFormData(); continue; } revisedattrs.push_back(attr); } // add two new attrs. Dwarf_Half attrnum = DW_AT_name; const char *attrname("vardata16"); IRAttr attr2(attrnum, DW_FORM_string, DW_FORM_string); attr2.setFormClass(DW_FORM_CLASS_STRING); IRFormString *f = new IRFormString(); f->setInitialForm(DW_FORM_string); f->setFinalForm(DW_FORM_string); f->setString(attrname); attr2.setFormData(f); revisedattrs.push_back(attr2); Dwarf_Form_Data16 data16 = { 0x01,0x08, 0x02,0x07, 0x03,0x06, 0x04,0x05, 0x05,0x04, 0x06,0x03, 0x07,0x02, 0x08,0x01 }; IRAttr attrc(DW_AT_const_value, DW_FORM_data16,DW_FORM_data16); attrc.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *fc = new IRFormConstant( DW_FORM_data16, DW_FORM_data16, DW_FORM_CLASS_CONSTANT, data16); attrc.setFormData(fc); revisedattrs.push_back(attrc); attrs = revisedattrs; alreadydone = true; } int testvals[3] = { -2018, -2019, -2018 }; const char *testnames[3] = { "myimplicitconst1", "myimplicitconst2newabbrev", "myimplicitconst3share1abbrev" }; static void addSUNfuncoffsets(Dwarf_P_Debug dbg , IRepresentation & Irep UNUSEDARG, UNUSEDARG Dwarf_P_Die ourdie, IRDie &inDie, UNUSEDARG IRDie &inParent, list& attrs, UNUSEDARG unsigned level) { if(!cmdoptions.addSUNfuncoffsets) { // No transformation of this sort requested. return; } Dwarf_Half dietag = inDie.getTag(); if (dietag == DW_TAG_compile_unit) { } if (dietag != DW_TAG_compile_unit) { return; } // add new attr. Dwarf_Half attrnum = DW_AT_SUN_func_offsets; IRFormBlock *f = new IRFormBlock(); Dwarf_Signed signar[5] = {-1,2000,-2500000000ll,60000000000ll,-2}; Dwarf_Unsigned block_len = 0; void *block_ptr; int res = dwarf_compress_integer_block_a(dbg, 5,signar, &block_len,&block_ptr,&error); if (res == DW_DLV_ERROR) { cerr << " FAIL: Unable to generate via " << "dwarf_compress_integer_block_a: err " << dwarf_errmsg(error) << endl; return; } else if (res == DW_DLV_NO_ENTRY) { cerr << " FAIL: NO_ENTRY impossible but got it" << " from dwarf_compress_integer_block_a: err " << endl; return; } f->setInitialForm(DW_FORM_block); f->setFinalForm(DW_FORM_block); Dwarf_Block bl; bl.bl_len = block_len; bl.bl_data = block_ptr; bl.bl_from_loclist = false; bl.bl_section_offset = 0; // FAKE f->insertBlock(&bl); IRAttr attr1(attrnum, DW_FORM_block, DW_FORM_block); attr1.setFormClass(DW_FORM_CLASS_BLOCK); attr1.setFormData(f); attrs.push_back(attr1); } static void addImplicitConstItem(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, IRDie &inParent, list& attrs, unsigned level) { static int alreadydone = 0; if (alreadydone > 2) { // The limit here MUST be below the size of // testvals[] and testnames[] above. // Some abbrevs should match // if the test case is right. Others not. return; } if(!cmdoptions.addimplicitconst) { // No transformation of this sort requested. return; } if (level < 2) { return; } Dwarf_Half dietag = inDie.getTag(); Dwarf_Half parenttag = inParent.getTag(); if(dietag != DW_TAG_variable || parenttag != DW_TAG_subprogram) { return; } list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_name){ // Avoid memory leak. attr.dropFormData(); continue; } if(attrnum == DW_AT_const_value){ // Avoid memory leak. attr.dropFormData(); continue; } revisedattrs.push_back(attr); } // add two new attrs. Dwarf_Half attrnum = DW_AT_name; const char *attrname(testnames[alreadydone]); IRAttr attr2(attrnum, DW_FORM_string, DW_FORM_string); attr2.setFormClass(DW_FORM_CLASS_STRING); IRFormString *f = new IRFormString(); f->setInitialForm(DW_FORM_implicit_const); f->setFinalForm(DW_FORM_implicit_const); f->setString(attrname); attr2.setFormData(f); revisedattrs.push_back(attr2); Dwarf_Signed myconstval = testvals[alreadydone]; IRAttr attrc(DW_AT_const_value, DW_FORM_implicit_const,DW_FORM_implicit_const); attrc.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *fc = new IRFormConstant( DW_FORM_implicit_const, DW_FORM_implicit_const, DW_FORM_CLASS_CONSTANT, IRFormConstant::SIGNED, 0,myconstval); attrc.setFormData(fc); revisedattrs.push_back(attrc); attrs = revisedattrs; ++alreadydone; } // Here we emit all the DIEs for a single Die and // its children. When level == 0 the inDie is // the CU die. static Dwarf_P_Die HandleOneDieAndChildren(Dwarf_P_Debug dbg, IRepresentation &Irep, IRCUdata &cu, IRDie &inDie, IRDie &inParent, unsigned level) { list& children = inDie.getChildren(); // We create our target DIE first so we can link // children to it, but add no content yet. Dwarf_P_Die gendie = 0; int res =dwarf_new_die_a(dbg,inDie.getTag(),NULL,NULL, NULL,NULL,&gendie,&error); if (res != DW_DLV_OK) { cerr << "Die creation failure. "<< endl; exit(1); } inDie.setGeneratedDie(gendie); Dwarf_P_Die lastch = 0; for ( list::iterator it = children.begin(); it != children.end(); it++) { IRDie & ch = *it; Dwarf_P_Die chp = HandleOneDieAndChildren(dbg,Irep, cu,ch,inDie,level+1); int res2 = 0; if(lastch) { // Link to right of earlier sibling. res2 = dwarf_die_link_a(chp,NULL,NULL,lastch,NULL,&error); } else { // Link as first child. res2 = dwarf_die_link_a(chp,gendie,NULL,NULL, NULL,&error); } if (res2 != DW_DLV_OK) { cerr << "Die link failure. "<< endl; exit(1); } lastch = chp; } { list& attrs = inDie.getAttributes(); // Now any special transformations to the attrs list. specialAttrTransformations(dbg,Irep,gendie,inDie,attrs,level); addData16DataItem(dbg,Irep,gendie,inDie,inParent,attrs,level); addImplicitConstItem(dbg,Irep,gendie,inDie,inParent,attrs,level); addSUNfuncoffsets(dbg,Irep,gendie,inDie,inParent,attrs,level); addSkipBranchOps( dbg,Irep,gendie,inDie,inParent,attrs,level); // Now we add attributes (content), if any, to the // output die 'gendie'. for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; AddAttrToDie(dbg,Irep,cu,gendie,inDie,attr); } } return gendie; } static void HandleLineData(Dwarf_P_Debug dbg, IRepresentation & Irep UNUSEDARG, IRCUdata&cu) { Dwarf_Error lerror = 0; // We refer to files by fileno, this builds an index. pathToUnsignedType pathmap; IRCULineData& ld = cu.getCULines(); std::vector & cu_lines = ld.get_cu_lines(); //std::vector &cu_srcfiles = ld.get_cu_srcfiles(); if(cu_lines.empty()) { // No lines data to emit, do nothing. return; } // To start with, we are doing a trivial generation here. // To be refined 'soon'. FIXME // Initially we don't worry about dwarf_add_directory_decl(). bool firstline = true; bool addrsetincu = false; for(unsigned k = 0; k < cu_lines.size(); ++k) { IRCULine &li = cu_lines[k]; const std::string&path = li.getpath(); unsigned pathindex = 0; pathToUnsignedType::const_iterator it = pathmap.find(path); if(it == pathmap.end()) { Dwarf_Error l2error = 0; Dwarf_Unsigned idx = 0; int res = dwarf_add_file_decl_a( dbg,const_cast(path.c_str()), 0,0,0,&idx,&l2error); if(res != DW_DLV_OK) { cerr << "Error from dwarf_add_file_decl() on " << path << endl; exit(1); } pathindex = idx; pathmap[path] = pathindex; } else { pathindex = it->second; } Dwarf_Addr a = li.getaddr(); bool addrsetinline = li.getaddrset(); bool endsequence = li.getendsequence(); if(firstline || !addrsetincu) { // We fake an elf sym index here. Dwarf_Unsigned elfsymidx = 0; if(firstline && !addrsetinline) { cerr << "Error building line, first entry not addr set" << endl; exit(1); } int res = dwarf_lne_set_address_a(dbg, a,elfsymidx,&lerror); if(res != DW_DLV_OK) { cerr << "Error building line, dwarf_lne_set_address" << endl; exit(1); } addrsetincu = true; firstline = false; } else if( endsequence) { int res = dwarf_lne_end_sequence_a(dbg, a,&lerror); if(res != DW_DLV_OK) { cerr << "Error building line, dwarf_lne_end_sequence" << endl; exit(1); } addrsetincu = false; continue; } Dwarf_Signed linecol = li.getlinecol(); // It's really the code address or (when in a proper compiler) // a section or function offset. // libdwarf subtracts the code_offset from the address passed // this way or from dwarf_lne_set_address() and writes a small // offset in a DW_LNS_advance_pc instruction. Dwarf_Addr code_offset = a; Dwarf_Unsigned lineno = li.getlineno(); Dwarf_Bool isstmt = li.getisstmt()?1:0; Dwarf_Bool isblock = li.getisblock()?1:0; Dwarf_Bool isepiloguebegin = li.getepiloguebegin()?1:0; Dwarf_Bool isprologueend = li.getprologueend()?1:0; Dwarf_Unsigned isa = li.getisa(); Dwarf_Unsigned discriminator = li.getdiscriminator(); int lires = dwarf_add_line_entry_c(dbg, pathindex, code_offset, lineno, linecol, isstmt, isblock, isepiloguebegin, isprologueend, isa, discriminator, &lerror); if(lires != DW_DLV_OK) { cerr << "Error building line, dwarf_add_line_entry" << endl; exit(1); } } if(addrsetincu) { cerr << "CU Lines did not end in an end_sequence!" << endl; } } // This emits the DIEs for a single CU and possibly line data // associated with the CU. // The DIEs form a graph (which can be created and linked together // in any order) and which is emitted in tree preorder as // defined by the DWARF spec. // static void emitOneCU( Dwarf_P_Debug dbg,IRepresentation & Irep, IRCUdata&cu, int cu_of_input_we_output UNUSEDARG) { // We descend the the tree, creating DIEs and linking // them in as we return back up the tree of recursing // on IRDie children. Dwarf_Error lerror; IRDie & basedie = cu.baseDie(); Dwarf_P_Die cudie = HandleOneDieAndChildren(dbg,Irep, cu,basedie,basedie,0); // Add base die to debug, this is the CU die. // This is not a good design as DWARF3/4 have // requirements of multiple CUs in a single creation, // which cannot be handled yet. Dwarf_Unsigned res = dwarf_add_die_to_debug(dbg,cudie,&lerror); if(res != DW_DLV_OK) { cerr << "Unable to add_die_to_debug " << endl; exit(1); } // Does fixup of IRFormReference targets. cu.updateClassReferenceTargets(); HandleLineData(dbg,Irep,cu); } // .debug_info creation. // Also creates .debug_line static void transform_debug_info(Dwarf_P_Debug dbg, IRepresentation & irep,int cu_of_input_we_output) { int cu_number = 0; std::list &culist = irep.infodata().getCUData(); // For now, just one CU we write (as spoken by Yoda). for ( list::iterator it = culist.begin(); it != culist.end(); it++,cu_number++) { if(cu_number == cu_of_input_we_output) { IRCUdata & primecu = *it; emitOneCU(dbg,irep,primecu,cu_of_input_we_output); break; } } } static void transform_cie_fde(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG) { Dwarf_Error err = 0; std::vector &cie_vec = Irep.framedata().get_cie_vec(); std::vector &fde_vec = Irep.framedata().get_fde_vec(); Dwarf_Unsigned cievecsize = cie_vec.size(); if (!cievecsize) { // If debug_frame missing try for eh_frame. // Just do one section, not both, for now. cie_vec = Irep.ehframedata().get_cie_vec(); fde_vec = Irep.ehframedata().get_fde_vec(); cievecsize = cie_vec.size(); } for(Dwarf_Unsigned i = 0; i < cievecsize ; ++i) { IRCie &ciein = cie_vec[i]; Dwarf_Unsigned version = 0; string aug; Dwarf_Unsigned code_align = 0; Dwarf_Signed data_align = 0; Dwarf_Half ret_addr_reg = -1; void * bytes = 0; Dwarf_Unsigned bytes_len = 0; Dwarf_Unsigned out_cie_index = 0; ciein.get_basic_cie_data(&version, &aug, &code_align, &data_align, &ret_addr_reg); ciein.get_init_instructions(&bytes_len,&bytes); // version implied: FIXME, need to let user code set output // frame version. char *str = const_cast(aug.c_str()); int res = dwarf_add_frame_cie_a(dbg, str, code_align, data_align, ret_addr_reg, bytes,bytes_len, &out_cie_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating cie from input cie " << i << endl; exit(1); } vector fdeindex; // This inner loop is C*F so a bit slow. for(size_t j = 0; j < fde_vec.size(); ++j) { IRFde &fdein = fde_vec[j]; Dwarf_Unsigned code_len = 0; Dwarf_Addr code_virt_addr = 0; Dwarf_Unsigned cie_input_index = 0; fdein.get_fde_base_data(&code_virt_addr, &code_len, &cie_input_index); if(cie_input_index != i) { // Wrong cie, ignore this fde right now. continue; } Dwarf_P_Fde fdeout = 0; res = dwarf_new_fde_a(dbg,&fdeout,&err); if(res != DW_DLV_OK) { cerr << "Error creating new fde " << j << endl; exit(1); } Dwarf_Unsigned ilen = 0; void *instrs = 0; fdein.get_fde_instructions(&ilen, &instrs); res = dwarf_insert_fde_inst_bytes(dbg, fdeout, ilen, instrs,&err); if(res != DW_DLV_OK) { cerr << "Error inserting frame instr block " << j << endl; exit(1); } Dwarf_P_Die irix_die = 0; Dwarf_Signed irix_table_offset = 0; Dwarf_Unsigned irix_excep_sym = 0; Dwarf_Unsigned code_virt_addr_symidx = Irep.getBaseTextSymbol(); Dwarf_Unsigned fde_index = 0; Dwarf_Unsigned end_symbol_index = 0; Dwarf_Unsigned offset_from_end_symbol = 0; res = dwarf_add_frame_info_c( dbg, fdeout,irix_die, out_cie_index, code_virt_addr, code_len, code_virt_addr_symidx, end_symbol_index, offset_from_end_symbol, irix_table_offset,irix_excep_sym, &fde_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating new fde " << j << endl; exit(1); } } } if (cmdoptions.addframeadvanceloc) { // Add a whole new fde, cie, and some instructions Dwarf_Unsigned code_align = 1; Dwarf_Signed data_align = 1; Dwarf_Half ret_addr_reg = 2; // fake, of course. void * bytes = 0; Dwarf_Unsigned bytes_len = 0; Dwarf_Unsigned out_cie_index = 0; const char *augstr = ""; int res = dwarf_add_frame_cie_a(dbg, (char *)augstr, code_align, data_align, ret_addr_reg, bytes,bytes_len, &out_cie_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating made-up addframeadvanceloc cie " << endl; exit(1); } Dwarf_P_Fde fdeout = 0; res = dwarf_new_fde_a(dbg,&fdeout,&err); if(res != DW_DLV_OK) { cerr << "Error creating addframeadvance fde " << endl; exit(1); } // These lead to a set of adv_loc ops values in the output // for the fde which looks odd in -f // output (-vvv -f makes more sense), might be // better to have some additional frame instrs in there // so plain -f looks more sensible. std::list adval; adval.push_back(48); adval.push_back(64); adval.push_back(17219); adval.push_back(4408131); adval.push_back(18308350787ull); // 0x30 0x40 0x4343 0x434343 0x434343434 unsigned i = 3; for( list::iterator it = adval.begin(); it != adval.end();it++ , ++i ) { Dwarf_Unsigned v = *it; res = dwarf_add_fde_inst_a(fdeout, DW_CFA_advance_loc,v,0,&err); if (res != DW_DLV_OK) { cerr << "Error adding advance_loc" << v << endl; exit(1); } res = dwarf_add_fde_inst_a(fdeout, DW_CFA_same_value,i,0,&err); if (res != DW_DLV_OK) { cerr << "Error adding dummy same_value op" << v << endl; exit(1); } } // We increase code len to account for the // big advance_loc values inserted above. Dwarf_P_Die irix_die = 0; Dwarf_Signed irix_table_offset = 0; Dwarf_Unsigned irix_excep_sym = 0; Dwarf_Unsigned code_virt_addr_symidx = Irep.getBaseTextSymbol(); Dwarf_Unsigned fde_index = 0; Dwarf_Unsigned end_symbol_index = 0; Dwarf_Unsigned offset_from_end_symbol = 0; Dwarf_Addr code_virt_addr = 0; Dwarf_Addr code_len = 0x444343434; res = dwarf_add_frame_info_c( dbg, fdeout,irix_die, out_cie_index, code_virt_addr, code_len, code_virt_addr_symidx, end_symbol_index, offset_from_end_symbol, irix_table_offset,irix_excep_sym, &fde_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating advance_loc fde " << endl; exit(1); } } } static void transform_macro_info(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG) { IRMacro ¯odata = Irep.macrodata(); std::vector ¯ov = macrodata.getMacroVec(); for(size_t m = 0; m < macrov.size() ; m++ ) { // FIXME: we need to coordinate with generated // CUs . cout << "FIXME: macros not really output yet " << m << " " << macrov.size() << endl; } Dwarf_Unsigned reloc_count = 0; int drd_version = 0; int res = dwarf_get_relocation_info_count(dbg,&reloc_count, &drd_version,&error); if( res != DW_DLV_OK) { cerr << "Error getting relocation info count." << endl; exit(1); } for( Dwarf_Unsigned ct = 0; ct < reloc_count ; ++ct) { } } // Starting at a Die, look through its children // in its input to find which one we have by // comparing the input-die global offset. static Dwarf_P_Die findTargetDieByOffset(IRDie& indie, Dwarf_Unsigned targetglobaloff) { Dwarf_Unsigned globoff = indie.getGlobalOffset(); if(globoff == targetglobaloff) { return indie.getGeneratedDie(); } std::list dielist = indie.getChildren(); for ( list::iterator it = dielist.begin(); it != dielist.end(); it++) { IRDie &ldie = *it; Dwarf_P_Die foundDie = findTargetDieByOffset(ldie, targetglobaloff); if(foundDie) { return foundDie; } } return NULL; } // If the pubnames/pubtypes entry is in the // cu we are emitting, find the generated output // Dwarf_P_Die in that CU // and attach the pubname/type entry to it. static void transform_debug_pubnames_types_inner(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG, IRCUdata&cu) { // First, get the target CU. */ Dwarf_Unsigned targetcuoff= cu.getCUdieOffset(); IRDie &basedie = cu.baseDie(); IRPubsData& pubs = Irep.pubnamedata(); std::list &nameslist = pubs.getPubnames(); if(!nameslist.empty()) { for ( list::iterator it = nameslist.begin(); it != nameslist.end(); it++) { IRPub &pub = *it; Dwarf_Unsigned pubcuoff= pub.getCUdieOffset(); Dwarf_Unsigned ourdieoff= pub.getDieOffset(); if (pubcuoff != targetcuoff) { continue; } Dwarf_P_Die targdie = findTargetDieByOffset(basedie, ourdieoff); if(targdie) { // Ugly. Old mistake in libdwarf declaration. char *mystr = const_cast(pub.getName().c_str()); Dwarf_Unsigned res = dwarf_add_pubname( dbg,targdie, mystr, &error); if(!res) { cerr << "Failed to add pubname entry for offset" << ourdieoff << "in CU at offset " << pubcuoff << endl; exit(1); } } else { cerr << "Did not find target pubname P_Die for offset " << ourdieoff << "in CU at offset " << pubcuoff << endl; } } } std::list &typeslist = pubs.getPubtypes(); if(!typeslist.empty()) { for ( list::iterator it = typeslist.begin(); it != typeslist.end(); it++) { IRPub &pub = *it; Dwarf_Unsigned pubcuoff= pub.getCUdieOffset(); Dwarf_Unsigned ourdieoff= pub.getDieOffset(); if (pubcuoff != targetcuoff) { continue; } Dwarf_P_Die targdie = findTargetDieByOffset(basedie, ourdieoff); if(targdie) { // Ugly. Old mistake in libdwarf declaration. char *mystr = const_cast(pub.getName().c_str()); Dwarf_Unsigned res = dwarf_add_pubtype( dbg,targdie, mystr, &error); if(!res) { cerr << "Failed to add pubtype entry for offset" << ourdieoff << "in CU at offset " << pubcuoff << endl; exit(1); } } else { cerr << "Did not find target pubtype P_Die for offset " << ourdieoff << "in CU at offset " << pubcuoff << endl; } } } } // This looks for pubnames/pubtypes // to generate based on an object file input. static void transform_debug_pubnames_types(Dwarf_P_Debug dbg, IRepresentation & Irep,int cu_of_input_we_output) { int cu_number = 0; std::list &culist = Irep.infodata().getCUData(); // For now, just one CU we write (as spoken by Yoda). for ( list::iterator it = culist.begin(); it != culist.end(); it++,cu_number++) { if(cu_number == cu_of_input_we_output) { IRCUdata & primecu = *it; transform_debug_pubnames_types_inner( dbg,Irep,cu_of_input_we_output,primecu); break; } } } void transform_irep_to_dbg(Dwarf_P_Debug dbg, IRepresentation & Irep,int cu_of_input_we_output) { transform_debug_info(dbg,Irep,cu_of_input_we_output); transform_cie_fde(dbg,Irep,cu_of_input_we_output); transform_macro_info(dbg,Irep,cu_of_input_we_output); transform_debug_pubnames_types(dbg,Irep,cu_of_input_we_output); } libdwarf-20210528/dwarfgen/ireptodbg.h0000664000175000017500000000311513644370703014430 00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ireptodbg.h void transform_irep_to_dbg(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output); libdwarf-20210528/dwarfgen/ChangeLog20160000664000175000017500000000342513644370703014367 00000000000000David Anderson * Makefile.in: Clean *~ 2016-11-20 David Anderson * Makefile.in: Now we have proper setting of CC and CFLAGS, which was missing before. 2016-10-07 David Anderson * dwarfgen.cc:For the reporting of .debug_str stats (just 3 lines of it) there is now a fixed prefix "Debug_Str:" so it is easier to verify things do not go wrong over time by just comparing those few lines, which should match across and across OS and libelf versions. There will still be 32/64bit differences though as the notion of 'short' string is longer with a 64bit offset in an object.. (pointer size is not the issue). 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize. * configure: Regenerated. 2016-09-21 David Anderson * Makefile.in: implement sanitize support. * configure.in: Add support for --enable-sanitize * configure: Regenerated. 2016-08-28 David Anderson * dwarfgen.cc: Now calls dwarf_pro_get_string_stats() and prints the string counts information. 2016-08-25 David Anderson * dwarfgen.cc: Clarified and expanded the debug output of dwarfgen about relocations (and added the -r option to expand the output further). * irepresentation.h: Added comments explaining the intent of two small classes. 2016-08-23 David Anderson * dwarfgen.cc: Added the -s option which has .debug_info strings generated into .debug_str. 2016-06-01 David Anderson * Makefile.in: Tweaked for debian build compatibility 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-01-14 David Anderson * irepform.h: Missing return *this from several functions. Fixed. libdwarf-20210528/dwarfgen/TESTmallocfail0000664000175000017500000000125613644370703015032 00000000000000#!/bin/bash # # This runs dwarfgen/libdwarf with a malloc failure # at the $ct'th call to malloc. # To expose errors in malloc failure handling. # Probably any small C file compiled -c will do # to produce test.o For example just use a .o # generated by the build of dwarfgen subj=test.o ct=0 while [ $ct -lt 500 ] do echo '===== START TEST' rm -f core rm -f dwarfgen sed -e "s/FAILCOUNT/$ct/" fakemalloc.c echo TEST $ct grep if fakemalloc.c make ./dwarfgen -h -t obj -c 0 -o $subj ./dwarfgen >junk.x cat junk.x if [ -f core ] then echo "CORE FILE EXISTS, test" $ct fi rm -f core echo '===== END TEST' ct=`expr $ct + 1` done libdwarf-20210528/dwarfgen/ChangeLog20150000664000175000017500000000262213644370703014364 000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. 2015-09-15 Carlos Alberto Enciso * createirepformfrombinary.cc: include the 'stdafx.h' for Windows port. Minor typo in the filename description. * createirepfrombinary.cc: include the 'stdafx.h' for Windows port. Use the Dwarfdump generic open_a_file() and close_a_file() calls. * dwarfgen.cc: include the 'stdafx.h' for Windows port. Include the Dwarfdump generic open_a_file(), close_a_file() and create_a_file() calls. Remove the 'extern "C"' around 'dwgetopt.h'. * irepattrtodbg.cc: include the 'stdafx.h' for Windows port. * ireptodbg.cc: include the 'stdafx.h' for Windows port. 2015-07-12 David Anderson * Now uses dwoptarg, dwoptind, not optarg, optind. 2015-02-22 David Anderson * Now uses dwgetopt.h, .c from dwarfdump. * dwarfgen.cc: Now references dwgetopt.h and dwgetopt(). * Makefile.in: Reaches around to libdwarf for dwgetopt. * configure.in: Removed getopt.h check * configure: regenerated 2015-01-06 David Anderson * dwarfgen.cc: Fixed indents and removed trailing whitespace. 2015-01-01 David Anderson * A new year begins. libdwarf-20210528/dwarfgen/ChangeLog20120000664000175000017500000000005413644370703014356 00000000000000ChangeLog2012 is empty, no changes in 2012. libdwarf-20210528/dwarfgen/irepattrtodbg.h0000664000175000017500000000327613644370703015333 00000000000000#ifndef IREPATTRTODBG_H #define IREPATTRTODBG_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // irepattrtodbg.h void AddAttrToDie(Dwarf_P_Debug dbg, IRepresentation & Irep, IRCUdata &cu, Dwarf_P_Die outdie,IRDie & irdie,IRAttr &irattr); #endif /* IREPATTRTODBG_H */ libdwarf-20210528/dwarfgen/Makefile.in0000664000175000017500000010257114054252021014337 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = dwarfgen$(EXEEXT) subdir = dwarfgen ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_dwarfgen_OBJECTS = dwarfgen-createirepformfrombinary.$(OBJEXT) \ dwarfgen-createirepfrombinary.$(OBJEXT) \ dwarfgen-dwarfgen.$(OBJEXT) dwarfgen-irepattrtodbg.$(OBJEXT) \ dwarfgen-ireptodbg.$(OBJEXT) dwarfgen_OBJECTS = $(am_dwarfgen_OBJECTS) dwarfgen_DEPENDENCIES = \ $(top_builddir)/dwarfdump/dwarfdump-dwgetopt.o \ $(top_builddir)/libdwarf/libdwarf.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dwarfgen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(dwarfgen_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/dwarfgen-createirepformfrombinary.Po \ ./$(DEPDIR)/dwarfgen-createirepfrombinary.Po \ ./$(DEPDIR)/dwarfgen-dwarfgen.Po \ ./$(DEPDIR)/dwarfgen-irepattrtodbg.Po \ ./$(DEPDIR)/dwarfgen-ireptodbg.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dwarfgen_SOURCES) DIST_SOURCES = $(dwarfgen_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_BIGENDIAN = @DWARF_BIGENDIAN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects dwarfgen_SOURCES = \ createirepformfrombinary.cc \ createirepfrombinary.h \ createirepfrombinary.cc \ dwarfgen.cc \ general.h \ irepattrtodbg.cc \ irepattrtodbg.h \ irepdie.h \ irepform.h \ irepframe.h \ irepline.h \ irepmacro.h \ ireppubnames.h \ irepresentation.h \ ireptodbg.cc \ ireptodbg.h \ strtabdata.h # dwarfdump here is so we find dwgetopt.h dwarfgen_CPPFLAGS = -I$(top_srcdir)/libdwarf -I$(top_srcdir)/dwarfdump -I$(top_builddir)/libdwarf dwarfgen_CXXFLAGS = $(DWARF_CXXFLAGS_WARN) dwarfgen_LDADD = \ $(top_builddir)/dwarfdump/dwarfdump-dwgetopt.o \ $(top_builddir)/libdwarf/libdwarf.la \ @DWARF_LIBS@ EXTRA_DIST = \ COPYING \ ChangeLog \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ NEWS \ README \ dwarfgen.1 \ TESTmallocfail \ $(dwarfgen_DATA) \ dwarf-generator.txt \ fakemalloc.in all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfgen/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfgen/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dwarfgen$(EXEEXT): $(dwarfgen_OBJECTS) $(dwarfgen_DEPENDENCIES) $(EXTRA_dwarfgen_DEPENDENCIES) @rm -f dwarfgen$(EXEEXT) $(AM_V_CXXLD)$(dwarfgen_LINK) $(dwarfgen_OBJECTS) $(dwarfgen_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-createirepformfrombinary.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-createirepfrombinary.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-dwarfgen.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-irepattrtodbg.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-ireptodbg.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< dwarfgen-createirepformfrombinary.o: createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepformfrombinary.o -MD -MP -MF $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo -c -o dwarfgen-createirepformfrombinary.o `test -f 'createirepformfrombinary.cc' || echo '$(srcdir)/'`createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepformfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepformfrombinary.cc' object='dwarfgen-createirepformfrombinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepformfrombinary.o `test -f 'createirepformfrombinary.cc' || echo '$(srcdir)/'`createirepformfrombinary.cc dwarfgen-createirepformfrombinary.obj: createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepformfrombinary.obj -MD -MP -MF $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo -c -o dwarfgen-createirepformfrombinary.obj `if test -f 'createirepformfrombinary.cc'; then $(CYGPATH_W) 'createirepformfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepformfrombinary.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepformfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepformfrombinary.cc' object='dwarfgen-createirepformfrombinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepformfrombinary.obj `if test -f 'createirepformfrombinary.cc'; then $(CYGPATH_W) 'createirepformfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepformfrombinary.cc'; fi` dwarfgen-createirepfrombinary.o: createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepfrombinary.o -MD -MP -MF $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo -c -o dwarfgen-createirepfrombinary.o `test -f 'createirepfrombinary.cc' || echo '$(srcdir)/'`createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepfrombinary.cc' object='dwarfgen-createirepfrombinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepfrombinary.o `test -f 'createirepfrombinary.cc' || echo '$(srcdir)/'`createirepfrombinary.cc dwarfgen-createirepfrombinary.obj: createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepfrombinary.obj -MD -MP -MF $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo -c -o dwarfgen-createirepfrombinary.obj `if test -f 'createirepfrombinary.cc'; then $(CYGPATH_W) 'createirepfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepfrombinary.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepfrombinary.cc' object='dwarfgen-createirepfrombinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepfrombinary.obj `if test -f 'createirepfrombinary.cc'; then $(CYGPATH_W) 'createirepfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepfrombinary.cc'; fi` dwarfgen-dwarfgen.o: dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-dwarfgen.o -MD -MP -MF $(DEPDIR)/dwarfgen-dwarfgen.Tpo -c -o dwarfgen-dwarfgen.o `test -f 'dwarfgen.cc' || echo '$(srcdir)/'`dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-dwarfgen.Tpo $(DEPDIR)/dwarfgen-dwarfgen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dwarfgen.cc' object='dwarfgen-dwarfgen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-dwarfgen.o `test -f 'dwarfgen.cc' || echo '$(srcdir)/'`dwarfgen.cc dwarfgen-dwarfgen.obj: dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-dwarfgen.obj -MD -MP -MF $(DEPDIR)/dwarfgen-dwarfgen.Tpo -c -o dwarfgen-dwarfgen.obj `if test -f 'dwarfgen.cc'; then $(CYGPATH_W) 'dwarfgen.cc'; else $(CYGPATH_W) '$(srcdir)/dwarfgen.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-dwarfgen.Tpo $(DEPDIR)/dwarfgen-dwarfgen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dwarfgen.cc' object='dwarfgen-dwarfgen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-dwarfgen.obj `if test -f 'dwarfgen.cc'; then $(CYGPATH_W) 'dwarfgen.cc'; else $(CYGPATH_W) '$(srcdir)/dwarfgen.cc'; fi` dwarfgen-irepattrtodbg.o: irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-irepattrtodbg.o -MD -MP -MF $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo -c -o dwarfgen-irepattrtodbg.o `test -f 'irepattrtodbg.cc' || echo '$(srcdir)/'`irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo $(DEPDIR)/dwarfgen-irepattrtodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='irepattrtodbg.cc' object='dwarfgen-irepattrtodbg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-irepattrtodbg.o `test -f 'irepattrtodbg.cc' || echo '$(srcdir)/'`irepattrtodbg.cc dwarfgen-irepattrtodbg.obj: irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-irepattrtodbg.obj -MD -MP -MF $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo -c -o dwarfgen-irepattrtodbg.obj `if test -f 'irepattrtodbg.cc'; then $(CYGPATH_W) 'irepattrtodbg.cc'; else $(CYGPATH_W) '$(srcdir)/irepattrtodbg.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo $(DEPDIR)/dwarfgen-irepattrtodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='irepattrtodbg.cc' object='dwarfgen-irepattrtodbg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-irepattrtodbg.obj `if test -f 'irepattrtodbg.cc'; then $(CYGPATH_W) 'irepattrtodbg.cc'; else $(CYGPATH_W) '$(srcdir)/irepattrtodbg.cc'; fi` dwarfgen-ireptodbg.o: ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-ireptodbg.o -MD -MP -MF $(DEPDIR)/dwarfgen-ireptodbg.Tpo -c -o dwarfgen-ireptodbg.o `test -f 'ireptodbg.cc' || echo '$(srcdir)/'`ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-ireptodbg.Tpo $(DEPDIR)/dwarfgen-ireptodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ireptodbg.cc' object='dwarfgen-ireptodbg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-ireptodbg.o `test -f 'ireptodbg.cc' || echo '$(srcdir)/'`ireptodbg.cc dwarfgen-ireptodbg.obj: ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-ireptodbg.obj -MD -MP -MF $(DEPDIR)/dwarfgen-ireptodbg.Tpo -c -o dwarfgen-ireptodbg.obj `if test -f 'ireptodbg.cc'; then $(CYGPATH_W) 'ireptodbg.cc'; else $(CYGPATH_W) '$(srcdir)/ireptodbg.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-ireptodbg.Tpo $(DEPDIR)/dwarfgen-ireptodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ireptodbg.cc' object='dwarfgen-ireptodbg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-ireptodbg.obj `if test -f 'ireptodbg.cc'; then $(CYGPATH_W) 'ireptodbg.cc'; else $(CYGPATH_W) '$(srcdir)/ireptodbg.cc'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dwarfgen-createirepformfrombinary.Po -rm -f ./$(DEPDIR)/dwarfgen-createirepfrombinary.Po -rm -f ./$(DEPDIR)/dwarfgen-dwarfgen.Po -rm -f ./$(DEPDIR)/dwarfgen-irepattrtodbg.Po -rm -f ./$(DEPDIR)/dwarfgen-ireptodbg.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dwarfgen-createirepformfrombinary.Po -rm -f ./$(DEPDIR)/dwarfgen-createirepfrombinary.Po -rm -f ./$(DEPDIR)/dwarfgen-dwarfgen.Po -rm -f ./$(DEPDIR)/dwarfgen-irepattrtodbg.Po -rm -f ./$(DEPDIR)/dwarfgen-ireptodbg.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libdwarf-20210528/dwarfgen/ChangeLog20110000664000175000017500000000171013644370703014355 00000000000000 2011-11-17 DavidAnderson * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc: Update copyright year. 2011-12-14 DavidAnderson * createirepfrombinary.cc, dwarfgen.cc, general.h, irepattrtodbg.cc, irepdie.h, irepline.h, irepresentation.h, ireptodbg.cc: Now reads in line table and creates line table output (still just DWARF2 though). 2011-06-12 DavidAnderson * dwarfgen.cc: Use dwarf_producer_init_c(), the newest interface to the producer. 2011-04-23 DavidAnderson * createirepformfrombinary.cc, createirepfrombinary.cc, dwarfgen.cc,general.h,irepattrtodbg.cc, irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepmacro.h,irepresentation.h,ireptodbg.cc, reptodbg.h,strtabdata.h: All the indentation is a multiple of 4 now. All the copyrights are updated. libdwarf-20210528/AUTHORS0000664000175000017500000000004513644370703011552 00000000000000David Anderson Carlos Alberto Enciso libdwarf-20210528/README0000664000175000017500000002121114051042535011350 00000000000000As of May 22, 2020 libdwarf and dwarfdump support DWARF5 .debug_rnglists section content, and do much better at containing malloc use (dwarf_finish() still cleans up,but it's not so crucial now). ========= As of September 29, 2018 you will find difficulties on FreeBSD 11.2 running make, as default make is not gnu-make compatible. The 2018 configure change to fully use autoconf/automake requires GNU make to build executables. ========== sh scripts/FIX-CONFIGURE-TIMES Because git does not record timestamps and sometimes a copy will lose the timestamps on the build files, it is usually necessary to sh scripts/FIX-CONFIGURE-TIMES at the top of the source tree before using configure. See the example scripts below. ========== BUILD PROBLEM SOLUTION: FIX-CONFIGURE-TIMES Because git does not record timestamps and sometimes a copy will lose the timestamps on the build files, the advice here is something you are likely to need to follow. From the top-level source do sh scripts/FIX-CONFIGURE-TIMES (before running configure) to fix the important timestamps. The command is safe to run at any time. The command checks that it is being run from an appropriate libdwarf top-level directory before doing anything. One clue the script is needed is the following warning. "WARNING: 'aclocal-1.15' is missing on your system." ========= End of aclocal issue... ========== CONFUSING BUILD PROBLEM If you do a full or partial in-source-tree build (see below) and then attempt an out-of-source-tree build you will get very confusing messages about build problems. Just ensure that the source tree is 'clean' (as by 'make distclean' or other means) before you attempt an out-of-source-tree build (see below for details). ========= End of confusing build problem ========= gcc under MinGW on windows The configure option --disable-libelf is no longer needed (but is allowed). Under MinGW the gcc CFLAGS -DHAVE_WINDOWS_H -DHAVE_NONSTANDARD_PRINTF_64_FORMAT \ -fno-dwarf2-cfi-asm have helped some people, though for my MinGW tests these are not necessary or appropriate. We have had success with MinGW without setting CFLAGS with (to save space in this example we do not show checking for errors): The option --enable-wall is optional. src=/path/to/code cd $src sh scripts/FIX-CONFIGURE-TIMES make distclean bld=/tmp/dwbld rm -rf $bld mkdir $bld cd $bld $src/configure --enable-wall \ --disable-libelf --enable-nonstandardprintf make check ========= End ofgcc under MinGW on windows ========= Standard Builds non-Windows Standard builds are done by configure/make as described below. Cross-Compiles are described below, see CROSS COMPILES. One need not --enable-dwarfgen --enable-dwarfexample. The option --enable-wall is also optional. BUILDING in UNIX/Linux src=/path/to/code cd $src sh scripts/FIX-CONFIGURE-TIMES make distclean bld=/tmp/dwbld rm -rf $bld mkdir $bld cd $bld $src/configure --enable-wall --enable-dwarfgen --enable-dwarfexample make check BUILDING in MacOS (tried on Catalina) Same as linux but as standard the Apple Command Line Tools provide no libelf (we don't need it). So the final two steps are: $src/configure --enable-wall --disable-libelf make check ========= End of Standard Builds non-Windows LIBRARY AND HEADER REQUIREMENTS zlib has to be installed to handle zlib compressed sections (common in linux, not normally found with Windows). in Ubuntu 16.04 and 18.04, install using: sudo apt-get install zlib1g zlib1g-dev zlib is available in source from http://zlib.net libelf is available in source from http://www.mr511.de/software/ though libelf is not (as of May 2019) needed. NOTE: When building out of source tree the source tree must be cleaned of any files created by a build in the source tree (just in case you tried that) before doing the out-of-source build. That's why the examples above do a 'make distclean'. BUILDING ALL THE TOOLS To build all the tools (including dwarfgen and dwarfexample) use a different configure command: ./configure --enable-dwarfgen --enable-dwarfexample ; make To see all the available options to configure do ./configure --help By default configure compiles and uses libdwarf.a. With ./configure --enable-shared both libdwarf.a and libdwarf.so are built. The runtimes built will reference libdwarf.so. With ./configure --enable-shared --disable-nonshared libdwarf.so is built and used; libdwarf.a is not built. THE USUAL ENVIRONMENT VARIABLES The following default to sensible values you may set environment variables as usual with GNU configure. CPPFLAGS CFLAGS LDFLAGS DEBUGGING MAKE To see what compile/link commands are actually being used by the generated Makefiles try V=1, as in make V=1 INSTALL AND UNINSTALL The default install is to /usr/local To change the install location use --prefix. For example: mkdir /tmp/testinst configure --prefix=/tmp/testinst So 'make install' (sudo make install) installs into /usr/local/bin, /usr/local/lib, /usr/local/include, and /usr/local/share/libdwarf. Doing 'make uninstall' (sudo make uninstall) deletes what 'make install' added but does not delete the /usr/local/share/libdwarf directory that the 'make install' created. CHECKING FOR MEMORY CORRUPTION Recent gcc has some checks that can be done at runtime. -fsanitize=address -fsanitize=leak -fsanitize=undefined which are turned on here by '/configure --enable-sanitize'. The --enable-sanitize option unlikely to work when cross-compiling. CROSS-COMPILES For those wishing to build libdwarf (and possibly dwarfdump) for a different host machine than the build machine it is now possible to do that. It has been tested with host and target set to an ARM with build on X86_64. See https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html for standard GNU usage of build, host, and target. See also: https://www.gnu.org/software/autoconf/manual/\ autoconf.html#Specifying-Target-Triplets The autoconf documentation strongly suggests adding --build to the configure commands and in the example below adding --build=i686-pc-linux-gnu is known to work on the test machine. The following is an example. Currently configure figures out the build environment for itself so we don't use --build here. On build machine: sudo apt-get install gcc-arm-linux-gnueabihf # Install libelf and zlib (libz) into # the gcc cross-build tree too. # I cheated: copied from arm machine into # gcc-arm-linux-gnueabihf. mkdir emptycross cd emptycross git clone git://git.code.sf.net/p/libdwarf/code cd code ./configure --host=arm-linux-gnueabihf make # done Doing a build on Ubuntu 18.04 (X86_64 environment) of a 32-bit libdwarf/dwarfdump requires some care. Doing sudo apt install gcc-6-multilib helps. It is a requirement that the build and host machines match with respect to the existence of system headers and of libraries. It seems necessary, in /usr/lib/i386-linux-gnu/ , to sudo cp libelf.so.1 libelf.so so the linker can find 32-bit libelf. In addition, one must build zlib for the host (if you have zlib in the build environment) (see above for the zlib source link) with CFLAGS=-m32 ./configure make sudo cp libz.a /usr/lib/i386-linux-gnu/ sudo cp libz.so /usr/lib/i386-linux-gnu/ #building libdwarf/dwarfdump in the source for no good reason: ./configure --host=i386-linux-gnu \ --build=x86_64-pc-linux-gnu \ CFLAGS="-O2 -m32" ------------------ notes on updating ------ To update configure after hand updating a Makefile.am or the configure.ac do the following command at the top level (where this file is): autoreconf -vif You will need the autotools installed including autoconf, automake, and libtool to run autoreconf. To run the basic checks of libdwarf/dwarfdump, first do ./configure make Then make check A further set of tests is available vi sh scripts/buildandreleasetest.sh which does configure, make check, make install (in temporary directories), make dist, and cmake. This script will not work on Windows. A full set of tests is sh scripts/run-all-tests.sh which requires the regressiontests directory also be present and if readelfobj is present will run its 'make check'. These tests outside the scope of this README. This script will not work on Windows. To create a release file on Linux do: ./configure --enable-dwarfexample --enable-dwarfgen make make dist will generate a libdwarf-yyyymmdd.tar.gz file with the files needed in a release scripts/CPTARTOWEBDIR is an example of generating fingerprints for the release file and copying the file. See the configure.ac for the version used. For example: 'm4_define([v_date], [20190505])])' David Anderson. Updated 7 November 2019 libdwarf-20210528/NEWS0000664000175000017500000002200014014262402011160 000000000000002021-02-15: dwarfdump given -ku now prints brief lists counting the uses of every TAG, ATtribute, and FORM, a concise summary of the basic building blocks of DWARF. 2021-01-23: dwarfdump now reports and checks-for-sensible-values the expression block offsets that DW_OP_bra and DW_OP_skip use. If an expression does not use either of those operators dwarfdump does not report the individual DW_OP expression offsets. 2020-12-23: dwarfdump --print-macinfo now follows DW_MACRO_imports and does several additional checks on .debug_macro section data. --check-macros skips printing most entries but does all that and reports even more about that section. Since .debug_macro does not reproduce all macro operations in the original source the MACRONOTEs printed are indications of things to consider, not errors. 2020-11-21: dwarfdump now prints DWARF expression operators each on its own line. This makes viewing DWARF expressions much nicer given the increased use of much longer expressions. Those expression operators that reference DIES are now followed, verified, and the target DW_TAG and DW_AT_name are printed. A new dwarfdump.conf command 'option:' lets one specify option: --format-expr-ops-joined in case you want the old style DWARF expression operators-on-one-line. Where the DWARF DIE children nest > nine-deep dwarfdump switches from indentation by spaces to a nest-level number. 2020-09-08: libdwarf/dwarfdump work well with DWARF4 and DWARF5, including DWP files. 2020-07-08: libdwarf now reads .debug_gnu_pubtypes & pubnames (non-standard but gcc creates them in DWARF5) via a small number of new functions and dwarfdump --print-debug-gnu prints both sections. Verifying the .debug_info offsets is not yet done. 2020-06-29: Dwarfdump now dumps DWARF5 .debug_rnglists and .debug_loclists. To handle DWARF5 there are a small number of new functions. All existing functions are still supported, but to read DWARF5 some small changes are required. In libdwarf see libdwarf2.1.pdf and also see libdwarf/ChangeLog for details. 2020-05-23: dwarfdump now takes much less malloc() to work, as measured by valgrind --tool=massif and massif-visualizer. A dwarfdump run that did 2.2Gib of malloc/free before the changes now does 1.4GiB. 2020-05-19: libdwarf and dwarfdump now support DWARF5 .debug_rnglists. The new interfaces are documented in libdwarf/libdwarf2.1.pdf. The new option to dwarfdump is "--print-raw-rnglists". 2019-11-04: The code (dwarfdump/libdwarf), regressiontests, and readelfobj directories and all their tests are known to work on Linux(Ubuntu on x86_64 and i686), FreeBSD, MacOS Catalina (with Apple Command Line Tools), and IBM s390 (Big Endian!) running Ubuntu Linux. On Windows-MinGW the full regression tests have not been tested, but 'make check' works for dwarfdump/libdwarf (the current dwarfdump make check actually does run dwarfdump and checks that dwarfdump basically works). 2019-04-16: Now a --disable-libelf configure/build of libdwarf/dwarfdump can read elf, mach-o DSYM, and PE executable/dll object files. Such a build will not need or use libelf or elf.h . The dwarfdump options that display Elf section headers or relocation record data are not available in a --disable-libelf build. Nor is dwarfdump's support of reading archive files available in a --disable-libelf build. This libdwarf detects corrupt Elf object files much sooner than before, but does not explain what the corruption really is. Use GNU readelf (or readelfobj, a project on sourceforge) to get more detail about the problems found. See https://www.prevanders.net/dwarf.html for the git clone command for readelfobj. With --disable-libelf the --enable-dwarfgen option does not work: the dwarfgen build will fail. 2019-02-18: For building on machines without a usable elf.h or libelf but possibly with a libelf.h visible, --disable-libelf ensures the build won't use libelf or elf.h anywhere. -lz will be done if zlib.h is visible, independent of libelf, libelf.h, and elf.h 2019-02-08: If one has a standard Bourne shell (sh) available (such as sh on MacOS and sh in MinGW on Windows) one may be able to build libdwarf and dwarfdump natively and they can read Mach-o dSYM and PE object files to access DWARF information. This has NOT been tested under MacOS, so will likely fail on MacOS. No elf.h, libelf.h or zlib.h should be present. For example, the following is known to work under MinGW and this general plan applies to all builds including all builds with elf.h and libelf: mkdir test cd test #(copy the source tree into test, if from git #the name of the top level will likely be 'code') cd code sh -x scripts/FIX-CONFIGURE-TIMES cd .. mkdir bld cd bld ../code/configure (choose your preferred options here) make 2019-01-15: The pre-build dwarf_names.[hc] and the tag related files are now part of the standard build so there is no longer any two-stage aspect of the build. The build simply compiles files in the distribution. If you use git to access the source be sure to sh scripts/FIX-CONFIGURE-TIMES to adjust the file timestamps as having timestamps in the right relationships is vital and git does not maintain timestamps. The script is always safe to run. It takes about 30 seconds. 2018-12-22: The complicated process of building certain .c and .h files has been relegated to the few people updating files libdwarf/libdwarf.h.in, libdwarf/dwarf_errmsg_list.h, dwarfdump/tag_attr_ext.list,dwarfdump/tag_attr.list, dwarfdump/tag_tree_ext.list, and dwarfdump/tag_tree.list. For everyone else the build is simply compiling the .c and .h files in the distribution. Simpler. sh scripts/buildstandardsource.sh creates these files. 2018-10-22: dwarfdump can now dump mach-o (MacOS) dSYM dwarf. All the usual libdwarf interfaces work. A new libdwarf initialization call dwarf_init_path() may be convenient for you to use. 2018-08-05: dwarfdump.conf is now installed by make install in /shared/libdwarf/dwarfdump . Any dwarfdump.conf or .dwarfdump.conf in your $HOME directory will be found before the one in shared. The file is only opened when one wants a more accurate register naming in frame reports (the default is just to name things r54 etc, choosing the right abi with -x abi= can be helpful at times). 2018-06-24: The configure has been completely rewritten to follow current standards and practices. For simple builds the standard ./configure make works as always, but the generated libdwarf.a appears in libdwarf/.libs/libdwarf.a , as does the shared object if "./configure --enable-shared" is used. To build dwarfgen one adds the configure option --enable-dwarfgen instead of using 'make all'. To build the example code one adds the configure option --enable-dwarfexample instead of using 'make all'. "mkdir /tmp/bld ; cd /tmp/bld ; /configure" continues to work, as does configure --host= . 2018-06-14: A small simplification of build options simplifies building across different environments. If your environment needs to use the non-standard elf_open() call instead of unix/linux open() then do /configure --enable-elf-open which sets HAVE_ELF_OPEN in config.h. 2018-03-27: All the DWARF5 FORMs appear to be dealt with. It's now possible to cross-compile libdwarf and dwarfdump. See the README. 2016-11-30: An alternative build mechanism using cmake is now in the source tree. The builds for product testing continue to be done using configure && make. 2016-09-20: --enable-sanitize option added to configure. This builds with -fsanitize=address to check for out of bounds memory access. 2016-09-05: dwarfexample/simpleexample.c now has a simple option letting one extract all .debug_info, .debug_types strings into a file by themselves in case one wanted to examine string frequencies, for example. 2016-06-01: Now we use DW_VERSION_DATE_STR for dates everywhere instead of __DATE__ __TIME__ so a repeated build gets identical object output. DW_VERSION_DATE_STR is updated by UPDATEDWARFDUMPVERSION.sh wherever that string is needed. 2015-11-26: If DWARF section data you intend to read with libdwarf is compressed by zlib (a section name like .zdebug_info indicates such compression) libdwarf etc will need zlib's headers and archive or shared-library at build and link time. If you do not have zlib everything will compile fine and will work on ordinary DWARF sections but libdwarf will not be able to read .zdebug_ compressed sections. zlib.h is the main zlib header and libz.a is the most likely zlib library you will encounter. 2015-11-15: It is now possible to build outside of the source tree. See README. So configure.in changed a little. 2015-01-13: Removed dwarfdump2 and references to it. dwarfdump has the (tsearch) features needed so the C++ version no longer a benefit. libdwarf-20210528/ChangeLog0000664000175000017500000000460314054252106012250 000000000000002021-05-28: David Anderson * CMakeLists.txt:Version string now 20210528 * Makefile.am: Added scripts ChangeLogs for 2019, 2020. Removed scripts items that were deleted from the source (no longer needed) * Makefile.in: Regenerated. * README.md: Removes reference to deleted script, references 'make dist' instead. * configure.ac: Version 20210528 * configure: regenerated 2021-05-20: David Anderson * CMakeLists.txt, configure.ac: Now version 20210520 * configure: Regenerated. 2021-05-17: David Anderson * CMakeLists.txt: Removed test that has been irrelevant for quite a while (and had a serious misspelling too). * config.h.in.cmake: Added two missing header file checks and the associated cmakedefine lines. Removed cmakedefine NO_MINUS_C_MINUS_O as it only applies to configure (not to cmake). 2021-05-17: David Anderson * README: Removed obsolete reference to libelf source. 2021-05-14: David Anderson * bugxml/bugrecord.py, bugxml/readbugs.py: Reformatted to standard python style. 2021-05-14: David Anderson * CMakeLists.txt: Updateing version to match configure.ac and adding comment to keep these files in sync. * configure.ac: Added comment to keep the version here and in CMakeLists.txt in sync. No other change. 2021-05-12: David Anderson * CMakeLists.txt: Fixing a disastrous error removing creation of libdwarf.h from the build. The mistake was made in a commit 24 November 2020. Now ctest -R passes again, with or without libelf. 2021-03-05: David Anderson * configure.ac: Now version 20210305. * configure: Regenerated. 2021-02-14: David Anderson 2021-02-19: David Anderson * scripts/ddbuild.sh: needed a -DSKIP_AF_CHECK to allow building a helper program that emits C source for dwarfdump. 2021-02-15: David Anderson * configure.ac: Now version 20210214. * configure: Regenerated. 2021-02-14: David Anderson * scripts/ddbuild.sh: Now also builds a table for initializing standard attr/form tables for checking attr/form combinations. 2021-01-19: David Anderson * scripts/conddef.py,scripts/find_pdfpages.py, scripts/funcfinderhdr.py,scripts/funcfindermm.py, scripts/funcfindersrcs.py,scripts/haveinclude.py: All now are fairly close to following the Python PEP 8 style guide.` libdwarf-20210528/config.sub0000755000175000017500000010645014054252020012455 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo "$1" | sed 's/-[^-]*$//'` if [ "$basic_machine" != "$1" ] then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2*) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsv-tandem) basic_machine=nsv-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh5el) basic_machine=sh5le-unknown ;; simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; x64) basic_machine=x86_64-pc ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases that might get confused # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) -es1800*) os=-ose ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -xray | -os68k* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4*) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=-eabi ;; *) os=-elf ;; esac ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac echo "$basic_machine$os" exit # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libdwarf-20210528/codingstyle.txt0000664000175000017500000002763113750412267013601 00000000000000Latest update: 3 November 2020 Adapted from the Cairo coding style document Libdwarf/dwarfdump coding style. This document is intended to be a short description of the preferred coding style for the cairo source code. Good style requires good taste, which means this can't all be reduced to automated rules, and there are exceptions. We want the code to be easy to understand and maintain, and consistent style plays an important part in that, even if some of the specific details seem trivial. If nothing else, this document gives a place to put consistent answers for issues that would otherwise be arbitrary. Most of the guidelines here are demonstrated by examples, (which means this document is quicker to read than it might appear given its length). Most of the examples are positive examples that you should imitate. The few negative examples are clearly marked with a comment of /* Yuck! */. Please don't submit code for libdwarf that looks like any of these. Indentation ----------- Each new level is indented 4 more spaces than the previous level, and an if is followed by a space and a left-paren: if (condition) { do_something(); } Done solely with space characters. The simple project on sourceforge.net, dicheck-da, detects all instances of tabs, improper indentation and line-ending whitespace. Similarly, for is to have a single space after the r followed by a left_paren. for (v; condition; v2) { do_something(); } Tab characters -------------- The tab character must never appear. Braces ------ Most of the code in cairo uses bracing in the style of K&R: if (condition) { do_this(); do_that(); } else { do_the_other(); } and that is the preferred style. Even if all of the substatements of an if statement are single statements, the optional braces must always appear. if (condition) { do_this(); } else { do_that(); } Never if (condition) /* Yuck */ do_this(); /* Yuck */ else /* Yuck */ do_the_other(); /* Yuck */ Note that this last example also shows a situation in which the opening brace can be on its own line, though usually it looks like this example. The following can be difficult to read. if (condition && other_condition && yet_another) { /* But we usually do put the brace here */ do_something(); } Whitespace ---------- Separate logically distinct chunks with a single newline. This obviously applies between functions, but also applies within a function or block and can even be used to good effect within a structure definition. But don't get carried away with blank lines: struct _Dwarf_Data_s { struct Something_s op; double tolerance; Dwarf_Unsigned line_width; Dwarf_Unsigned line_height; Dwarf_Unsigned line_thickness; /* Notice the _s on struct declarations And notice indent of this comment and the blank line above this comment to make it clear the comment applies to fill_rule. */ struct Reg_Struct_s fill_rule; Dwarf_Signed distance_from_end; ... }; Never use a space before a function-call left parenthesis or a macro-call left parenthesis. Don't eliminate newlines just because things would still fit on one line. This breaks the expected visual structure of the code making it much harder to read and understand: (); /* Yuck! */ Eliminate trailing whitespace on any line. Also, avoid putting initial or final blank lines into any file, and never use multiple blank lines instead of a single blank line. Use dicheck (see above) to find trailing whitespace and indentation inconsistencies. You might find the git-stripspace utility helpful which acts as a filter to remove trailing whitespace as well as initial, final, and duplicate blank lines. As a special case of the bracing and whitespace guidelines, function definitions in libdwarf should always take the following form: int my_function (Dwarf_Debug dbg, Dwarf_Unsigned second_arg, Dwarf_Unsigned* ret_value; Dwarf_Error *error) { do_my_things(); /* The meaning of life */ *ret_value = 42; return DW_DLV_OK; } And in dwarfdump, etc, the code tends to follow this form too (but far from always). Function prototypes inside libdwarf headers (as opposed to .c files) usually have the return type (and associated specifiers and qualifiers) the same line as the function name. If the line gets long addtional lines are appropriate. Function prototypes inside libdwarf.h always comment out argument names (but not types) to preserve the caller's macro namespace. Because it is a public header, unlike all the other headers in libdwarf/dwarfdump/simpleexample. In .c files the function name starts a line as shown above. Notice, above, how a too-long argument line gets folded with standard indentation(4). Break up long lines (> ~72 characters) and use whitespace to align things nicely. For example the arguments in a long list to a function call should all (but the first) be aligned with each other: align_function_arguments (argument_the_first, argument_the_second, argument_the_third); And as a special rule, in a function prototype, (as well as in the definition), whitespace should be inserted between the parameter types and names so that the names are aligned: void align_parameter_names_in_prototypes (const char *char_star_arg, int int_arg, double *double_star_arg, double double_arg); Parameters with a * prefix are aligned one character to the left so that the actual names are aligned. Struct Format and Content ------------------------- Usually, avoid adding a comment alongside declarations unless it is a very short comment. The following example uses meaningless x y z field names (sorry), but but does show a short prefix related to the struct name. Generally struct members should have a prefix common to that struct and hopefully distinct from other struct declarations. This short prefix makes it much easier to find all uses of a particular field in the code (with grep). struct Dwarf_Nothing_Special_s { int ns_x; /* usually avoid comment here this is Yuck! and this is even worse as continuation. Yuck! */ /* Comment here about y with blank line above and belows to make it clear which line referred to. */ unsigned ns_y; unsigned ns_z; }; Managing nested blocks ---------------------- Long blocks that are deeply nested make the code very hard to read. Fortunately such blocks often indicate logically distinct chunks of functionality that are begging to be split into their own functions. Please listen to the blocks when they beg. You will notice many exceptions to this in the code, unfortunately. In other cases, gratuitous nesting comes about because the primary functionality gets buried in a nested block rather than living at the primary level where it belongs. Consider the following: foo = malloc (sizeof (foo_t)); if (foo) { /* Yuck! The error return becomes hard to see. */ ... /* lots of code to initialize foo */ ... return DW_DLV_OK; } _dwarf_error(dbg,error,DW_DLE_MALLOC_RETURNS_NULL); return DW_DLV_ERROR; This kind of gratuitous nesting can be avoided by following a pattern of handling exceptional cases early and returning: foo = malloc (sizeof (foo_t)); /* A test foo == NULL is fine but the following is better as there is no danger of turning == into = by accident. */ if (!foo) { _dwarf_error(dbg,error,DW_DLE_MALLOC_RETURNS_NULL); return DW_DLV_ERROR; } ... lots of code to initialize foo */ return DW_DLV_OK; The return statement is often the best thing to use in a pattern like this. If it's not available due to additional nesting above which require some cleanup after the current block, then consider splitting the current block into a new function before using goto. Test or Loop with Side Effect ----------------------------- Never do: if ((foo = malloc (sizeof (foo_t)))) { or if (foo = malloc (sizeof (foo_t))) { as the reader has to think carefully about it, whereas foo = malloc (sizeof (foo_t)); if (foo) { is more transparent (in some sense) and makes it easier to stop( in debugger) or add a printf in case this is a point where things might be going wrong somehow. Also see "Managing nested blocks" just above. Macro Tests Commented --------------------- #ifdef SOME_MACRO #else /* !SOME_MACRO */ #endif /* !SOME_MACRO */ #ifdef OTHER_MACRO #endif /* OTHER_MACRO */ The comments add clarity when one is not familiar with code in the area but are not required if the #else #endif are within a couple lines of the #if(def). In a spot with nested #if(def) the comments become necessary to avoid confusing the reader. There is nothing wrong with adding them everywhere. Lookup Tables ----------------- Any situation requiring a lookup table should use one or the other tsearch functions. The practical ones are dwarf_tsearchhash.c and dwarf_tsearchbal.c. dwarfdump and libdwarf each use one of them and only one of them. See the tsearch directory to see the full set available. These use the traditional UNIX tsearch arguments and return values even though those are not good designs by current standards. Expanded to have destroy() functions whose prototype was copied from GNU man pages. GNU libc has much nicer (in the sense of much nicer interface designs) non-standard tsearch functions, but we've ignored those to keep to the official Single Unix Specification standard interfaces. Libdwarf Namespace ----------------- In libdwarf we are careful to name things visible to callers (and in libdwarf.h) starting with with dwarf (for public stuff) or _dwarf (for functions in the library not intended for public use. Structs begin with Dwarf. Macros begin with DW (dwarf.h is full of those!). Memory allocation ----------------- In general, be wary of performing any arithmetic operations in an argument to malloc. You should explicitly check for integer overflow yourself in any more complex situations. In libdwarf most allocations use _dwarf_alloc() instead of malloc. And the tables of valid types (which are predefined in libdwarf) allow for constructor/destructor functions. The _dwarf_alloc() code keeps a record of what is allocated so a careless user can simply call dwarf_finish() at the end and all the allocated data will be freed that was not already freed via user calls to dwarf_dealloc(). Checking For Overflow --------------------- Libdwarf and dwarfdump are often dealing with offsets and indexes read from disk object files and all such should be checked before use. That approach means that dwarfdump (and libdwarf callers in general) need not check the things that libdwarf has returned (at least those libdwarf could check). When it is possible that X +Y might overflow make every effort to check X an Y independently before attempting an addition. If you are confident X and Y are sensible (given available data like section sizes) you can add them and then determine if the sum (say an offset) is still within the relevant section or data-item usable range. There are many libdwarf-internal functions to read data from an object, and all of them require an end-pointer argument so the code can easly check for corrupt object-file or DWARF values without duplicating the error-code-setting. Dwarfdump Flags Data --------------------- Dwarfdump has a large number of options and nearly all the option values are recorded as fields in a single global structure glflags (see dwarfdump.c). Option data not in that structure should be moved into it, in general. This makes it much simpler to find instances using flags and to know, reading dwarfdump source, when flags are being referred to.. The text in this document (not the examples!) was formatted with the vi command "!}fmt -64"...without the quotes. libdwarf-20210528/README.md0000664000175000017500000000503314054013733011754 00000000000000[![Travis Build Status](https://travis-ci.org/dvirtz/libdwarf.svg?branch=cmake)](https://travis-ci.org/dvirtz/libdwarf) [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/oxh8pg7hsuav2jrl?svg=true)](https://ci.appveyor.com/project/dvirtz/libdwarf) # This is README.md ## BUILDING To just build libdwarf and dwarfdump, if the source tree is in `/a/b/libdwarf-1` ### Using CMake August 23 2018 and the following seems to work: rm -rf /tmp/bld mkdir /tmp/bld cd /tmp/bld cmake /a/b/libdwarf-1 # The following does not necessarily work. ? To build using CMake one might do * `cd /a/b/libdwarf-1` * configure: `cmake . -B_Release -DCMAKE_BUILD_TYPE=Release` * build: `cmake --build _Release --target dd` * (optionally install): `sudo cmake --build _Release --target install` # for autotools builds, see README ### Using autotools #### Builing in Source Tree ```bash cd /a/b/libdwarf-1 ./configure make dd #You may need to be root to do the following copy commands cp dwarfdump/dwarfdump /usr/local/bin cp dwarfdump/dwarfdump.conf /usr/local/lib #The following is optional, not needed to run dwarfdump #when doing the default build. cp libdwarf/libdwarf.a /usr/local/lib ``` #### Building Out of Source Tree ```bash mkdir /var/tmp/dwarfex cd /var/tmp/dwarfex /a/b/libdwarf-1/configure make dd ``` In this case the source directory is not touched and all objects and files created are under `/var/tmp/dwarfex` NOTE: When building out of source tree the source tree must be cleaned of any files created by a build in the source tree. This is due to the way GNU Make VPATH works. ### Build All To build all the tools (including dwarfgen and dwarfexample) use `--target all` on CMake or `make all` on autotools. There are known small compile-time issues with building dwarfgen on MaxOSX and most don't need to build dwarfgen. ### Options By default configure compiles and uses libdwarf.a. With `-Dshared=ON` (CMake) or `--enable-shared` (autotools) appended to the configure step, both libdwarf.a and libdwarf.so are built. The runtimes built will reference libdwarf.so. With `-Dnonshared=FALSE` (CMake) or `--disable-nonshared` (autotools) appeded to the configure step, libdwarf.so is built and used; libdwarf.a is not built. Sanity checking: Recent gcc has some checks that can be done at runtime. -fsanitize=undefined which are turned on here by --enable-sanitize at build time. ### Distributing When ready to create a new source distribution do a build and then make dist David Anderson. Updated May 2021 libdwarf-20210528/Makefile.am0000664000175000017500000000366014054017470012537 00000000000000###Copyright (C) 2018 Vincent Torri . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and libdwarf-list -at- $0: linuxmail -dot- org about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libdwarf' PACKAGE_TARNAME='libdwarf' PACKAGE_VERSION='20210528' PACKAGE_STRING='libdwarf 20210528' PACKAGE_BUGREPORT='libdwarf-list -at- linuxmail -dot- org' PACKAGE_URL='' ac_unique_file="configure.ac" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS ALLOCA DWARF_CFLAGS_WARN DWARF_CXXFLAGS_WARN DWARF_BIGENDIAN struct_elf DWARF_LIBS CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX release_info version_info CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL OBJDUMP DLLTOOL AS AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR HAVE_WIN32_FALSE HAVE_WIN32_TRUE host_os host_vendor host_cpu host build_os build_vendor build_cpu build dwarf_namestable HAVE_DWARFEXAMPLE_FALSE HAVE_DWARFEXAMPLE_TRUE HAVE_DWARFGEN_FALSE HAVE_DWARFGEN_TRUE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dwarfgen enable_dwarfexample enable_globalallocsums enable_sanitize enable_oldframecol enable_namestable enable_libelf enable_windowspath enable_wall enable_nonstandardprintf enable_havecustomlibelf enable_dependency_tracking enable_silent_rules enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP CXX CXXFLAGS CCC CXXCPP DWARF_LIBS DWARF_BIGENDIAN' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libdwarf 20210528 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libdwarf] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libdwarf 20210528:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dwarfgen enable dwarfgen compilation [default=no] --enable-dwarfexample enable dwarfexample compilation [default=no] --enable-global-alloc-sums Enables some allocation counting in dwarf_alloc.c (default is NO) --enable-sanitize enable sanitize compiler option [default=no] --enable-oldframecol enable old frame columns [default=no] --enable-namestable enable name string functions implemented as binary search (default is with C switch) [default=no] --disable-libelf disable use of libelf (default is enable) [default=yes] --enable-windowspath Detect certain Windows paths as full paths (default is NO) --enable-wall enable -Wall and other options [default=no] --enable-nonstandardprintf Use a special printf format for 64bit (default is NO) --enable-havecustomlibelf including a custom libelf library (default is NO) --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-shared[=PKGS] build shared libraries [default=no] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor DWARF_LIBS linker flags when linking libdwarf DWARF_BIGENDIAN big endian yes/no needed for dwarfexample test Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libdwarf configure 20210528 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------------------------------- ## ## Report this to libdwarf-list -at- linuxmail -dot- org ## ## ----------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libdwarf $as_me 20210528, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ### Additional options to configure # Check whether --enable-dwarfgen was given. if test "${enable_dwarfgen+set}" = set; then : enableval=$enable_dwarfgen; if test "x${enableval}" = "xyes"; then : enable_dwarfgen="yes" else enable_dwarfgen="no" fi else enable_dwarfgen="no" fi if test "x${enable_dwarfgen}" = "xyes"; then HAVE_DWARFGEN_TRUE= HAVE_DWARFGEN_FALSE='#' else HAVE_DWARFGEN_TRUE='#' HAVE_DWARFGEN_FALSE= fi # Check whether --enable-dwarfexample was given. if test "${enable_dwarfexample+set}" = set; then : enableval=$enable_dwarfexample; if test "x${enableval}" = "xyes"; then : enable_dwarfexample="yes" else enable_dwarfexample="no" fi else enable_dwarfexample="no" fi if test "x${enable_dwarfexample}" = "xyes"; then HAVE_DWARFEXAMPLE_TRUE= HAVE_DWARFEXAMPLE_FALSE='#' else HAVE_DWARFEXAMPLE_TRUE='#' HAVE_DWARFEXAMPLE_FALSE= fi ### Solely for checking libdwarf allocation counts,sizes ### Do not use without a good reason . See libdwarf/dwarf_alloc.c # Check whether --enable-globalallocsums was given. if test "${enable_globalallocsums+set}" = set; then : enableval=$enable_globalallocsums; $as_echo "#define HAVE_GLOBAL_ALLOC_SUMS 1" >>confdefs.h enable_globalallocsums="yes" else enable_globalallocsums="no" fi # Check whether --enable-sanitize was given. if test "${enable_sanitize+set}" = set; then : enableval=$enable_sanitize; if test "x${enableval}" = "xyes"; then : enable_sanitize="yes" else enable_sanitize="no" fi else enable_sanitize="no" fi # Check whether --enable-oldframecol was given. if test "${enable_oldframecol+set}" = set; then : enableval=$enable_oldframecol; if test "x${enableval}" = "xyes"; then : enable_oldframecol="yes" else enable_oldframecol="no" fi else enable_oldframecol="no" fi if test "x${enable_oldframecol}" = "xyes"; then : $as_echo "#define HAVE_OLD_FRAME_CFA_COL 1" >>confdefs.h fi # Check whether --enable-namestable was given. if test "${enable_namestable+set}" = set; then : enableval=$enable_namestable; if test "x${enableval}" = "xyes"; then : enable_namestable="yes" else enable_namestable="no" fi else enable_namestable="no" fi if test "x${enable_namestable}" = "xyes"; then : dwarf_namestable=-s else dwarf_namestable=-t fi # Check whether --enable-libelf was given. if test "${enable_libelf+set}" = set; then : enableval=$enable_libelf; if test "x${enableval}" = "xyes"; then : dwarf_with_libelf="yes" else dwarf_with_libelf="no" fi else dwarf_with_libelf="yes" fi # Check whether --enable-windowspath was given. if test "${enable_windowspath+set}" = set; then : enableval=$enable_windowspath; $as_echo "#define HAVE_WINDOWS_PATH 1" >>confdefs.h enable_windowspath="yes" else enable_windowspath="no" fi # Check whether --enable-wall was given. if test "${enable_wall+set}" = set; then : enableval=$enable_wall; if test "x${enableval}" = "xyes"; then : enable_wall="yes" else enable_wall="no" fi else enable_wall="no" fi # Check whether --enable-nonstandardprintf was given. if test "${enable_nonstandardprintf+set}" = set; then : enableval=$enable_nonstandardprintf; $as_echo "#define HAVE_NONSTANDARD_PRINTF_64_FORMAT 1" >>confdefs.h enable_nonstandardprintf="yes" else enable_nonstandardprintf="no" fi # Check whether --enable-havecustomlibelf was given. if test "${enable_havecustomlibelf+set}" = set; then : enableval=$enable_havecustomlibelf; $as_echo "#define HAVE_CUSTOM_LIBELF 1" >>confdefs.h enable_havecustomlibelf="yes" else enable_havecustomlibelf="no" fi ### Default options with respect to host ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac have_win32="no" case "$host_os" in mingw*) have_win32="yes" ;; esac if test "x${have_win32}" = "xyes"; then HAVE_WIN32_TRUE= HAVE_WIN32_FALSE='#' else HAVE_WIN32_TRUE='#' HAVE_WIN32_FALSE= fi ### Checks for programs # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac ### We don't use dist-xz *.xz output from make dist, ### so don't mention it. am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 $as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 $as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libdwarf' VERSION='20210528' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cr} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cr libconftest.a conftest.o" >&5 $AR cr libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=no fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi enable_dlopen=no # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: version_info="1:0:0" release_info="" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi ###PKG_PROG_PKG_CONFIG Intentionally not using pkg-config ### Checks for libraries ### Checks for header files ### MacOS does not have malloc.h for ac_header in unistd.h sys/types.h regex.h malloc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ### for uintptr_t for ac_header in stdint.h inttypes.h stddef.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in windows.h do : ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" if test "x$ac_cv_header_windows_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINDOWS_H 1 _ACEOF fi done for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF fi done if test "x${ac_cv_header_zlib_h}" = "xyes"; then : have_pc_zlib="yes" ; echo "have zlib" ; DWARF_LIBS="${DWARF_LIBS} -lz" else have_pc_zlib="no" ; echo "no zlib" fi ### for use in casts to uint to avoid 32bit warnings. ### Also needed by C++ cstdint ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define uintptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" if test "x$ac_cv_type_intptr_t" = xyes; then : $as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h else for ac_type in 'int' 'long int' 'long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define intptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ### Now we know uintptr_t is either in stdint.h or ### is defined in config.h by configure. # test Elf headers in the preprocessor path search CPPFLAGS_save=${CPPFLAGS} ### we set $dwarf_with_libelf above. if test $dwarf_with_libelf = "yes" ; then for ac_header in sgidefs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sgidefs.h" "ac_cv_header_sgidefs_h" "$ac_includes_default" if test "x$ac_cv_header_sgidefs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SGIDEFS_H 1 _ACEOF fi done for ac_header in libelf.h libelf/libelf.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in elf.h elfaccess.h sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h sys/ia64/elf.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ### if no libelf.h add no -lelf and turn off ### libelf recognition. if test "x${ac_cv_header_libelf_h}" != "xyes" -a "x${ac_cv_header_libelf_libelf_h}" != "xyes" ; then : dwarf_with_libelf="no" echo "no libelf headers, no libelf" else DWARF_LIBS="${DWARF_LIBS} -lelf" dwarf_with_libelf="yes" echo "Allowing use of libelf." $as_echo "#define DWARF_WITH_LIBELF 1" >>confdefs.h fi ### begin checking for Elf structs # Elf64_Rela in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rela p; p.r_offset = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_RELA 1" >>confdefs.h have_elf64_rela="yes" else have_elf64_rela="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_rela}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rela p; p.r_offset = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_RELA 1" >>confdefs.h have_elf64_rela="yes" else have_elf64_rela="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Rela in elf.h" >&5 $as_echo_n "checking for Elf64_Rela in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_rela}" >&5 $as_echo "${have_elf64_rela}" >&6; } # Elf64_Rel in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rel p; p.r_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_R_INFO 1" >>confdefs.h have_elf64_rel="yes" else have_elf64_rel="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_rel}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rel p; p.r_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_R_INFO 1" >>confdefs.h have_elf64_rel="yes" else have_elf64_rel="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Rel in elf.h" >&5 $as_echo_n "checking for Elf64_Rel in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_rel}" >&5 $as_echo "${have_elf64_rel}" >&6; } # Elf64_Sym in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Sym p; p.st_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_SYM 1" >>confdefs.h have_elf64_sym="yes" else have_elf64_sym="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_sym}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Sym p; p.st_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_SYM 1" >>confdefs.h have_elf64_sym="yes" else have_elf64_sym="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Sym in elf.h" >&5 $as_echo_n "checking for Elf64_Sym in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_sym}" >&5 $as_echo "${have_elf64_sym}" >&6; } ### end checking for Elf structs ### Checks for Elf structures # test if struct _Elf is used instead of struct Elf cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; int main () { struct _Elf *a = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_struct__elf="yes" struct_elf="struct _Elf" else have_struct__elf="no" struct_elf="struct Elf" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct _Elf is used" >&5 $as_echo_n "checking whether struct _Elf is used... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_struct__elf}" >&5 $as_echo "${have_struct__elf}" >&6; } else ### end where dwarf_with_libelf == "no" via ### --disable-libelf have_struct__elf="no" struct_elf="struct Elf" have_elf64_rela="no" have_elf64_rel="no" have_elf64_sym="no" fi ### Checks for compiler characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac DWARF_BIGENDIAN=${ac_cv_c_bigendian} # gcc accepts even totally bogus -Wno flags. Other compilers..no # -Wno-long-long suppresses warnings on 'long long' # -Wno-pedantic-ms-format (which only exists in mingw) # suppresses warnings about I64 printf format. if test "x$enable_wall" = "xyes" ; then : cxx_compiler_flags="-Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" c_compiler_flags="-Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs -Werror" fi if test "x$enable_nonstandardprintf" = "xyes" ; then : cxx_compiler_flags="$cxx_compiler_flags -Wno-pedantic-ms-format" c_compiler_flags="$c_compiler_flags -Wno-pedantic-ms-format" fi option="${cxx_compiler_flags}" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports ${cxx_compiler_flags}" >&5 $as_echo_n "checking whether the C++ compiler supports ${cxx_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CXXFLAGS="${CXXFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} ${cxx_compiler_flags}" fi if test "${have_flag}" != "yes"; then : option="${cxx_compiler_flags}" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports ${cxx_compiler_flags}" >&5 $as_echo_n "checking whether the C++ compiler supports ${cxx_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CXXFLAGS="${CXXFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} ${cxx_compiler_flags}" fi fi option="${c_compiler_flags}" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports ${c_compiler_flags}" >&5 $as_echo_n "checking whether the C compiler supports ${c_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="${CFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} ${c_compiler_flags}" fi if test "${have_flag}" != "yes"; then : option="${c_compiler_flags}" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports ${c_compiler_flags}" >&5 $as_echo_n "checking whether the C compiler supports ${c_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="${CFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} ${c_compiler_flags}" fi fi # unused attribute cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ static unsigned int foo(unsigned int x, __attribute__ ((unused)) int y){ unsigned int x2 = x + 1; return x2; } int goo() { unsigned int y = 0; y = foo(12, y); } int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_unused="yes" $as_echo "#define HAVE_UNUSED_ATTRIBUTE 1" >>confdefs.h else have_unused="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \"unused\" attribute is available" >&5 $as_echo_n "checking whether \"unused\" attribute is available... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_unused}" >&5 $as_echo "${have_unused}" >&6; } # sanitize if test "x${enable_sanitize}" = "xyes"; then : CFLAGS_save=${CFLAGS} CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" DWARF_CFLAGS= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : enable_sanitize="yes" DWARF_CFLAGS="$DWARF_CFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" else enable_sanitize="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="${CFLAGS_save} ${DWARF_CFLAGS}" DWARF_CFLAGS= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sanitize options are used" >&5 $as_echo_n "checking whether sanitize options are used... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_sanitize}" >&5 $as_echo "${enable_sanitize}" >&6; } ### Checks for linker characteristics ### Checks for library functions ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi if test $dwarf_with_libelf = "yes" ; then # elf64_getehdr CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS}" LIBS_save=${LIBS} LIBS="${LIBS} ${DWARF_LIBS}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing elf64_getehdr" >&5 $as_echo_n "checking for library containing elf64_getehdr... " >&6; } if ${ac_cv_search_elf64_getehdr+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char elf64_getehdr (); int main () { return elf64_getehdr (); ; return 0; } _ACEOF for ac_lib in '' elf; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_elf64_getehdr=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_elf64_getehdr+:} false; then : break fi done if ${ac_cv_search_elf64_getehdr+:} false; then : else ac_cv_search_elf64_getehdr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_elf64_getehdr" >&5 $as_echo "$ac_cv_search_elf64_getehdr" >&6; } ac_res=$ac_cv_search_elf64_getehdr if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_getehdr="yes" $as_echo "#define HAVE_ELF64_GETEHDR 1" >>confdefs.h else have_getehdr="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing elf64_getshdr" >&5 $as_echo_n "checking for library containing elf64_getshdr... " >&6; } if ${ac_cv_search_elf64_getshdr+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char elf64_getshdr (); int main () { return elf64_getshdr (); ; return 0; } _ACEOF for ac_lib in '' elf; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_elf64_getshdr=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_elf64_getshdr+:} false; then : break fi done if ${ac_cv_search_elf64_getshdr+:} false; then : else ac_cv_search_elf64_getshdr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_elf64_getshdr" >&5 $as_echo "$ac_cv_search_elf64_getshdr" >&6; } ac_res=$ac_cv_search_elf64_getshdr if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_getshdr="yes" $as_echo "#define HAVE_ELF64_GETSHDR 1" >>confdefs.h else have_getshdr="no" fi CPPFLAGS=${CPPFLAGS_save} LIBS=${LIBS_save} else have_getehdr="no" have_getshdr="no" fi if test "x${have_pc_zlib}" = "xno" -a "x${have_zlib}" = "xyes"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing z" >&5 $as_echo_n "checking for library containing z... " >&6; } if ${ac_cv_search_z+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char z (); int main () { return z (); ; return 0; } _ACEOF for ac_lib in '' have_zlib="yes"; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_z=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_z+:} false; then : break fi done if ${ac_cv_search_z+:} false; then : else ac_cv_search_z=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_z" >&5 $as_echo "$ac_cv_search_z" >&6; } ac_res=$ac_cv_search_z if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_zlib="no" fi fi if test "x${have_pc_zlib}" = "xyes" -o "x${have_zlib}" = "xyes"; then : have_zlib="yes" $as_echo "#define HAVE_ZLIB 1" >>confdefs.h $as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h else have_zlib="no" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_REGEX_H # include #endif int main () { int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_REGEX 1" >>confdefs.h have_regex="yes" else have_regex="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regex library" >&5 $as_echo_n "checking for regex library... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_regex}" >&5 $as_echo "${have_regex}" >&6; } ### Checks for system services ac_config_files="$ac_config_files Makefile libdwarf/Makefile dwarfdump/Makefile dwarfgen/Makefile dwarfexample/Makefile" ### libdwarf needs to be adjusted to support struct Elf ### or struct _Elf, whichever the system defines in libelf. ac_config_commands="$ac_config_commands libdwarf/libdwarf.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${HAVE_DWARFGEN_TRUE}" && test -z "${HAVE_DWARFGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWARFGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DWARFEXAMPLE_TRUE}" && test -z "${HAVE_DWARFEXAMPLE_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWARFEXAMPLE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_WIN32_TRUE}" && test -z "${HAVE_WIN32_FALSE}"; then as_fn_error $? "conditional \"HAVE_WIN32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libdwarf $as_me 20210528, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libdwarf config.status 20210528 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' haself=${have_struct__elf} top=${ac_pwd} src=${srcdir} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libdwarf/Makefile") CONFIG_FILES="$CONFIG_FILES libdwarf/Makefile" ;; "dwarfdump/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfdump/Makefile" ;; "dwarfgen/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfgen/Makefile" ;; "dwarfexample/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfexample/Makefile" ;; "libdwarf/libdwarf.h") CONFIG_COMMANDS="$CONFIG_COMMANDS libdwarf/libdwarf.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; "libdwarf/libdwarf.h":C) sh $src/scripts/fixlibdwarfelf.sh $haself $src $top ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo echo "$PACKAGE $VERSION" echo echo "Configuration Options Summary:" echo echo " BuildOS..............: ${build_os}" echo " HostOS...............: ${host_os}" echo echo " shared library.......: ${enable_shared}" echo " static library.......: ${enable_static}" echo echo " zlib support.........: ${have_zlib}" echo " sanitize support.....: ${enable_sanitize}" echo " BuildOS-BigEndian....: ${ac_cv_c_bigendian}" echo echo " libdwarf.............: always" echo " old frame column...: ${enable_oldframecol}" echo " names table........: ${enable_namestable}" echo " elf64_getehdr......: ${have_getehdr}" echo " elf64_getshdr......: ${have_getshdr}" echo " Elf64_Rela.........: ${have_elf64_rela}" echo " Elf64_Sym..........: ${have_elf64_sym}" echo " Elf spelled........: ${struct_elf}" echo " libelf.............: ${dwarf_with_libelf}" echo " Windows path corr..: ${enable_windowspath}" echo " Nonstandardprintf..: ${enable_nonstandardprintf}" echo " Custom libelf......: ${enable_havecustomlibelf}" echo " dwarfdump............: always" echo " elf64_getehdr......: ${have_getehdr}" echo " Elf64_Rel (r_info).: ${have_elf64_rel}" echo " regex..............: ${have_regex}" echo " dwarfgen.............: ${enable_dwarfgen}" echo " dwarfexample.........: ${enable_dwarfexample}" echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS ${c_compiler_flags}" echo " LDFLAGS..............: $LDFLAGS" echo " LIBS.................: $LIBS" echo " DWARF_LIBS...........: $DWARF_LIBS" echo echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" echo libdwarf-20210528/ltmain.sh0000644000175000017500000117716714054252014012333 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-14" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2015-10-07.11; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd _G_rc_run_hooks=false case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do if eval $_G_hook '"$@"'; then # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift _G_rc_run_hooks=: fi done $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, you may remove/edit # any options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. In this case you also must return $EXIT_SUCCESS to let the # hook's caller know that it should pay attention to # '_result'. Returning $EXIT_FAILURE signalizes that # arguments are left untouched by the hook and therefore caller will ignore the # result variable. # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). There is # # no need to do the equivalent (but slower) action: # # func_quote_for_eval ${1+"$@"} # # my_options_prep_result=$func_quote_for_eval_result # false # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@", we could need that later # # if $args_changed is true. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # if $args_changed; then # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # fi # # $args_changed # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # false # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd _G_func_options_finish_exit=false if func_run_hooks func_options ${1+"$@"}; then func_options_finish_result=$func_run_hooks_result _G_func_options_finish_exit=: fi $_G_func_options_finish_exit } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_rc_options=false for my_func in options_prep parse_options validate_options options_finish do if eval func_$my_func '${1+"$@"}'; then eval _G_res_var='$'"func_${my_func}_result" eval set dummy "$_G_res_var" ; shift _G_rc_options=: fi done # Save modified positional parameters for caller. As a top-level # options-parser function we always need to set the 'func_options_result' # variable (regardless the $_G_rc_options value). if $_G_rc_options; then func_options_result=$_G_res_var else func_quote_for_eval ${1+"$@"} func_options_result=$func_quote_for_eval_result fi $_G_rc_options } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= _G_rc_options_prep=false if func_run_hooks func_options_prep ${1+"$@"}; then _G_rc_options_prep=: # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result fi $_G_rc_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= _G_rc_parse_options=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. if func_run_hooks func_parse_options ${1+"$@"}; then eval set dummy "$func_run_hooks_result"; shift _G_rc_parse_options=: fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_rc_parse_options=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_rc_parse_options=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac $_G_match_parse_options && _G_rc_parse_options=: done if $_G_rc_parse_options; then # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result fi $_G_rc_parse_options } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd _G_rc_validate_options=false # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" if func_run_hooks func_validate_options ${1+"$@"}; then # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result _G_rc_validate_options=: fi # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE $_G_rc_validate_options } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-14 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result fi $_G_rc_lt_options_prep } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result fi $_G_rc_lt_parse_options } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer # -fuse-ld=* Linker select flags for GCC # -static-* direct GCC to link specific libraries statically # -fcilkplus Cilk Plus language extension features for C/C++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: libdwarf-20210528/Makefile.in0000664000175000017500000006650014054252020012542 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ ###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_DWARFGEN_TRUE@am__append_1 = dwarfgen ###if HAVE_LIBELF ###SUBDIRS += dwarfgen ###endif ###if HAVE_LIBELF_LIBELF ###SUBDIRS += dwarfgen ###endif @HAVE_DWARFEXAMPLE_TRUE@am__append_2 = dwarfexample subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = libdwarf dwarfdump dwarfgen dwarfexample am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING ChangeLog INSTALL NEWS README ar-lib compile \ config.guess config.sub install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_BIGENDIAN = @DWARF_BIGENDIAN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = libdwarf dwarfdump $(am__append_1) $(am__append_2) DISTCLEANFILES = \ libdwarf/libdwarf.h MAINTAINERCLEANFILES = \ Makefile.in \ aclocal.m4 \ ar-lib \ compile \ config.guess \ config.h.in \ config.h.in~ \ config.sub \ configure \ depcomp \ install-sh \ ltmain.sh \ m4/libtool.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/lt~obsolete.m4 \ missing \ $(distdir).tar.gz \ $(distdir).tar.xz EXTRA_DIST = \ appveyor.yml \ bugxml \ ChangeLog \ ChangeLog2018 \ cmake \ CMakeLists.txt \ codingstyle.txt \ config.h.in.cmake \ dwarfdump/runtests.sh \ libdwarf/runtests.sh \ README.md \ scripts/baseconfig.h \ scripts/buildandreleasetest.sh \ scripts/buildstandardsource.sh \ scripts/ChangeLog \ scripts/ChangeLog2018 \ scripts/ChangeLog2019 \ scripts/ChangeLog2020 \ scripts/CLEANUP \ scripts/ddbuild.sh \ scripts/FIX-CONFIGURE-TIMES \ scripts/fixlibdwarfelf.sh \ scripts/libbuild.sh \ scripts/UPDATEDWARFDUMPVERSION.sh \ scripts/UPD.awk \ tsearch/ChangeLog \ tsearch/ChangeLog2014 \ tsearch/ChangeLog2015 \ tsearch/ChangeLog2016 \ tsearch/ChangeLog2017 \ tsearch/ChangeLog2018 \ tsearch/ChangeLog2019 \ tsearch/ChangeLog2020 \ tsearch/config.h \ tsearch/dwarf_incl.h \ tsearch/dwarf_tsearchbal.c \ tsearch/dwarf_tsearchbin.c \ tsearch/dwarf_tsearch.c \ tsearch/dwarf_tsearchepp.c \ tsearch/dwarf_tsearch.h \ tsearch/dwarf_tsearchhash.c \ tsearch/dwarf_tsearchred.c \ tsearch/ESSAY.txt \ tsearch/Makefile \ tsearch/README \ tsearch/RUNTEST \ tsearch/scripts \ tsearch/tsearch.c \ tsearch/tsearchlibtimes.csv \ tsearch/tsearchlibtimes.ods \ tsearch/tsearch_tester.c all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # AUTHORS, ChangeLog and COPYING must be present # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libdwarf-20210528/tsearch/0000775000175000017500000000000014054271043012205 500000000000000libdwarf-20210528/tsearch/tsearchlibtimes.ods0000664000175000017500000004052013644370703016026 00000000000000PKÁŠ=D…l9Š..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKÁŠ=DOH€$$Thumbnails/thumbnail.png‰PNG  IHDRº‹Jû#ßIDATxœí pUÅÇO•H[†&-’”ŽcB¤Zhy –IÁ–GØM1BŠ55ªm „ʈ›V(R‹vÆT¨L qÄ‚LlÇú(122 ”PBB¡À‚Ejû¿Ù°ù²»÷Üçî¹¹{þ3ÆsÏ9÷îwÎùÎ>~|»_¯ÿýïŽ/_á©þûøãñ÷Š+®ÀþzmR”™[K)¨>ñ‰OÄh@À]î¹çžÌÌ̹sçÞwß}?ýéO?ÿùÏÇø£QëÅ_üÒ—¾”““ÅQ¯Ä¬Ú½{÷w¿ûÝ~ýúi- OjÅŠýû÷ô‹ûÛßöîÝûÃþ0Fz±ÿ¥¤¤0·ýÍo~óÑGÁit_¹R›7o2dÈüùóׯ_ß«W¯Ÿüä'¸È­[·4hÉ’%ìèwÜ£ÿýïW®\ÙÒÒòøãðÁ'N|õÕWÙimmmüëŸýìg£³ä™gž™>}zkk+Šøä'?Émà?9xðà-·Ü¬ÊÎή®®>{öì‘#GFŒdzjÕªK—.Ån ½¶§©©‰]5ÊEÿüç?áC{öì‘ÄWÎ;÷ë_ÿú?ÿùÏW¾ò•è  êt—††¼ظùæ›Qe¡0Xû¯GªQ£FÝpà ååå¨êŽ?ß=vìØÔ©Sûöí ÿ`G׬YG9|øðÑ£Gñ,ï¾ûª‚‚‚mÛ¶±Óè×KKK£³¤¾¾~Ò¤I'Nœ8pàÀ[o½Åmà?~ÓM7566^wÝu̪§Ÿ~úäÉ“EEExëp&\mçÎ/¿ürì–ÐËa{páìªqE\yå•8ôþûïËFb?nу>¸cÇŽ3gÎDgU/á3^”wúôéØ:j:u Þ€÷fäÈ‘³fÍz饗pkx„ËFmŒÖóÃ?|íµ×p¿>õ©O£&`§Ñ¯GmÞ4ö.\ÀvII ·ÿøµ×^ûå/Yè <øí·ß¾êª«° {âb ý‘]»va¿j<©ŒŒ thð¼”Fâ+¨ŠP±á±Â°¨màÝåç?ÿ9ª¯E‹ÅþÓQè‹_übeeå~ðtP±Ï™3çüãùóçSSSûôéÎΜ9õ-jàÕ«Wã…†ë þß²e lf§Ñ¯Gm ê tð$ÆŽKmà?ŽŠÚÜ»woùGâb‰ü#üª±³¬¬ nq×]w)ÄW¾÷½ï¡IÂíúÆ7¾µ \wùå/É>`ãã¡Ù‹ý§£\•Þ~ûíl-þÆn -w{øU£‰7CÜŠaÆ3òÛßþv,P‰nqE‡âòÓщÝwê¯ìУôâùQù´E+ ÷w)..–È?ÂìÉÏÏG5_q72^¾âÈîâ«éë_ÿºáîBN0˜#"­`J0Ééè{*Ïì¡hQyŸéµÄ…ªÅn‰p4à.ëÖ­Ó¡½{÷ÖÔÔ(‡Ð.[¶Œ<ô51=Ê”°Õ€0Z¼xñW¿úUz&:}²¾þúëq·A«Þ|óÍGy<ð.íä×òÎ;ïà’ÑÅpïúë¯÷Ð Äžyæ´e«V­bÃ=EcÄ)e_Ø¿aà Ø0¦G÷›É™~tÁ‚õõõøéX®ðرcœ)ñmx7. ãÀ;w~á _ÀNüE= ó~ñ‹_`4uq^iÓ¦MëׯÿÇ?þñä“ObÌvòkÁÍ_¾|y{{;.Ó[K0ÚúýïßÜÜŒÓ0s¸»¬]»Îo>|8§@”}᜼¼<\Cuu5:ÞxŠØÉ™*.8Ùþð‡|0ëï¿ÿ~Δèö¿ÿýolÿêW¿ºï¾ûp1þóŸ÷ïßÿþûïcTòØcÅR¢'ÂÝûô§?xkk+ÛóÄOðkyï½÷¶nÝŠ·%777==ÝCK†úÛßþ÷ÿÔ©Sìh§» eá‘’}áœÌÌL¸ ؾ};\ 3=œù裢‹Ž²c±-gJ|û¥—^úÑ~´fÍ\Õ¹sç>ó™Ï`÷ôÅ_|ë­·ÐZÁ§’î)Â]Âm OŠo¹†åŽÎ 8J˜– KÃt¨ÞÐym…½êŒ¦s¯$Ì£°¤ÇtTJPæ-¦ã;˜NFp‚Bž_%=¦£’A™·˜Ž–~á ¤?ú裵k×b4ãðƈ#8ü “Ñé%˜ŽJeÞb:ZzMMÍìÙ³›ššöíÛ×Í]8‚ËÎÎvgt ,Ðg½%˜ŽJeÞb:Zúˆ#~øaÔ4¸óìh§»p’ÑiµÞLG%ƒ2o1-½¹¹ù©§ž:~ü8š$¼¨Ž<2 Éè´ÊLG%ƒ²¢¢"1-ýÝwß]ºt)Þ[ópÁ…Ãè4ÉLG¥eÞb:^úðáÃg̘qe‡Ø!w “Ñi’%˜ŽJ¾Lo1-ÝzÈÇt¾"Pg4Ú*ø”€k(3LÃ’ÓÉpLØcìºBZÂ|ƒmÜÝ ¬Ñ«ÅI|î“Ó}Š¥¾Ø9YIéd8†K @ÌØuÉ–tÛ;„Ž,;¿³1*--E‡ãxÖ¡C‡©koo§?÷Ø9Y–`:Žá±Q fìºdKhÝ÷¿ÿ}l\¼x‘Ÿßé.«W¯FßÕÎ¥K—x4ª¸Hkk«¦Ø9Y–`:ŽQ FãÙÌ[B#è²:D'âwºKYYjÔ„¨éœJÒ;'ËL'ñ 6p vðàAc×%["GÐQuÕ.iiiøÆµµµŒÔÁE±s²,Át2Ã%p 6fÌÇÔuÉ–à† tTwfŠÐ™¤|§ŽØ9Y–`:%€˜™ëRZ"DÐQKBDÓQ™™k ¦“/MbZâòÏ>>¦óº0j¤`ì™sOØ‘˜.A,QDÓ¡³ÒØØ8pàÀC‡•–– ÿŽH¡™Xg9¦Ã½Iô$fÏž=zôh-ÁˆXM‡'9žÍóÏ?Ÿ‘‘ÁV6+,,D7GXÖL+¬ó1ݾ}ûZZZ0Ä0°À‚»%Ò«£éPÁÀ z÷î/¯\¹’­l–““ƒ!ef`ép¨2ÑÂnß¾ýÀxc=´¤_¿~êh:xÜ®€î _Ù,==C33°ÎÇt¨ü§L™2vìØ¶¶6¼!ºÝÅÝTA£é0xÆ®¥K—ò•Í 843ë|Lwûí·£ÖÄ5^¼xÑ“h:j *E4œ€}9r$žCVTC EÇåºaé t"óòòpÈÀˆ/$0 Mç•Íd†£Öù˜Î1‹ì"²ÄÇt¾"P—»|ðÁ}ûö %j‹ù˜.q®KŒ¦»páÂÂ…  €1Ѹqãx¿F)¤ÎBL'İ%Îu)¢é6mÚ4sæLt °AiUUFq,++«««ã™ÆϾ£ÔY‹é„Uàäº`¡"šnß¾}ùùùgΜÁ@u`ïÞ½gÍš5tèÐÚÚÚýû÷óL YYYºIµ˜ŽÆ°™Œ¦s—:š.''u>LÄš;w.Tééé¨?PÁÐL Hµ˜ŽÆ°%òuÜ¥¨¨èÎ;ïD󉪅/®ÊD3) uÖb:ÃÆîgb^WÀ]úôéƒ o3º ¼̧¸ÒL ŽfRg3¦s‰aóVêhº`1Trê­¤ÎZLgr邨åc:_(„»$BˆWRbº¢pÌÛrELLñJ©’Ó…”Ç<,WéÐhll?~ü+¯¼¢#=hø²Ó¹K†c^•«Ætõõõ·Ýv}+V¬àÿî览Nô*0âÃ+[XXˆ!k8GMZV¦×µk×â Fƒjhh˜={6¶‡Š·p‘9sæø)$bÅ_øX[[;eʾȱûQ“–„•é¯] ŒŒ ô øê?…DŒbäÐàî…yÔ¤%aezeµ 6ظ£¬¬ _˜6mÛÀÎaÆ9~ ‰$ÄÈ᮲å¢d8Fš·$t¦WžB‚ ^ôgñwÉ’%Øàc?…DÔbä6oÞÌ6”pŒ5o‰i¦×üüüþýûÃEø=ê§HzE–é•çt3Ü-Rù˜Î[ua:Ô".é\ Ó°¤ÄtTîS\u#»ˆJ1:5ûöíKMMÅI3?ùä“è<öë×þ„@Ç””˜ŽŠ‚2ü²©Ò\«lÉÒÃÂt¥¥¥è`ÜÏJII©®®ÆÐœe‘à.¢Ð1%1¦£¢W„»-dS¥¹Vu¸‹{éaaºÕ«Wc°ƒjꆆ¼µp=–EbêÔ©Sc:* Êð<„lª4תùÒÃÂt¨EP» Fâ;Ï"aÐ1%1¦£¢ ¬¤¤DȦJs­²=&K Ó¡vIKKÃaÜñ /Ð3ÌäxeJbLGEAͬ*çZ5_zhL·bÅ º‹71<‹„£Ð1%1¦£@™MU¹Çdé‘aº`Ò è˜,Ätò?%šÌô*—¦Kdù˜Î[%¨»$%¦óÍÅŪDt—¤Ät»vízúé§áÜ=ôÐo¼!¬>GצkmmEorðàÁ³gÏ=z´‡VÑ£ ¿Ü¥­­mýúõ,yÄŽ;\Bét+‰1n÷£>ºqãÆwß}W˜Xêt_›îsŸûF‚¸þÍÎÝ*z´Ë]ÊËËçÎË’Gœ={V¥»÷Þ{uÛ͔ĘT V§N:nÜ8aõ9º6þâ…Þ¾}û =´Še{îrêÔ)ž<OB¥Ój1UcºW_}uüøñ™™™¿ûÝïJJJ„ÕçèÚtW_}õرcQåãÉévw«èQ†WîB“G8ªP:­S%1¦ÃãGŸÕäÂ… )(cEtmº¿ÿýï¸Æ‹/.Z´È[«póùQv~À]hòøM°P:JbL—ŸŸ*—lõ9šû5//F|!­âGÙÇËÿ»üÙ=”΀’ÓõíÛ×å(½X“˜ÎÝ*á¨8NäP:ÇÇt^KL!‘ Ô+)1UЦsK!¡ ¥3¬¤ÄtT566 (Lw4]D¥‡H!,”ÎŒ’ÓQ øK@aº£é"*=D 8 ¥›?~ÜÍuQc:*Š¿²²²¦;š.üÒC§`ýsJ§Ã\%1¦£¢ø U½€ÂtGÓ…_: D ƾ¼Rc:* ÇŽ9·ÍDÓ…_:›6ï–B‚§¥§¡tÆ”Ä˜ŽŠÂ1Üd…9š£é"-=D o•Ä˜ŽŠâ/”éÆtQ—žˆñ..ò1·êœô2ǨLÃtð1¾Jlªâ(ÈU"<ååÈI%Í’€»¬[·nL‡öîÝ[SS#L `*--]¶lÅ0:¦Á>òÈ#$8°wïÞ|?wáËäD݈DcçØ²:Iå°gÏcÑt‘Z¢hŒšššX²×‰'bÐ5hР%K–8C,Œ´ËËËSSSÙ™:¦Á¢¬n¸¤àî±ÇC)[®\¹Ã¥ &pd7lØ0Ȳ`œ9s†[è-§DcçJJJœî©ŒEÓEjI·Õ£à Ç?zô(KöZPP€7ºB¬ÈËËkoo¯®®ž6mš¾i°¦mÞ¼yüøñßüæ7Q ~ð¡‡b°®±±¶=õÔS³fÍÂk*‡#»gŸ}–ò,ýë_™…Ê*Ó+ÑØ9¶‡N/EÍj,š.RKº­MÇ#žìµ¸¸¿¿ÉÉÉÁ9™™™p u,šeÄü4X*Ù)}"qð£ ÷¼®&£é"²$±^»ˆä#;ó£é”2™9ÂÇtÁ޳DØC?ÜEFp‚Bž/ù˜ýEÝÑtî–Еëúöí‹*Æ›èÝ2œÖÙq‡¿a2:Mò1îh:wKhìâñãÇ—/_ÞÞÞ·ÙîÂ\vv¶;£ÃÓz>¦ÓMçn ]¹îÇ?þñÖ­[ñÆæææ¦§§;Ü]8‚ Éèt_€étGÓ¹[BW®Ã¸MÒÉ“'ÑDNŸ>Ý‘GF!1Y‹étGÓ¹[B“YÁuð¾uÃt‚ ‡Ñi’éðwæÌ™Z£éÜ-’Y°'ÞmÕnAa2:cò1‡–.›X¯]Dò1yu¥É5ºÁ—é Ó)Ö¦«¨¨ÀuàÀè”–– ŠÈtƒ/Ó¡Ë($q0l Åt «Õu6Fø##ƒ!¯ÂÂBt¾"ãèN$ác:šÄ¡¬¬Ì°%Óáž «Õuº ^eÜV¼Óø2C^999b1DÖÚÚj&‘„éhó–PL‡ýÂju]y¤áJ¸¿h;9òJOOçˆÌX" Ó¹'qÐm ÅtBNX‡ŽŒ0lF=¿téR޼ 8"3™H‚ÉZL·{÷n—$º-¡˜nÛ¶m4'¬#dzÅ«‰Æyá¥ãr݉$|LçtLJ’8˜´„:.s*õ}ä÷Wf8æÁ—…˜Îä?¼¸["(±^»ˆäc:óRdzå2¿f͘.œ©Çæ-qäµé„L¯ü&¨ã;ÍdzµÓ 1lòzq^Yâ„“éUGçò²Ó¹§u0i‰ Äzí"’éÌ«»‹/ó á.†³ÕúT—49/=ü|'nîKE>ÕU²T¯,¿*–2D‡±±±cýW^y…Q >9KÕm± ŸêÊ,Õ+KÒÒÒKÖ××ßvÛm6Ï›7Ñ––žíÀÑT>Õ•YªW–ÔÕÕ©—2„/Ÿ>}šƒÑ¦¦&ÎR MåS]“™TÜ-q[Ê‚QšùC«¹.²–êšÌ¤ân Þ7ÅR†¨ÿîéËÙ>t›+ȧº\f2©„´Äm)Cz[ÍûJ0YHuMÊ_ÊЗ.]ÊÐÆåcº`GÁ*GN ÌE#/ÉÇt‹/Æ_cKº[ES³Û(&Æ8JyiL>¦KII1¶”¡»UrÚ`110:Æ4òÒ˜­\>¦knn6¶”¡»U4…0Û#&"/ÍËÇtx³-eèn•*&®¬¬¤‘—ÊZLgr)Cw«pÛ…0P11°2òÒ˜|LÇdl)Cw«) T‘8AV0ä²Ó™\ÊJ¶JM¬×."ù˜Î¼ºÜU7\)d¨•}ù˜.ØÑ±$à..\@_fÀ€_Œ7퇥•}ù˜Î0¦sGso¼ñ†b)ÃM›6Íœ9]loÛ¶­ªªŠa®²²²ºººéÓ§c ÞÒÒ‚1+CëdiÓ™ÄtîhNˆñs˜»À¬üü|Ü\< ¸Þl†¹jkk÷ïß?iÒ$ŒÅ8••e`²´éLb:w4‡¦F±”aNNn=* ¸qÓ1ˆb˜ /(î5Z/´VŽ©ÉÒ>¦3‰éÜÑ,Q,eXTTtçw¢ÑBÕÂWfÂX=ì;v¬áÉÒ>¦ó$ãEsxÖŠ¥ ûôéóÄOÀ>tAøx„ç™1cš'^€ÖÉÒ>¦cò0ãˆCÐ\ee¥p~×} ¶|õ&ÃìËÇt†-q™¡X¯]Dò1y%–»ø˜Žìy“^ÍËZL'Ä­y8é•ZÒÒÒ¢˜ôŠñ*ç]‘2Æ•Aµè ÈNL'Ä­y8é•Z)&½b`Íy\‡3®ÂÂBèLº‹˜ŽÂ1o'½RK>¬˜ôzîÜ9λð‘1®K—.q@gRvb: Çp9Nz¥–äåå)&½Þzë­œwñ¢€N«ÅÁd¦£pŒá.¯&½RKš››“^)ïbavhÀêêêàw2tÑ*k1#Å­y5é•ZÇULzx—a_ &K0Éå ÷D1鵇ò®jv–"㈇s`mÆtŽw#ÃtBÆ ÁÑÉ@…Ÿq$Žzýõ×åx9ŽæöìÙ#À1}’“SpWSSƒr¢;ÈâGRRRª««ÑOduüvûGâ%<9^Ž£¹††Žé“œ„Xw¨ì1„...fç+2ŽÀ\x:FS, ýd?ãH|5bÄ!^Ž¢9Ô¬Ó'9 ±îàS¦Lá^Eƶ‡ÔùGâ® 6ñrt=:yE8}’“ àî¹çžÃ³æç+2޼ð ôýŒ#q—cpŒ®GWUU%À1}¢Iˆ™%Üáx „RdáM ¨süŒ#qÚe¼CshC8¦O4 1Fl'wØFÇ€žÁ}ô3ŽÄQîñr&£éä(J—H¿Äzí"’éÌ« Óu~v­·us$Ë1§^Y¬ô€sTTT ËÃ(ÍòåËy&K7ø²Ó hn{‡ ¬™"c:§cxÁJß´i“Ó•””Œ3†m£gÞÒÒ‚Žä!C0Å®„¯â¡ÖÙ‰é(šCG¾¹¹##–È˜Ž–~Çw¨1Ü|À€¨ð~Ãt\ ¶‡Šw¸é_™uvb:Íeee™É $cº¬ñÒÕ˜U ¯] ŒŒ XÏ7Pǃuvb:“hŽJÆt‚Ô˜ŽÕ.Ø`c ÔKø <¶¨í³°Î*LG1†æ¨dL'̧T`:8ð+è𢇈¿èI`ƒw’uÃ:›1€æÌDÓ)1-=4¦ÃOôïßWÂ7èQóàËLçÕztÁ&;+¥¸ÅüßÍ üz,ò1y%V-í+Á%fñ–„ÚLu /eȹ­{Y!2Ž(#/ɪ+³TºÝyÝKrn+Ï‘¦$£$Á1ãH°ÈKc²êÊ,•îIMMÕº”!å¶òiJrqÃKÄŒ#py9þü¸›ë.¨®ÌRéžo¼QëR†”ÛÊs¤Breú,fa£Vy©Ã\wÙ@ue–J÷ÈÌWŸä9Ò!¹²%bƘJbª+³T\ ßsõÕW{¸”!î3'¹ò¢ŠbÆtØyiL–P]%Kå{‚…fÆWŒÛ*çHs’+[¢È8’hJJª+³TºÇÛ¥ ©üÄÀ¾¢Wb¹‹=˜ÎqeÞb:—EË],ÁtŽ+(“Óñš,] U ¸K[[e\.‘—d¦ser:^“¥ ¡Â¢Šw)//§ŒK޼¼÷Þ{ãnt0Ù€éÜA™œŽ×déÍÉ‹*ÜE`\r䥣ƒÉLGN:^“¥S4‡ZXT1à.ã’#/µZLIŒé¨ÂIÇk²tŠæXø6]T1à.ð θpÓƒE^%˜ŽÉ” Ë.]@s4 ôr~àË–¹G^z¢¤ÄtTÞ.k(—î Å[ÜS"/Óy¡Î9Ò!ã¸d䥂…Œë£æ%8… _ÍRö¶ô€»¬[·nL‡0r®©©QŽ9KKK1f¡@£±|B\ß;#16ºÞÅÅÅ×_½±œº%ƒ2‡`4oK—UT´÷MMMèÝ Ÿ8qâD ê „>¯Ó1Ĉ´¼¼<55•÷ùÒ)))UUUèÉÞrË-ØÆ¸Ö¬YúÓŸÐ…Iè}···³!Ÿ±œº%ƒ2“s¤ÝK—Uì6‹Þ0|øð£GÞ}÷Ýxlp£ÛÅþ'//O«ºº#)Mó¥a_[[êë®»îÙgŸ…ÓÌ›7oäÈ‘°í½÷ÞÛºuë±cÇrsswíÚe,'‡nÉ L˜¥ìaéò¢ŠÝæH³Æèµ×^{ùå—Ñ=ÆcïÀorrrpNff&\èž/jƒµ¦iiiçÏŸÏÈÈp:*žÅ‹£ B%‰á´±œº¥ŒgKÒå™ÛŠÆCè#GŽlÙ²eÑ¢Ehz„à c‹þìg?CËúðãF)**‚SÂ;Qª@ÇTNÝRƳ%Hé¨Gøê×vx§ñ6ã=fÎåõ u/nHÛ2¾ÍâF¯¹æV´õ\)A™ãiÆ'ø¢ŠjnÈÿ Úýߢ C°D`†:äÏæméÉMç˼ÄI¯Jbö`:oÑ\Ô–ÜEFp‚Bž/Y‚éÜᘼ€`âXÒÙq‡¿a2:²Ó¹Ã1yÁı¤Ó]8‚ËÎÎvgt ,Ðg½%˜.$šLK:Ý…#¸ŒN÷8`ºhNX@0q,GF!I%+¦ ‰æ„Ç’€».F§I–`ºhNX@0q,Qp—0y%¦óÍQEd‰é|E Eb`.ókÖÙŒé\¦šzk •"10?vÏ=÷¬X±=_ÇÔRk1ÝŽ;0ùðÃ1úCgÂØÕ¹[UGÓÑÄÀ¦2R×ÞÞNÚ@b`k1^T<¶·ß~{çÎpcWçnIZZš:šŽ&æÑtð,¸Hkk«±ÄÀÖbºI“&áýÄýTN5õÊ’ºº:u4M ÌI㹆;Vb:lã®®Y³OŽ& Ö}uî–¦£‰kkk©ƒ‹8Þ%vlÂthjñbà© Ù¥I‚½µ}E40S¤¢¢‚“:¾ÓLb`k1péU4`IdÑtTžO õ1ùÑt¾tÉw_èÿyËL‰TÖ0YIEND®B`‚PKÁŠ=D styles.xmlÝY[oÛ6~߯0”¡hÉ’œ´ÝØÁ°¢è€¶(zÙ;#Q2WJHÊ—þú’"-Y—¨—¡ë#‰Èï~çÂCåæöÓÙsAX±ö¢yèÍp³„ÙÚûøá…íÝn~¹aiJb¼JX\帾GŠÅ „ ±2“k¯âÅŠ!AĪ@9+¯X‰ +´j¢Wz)3¢•M×঴Ä9UXa[²ènúÊÜ”N8ÚOVXà´)ž²©ÂAý”ù1ËK$É™JŠOko+e¹ ‚ý~?ß_ÎÏ‚h¹\zÖ;\YqªQI`ŠÕb"ˆæQ`±9–hª} Û4©¨ò;Ì'Sƒ$êxµäX¶«ârš¢¦L+¾vÙäèÚe4Ç[Ä'Ç™·Cå2™*—IS6Gr;àßëà5Lê¯_âŠçS×RØU1'åämtSž1æLU&Ùµ¹‹0¼ Ìs½…ï9‘˜7àñ(¾÷Î}(¨8±z,äóÖÎÔ íÄoºjÕEña\±mɹj7õçí˜Æ77æL¯ö– 'oBï 4«ŸrRø¤8¹„dD È^½PN§#®8‡NôØ·T^½ í.vŒBéQmœäözó;F­5mYlÃk›_ag*öaKrDý’BÃÞÞøÎílÆYUê>[Þ ¤½÷©”xCñ«Ã’2hÈ.Ò4„/µV­Sa7¾[Y?þÄ rTº‡’ezÈ¢~øèA&Ÿ­]𠲤5Ÿ~+¸F¼a$»>xnÆ»¿:ÝS`N ٮ͊ëp_^¥O²CÕú„hUíÆî‡©x‡Å83W¦ÝmÒo³8ÌÚÆúÒH Ã ±Õ§ÁЋ`×l1‚Q’ @ö$QÝ5ª$@Ô©£Õ{Ά=&ÙšˆìäKÉY|;mbux¼§4è.ý#u³ÿ>ŽqB=g¬¢“¾`WglJV94Ó)2!±  /ET4²·÷ìÊOJ×^ ‚p1<²]”ϰvô¤”ÞPä|›3kF£¯¢Ôºc ¥œ™‹­ÕW™¿ »Fg­Sý¨‚.‘ô힪T}EGVÉÖž^—yäõ€ºF©ûlÀÏYr”ûòîä“-ìît¬·ÆRÆÀ}gSµ~[;!œ/–/‰é©rÄ3˜£8U3íA^ãÛ£wLJuÿ çáòúÊôvÁ°Uµ9?ÂRhD{Íl›t|1Á‡‹ÿ™ÕÜã‰z³´˜_-Kرªì³‹Pi@‰óîħ‘Cñ'Õ,‰-çq¨¾E ´"îLg»?GDýWI»?¾ƒÁêUOäH8âÔúéA¥i¬9kfDOÑ3æonôûâ²þ-¶ôæööö&8¬GÊ3ÎܯO¶°ì´*y4žã³ áÉs ñûo–Ž3ô§¬ø¾¤ÚØîyÙq…UÌÕ€nÌIHˆ†±x¼/ r<(ÿ×¼†ïrF”0”­<ïŽáõ¤:ÆXÐT=¨ê»bÄ8AdL†Êº­‰J«¥`½\ôôoòçjð‰¤â ïHÆÅ÷5Lð2¥4ùNø’ÉÁ¯,ØEN5Ì›q².µÝ>œ¬$Wc "ŸªQ‹Ï“'¹S¶§]tL5Æ«$RÖLi”æ’Q1˜óé,§äcF•\U†ºèCŽ{ø†Ez³ÍÉ$`iÁ¿Fç2·ü·œožS!uVe”\R¶XJ]¸sçUé/3^ jðL²„ÄF=¹ÌWôsˆ»oI|ûÜôÔDMè„G*§87äì¿T­‹]q1ãÑîh•Õ–DbI©|¼/‹.>÷4JΟt´zÐ2¬ÈÎ8>ÿIº}O=-:ü>×b®¾‡ CM,(‘T€þ•µd„4Žz.‡ê³NKU-x¦HÝŸ±SùUÉWÔ»L!…ÌUŇÁùLœÊHÇd1›Ý[ûï÷ÖóÜß¾Ì%®XRu Ruð¤Ú;«Ú´§W§Àf©ˆäg´Í;àu"¼)õZà*Õ.»´u·¾ÿçà]ì£RÛpʳœm_™}Å‚zGiì¿¿ ÜÿÐ@öâÎý—ˆ´ x£s#°¤7ƒ„^Žwçþf >N\cwó= ý1ð¶³vD¨-ìÉ# µm•\Á§> µi'®J[ö.^×È0 ضpY¦Ð5އ¶Èñ ÆÔë©1íÃ¥cd•¶mËTÎÐE”‡´ˆòÖQ4°#*múô²JÛ6dסRà ¯€ô[pÁc Õ ÕAªcBßá€Tþ¸¯©‘i î÷ÞËhO<{Ú²PûpÍW¥c CS±(ÜÁvÄ4ð¶Ô¿VÇ;²J¡.èù´ã!m¯óûât_¯q×QÀWáÙh¯ÂS9C·om,£µª÷w¼™PË€·q½ÛP§ªõf)¸k¤±y-¸Þ¯@IP¯'Ö[—œ;ðŽ;sˆ£wÎMIú§\À¿äÒ•ÃM;¯Ñç`нlm/xGÇF»£ãÐ_È:³÷Ò´Çå Ì]ÛJvmàÑ: 숹káPÙMIÅËü€gg\ÀMT¸µ=®);›i`G R >ZÜ)Øz£„v£dŽ`RÕ@$‹çÛÀ¥‚vDª-øi±¥ U*Ø~­" uÝufw¤i®J}Ó†½nR±(ÛúhÇmÛÞ{éÃyl_‹ê£½Õ7}˜E×Àî-uê!ŠZŸ‘A·YN…`<Ö!&"ê/*-ITœsy>=½KyºKøJ<}ZR*Ÿ~|ÿô¤ºÝ¡Ü|Ae™Î Q¤K|@Ç|çL÷ß~U_<—õïÆl·ÏlÎh夸•»#»}}‘•ä ‘,Z,Üײ°ê”¬s•q!XUµod¡ª™DB?è1pÆ£Ýñ¿ˆ‡«„¦R­¶R©þ>þ PKëz-¤@ PKÁŠ=Dmeta.xml“O›0ÅïýˆîÕø$€EX©ªzÚª•š=¯ˆ=›õÖ±#c6Ùo_0%m=úÍoæ=ìêþ|ÐѸVY³‰iB⌰R™ý&~Ü~CE|_ªìó³À¥ÝŒGðMÔ·š–¥MÜ9ÃmÓª–›æ-÷‚Û#˜¹…/iŒF嬕ù½‰_¼?rŒO§SrJëö˜–e‰CuF¥¸pÇÎé@IAÃàÐbšP<³CÂÿ 5°ËHÖÚ‹Ñ€¡ƒ#$Ããy¦÷NJ}ë=›â>aãô¦àô9ަë/ÎâzÞBe”WFÂAã­«¿F¾Yñpê¢Þ jFh†E,ßÒ”ʳ<ÉWeQ–Y^Ns®;*)øuk¹%%gŒ–d«‚Ñ‚0Ráøe´Åq ²iöHv.ØÔ?·iñ­MöÿÔ¯ÛÄ»ÐÐÖù_ô$ì ¸`ù v~„â,¡Iš°»eºóÓ¹XG‹êÓÑÙWg”ÈÝ—Ni‰Ødò1oœtÊxh÷þ±ý…¶€nm=+xÚ¿¨5É‹¼,ÖËþiåA¸|¨Ö÷{h½QÐ}³Ó€„íŒïI<Š´ž5–­&Õî†+Í:‰q]á«…o}ÞúPKv·”òÓúPKÁŠ=D settings.xmlíY[sª:~?¿¢Ãë™VÁ¶§:­{ðV{±*"^Þ¤šmH˜$ˆö×ï Ú±n9µ }fŽ/J.ßú\YY7n,<|6‡Œ#Jîõ"¯œAâP‘ÉÒ7ç7Êò_·ôõ9°äR'ð ç !—ð3¹ðR<}§Œ”(àˆ—ð / §D}H6ÛJÛ«K+añÈ#2»S¦Bø¥\. ˰pAÙ$§‹ÅÜjv³Ô¡äM¯ÞE)}mˆÉ¬„iùüe.~VÎÖ$·T£)å6¿|»#½H7gëáˆÚ"E–æ†ïZSöíû¸ÇBÙê “úÊfR,}9‰ˆPÊùÛÜï _~†¯"ärÅt´ªj77'Ã7!šL÷R×ÔëÂ塸çðÏqẻ²`¸ÿ”V{¤}±å!ŒaøàîÐä‚IPÊ‘A¨_bîð4ÔÈgD?néM!êX §¬C9ò S4”È£‘›”¡7JÀ=#Ñ¢.ÜUÿ”²L2œ¬ÐwØo”æÝ柾î4‡+tI‚z´ãÀ7|Sv[X#ɧœˆ›®ûÞ V¨ÔKxL©gJ”T-:µvQãXP(©0‘oýWôë#)÷¦4¼gh×mÛ”bˆR,€û‘÷ nG‹¤é•[?ôj­~BD‰=ûÉ®Çac°Ä®ýó¿‰lb‘€ŠLef£T ÉÜ^æ övˆ˜1dtÅŸÝžÁ¡"+èã.ágÈj•bÊv 1®ª]4íê:…sÍ@+MÀ%õÀ# ›¸²4ÉDÈÊ‘HO“úoB–s°·ôlŠyî†ÜT„ôðMj.àîA§q³bà¾.I2“`@.Ï;1ýVöÄ»ð{sðSá{í¢9â‰ôSßOþXÓ‰áõâ½%q¦Œô¿/X—£ûp(ï8ÄÑ¥õP÷lè6d2xÿO0ìþÑ9¤G`O ’† ¾ïL¦Ðó±ü¾£y¦À5¤#¦/3ÑUmÝÍêMK6ÂDè U€ udf]V(‚Ý"È^_Vl©”'aóïœú’‡ƒ…ê,ÕZ»6ÑÿäOWµºý7ßt›˜»Ã–è¾M.–t½¥ûÝ÷ç½1îËï™-Çz^÷ü¨§/ª¤²ƒ«üxøPìŒ+»i½=÷[—mÝŸ;žÌɉ1uïñÜþ©víÂcÞñ¾«û?íBÅ[ÅV×£á#‘³ÑÀW‚!Ưcê¼U Ãçšþ4ÒŠ\<¨å—/º:Ú»žÅåº'çÞðÆ÷–/¸cÖ·Öý‘Ö/Fÿ¤_7j¶ñœÖGCcZÅ•éX³L0ôq{&±šväñÕ'•š™W»]Ëx5V׬[£a^íõ~[¯V¿¾h EËœ‰¶©ºí?5¯øE>$U^b‰~^=¶µ™q8N/¨}&©*ýp¤¨*õ|yžS¯ø2Î2Ï¿%Ï4˺ˆÊ²jÍ4}ì9´â7FmRÅ”gátßÇË>‡¬È ©Ad'OÉ î#»*ßRýéË2<òÙÔ®â@ü_jP|C!Ãúþ„žPbÁ“ûí¥k.éutùPK}0?ÙÐPKÁŠ=D manifest.rdfÍ“Ínƒ0„ï<…eÎØ@/r(ʹjŸÀ5†X/òšÞ¾Ž“VQ¤ªêŸÔã®F3ߎ´›íaÈ‹²¨ÁT4c)%ÊHhµé+:».¹¥Û:ÚØ¶+šñjƒ¥Ÿ*ºwn*9_–…-7 lϳ¢(xšó‹ÐÆÞáØ‰í{û*6ëÅ*të³ÑÔ>¤‹Û‰’QGCŽ4š¤Ùê˜ûhKdý½^Ÿ˜.Þ€¥X/š+ßà<´µ?¯ÕCñ¾M†wP÷@®á½3-t¤ä5\ËÔ{y,ouJJLO;jŽ”í®„O4Γâ³)Žw¤¸`FPS~ ñÑÉ:Í;¸ VSz¬ÈÓé€ÍÃA ˜ë~>~ ç˜Ìýð‡ ªUO³9Þ"n,ùAKe¬ÕYÙ’óï·ð?®?¾ *8IÅI{‹0‘¯Ô¯`ýPK³5\ EPKÁŠ=D…l9Š..mimetypePKÁŠ=DOH€$$TThumbnails/thumbnail.pngPKÁŠ=DÃOó) ¢$styles.xmlPKÁŠ=Dëz-¤@  ó*content.xmlPKÁŠ=Dv·”òÓúl4meta.xmlPKÁŠ=D}0?ÙÐ u6settings.xmlPKÁŠ=D´÷hÒƒ ˆ;manifest.rdfPKÁŠ=D'Ç<Configurations2/accelerator/current.xmlPKÁŠ=D=Configurations2/images/Bitmaps/PKÁŠ=D³5\ E[=META-INF/manifest.xmlPK |¾>libdwarf-20210528/tsearch/scripts/0000775000175000017500000000000014050026360013670 500000000000000libdwarf-20210528/tsearch/scripts/badsample0000664000175000017500000000060513644370703015477 00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen libdwarf-20210528/tsearch/scripts/comparatorsample0000664000175000017500000000065313644370703017123 00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 760 === -tv -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen libdwarf-20210528/tsearch/scripts/secondsample0000664000175000017500000000065313644370703016227 00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 760 === -tv -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen libdwarf-20210528/tsearch/scripts/concatlines.py0000664000175000017500000000450514050024700016464 00000000000000#!/usr/bin/python3 # extracts a couple preferred numbers from the /bin/time output # interspersed with script output... # From running a debug dwarfdump. # David Anderson March 2013. import sys def extractnum(w): r = "" dot = "n" for c in w: if c.isdigit(): r = r + c continue if c == ".": dot = "y" r = r + c continue return r, dot return r, dot def istime(w): """Return "y" if the number looks like a time: d*.d*""" t, d = extractnum(w) if len(t) < 4: return "n" if d == "n": return "n" if w[0].isdigit(): if w[1].isdigit: return "y" elif w[1] == ".": return "y" return "n" def findfinal(d): beforenums = "y" wds = d.split() o = "" o2 = "" for w in wds: if istime(w) == "y": beforenums = "n" if beforenums == "y": o += " " o += w continue else: if w.endswith("user"): t = "" for c in w: if not c == "u": t += c else: o2 += " " o2 += t elif w.endswith("maxresident)k"): t = "" for c in w: if not c == "m": t += c else: o2 += " " o2 += t else: ign = "" return (o, o2) final = "" myfile = sys.stdin ct = 0 # if len(sys.argv) > 1: # print("argv[1] = ", sys.argv[1]) # v = sys.argv[1] # if v == "-t": # testonly = "y" # elif v == "-v": # testonly = "v" # else: # print("Argument: ", v, " unknown, exiting.") # sys.exit(1) while 1: # if int(ct) > 5: # break; ct = ct + 1 try: rec = myfile.readline() except: print(final) break if len(rec) < 1: f, v = findfinal(final) print(v, f) break if rec.startswith("===") == 1: f, v = findfinal(final) print(v, f) final = rec.strip() else: if rec.startswith("Command") == 1: disc = rec.strip() else: final += " " final += rec.strip() libdwarf-20210528/tsearch/scripts/testin0000664000175000017500000000003413644370703015051 00000000000000=======a b c d ========e f libdwarf-20210528/tsearch/scripts/concatlinesample0000664000175000017500000000336013644370703017071 00000000000000=== -s -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 856maxresident)k 0inputs+0outputs (0major+292minor)pagefaults 0swaps === -ta -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+244minor)pagefaults 0swaps === -tf -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+244minor)pagefaults 0swaps === -tv -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+245minor)pagefaults 0swaps === -y -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 752maxresident)k 0inputs+0outputs (0major+242minor)pagefaults 0swaps === -w -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 756maxresident)k 0inputs+0outputs (0major+243minor)pagefaults 0swaps === -N -v dwgenb/dwarfgen 0.00user 0.00system 0:00.01elapsed 44%CPU (0avgtext+0avgdata 936maxresident)k 0inputs+0outputs (0major+288minor)pagefaults 0swaps === -b -v -v dwgenb/dwarfgen 0.00user 0.00system 0:00.01elapsed 47%CPU (0avgtext+0avgdata 1380maxresident)k 0inputs+0outputs (0major+467minor)pagefaults 0swaps === -c -v -v dwgenb/dwarfgen Command exited with non-zero status 1 0.01user 0.00system 0:00.03elapsed 62%CPU (0avgtext+0avgdata 1208maxresident)k 0inputs+0outputs (0major+355minor)pagefaults 0swaps === -f -v -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 792maxresident)k 0inputs+0outputs (0major+252minor)pagefaults 0swaps === -F -v -v dwgenb/dwarfgen 1.13user 0.00system 0:01.20elapsed 94%CPU (0avgtext+0avgdata 2172maxresident)k 0inputs+0outputs (0major+606minor)pagefaults 0swaps libdwarf-20210528/tsearch/scripts/TEST.sh0000664000175000017500000000016213644370703014735 00000000000000 set -x python concatlines.py comparatorsample.new diff comparatorsample comparatorsample.new libdwarf-20210528/tsearch/scripts/comparator.py0000664000175000017500000000570214050026366016343 00000000000000#!/usr/bin/python3 # Tries to make sense of a group of timeing runs. # From running a debug dwarfdump. # David Anderson March 2013. import sys def myreadin(name): l = [] try: file = open(name, "r") except IOError: print (" File could not be opened:", name) sys.exit(1) while 1: try: rec = file.readline() except: break if len(rec) < 1: break line = rec.strip() if len(line) < 1: # Ignore empty lines continue l += [line] # print("line ",line) return l def splitup(rec): w = rec.split() rest = "" ct = 2 while ct < len(w): rest = rest + " " + w[ct] ct += 1 return (len(w), float(w[0]), float(w[1]), rest) def computebasename(n): s = n.split("/") v = len(s) if v == 1: return n return s[v - 1] def absdiff(a, b): if float(a) < float(b): return float(b) - float(a) return float(a) - float(b) ct = 0 print (len(sys.argv)) if len(sys.argv) <= 1: print ("Nothing to do") sys.exit(1) argn = 1 filenames = [] files = [] filelen = 0 minrtdiff = 1.0 minsizediff = 50 while argn < len(sys.argv): name = sys.argv[argn] if name == "-drt": argn += 1 minrtdiff = float(sys.argv[argn]) argn += 1 continue if name == "-dsz": argn += 1 minsizediff = float(sys.argv[argn]) argn += 1 continue print ("argv[", argn, "] = ", name) r = myreadin(name) if filelen == 0: filelen = len(r) else: if filelen != len(r): print ("file len mismatch", filelen, " vs ", len(r), " on ", name) print (len(r)) basename = computebasename(name) filenames += [basename] files += [r] argn += 1 print (len(files), " files read") lnum = 0 while lnum < filelen: fnum = 0 basell = 0 basernt = 0.0 basesz = 0.0 basedet = "" basename = "" linereport = "n" while fnum < len(filenames): name = filenames[fnum] # print(" line ",lnum," file ",name) lines = files[fnum] ll, rnt, sz, det = splitup(lines[lnum]) if fnum == 0: basename = name basell = ll basernt = rnt basesz = sz basedet = det else: if det != basedet: print ("mismatch line ", lnum, "file ", basename, " vs ", name) print basedet, " vs ", det sys.exit(1) rntdiff = absdiff(rnt, basernt) szdiff = absdiff(basesz, sz) if rntdiff < minrtdiff: if szdiff < minsizediff: fnum = fnum + 1 continue if linereport == "n": linereport = "y" print " " print basename, basernt, basesz, print name, rnt, sz, det fnum += 1 lnum += 1 sys.exit(0) libdwarf-20210528/tsearch/ChangeLog20200000664000175000017500000000156713772423635014230 000000000000002020-12-26 David Anderson * tsearch_tester.c: Mostly the same codingstyle issues, but the call to getline() in libc was coded in a way that violated the calling rules. Unless one accidentally passed in a file name that lead to something with really long lines (ie, not a test in the testsuite) one would not notice. But still, it was wrong. Now fixed. * RUNTEST: Now uses logic that lets the tests be meaningful while allowing the tests to PASS if all is well. * README: Now explains how to run the tests. 2020-12-26 David Anderson * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchhash.c,dwarf_tsearchred.c,tsearch.c, tsearch_tester.c: No logic changes, just altering to fit libdwarf codingstyle consisently, with no too-long lines. * tsearch.c: Same changes, codingstyle. libdwarf-20210528/tsearch/config.h0000664000175000017500000000207113644370703013552 00000000000000/* Nothing here, really, a placeholder to enable testing. */ #define HAVE_CONFIG_H 1 /* Define to 1 if tsearch is based on the AVL algorithm. */ /* #define TSEARCH_USE_BAL 1 */ /* Define to 1 if tsearch is based on the binary algorithm. */ /* #define TSEARCH_USE_BIN 1 */ /* Define to 1 if tsearch is based on the chepp algorithm. */ /* #define TSEARCH_USE_EPP 1 */ /* Define to 1 if tsearch is based on the hash algorithm. */ /* #define TSEARCH_USE_HASH 1 */ #define TSEARCH_USE_HASH 1 /* Define to 1 if tsearch is based on the red-black algorithm. */ /* #define TSEARCH_USE_RED 1 */ /* Assuming we have stdint.h and it has uintptr_t. Not intended to work everywhere, the tsearch directory stands a bit outside of libdwarf/dwarfdump. */ #define HAVE_STDINT_H 1 /* Define 1 if we have the Windows specific header stdafx.h */ #undef HAVE_STDAFX_H /* Just for building tsearch independent of libdwarf/dwarfdump/dwarfgen. */ #define HAVE_UNUSED_ATTRIBUTE #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif libdwarf-20210528/tsearch/ChangeLog20140000664000175000017500000000114413644370703014215 000000000000002014-12-09: David Anderson * dwarf_tsearchhash.c(tsearch_inner): Add check for NULL so we do not just coredump if out of memory. * dwarf_tsearchred.c(tsearch_inner): Add check for NULL so we do not just coredump if out of memory. 2014-09-10: David Anderson * dwarf_tsearchhash.c(calculate_allowed_fill): Moved a declaration to avoid using C99 feature. 2014-08-04: David Anderson * dwarf_tsearchhash.c: Changed to avoid compiler warnings about const casts whereever possible. 2014-01-29: David Anderson * All files: All added. Trailing whitespace removed. libdwarf-20210528/tsearch/ChangeLog20180000664000175000017500000000237413644370703014227 000000000000002018-09-11 David Anderson & Carlos Alberto Enciso * dwarf_tsearchhash.c: Remove trailing blank. Now matches version in libdwarf. * dwarf_tsearchbal.c: Change int to size_t where applicable. Fix too-long lines in a couple places 2018-07-20 David Anderson * dwarf_tsearchhash.c: Added UNUSEDARG where appropriate. 2018-07-16 David Anderson * dwarf_tsearch.h: Corrected obsolete web references. Refined HAVE_STDAFX_H ifdef. Realigned text formatting for a better presentation. * config.h: Undef HAVE_STDAFX_H. This is hand coded, not generated. Never changes. 2018-07-10 David Anderson * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchhash.c,dwarf_tsearchred.c: Removed dependency on dwarf_incl.h. All we need is appropriate definition of UNUSEDARG macro. * ESSAY.txt: Fixed a typo and made line lengths more even. 2018-07-14 David Anderson * config.h: Removed leading blank line. * dwarf_tsearch.h: Removed three trailing blank lines. 2018-07-13 David Anderson * dwarf_tsearchbal.c,dwarf_tsearch.c, dwarf_tsearchhash.c, dwarf_tsearchbin.c,dwarf_tsearchepp.c,dwarf_tsearchred.c: Removed 3 trailing blank lines from each. libdwarf-20210528/tsearch/tsearch_tester.c0000664000175000017500000010372513772424363015333 00000000000000/* Copyright (c) 2014, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Testing tsearch etc. tsearch [-adds] [-std] -byvalue inputfile ... If one or more inputfile is listed then 'standard' tests are not done. If -std is given then (even with inputfile) standard tests are done. If -adds is given then extra tdump output is generated from one of the test driver functions. If -showa is given then extra output is generated identifying some some add/delete actions. If -byvalue is given then the tests are run using values not pointers. Run like this it is impossible to differentiate whether dwarf_tsearch() adds a new tree entry or just finds an existing one. In the right circumstances this approach is useful in that it is a bit faster than the default. See applybyvalue() and applybypointer. For timing tests, you probably want to compile with -DFULL_SPEED_RUN */ #include "config.h" #include #include #include #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include "dwarf_tsearch.h" /* These defines rename the call targets to Unix standard names (or to nothing where there is no standard version). */ #ifdef LIBC_TSEARCH #define _GNU_SOURCE /* for tdestroy */ #define __USE_GNU /* tdestroy */ #include #define dwarf_tsearch(a,b,c) tsearch(a,b,c) #define dwarf_tfind(a,b,c) tfind(a,b,c) #define dwarf_tdelete(a,b,c) tdelete(a,b,c) #define dwarf_twalk(a,b) twalk(a,b) #define dwarf_tdestroy(a,b) tdestroy(a,b) #define dwarf_tdump(a,c,d) #define dwarf_initialize_search_hash(a,b,c) #define DW_VISIT VISIT #define dwarf_preorder preorder #define dwarf_postorder postorder #define dwarf_endorder endorder #define dwarf_leaf leaf #endif /* LIBC_TSEARCH */ /* The struct is trivially usable to implement a set or map (mapping an integer to a string). The following struct is the example basis because that is the capability I wanted to use. tsearch has no idea what data is involved, only the comparison function mt_compare_func() and the free function mt_free_func() (passed in to tsearch calls) know what data is involved. Making tsearch very flexible indeed. Obviously the use of a struct (and this particular struct) is arbitrary, it is just an example. */ struct example_tentry { unsigned mt_key; /* When using this as a set of mt_key the mt_name field is set to 0 (NULL). */ char * mt_name; }; /* Used to hold test data. It would be a much better testing regime to add two flags here. One indicating pass/fail for normal interfaces (as with use of struct example_tentry here), one indicating pass/fail for -byvalue runs (-byvalue has limitations in that its impossible to detect if an add is a duplicate or a new add). That is good reason to avoid -byvalue in most situations. */ struct myacts { char action_; unsigned addr_; }; /* Another example of tree content is a simple value. Since the tree contains a pointer for each object we save, we can only directly save a value that fits in a pointer. */ typedef unsigned VALTYPE; enum insertorder { increasing, decreasing, balanced }; static int applybypointer(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); static int applybyvalue(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); int(*applyby)(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); static const int increaseorder[] = {1,2,3,4,5,6}; static const int decreaseorder[] = {6,5,4,3,2,1}; /* The following a pseudo-random order. */ static const int balanceorder[] = {3,6,2,5,4,1}; /* From real code exposing a bug: */ static struct myacts sequence1[] = { {'a', 0x33c8}, {'a', 0x34d8}, {'a', 0x35c8}, {'a', 0x3640}, {'a', 0x3820}, {'a', 0x38d0}, {'a', 0x3958}, {'a', 0x39e8}, {'a', 0x3a78}, {'a', 0x3b08}, {'a', 0x3b98}, {'a', 0x3c28}, {'a', 0x3cb8}, {'d', 0x3c28}, {'a', 0x3d48}, {'d', 0x3cb8}, {'a', 0x3dd8}, {'d', 0x3d48}, {'a', 0x3e68}, {'d', 0x3dd8}, {'a', 0x3ef8}, {'a', 0x3f88}, {'d', 0x3e68}, {'a', 0x4018}, {'d', 0x3ef8}, {0,0} }; static struct myacts sequence2[] = { {'a', 0x931d2e0}, {'a', 0x931d340}, {'a', 0x931d378}, {'a', 0x931d3b8}, {'a', 0x931d0b0}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'d', 0x931d378}, {'a', 0x931d378}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'a', 0x931f9a8}, {'a', 0x931f9f0}, {'a', 0x931fa38}, {'a', 0x93224c0}, {'a', 0x93224f0}, {'a', 0x9322538}, {'a', 0x9322568}, {'a', 0x93225b0}, {'a', 0x93225e0}, {'a', 0x9322628}, {'a', 0x9322658}, {'a', 0x93226a0}, {'a', 0x93226d0}, {'d', 0x93224c0}, {'d', 0x9322538}, {'d', 0x93225b0}, {'d', 0x9322628}, {'d', 0x93226a0}, {'a', 0x931f918}, {'d', 0x931f918}, {'a', 0x931f918}, {0,0} }; /* This test is meant to ensure we can add a value with key of zero. */ static struct myacts sequence3[] = { {'a', 0x0}, {'a', 0xffffffff}, {'a', 0xffff}, {0,0} }; static struct myacts sequential64[] = { {'a', 1}, {'a', 2}, {'a', 3}, {'a', 4}, {'a', 5}, {'a', 6}, {'a', 7}, {'a', 8}, {'a', 9}, {'a', 10}, {'a', 11}, {'a', 12}, {'a', 13}, {'a', 14}, {'a', 15}, {'a', 16}, {'a', 17}, {'a', 18}, {'a', 19}, {'a', 20}, {'a', 21}, {'a', 22}, {'a', 23}, {'a', 24}, {'a', 25}, {'a', 26}, {'a', 27}, {'a', 28}, {'a', 29}, {'a', 30}, {'a', 31}, {'a', 32}, {'a', 33}, {'a', 34}, {'a', 35}, {'a', 36}, {'a', 37}, {'a', 38}, {'a', 39}, {'a', 40}, {'a', 41}, {'a', 42}, {'a', 43}, {'a', 44}, {'a', 45}, {'a', 46}, {'a', 47}, {'a', 48}, {'a', 49}, {'a', 50}, {'a', 51}, {'a', 52}, {'a', 53}, {'a', 54}, {'a', 55}, {'a', 56}, {'a', 57}, {'a', 58}, {'a', 59}, {'a', 60}, {'a', 61}, {'a', 62}, {'a', 63}, {'a', 64}, {0,0} }; static int runstandardtests = 1; static int g_hideactions = 1; /* showallactions is for debugging tree add/delete and should almost always be zero. */ static int g_showallactions = 0; static char filetest1name[2000]; static struct myacts *filetest1 = 0; static char filetest2name[2000]; static struct myacts *filetest2 = 0; static char filetest3name[2000]; static struct myacts *filetest3 = 0; static char filetest4name[2000]; static struct myacts *filetest4 = 0; static int get_record_id(enum insertorder ord,int indx) { int i = 0; switch(ord) { case increasing: i = increaseorder[indx]; break; case decreasing: i = decreaseorder[indx]; break; case balanced: i = balanceorder[indx]; break; default: printf("FAIL, internal error in test code\n"); exit(1); } return i; } /* We allow a NULL name so this struct acts sort of like a set and sort of like a map. */ static struct example_tentry * make_example_tentry(unsigned k,char *name) { struct example_tentry *mt = (struct example_tentry *)calloc( sizeof(struct example_tentry),1); if (!mt) { printf("calloc fail\n"); exit(1); } mt->mt_key = k; if (name) { mt->mt_name = strdup(name); } return mt; } static void mt_free_func(void *mt_data) { struct example_tentry *m = mt_data; if (!m) { return; } free(m->mt_name); free(mt_data); return; } #ifdef HASHSEARCH static DW_TSHASHTYPE mt_hashfunc(const void *keyp) { /* our key here is particularly simple. */ const struct example_tentry *ml = keyp; return ml->mt_key; } #endif /* HASHSEARCH */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } static int mt_compare_func(const void *l, const void *r) { const struct example_tentry *ml = l; const struct example_tentry *mr = r; if (ml->mt_key < mr->mt_key) { return -1; } if (ml->mt_key > mr->mt_key) { return 1; } return 0; } static void walk_entry(const void *mt_data,DW_VISIT x,int level) { const struct example_tentry *m = *(const struct example_tentry **)mt_data; printlevel(level); printf("Walk on node %s %u %s \n", x == dwarf_preorder?"preorder": x == dwarf_postorder?"postorder": x == dwarf_endorder?"endorder": x == dwarf_leaf?"leaf": "unknown", m->mt_key,m->mt_name); return; } static void value_only_walk_entry(const void *data,DW_VISIT x,int level) { VALTYPE val = (VALTYPE)(uintptr_t)data; printlevel(level); printf("Walk on node %s 0x%lu\n", x == dwarf_preorder?"preorder": x == dwarf_postorder?"postorder": x == dwarf_endorder?"endorder": x == dwarf_leaf?"leaf": "unknown", (unsigned long)val); return; } #ifndef LIBC_TSEARCH static char * mt_keyprint(const void *v) { static char buf[50]; const struct example_tentry *mt = (const struct example_tentry *)v; buf[0] = 0; snprintf(buf,sizeof(buf),"0x%08x",(unsigned)mt->mt_key); return buf; } static char * value_keyprint(const void *v) { VALTYPE val = (VALTYPE)(uintptr_t)v; static char buf[50]; buf[0] = 0; snprintf(buf,sizeof(buf),"0x%08lx (%lu)",(unsigned long)val, (unsigned long)val); return buf; } #endif /* LIBC_TSEARCH */ static int insertrecsbypointer(int max, void **tree, const enum insertorder order) { int indx = 0; for (indx = 0 ; indx < max ; ++indx) { int i = 0; int k = 0; char kbuf[40]; char dbuf[60]; struct example_tentry *mt = 0; struct example_tentry *retval = 0; i = get_record_id(order,indx); snprintf(kbuf,sizeof(kbuf),"%u",i); strcpy(dbuf," data for "); strcat(dbuf,kbuf); printf("insertrec %d\n",i); /* Do it twice so we have test the case where tsearch adds and one where it finds an existing record. */ for (k = 0; k < 2 ;++k) { mt = make_example_tentry(i,dbuf); errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if (retval == 0) { printf("FAIL ENOMEM in search on %d, " "give up insertrecsbypointer\n",i); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if (re != mt) { if (!k) { printf("FAIL found existing an error %u\n",i); mt_free_func(mt); return 1; } else { printf("found existing ok %u\n",i); } /* Prevents data leak: mt was already present. */ mt_free_func(mt); } else { if (!k) { printf("insert new ok %u\n",i); } else { printf("FAIL new found but expected " "existing %u\n",i); } /* New entry mt was added. */ } } } } return 0; } static int findrecsbypointer(int max,int findexpected, const void **tree, const enum insertorder order) { int indx = 0; for (indx = 0 ; indx < max ; ++indx) { char kbuf[40]; char dbuf[60]; struct example_tentry *mt = 0; struct example_tentry *retval = 0; int i = 0; dbuf[0] = 0; kbuf[0] = 0; i = get_record_id(order,indx); snprintf(kbuf,sizeof(kbuf),"%u",i); mt = make_example_tentry(i,dbuf); printf("findrec %d\n",i); retval = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (!retval) { if (indx < findexpected) { mt_free_func(mt); printf("FAIL tfind on %s is FAILURE\n",kbuf); return 1; } else { printf("Not found with tfind on %s is ok\n",kbuf); } } else { printf("found ok %u\n",i); if (indx >= findexpected) { mt_free_func(mt); printf("FAIL: found with tfind on %s is FAILURE\n", kbuf); return 1; } else { printf("Found with tfind on %s is ok\n",kbuf); } } mt_free_func(mt); } return 0; } /* The dodump flag is so we can distinguish binarysearch actions from the binarysearch with eppinger mods easily in the test output. The difference is slight and not significant, but the difference is what we look for when we look. */ static int delrecsbypointer(int max,int findexpected, void **tree, const enum insertorder order,int dodump) { int indx = 0; for (indx = 0; indx < max; indx++) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int i = 0; i = get_record_id(order,indx); mt = make_example_tentry(i,0); printf("delrec %d\n",i); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { /* This is what tdelete will delete. tdelete just removes the reference from the tree, it does not actually delete the memory for the entry itself. In fact there is no way to know for sure what was done just given the return from tdelete. You just just assume the delete worked and use the tfind result to delete your contents if you want to.*/ re3 = *(struct example_tentry **)r; if (indx < findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should not have found " "record to delete for %d\n",i); return 1; } r = dwarf_tdelete(mt,tree,mt_compare_func); if (! *tree) { printf("tree itself now empty\n"); } /* We don't want the 'test' node left around. */ if (r) { /* If the node deleted was root, r is really the new root, not the parent. Or r is non-null but bogus. (so don't print). */ printf("tdelete returned parent or something.\n"); } else { printf("tdelete returned NULL, tree now empty.\n"); #ifdef HASHSEARCH printf("Only really means some hash chain is " "now empty.\n"); #endif /* HASHSEARCH */ } mt_free_func(mt); mt_free_func(re3); } else { if (indx >= findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should have found " "record to delete for %d\n",i); return 1; } /* There is no node like this to delete. */ /* We don't want the 'test' node left around. */ mt_free_func(mt); } if (dodump) { dwarf_tdump( *tree,mt_keyprint,"In Delrecs"); } dwarf_twalk( *tree,walk_entry); } return 0; } /* mt must point to data in static storage for this to make any sense. Malloc()ed data or unique static data for this instance mt points at. For example, if there was an immobile array and make_example_tentry() somehow selected a unique entry. */ static int insertonebypointer(void **tree, unsigned long addr,int ct) { struct example_tentry *mt = 0; void *retval = 0; mt = make_example_tentry(addr,0); /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if (retval == 0) { printf("FAIL ENOMEM in search on rec %d adr 0x%lu," " error in insertonebypointer\n", ct,(unsigned long)addr); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if (re != mt) { /* Found existing, error. */ printf("insertonebypointer rec %d addr %lu 0x%lx " "found record preexisting, error\n", ct, (unsigned long)addr, (unsigned long)addr); mt_free_func(mt); return 1; } else { /* inserted new entry, make sure present. */ #ifndef FULL_SPEED_RUN struct example_tentry *mt2 = make_example_tentry(addr,0); retval = dwarf_tfind(mt2,tree,mt_compare_func); mt_free_func(mt2); if (!retval) { printf("insertonebypointer record %d addr 0x%lu " "failed to add as desired," " error\n", ct,(unsigned long)addr); return 1; } #endif /* FULL_SPEED_RUN */ } } return 0; } /* For tfind and tdelete one can use static data and take its address for mt instead of using malloc/free. */ static int deleteonebypointer(void **tree, unsigned addr,int ct) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int err=0; mt = make_example_tentry(addr,0); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { re3 = *(struct example_tentry **)r; dwarf_tdelete(mt,tree,mt_compare_func); mt_free_func(mt); mt_free_func(re3); } else { printf("deleteonebypointer could not find rec %d ! " "error! addr" " 0x%lx\n", ct,(unsigned long)addr); mt_free_func(mt); err = 1; } return err; } #ifdef HASHSEARCH /* Only needed for hash based search in a tsearch style. */ #define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) #else #define INITTREE(x,y) #endif /* HASHSEARCH */ static const char * describe_action(char a) { static const char* ad = "add "; static const char* de = "delete "; static const char* un = "unknown"; switch(a) { case 'a': return ad; case 'd': return de; } return un; } static int applybypointer(struct myacts *m, const char *msg, int hideactions, UNUSEDARG int printwalk, UNUSEDARG int dumpeverystage) { unsigned ct = 1; void *treesq1 = 0; int errcount = 0; INITTREE(treesq1,mt_hashfunc); printf("special sequence applybypointer %s\n",msg); for (; m->action_ != 0; m++,ct++) { if (!hideactions) { printf("Action %2u: %s 0x%x val 0x%x\n",ct, describe_action(m->action_), m->action_,m->addr_); } if (m->action_ == 'a') { errcount += insertonebypointer(&treesq1,m->addr_,ct); continue; } if (m->action_ == 'd') { errcount += deleteonebypointer(&treesq1,m->addr_,ct); continue; } printf("Fail applybypointer, bad action %s entry %d.\n", msg,ct); return 1; } dwarf_tdestroy(treesq1,mt_free_func); return errcount; } #ifdef HASHSEARCH static DW_TSHASHTYPE value_hashfunc(const void *keyp) { VALTYPE up = (VALTYPE )(uintptr_t)keyp; return up; } #endif /* HASHFUNC */ static int value_compare_func(const void *l, const void *r) { VALTYPE lp = (VALTYPE)(uintptr_t)l; VALTYPE rp = (VALTYPE)(uintptr_t)r; if (lp < rp) { return -1; } if (lp > rp) { return 1; } return 0; } /* Nothing to free for the 'value' example. */ static void value_node_free(UNUSEDARG void *valp) { } static int insertbyvalue(void **tree, VALTYPE addr,int ct) { void *retval = 0; /* tsearch adds an entry if its not present already. */ /* Since in this test we do not malloc anything there is no free needed either. Instead we just let tsearch store the value in the pointer in the tree. */ VALTYPE newval = addr; retval = dwarf_tsearch((void *)(uintptr_t)newval, tree, value_compare_func ); if (retval == 0) { printf("FAIL ENOMEM in search on item %d, value %lu, " "error in insertbyvalue\n", ct, (unsigned long)newval); exit(1); } else { /* Since we insert a value there is no possible distinction to be made between newly-inserted and found-in-tree. */ #ifndef FULL_SPEED_RUN { /* For debugging. */ VALTYPE mt2 = addr; retval = dwarf_tfind((void *)(uintptr_t)mt2, tree,value_compare_func); if (!retval) { printf("insertone record %d value 0x%lu failed to add" " as desired, error\n", ct,(unsigned long)mt2); return 1; } } #endif /*FULL_SPEED_RUN */ } return 0; } static int deletebyvalue(void **tree, unsigned addr,int ct) { void *r = 0; int err=0; VALTYPE newval = addr; /* We are not mallocing, so nothing to free he tree holds simple values for us. */ r = dwarf_tfind((void *)(uintptr_t)newval, (void *const*)tree,value_compare_func); if (r) { void *r2 = dwarf_tdelete((void *)(uintptr_t)newval, tree,value_compare_func); if (r2) { /* tdelete returned parent */ } else { /* tdelete returned NULL, tree now empty */ } } else { printf("deletebyvalue action %d could not find rec! error!" " addr 0x%x\n", addr,ct); err = 1; } return err; } /* This demonstrates using a simple integer as the value saved, as itself, not a pointer, per-se. The various flags are not important except in that they can help in case bugs still exist. */ static int applybyvalue(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage) { unsigned ct = 1; void *treesq1 = 0; int errcount = 0; INITTREE(treesq1,value_hashfunc); printf("special sequence applybyvalue %s\n",msg); for (; m->action_ != 0; m++,ct++) { if (!hideactions) { printf("Action %2u: %s 0x%x val 0x%x\n",ct, describe_action(m->action_), m->action_,m->addr_); } if (m->action_ == 'a') { errcount += insertbyvalue(&treesq1,m->addr_,ct); if (ct == 0) { printf("Add done. action# %2d value 0x%x\n", ct,m->addr_); dwarf_tdump(treesq1,value_keyprint, "first sequence2 added"); } else if (dumpeverystage) { dwarf_tdump(treesq1,value_keyprint,"after add"); } continue; } if (m->action_ == 'd') { errcount += deletebyvalue(&treesq1,m->addr_,ct); if (dumpeverystage) { printf("Delete done. action# %2d value 0x%x\n", ct,m->addr_); dwarf_tdump(treesq1,value_keyprint,"after delete"); } continue; } printf("Fail applybyvalue, bad action %s entry %d.\n",msg,ct); return 1; } if (printwalk) { printf("Twalk start, simple value \n"); dwarf_twalk(treesq1,value_only_walk_entry); printf("Twalk end, simple value\n"); dwarf_tdump(treesq1,value_keyprint, "tdump simple value from applybyvalue"); } dwarf_tdestroy(treesq1,value_node_free); return errcount; } static int standard_tests(void) { void *tree1 = 0; int errcount = 0; if (applyby == applybypointer) { printf("Test with increasing input\n"); INITTREE(tree1,mt_hashfunc); errcount += insertrecsbypointer(3,&tree1,increasing); errcount += findrecsbypointer(6,3,(const void **)&tree1, increasing); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint, "Dump Tree from increasing input"); errcount += delrecsbypointer(6,3,&tree1,increasing,0); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if (tree1) { printf("FAIL: delrecsbypointer of increasing did " "not empty the tree.\n"); exit(1); } printf("Test twalk with empty tree\n"); dwarf_twalk(tree1,walk_entry); INITTREE(tree1,mt_hashfunc); printf("Insert decreasing, try tdestroy\n"); errcount += insertrecsbypointer(6,&tree1,decreasing); dwarf_twalk(tree1,walk_entry); dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; INITTREE(tree1,mt_hashfunc); printf("Now test with decreasing input and test twalk " "and tdelete\n"); errcount += insertrecsbypointer(5,&tree1,decreasing); errcount += findrecsbypointer(6,5,(const void **)&tree1, decreasing); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint, "Dump Tree from decreasing input"); errcount += delrecsbypointer(6,5,&tree1,decreasing,0); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if (tree1) { printf("FAIL: delrecsbypointer of decreasing " "did not empty the tree.\n"); exit(1); } INITTREE(tree1,mt_hashfunc); printf("Now test with balanced input and test twalk and " "tdelete\n"); errcount += insertrecsbypointer(4,&tree1,balanced); errcount += findrecsbypointer(6,4,(const void **)&tree1, balanced); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint, "Dump Tree from balanced input"); errcount += delrecsbypointer(6,4,&tree1,balanced,1); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if (tree1) { printf("FAIL: delrecsbypointer of balanced did not " "empty the tree.\n"); exit(1); } dwarf_twalk(tree1,walk_entry); if (errcount > 0) { printf("FAIL tsearch test.\n"); exit(1); } errcount += applyby(&sequence1[0],"Sequence 1", g_hideactions,0,0); errcount += applyby(&sequence2[0],"Sequence 2, a", g_hideactions,0,0); } else { errcount += applyby(&sequence2[0],"Sequence 2, b", g_hideactions,0,0); errcount += applyby(&sequence3[0],"Sequence 3", g_hideactions,0,0); errcount += applyby(&sequential64[0],"Sequential 64", g_hideactions,1,0); } return errcount; } static int getaddr(const char *in, unsigned long *addrout) { unsigned long int res = 0; errno = 0; res = strtoul(in,0,0); if (errno) { return 1; } *addrout = res; return 0; } /* Valid input lines start with # (the rest of the line ignored) or a 12345 or d 0x12345 meaning add a tree record or delete one, respectively. Where the value is the key. Leading spaces on a line are not allowed. Only a single space after the 'a' or 'd' and before the value is allowed. */ static int build_filetest(struct myacts **tout, char *pathout, const char *filename,FILE *f) { size_t bufsize = 500; size_t filelen = 0; size_t ct = 0; int done = 0; size_t ixout = 0; struct myacts *recordacts = 0; char *buf = 0; buf = (char *)calloc(1,bufsize); if (!buf) { printf("FAIL malloc bufsize %lu fails line %d\n", (unsigned long)bufsize,__LINE__); } while(!done) { ssize_t charsread = 0; charsread = getline(&buf,&bufsize,f); if (charsread < 0) { done = 1; break; } ++filelen; } rewind(f); /* Leave zeroed entry (at least one) at the end. */ recordacts = calloc(sizeof(struct myacts),filelen+2); *tout = recordacts; strcpy(pathout,filename); done = 0; for (ct = 0; !done && ( ct < filelen); ++ct) { ssize_t charsread = 0; charsread = getline(&buf,&bufsize,f); if (charsread < 0) { done = 1; break; } if (buf[0] == '#') { continue; } if (buf[0] == 'a' && buf[1] == ' ') { int readaddrfail = 0; unsigned long addr = 0; recordacts[ixout].action_ = 'a'; readaddrfail = getaddr(&buf[2],&addr); if (readaddrfail) { fprintf(stderr,"Improper value input, " "line %lu of file %s\n %s\n", (unsigned long)ct,filename,buf); return 1; } recordacts[ixout].addr_ = addr; } else if (buf[0] == 'd' && buf[1] == ' ') { int readaddrfail = 0; unsigned long addr = 0; recordacts[ixout].action_ = 'd'; readaddrfail = getaddr(&buf[2],&addr); if (readaddrfail) { fprintf(stderr,"Improper value input, line %lu " "of file %s\n %s\n", (unsigned long)ct,filename,buf); return 1; } recordacts[ixout].addr_ = addr; } else { fprintf(stderr,"Improper input, line %lu of file %s\n" "%s\n", (unsigned long)ct,filename,buf); return 1; } ixout++; } return 0; } static int fill_in_filetest(const char *filename) { FILE *f = 0; int errcount = 0; f = fopen(filename,"r"); if (!f) { fprintf(stderr,"Open of %s failed",filename); return 1; } if (!filetest1) { errcount += build_filetest(&filetest1,filetest1name, filename,f); } else if (!filetest2) { errcount += build_filetest(&filetest2,filetest2name, filename,f); } else if (!filetest3) { errcount += build_filetest(&filetest3,filetest3name, filename,f); } else if (!filetest4) { errcount += build_filetest(&filetest4,filetest4name, filename,f); } else { printf("Exceeded limit on input files. %s ignored\n", filename); errcount = 1; } fclose(f); return errcount; } static void print_usage(const char *a, const char *b,const char *app) { fprintf(stderr,"%s : %s\n",a,b); fprintf(stderr,"run as\n"); fprintf(stderr," %s [-std] [samplefile]...\n",app); fprintf(stderr,"By default runs standard tests\n"); fprintf(stderr,"with pathnames, standard tests are not run\n"); fprintf(stderr,"unless -std passed in as first arg.\n"); exit(1); } static void readargs(int argc, char **argv) { int ix = 0; int notedstd = 0; int defaultstd = 1; if (argc < 2) { /* No arguments, take defaults. */ return; } for (ix = 1; ix are correct. ================== IMPLEMENTATION ODDITIES: The code uses names like dwarf_tsearch() instead of just tsearch() so one can have both this tsearch() and GNU or a standard tsearch code available simultaneously with no interference at runtime. The code here operates like GNU or UNIX tsearch() but is internally incompatible. We'll usually refer to tsearch() not dwarf_tsearch() (etc) but we mean either and both unless otherwise specified here. The use of tsearch() and friends is a little tricky. That is just the way it is. The best reference is the code in tsearch_tester.c. See the trivial set of #defines in tsearch_tester.c that result in a standard-based naming of the functions. The return value from tdelete() is particularly problematic because it purports to return a pointer to another record than the one deleted, yet no such record necessarily exists. And in the case of The hash version requires use of the new function dwarf_initialize_search_hash() to provide a hashing function. And the hash version does not set the root pointer to NULL on tdelete() of the last record, since that would result in losing the hashing function pointer. Use tdestroy() to free up any remaining space. dwarf_tdump() is an invention and unique to this code. It is for debugging. It prints a representation of the data in the tree or hash to stdout. The #include .h file set used here makes it much easier for me to move these files to another project as necessary. You will probably want to revise the #include set a little. ================== OTHER DIRECTORIES: testdata contains a set of sample allocations, where lines starting with 'a' mean add and 'd' means delete. These are used for testing the library code. scripts contains some python scripts for converting results produced by printf added to libdwarf alloca() code. These were used massage the print output from running dwarfdump on real object files into the testcase/* format. It is unlikely you will find them much use except as starting points. ================== RUNNING TESTS The test scheme should be revised to do each test 'right' and do something about those pointer values printed. But for now this is how it works. Getting started: rm -rf testcases cp -r ../regressiontests/tsearchtests mv tsearchtests testcases cd testcases gunzip action-F-dwgenb-dwarfgen.log.gz gunzip action-f-v-v-irix64-libc.so.log.gz gunzip action-i-dwarf4-dd2g4.5dwarf-4.log.gz gunzip action-l-irix64-libc.so.log.gz cd .. All the files in testcases except two are just data for the tests. testcases/testfail.base and testcases/testpass.base are baseline outputs and if what the test cases or dwarf_dump changes those are what need to be updated. All the tests are done by the script RUNTEST. sh RUNTEST [-save] The -save option tells the script to save (rather than delete) the temp files it writes to. First tests run and are saved in 'testfail' Then that content (which includes passes and fails and all that is normal) diff testfail testcases/testfail.base should show no differences. The second part involves the file testpass which takes a little longer. The message from the script suggests you inspect the difference with a graphical compare tool (I use fldiff) because most lines that appear involve printing pointers and of course those do not match between runs. The actual diff is on files with hex numbers transformed to 0xyyy so an overall PASS is normal.. Overall on an ordinary 3GHz 64Bit machine a run takes around seven minutes. ================== REFERENCES: Donald E Knuth, The Art of Computer Programming Volume 3, Second Edition. (Quite difficult to interpret some parts of Knuth's algorithms, but then I always found Knuth hard to understand. Still, Knuth is the essential source for algorithms.) The Open Group, The Single UNIX Specification, Version 3(2001). The Single Unix Specification (or whatever it is called now) is a reference source everyone should have. Robert Sedgewick and Kevin Wayne, Algorithms (4th Ed). This is the crucial reference on red-black trees. There is a crucial fix in the errata of the 3rd printing. In addition, in dwarf_tsearchred.c in two places I had to fix things, look for 'Mistake' in the source. http://www.prevanders.net/tsearch.html libdwarf-20210528/tsearch/tsearchlibtimes.csv0000664000175000017500000000257713644370703016046 00000000000000lib,testcase,usertime,elapsed,maxmem Hash-bv,dd2g4,0.46,0.49,17640 hash,dd2g4,0.6,0.68,17908 Bal-bv,dd2g4,0.84,0.91,17328 Red-bv,dd2g4,0.85,0.88,17296 Gnu-bv,dd2g4,0.94,1,17296 red,dd2g4,1,1.1,17560 bal,dd2g4,1.02,1.14,17716 gnu,dd2g4,1.14,1.24,17564 Epp-bv,dd2g4,27.27,27.91,17032 Bin-bv,dd2g4,28.8,28.91,17032 epp,dd2g4,32.05,32.3,17564 bin,dd2g4,33.8,33.84,17560 Hash-bv,F-dwgenb,0.15,0.15,6164 hash,F-dwgenb,0.18,0.26,6160 Red-bv,F-dwgenb,0.19,0.22,6160 Bal-bv,F-dwgenb,0.23,0.24,6160 red,F-dwgenb,0.24,0.25,6160 bal,F-dwgenb,0.28,0.3,6160 Gnu-bv,F-dwgenb,0.28,0.32,6160 gnu,F-dwgenb,0.34,0.35,6160 Bin-bv,F-dwgenb,8.45,9.07,6164 Epp-bv,F-dwgenb,8.51,9.17,6160 bin,F-dwgenb,9.98,10.78,6160 epp,F-dwgenb,10.3,10.84,6160 Hash-bv,irix64,0.1,0.15,6028 hash,irix64,0.17,0.17,6296 Bal-bv,irix64,0.24,0.25,5688 Gnu-bv,irix64,0.25,0.26,5688 bal,irix64,0.3,0.32,5692 Red-bv,irix64,0.31,0.36,5688 gnu,irix64,0.32,0.37,5956 red,irix64,0.36,0.37,5952 Bin-bv,irix64,1.36,1.4,5428 Epp-bv,irix64,1.36,1.37,5428 bin,irix64,1.63,1.75,5692 epp,irix64,1.64,1.78,5688 Hash-bv,vvirix64,0.02,0.03,1988 hash,vvirix64,0.04,0.04,2056 Bal-bv,vvirix64,0.05,0.05,1796 Red-bv,vvirix64,0.05,0.05,1760 bal,vvirix64,0.06,0.07,1928 red,vvirix64,0.06,0.06,2024 Gnu-bv,vvirix64,0.06,0.06,1756 gnu,vvirix64,0.07,0.07,2020 Bin-bv,vvirix64,4.34,4.47,1500 Epp-bv,vvirix64,4.4,4.43,1496 epp,vvirix64,5.09,5.31,1760 bin,vvirix64,5.19,5.54,1756 libdwarf-20210528/tsearch/ChangeLog0000664000175000017500000000017214050027222013671 000000000000002021-05-14 David Anderson * scripts/comparator.py,scripts/concatlines.py: Reformatted to standard python style. libdwarf-20210528/tsearch/RUNTEST0000664000175000017500000001043613772445730013234 00000000000000#!/bin/sh # test2 is supposed to fail, do not expect success. # With -byvalue it gets one error, without -byvalue it gets two. echo "start at " `date` # test17 is also supposed to fail, it adds 8 twice. myexit=0 #The following line assumes the test cases have been #placed in a directory named 'testcases' and #that the .gz versions expanded. #The tsearch test data is in the #libdwarf regression tests (available from sourceforge) #in the directory # tsearchtests # It's appropriate to copy the tests from regressiontests # into 'testcases' # Not change what b refers to. # gunzip the .gz files in testcases, not in regressiontets # Note that the output file testpass and the basline # testcases/testpass.base # are filled with pointers as hex # values so we transform those below before diff-ing. # savetemps=n rmtemps() { rm -f testpasserrs rm -f junkdiffout rm -f junkbase rm -f junknew rm -f testpass rm -f testfails } fixpointers() { sed 's/0x[0-9a-f]*/0xyyy/g' <$1 >$2 } rmtemps if [ $# -ne 0 ] then if [ "$1" = "-save" ] then savetemps=y else echo " Option $1 is unrecognized." echo " Perhaps you meant -save" echo " to save the temp files, not delete them" exit 1 fi fi stsecs=`date '+%s'` b=testcases #These test expecting failure. echo >testfail for opts in "" -byvalue do for test in $b/test2 $b/test17 do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts $test '====' >>testfail $app $opts $test >>testfail done done done diff $b/testfail.base testfail >junkdiffout r=$? head -12 junkdiffout if [ $r -ne 0 ] then echo "FAIL because testfail got unexpected output." echo "We only show the first 12 lines of difference" echo "To update: mv testfail $b/testfail.base" echo "To diff : diff $b/testfail.base testfail" myexit=1 else echo PASS the testfail set of tests. fi echo >testpass for opts in "" -byvalue do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts '====' >>testpass $app $opts >>testpass done done for opts in "" -byvalue do for test in $b/action-F-dwgenb-dwarfgen.log $b/action-f-v-v-irix64-libc.so.log \ $b/action-i-dwarf4-dd2g4.5dwarf-4.log \ $b/action-l-irix64-libc.so.log \ $b/test10 \ $b/test11 \ $b/test11b \ $b/test11c \ $b/test18 \ $b/test32 \ $b/test547 \ $b/test6 \ $b/test64 \ $b/test8 \ $b/test9 do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts $test '====' >>testpass $app $opts $test >>testpass done done done fixpointers $b/testpass.base junkbase fixpointers testpass junknew diff junkbase junknew >junkdiffout r=$? head -12 junkdiffout if [ $r -ne 0 ] then echo "FAIL because testpass got unexpected output." echo "Just showing the first 12 lines of the diff." echo "To see the detailed diff" echo "try fldiff $b/testpass.base testpass" echo "To update baseline mv testpass $b/testpass.base" myexit=1 else echo "PASS the testpass set of tests. Congratulations." echo "Note that we turned all hex values into 0xyyy" echo "as pointers rarely match." fi lcb=`wc -l < $b/testpass.base` lcn=`wc -l < testpass` if [ $lcb -eq $lcn ] then echo "Line counts match: $b/testpass.base testpass" else echo "Line counts NO NOT match: $b/testpass.base testpass" fi ndsecs=`date '+%s'` showminutes() { t=`expr \( $2 \- $1 \+ 29 \) \/ 60` echo "Run time in minutes: $t" } showminutes $stsecs $ndsecs # An 'error' reported in testpass does not mean anything # is wrong. A FAIL does. #grep error testpass >testpasserrs grep FAIL testpass >>testpasserrs ct=`wc -l /* for printf */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* INVARIANT: The head node has no user data. head->llink is null, head->rlink points to the real user top node (root of the user tree). So the physical top node we call 'head'. No user data. The user top node we call 'root' here. It has a user key. Though we intend that head->rlink be non-NULL except briefly when a tdelete removes the last node (in which case we remove the head too before returning) the code is a bit cautious and tests for a non-NULL head->rlink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. */ const void *keyptr; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging. Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* For debugging */ static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if (!t) { return; } dumptree_inner(t->rlink,keyprint,"left ",level+1); if (t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"right",level+1); } static struct ts_entry* getlink(struct ts_entry*t,int a) { if (a < 0) { return(t->llink); } return(t->rlink); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if (!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if (!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head, msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root, msg); dumptree_inner(root,keyprint,"top",0); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } e->keyptr = key; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *e = allocate_ts_entry(key); if (!e) { /* out of memory */ return NULL; } if (kc < 0) { p->llink = e; } else { p->rlink = e; } /* Non-NULL means inserted. */ return e; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if (q) { *inserted = 1; } return q; } /* Algorithm T of Knuth 6.2.2.2 key is pointer to a user data area containing the key and possibly more. We iterate like Knuth does, but using for (;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* localrootp, int (*compar)(const void *, const void *), int*inserted) { struct ts_entry* p = localrootp; for (;;) { struct ts_entry *r = 0; /* T2. */ int kc = compar(key,p->keyptr); if (kc < 0) { /* T3. */ struct ts_entry *l = p->llink; if (l) { p = l; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } else if (kc > 0 ) { /* T4. */ struct ts_entry *r2 = p->rlink; if (r2) { p = r2; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } return 0; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry *head = 0; struct ts_entry *root = 0; struct ts_entry *r = 0; int inserted = 0; if (!headpin) { return NULL; } head = (struct ts_entry *)*headpin; if (head) { root = head->rlink; } if (!head || !root) { int allocatedhead = 0; if (!head) { head = allocate_ts_entry(0); allocatedhead = 1; } if (!head) { return NULL; } root = allocate_ts_entry(key); if (!root) { if (allocatedhead) { free(head); } return NULL; } head->rlink = root; *headpin = head; return (void *)(&(root->keyptr)); } root = head->rlink; r = tsearch_inner(key,root,compar,&inserted); if (!r) { return NULL; } /* Was this found or inserted? Value is the same either way, but the pointer to return is not the same! */ /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*headppin, int (*compar)(const void *, const void *)) { struct ts_entry *head = (struct ts_entry *)*headppin; struct ts_entry **proot = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; if (!headppin) { return NULL; } head = (struct ts_entry *)*headppin; if (!head) { return NULL; } proot = &head->rlink; root = *proot; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry * p= 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; /* We don't really care much if multiple tree tables use this simultaneously. This left/right is a practical thing not supported by known theory, according to Knuth. We start with eppingerleftr=1 because that happens to show a different tree than standard knuth in one of our standard tsearch regression test sequences. */ static unsigned eppingerleft = 1; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if (!p) { return NULL; } { struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. *q is what Knuth calls q. */ t = *q; if (!eppingerleft) { struct ts_entry *r = 0; eppingerleft = 1; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if (s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } } else { struct ts_entry *l = 0; eppingerleft = 0; l = t->llink; if (!l) { *q = t->rlink; done = 1; } else { /* D2. */ if (!l->rlink) { l->rlink = t->rlink; *q = l; done = 1; } } while (!done) { /* D3. */ s = l->rlink; if (s->rlink) { l = s; continue; } s->rlink = t->rlink; l->rlink = s->llink; s->llink = t->llink; *q = s; done = 1; } } /* Step D4. */ if (!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if (emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if (!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if (p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if (p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *headin, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)headin; const struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if (p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if (p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. The user must zero out the head node, we have no way to do that in the defined interface. */ void dwarf_tdestroy(void *headin, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)headin; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (head) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } libdwarf-20210528/tsearch/dwarf_tsearchred.c0000664000175000017500000005551613771750631015626 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Implements a red-black tree. Based on Sedgewick "Algorithms" 4th Edition. Right now showing Kindle 'locations', I do not have page numbers. On a Kindle, the insert algorithm is found at Location 7930, and rotate{left,right} precede that a little. Delete as a topic starts at location 7938. Delete supporting algos are at about location 8155. We insert a ts_entry node as head that has a NULL llink and an rlink pointing to the real tree root so that the use does not see the root changing in flight. Kindle location 7808. Red-black BSTs are BSTs with red and black links satisfying: a)Red links lean left b)No node has two red links connected to it. c)The tree has 'perfect black balance': every path from the root to a null link has the same number of black links. Sedgewick defines: a 3-node is a pair of 2-nodes with a red link that leans left. So a 2-node is a node which is not marked red and whose llink is not marked red. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #include /* for printf */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define TRUE 1 #define RED 1 #define FALSE 0 #define BLACK 0 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* DW_CHECK_CONSISTENCY */ struct ts_entry { /* Keyptr usually points to a a record the user saved, the user record contains the user's key itself and perhaps more. However, the values actually present are controlled by the user. */ const void *keyptr; /* Non-zero (RED) red indicates the link pointing into this node is red, otherwise it is a black link pointing to this node. A null llink or rlink (below) means the llink or rlink (respectively) is considered black. */ unsigned char color; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE ( * hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } static int isred(const struct ts_entry*n) { if (n && n->color == RED) { return TRUE; } return FALSE; } /* Meaning the node is not part of a 3-node. We define NULL as a 2-node. */ static int is_twonode(const struct ts_entry *h) { if (!h) { return TRUE; } if (isred(h)) { return FALSE; } if (isred(h->llink)) { return FALSE; } return TRUE; } #if 0 /* DEBUG ONLY */ static const char * printnode(struct ts_entry*n) { static char b[400]; if (!n) { return "Null node"; } snprintf(b,sizeof(b),"0x%x 2-node %d red %d l 0x%x r 0x%x", (unsigned)n, is_twonode(n), n->color, (unsigned)n->llink, (unsigned)n->rlink); return b; } /* For debugging. Use this to call dumptree_inner from inside this file. */ static char * v_keyprint(const void *l) { unsigned long v = (unsigned long)l; static char buf [50]; snprintf(buf,sizeof(buf),"0x%08" DW_PR_DUx, (Dwarf_Unsigned)(uintptr_t)v); return buf; } #endif /* DEBUG ONLY */ /* Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if (!t) { return; } dumptree_inner(t->rlink,keyprint,"right",level+1); if (t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> <2-node %d red %u> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, is_twonode(t), t->color, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"left ",level+1); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if (!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if (!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head,msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root,msg); dumptree_inner(root,keyprint,"top",0); fflush(stdout); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the count of black links. a)Red links lean left b)No node has two red links connected to it. c)The tree has 'perfect black balance': every path from the root to a null link has the same number of black links. */ struct balance_s { int countset_; int blackcount_; void *firstcount_; }; static struct balance_s zerobal; static void check_or_set(struct ts_entry*t, int* errcount, struct balance_s *balcount, int linkcount, const char *prefix) { if (!balcount->countset_) { balcount->blackcount_ = linkcount; balcount->countset_ = 1; balcount->firstcount_ = t; return; } if (balcount->blackcount_ == linkcount) { return; } printf("%s Black link count does not match: node 0x%" DW_PR_DUx " %d vs 0x%" DW_PR_DUx " %d\n", prefix, Dwarf_Unsigned(uintptr_t)t, linkcount, (Dwarf_Unsignedbalcount->firstcount_, balcount->blackcount_); ++(*errcount); } int dwarf_check_balance_inner(struct ts_entry *t, int level, int maxdepth, int blacklinkcount, struct balance_s *balcount, int *founderror,const char *prefix) { int redcount = 0; int leftbcount = blacklinkcount; int rightbcount = blacklinkcount; if (level > maxdepth) { printf("%s Likely internal erroneous link loop, " "got to depth %d.\n", prefix,level); exit(1); } if (!t) { return 0; } redcount = isred(t) + isred(t->llink) + isred(t->rlink); if (redcount > 1) { printf("%s red count error error at node 0x%" DW_PR_DUx ": %d\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, redcount); (*founderror)++; } if (isred(t->rlink)) { printf("%s red right link an error at node 0x%" DW_PR_DUx "\n", prefix, (Dwarf_Unsigned)(uintptr_t)t) (*founderror)++; } if (t->llink) { if (!isred(t->llink)) { leftbcount++; } } else { check_or_set(t,founderror,balcount,leftbcount,prefix); } if (t->rlink) { if (!isred(t->rlink)) { rightbcount++; } } else { check_or_set(t,founderror,balcount,rightbcount,prefix); } dwarf_check_balance_inner(t->llink,level+1,maxdepth, leftbcount,balcount,founderror,prefix); dwarf_check_balance_inner(t->rlink,level+1,maxdepth, rightbcount,balcount,founderror,prefix); return isred(t); } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 1000; /* prevent runaway loop. */ int errcount = 0; int depth = 0; int blackcount = 0; struct balance_s balancect; struct ts_entry*root = 0; if (finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } balancect = zerobal; if (!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; if (!root) { printf("%s check balance null tree ptr\n",prefix); return; } /* Counting in levels, not level number of top level. */ depth = dwarf_check_balance_inner(root,depth,maxdepth, blackcount, &balancect,&errcount,prefix); if (errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* DW_CHECK_CONSISTENCY */ static struct ts_entry* getlink(struct ts_entry*t,int a) { if (a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } e->keyptr = key; e->color = BLACK; /* That is, set black. */ e->llink = 0; e->rlink = 0; return e; } static void flipcolors(struct ts_entry*h) { /* Sedgewick does not verify llink rlink non-null? */ h->color = RED; if (h->llink) h->llink->color = BLACK; if (h->rlink) h->rlink->color = BLACK; } /* Kindle loc 7840. */ static struct ts_entry* rotateleft(struct ts_entry *h) { struct ts_entry *x = h->rlink; h->rlink = x->llink; x->llink = h; x->color = h->color; h->color = RED; return x; } /* Kindle loc 7848. */ static struct ts_entry* rotateright(struct ts_entry *h) { struct ts_entry *x = h->llink; h->llink = x->rlink; x->rlink = h; x->color = h->color; h->color = RED; return x; } static struct ts_entry* moveredright(struct ts_entry *h) { flipcolors(h); /* In 4th Ed. book had ! before isred, corrected in errata, Oct 2012. */ if (isred(h->llink->llink)) { h = rotateright(h); } return h; } /* Kindle loc 8155. */ static struct ts_entry* moveredleft(struct ts_entry *h) { flipcolors(h); /* Added test for h->rlink.. davea. */ if (h->rlink && isred(h->rlink->llink)) { h->rlink = rotateright(h->rlink); h = rotateleft(h); } return h; } static struct ts_entry * tsearch_insert( const void *key, struct ts_entry* h, int (*compar)(const void *, const void *), int*inserted, struct ts_entry **insertednode) { int kc = 1; if (!h) { h = allocate_ts_entry(key); if (!h) { return h; } h->color = RED; *inserted = TRUE; *insertednode = h; return h; } kc = compar(key,h->keyptr); if (kc < 0) { struct ts_entry *t = tsearch_insert(key,h->llink,compar, inserted, insertednode); if (!t) { /* out of memory */ return t; } h->llink = t; } else if (kc > 0) { struct ts_entry *t = tsearch_insert(key,h->rlink,compar, inserted, insertednode); if (!t) { /* out of memory */ return t; } h->rlink = t; } else { /* Found existing. Return it. */ return h; } /* Now fix up links so left is red and right is black. */ if (isred(h->rlink) && !isred(h->llink)) { /* Maintaining red on left. */ /* insert is between. */ h = rotateleft(h); } if (isred(h->llink) && isred(h->llink->llink)) { /* Avoiding sequencial red links, turning into paired reds fixed just below. */ h = rotateright(h); } if (isred(h->llink) && isred(h->rlink)) { /* Pair reds below h,flip to black. */ flipcolors(h); } return h; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headpin; struct ts_entry *head = *headp; struct ts_entry *root = 0; struct ts_entry *r = 0; struct ts_entry *insertednode = 0; int inserted = 0; if (!head) { struct ts_entry *rhead = 0; struct ts_entry *r2 = 0; rhead = allocate_ts_entry(0); if (!rhead) { return NULL; } r2 = allocate_ts_entry(key); if (!r2) { free(rhead); return NULL; } *headp = rhead; rhead->rlink = r2; r2->color = BLACK; return (void *)&(r2->keyptr); } root = head->rlink; r = tsearch_insert(key,root,compar,&inserted,&insertednode); if (!r) { return NULL; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif /* DW_CHECK_CONSISTENCY */ if (inserted) { /* Discards const. Required by the interface definition. */ /* root might change, but never the head pointer, so no need to update *headp. Do need to update head.rlink as balancing might have changed root node. */ head->rlink = r; return (void *)&(insertednode->keyptr); } /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = *phead; struct ts_entry *p = 0; if (!head) { return NULL; } p = head->rlink; while( p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } static void complementcolors( struct ts_entry *h) { h->color = !h->color; if (h->llink) { h->llink->color = !h->llink->color; } if (h->rlink) { h->rlink->color = !h->rlink->color; } } /* Kindle loc 8155. */ static struct ts_entry * balance( struct ts_entry *h) { if (!h) { return NULL; } if (isred(h->rlink)) { h = rotateleft(h); } /* The following from the insert code. loc 7930. plus complementcolors() */ if (isred(h->rlink) && !isred(h->llink)) { h = rotateleft(h); } if (isred(h->llink) && isred(h->llink->llink)) { h = rotateright(h); } if (isred(h->llink) && isred(h->rlink)) { complementcolors(h); } return h; } /* Kindle Location 8154. */ /* This finds the min record that findmin will find and delete. Meaning the record with llink NULL, descending left links. */ static struct ts_entry * findmin(struct ts_entry *h) { if (!h) { return NULL; } while (h->llink) { h = h->llink; } return h; } /* At Loc 8154 in Kindle. We copied out relevant data, so now delete the lowest key record (possibly while reorganizing the tree). Invariant: current node is not a 2-node. */ static struct ts_entry * deletemin(struct ts_entry *h) { if (!h->llink) { /* Found minimum with key > key to delete. Sedgewick does not do this, so something is wrong somewhere. Mistake in Sedgewick? */ return h->rlink; } if (!isred(h->llink) && !isred(h->llink->llink)) { h = moveredleft(h); } h->llink = deletemin(h->llink); h = balance(h); return h; } enum delete_result_e { dr_unknown, dr_notfound, dr_deleted, dr_noteparent }; /* Kindle location 8168 for the algorithm. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *h, int (*compar)(const void *, const void *), struct ts_entry **parent, enum delete_result_e *dr) { int kc = 0; if (!h) { *dr = dr_notfound; return NULL; } kc = compar(key,h->keyptr); if (kc < 0) { if (!isred(h->llink) && (h->llink && !isred(h->llink->llink))) { h = moveredleft(h); } h->llink = tdelete_inner(key,h->llink, compar, parent,dr); if (*dr == dr_noteparent) { *dr = dr_deleted; *parent = h; } } else { if (isred(h->llink)) { h = rotateright(h); } kc = compar(key,h->keyptr); if (!kc && !h->rlink) { struct ts_entry *l = h->llink; /* This is a case where h is deleted (it matches our key value) and no rlink means it is end of chain at right, so it is replaced with left (corrected by davea). */ free(h); *dr = dr_noteparent; return l; } /* Fixed test. Mistake in Sedgewick. Unless both links off h are non-null we crash. */ if (h->rlink && h->llink && !isred(h->rlink) && !isred(h->rlink->llink)) { h = moveredright(h); } kc = compar(key,h->keyptr); if (!kc) { struct ts_entry *r = 0; /* ASSERT: We have non-null rlink. */ r = findmin(h->rlink); h->keyptr = r->keyptr; h->rlink = deletemin(h->rlink); /* r is the node we are to delete. r value moved to h so we keep the changed h. */ free(r); *dr = dr_noteparent; } else { h->rlink = tdelete_inner(key,h->rlink,compar,parent,dr); if (*dr == dr_noteparent) { *parent = h; *dr = dr_deleted; } } } h = balance(h); return h; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **proot = (struct ts_entry **)rootp; struct ts_entry *head = *proot; struct ts_entry *p= 0; struct ts_entry *root= 0; struct ts_entry *parent= 0; enum delete_result_e dr = dr_unknown; if (!head) { return NULL; } root = p = head->rlink; if (!p) { return NULL; } if (!isred(p->llink) && !isred(p->rlink)) { p->color = RED; } p = tdelete_inner(key,root,compar,&parent,&dr); if (dr == dr_unknown || dr == dr_notfound ) { return NULL; } if (dr == dr_noteparent) { parent = p; dr = dr_deleted; } /* INVARIANT: dr == dr_deleted. */ if (p) { /* ASSERT: parent non-null */ root = p; root->color = BLACK; /* We have a root, might be unchanged (or changed). */ head->rlink = root; #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif /* DW_CHECK_CONSISTENCY */ /* ASSERT: any rebalancing would leave parent set to the same parent node, just links might have changed and it might not literally be parent due to rebalancing. */ return(void *)(&(parent->keyptr)); } /* The tree is empty. Remove it. */ free(head); *rootp = NULL; return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if (p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if (p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; const struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if (p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if (p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { free(head); return; } dwarf_tdestroy_inner(root,free_node,0); free(head); } libdwarf-20210528/tsearch/tsearch.c0000664000175000017500000001413713771750115013737 00000000000000/* Copyright David Anderson 2010-2014. This is free software. Permission hereby granted for anyone to copy or use this code for any purpose without restriction. Attribution may be given or may not, it is your choice. September 8, 2011: The tdelete example code was wrong in that it did not clean up entirely. So was the tsearch example code. Both are now fixed (it's surprisingly difficult to do this all correctly, but then the available documentation is at best a hint). The GNU/Linux tsearch man page (in the man-page 3.54 edition) suggests that tdestroy() takes a pointer to a variable which points to the root. In reality tdestroy() takes a pointer to the root. As revealed by trying tdestroy() both ways. */ /* tsearch() tfind() tdelete() twalk() tdestroy() example. */ #include #include #include #include #include /* __USE_GNU exposes the GNU tdestroy() function, a function that is not mentioned by the Single Unix Specification. */ #define __USE_GNU 1 #include /* The struct is trivially usable to implement a set or map (mapping an integer to a string). The following struct is the example basis because that is the capability I wanted to use. tsearch has no idea what data is involved, only the comparison function mt_compare_func() and the free function mt_free_func() (passed in to tsearch calls) know what data is involved. Making tsearch very flexible indeed. Obviously the use of a struct is arbitrary, it is just an example. */ struct my_tentry { unsigned mt_key; /* When using this as a set of mt_key the mt_name field is set to 0 (NULL). */ char * mt_name; }; /* We allow a NULL name so this struct acts sort of like a set and sort of like a map. */ struct my_tentry * make_my_tentry(unsigned k,char *name) { struct my_tentry *mt = (struct my_tentry *)calloc(sizeof(struct my_tentry),1); if (!mt) { printf("calloc fail\n"); exit(1); } mt->mt_key = k; if (name) { mt->mt_name = strdup(name); } return mt; } void mt_free_func(void *mt_data) { struct my_tentry *m = mt_data; if (!m) { return; } free(m->mt_name); free(mt_data); return; } int mt_compare_func(const void *l, const void *r) { const struct my_tentry *ml = l; const struct my_tentry *mr = r; if (ml->mt_key < mr->mt_key) { return -1; } if (ml->mt_key > mr->mt_key) { return 1; } return 0; } void walk_entry(const void *mt_data,VISIT x,int level) { struct my_tentry *m = *(struct my_tentry **)mt_data; printf("<%d>Walk on node %s %u %s \n", level, x == preorder?"preorder": x == postorder?"postorder": x == endorder?"endorder": x == leaf?"leaf": "unknown", m->mt_key,m->mt_name); return; } int main() { unsigned i; void *tree1 = 0; #define RECMAX 3 for (i = 0 ; i < RECMAX ; ++i) { int k = 0; char kbuf[40]; char dbuf[60]; struct my_tentry *mt = 0; struct my_tentry *retval = 0; snprintf(kbuf,sizeof(kbuf),"%u",i); strcpy(dbuf," data for "); strcat(dbuf,kbuf); /* Do it twice so we have test the case where tsearch adds and one where it finds an existing record. */ for (k = 0; k < 2 ;++k) { mt = make_my_tentry(i,dbuf); errno = 0; /* tsearch adds an entry if its not present already. */ retval = tsearch(mt,&tree1, mt_compare_func ); if (retval == 0) { printf("Fail ENOMEM\n"); exit(1); } else { struct my_tentry *re = 0; re = *(struct my_tentry **)retval; if (re != mt) { printf("found existing ok %u\n",i); /* Prevents data leak: mt was already present. */ mt_free_func(mt); } else { printf("insert ok %u\n",i); /* New entry mt was added. */ } } } } for (i = 0 ; i < 5 ; ++i) { char kbuf[40]; char dbuf[60]; dbuf[0] = 0; struct my_tentry *mt = 0; struct my_tentry *retval = 0; snprintf(kbuf,sizeof(kbuf),"%u",i); mt = make_my_tentry(i,dbuf); retval = tfind(mt,&tree1,mt_compare_func); if (!retval) { if (i < RECMAX) { printf("Fail TSRCH on %s is FAILURE\n",kbuf); exit(1); } else { printf("Fail TSRCH on %s is ok\n",kbuf); } } else { printf("found ok %u\n",i); } mt_free_func(mt); } twalk(tree1,walk_entry); { struct my_tentry *mt = 0; struct my_tentry *re3 = 0; void *r = 0; mt = make_my_tentry(1,0); r = tfind(mt,&tree1,mt_compare_func); if (r) { /* This is what tdelete will delete. tdelete just removes the reference from the tree, it does not actually delete the memory for the entry itself. */ re3 = *(struct my_tentry **)r; r = tdelete(mt,&tree1,mt_compare_func); /* We don't want the 'test' node left around. */ mt_free_func(mt); if (r) { struct my_tentry *re2 = 0; re2 = *(struct my_tentry **)r; printf("tdelete returned parent: %u %s\n", re2->mt_key, re2->mt_name); } else { printf("tdelete returned NULL, tree now empty.\n"); } /* Delete the content of the node that tdelete removed. */ mt_free_func(re3); } else { /* There is no node like this to delete. */ /* We don't want the 'test' node left around. */ mt_free_func(mt); } } twalk(tree1,walk_entry); tdestroy(tree1,mt_free_func); printf("PASS tsearch test.\n"); exit(0); } libdwarf-20210528/tsearch/dwarf_incl.h0000664000175000017500000000261513644370703014421 00000000000000/* Copyright (c) 2013, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "stdlib.h" /* for exit() */ #ifndef UNUSEDARG #define UNUSEDARG #endif libdwarf-20210528/tsearch/dwarf_tsearch.h0000664000175000017500000000776413644370703015137 00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ #include "config.h" /* SN-Carlos: Windows specific */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ /* The hashfunc return is now easily changed with cc -Duintptr_t or something. */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, dwarf_postorder, dwarf_endorder, dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. */ void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ libdwarf-20210528/tsearch/ChangeLog20160000664000175000017500000000273213644370703014223 000000000000002016-02-17 David Anderson * tsearch/config.h: Add some things convenient for testing. * tsearch/dwarf_tsearch.c: Convenient for some testing. * dwarf_tsearch.h: Modifications aid in testing tsearch. 2016-02-07 David Anderson * RUNTEST: the script had a couple of problems (typos). Fixed. Added comments about running the tests. * dwarf_tsearch.h: Provide a default DW_TSHASHTYPE for tsearchhash and use DW_TSHASHTYPE. * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchred.c: Use DW_TSHASHTYPE. * dwarf_tsearchhash.c: use DW_TSHASHTYPE, add UNUSEDARG use. Now the primes list starts at 79, not 5 (the low numbers were really only for basic testing). Add UNUSEDARG though it is defined as empty here (it is for gcc to suppress some warnings). * tsearch_tester.c: Use DW_TSHASHTYPE. Changed one error message to help match with input test files. 2016-02-07 David Anderson * All .h, .c: Changed the return type of the hashfunc to be DW_TSHASHTYPE so it can easily be overridden. Unsigned long did not work well on a P64, IL32 environment. Now it is easy to use -D to for folks in such an environment. 2016-01-20 David Anderson * dwarf_tsearchbal.c: Deleted the unused little function rotatex(). 2016-01-14 David Anderson * dwarf_tsearchtester.c: Fixed compilation warnings (some of them). * dwarf_tsearchbal.c: Added a comment. libdwarf-20210528/tsearch/dwarf_tsearchhash.c0000664000175000017500000004655413771751260016000 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch or any hashing code. An additional interface is added (compared to a real tsearch) to let the caller identify a 'hash' function with each hash table (called a tree below, but that is a misnomer). So read 'tree' below as hash table. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.4 This uses a hash based on the key. Collision resolution is by chaining. twalk() and tdestroy() walk in a random order. The 'preorder' etc labels mean nothing in a hash, so everything is called a leaf. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() etc */ #include /* for printf() */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DUu "I64u" #else #define DW_PR_DUx "llx" #define DW_PR_DUu "llu" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* A table of primes used to size and resize the hash table. From public sources of prime numbers, arbitrarily chosen to approximately double in size at each step. */ static unsigned long primes[] = { #if 0 /* for testing only */ 5,11, 17,23, 31, 47, 53, #endif 79, 1009, 5591, 10007, 21839, 41413, 99907, 199967, 400009, 800029, 1600141, 3000089, 6000121, 12000257, 24000143, 48000203, 100000127, 200001611, 400000669, 800000573, 0 /* Here we are giving up */ }; static unsigned long allowed_fill_percent = 90; struct hs_base { unsigned long tablesize_; unsigned long tablesize_entry_index_; unsigned long allowed_fill_; /* Record_count means number of active records, counting all records on chains. When the record_count is > 90% of a full tablesize_ we redo the table before adding a new entry. */ unsigned long record_count_; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ struct ts_entry * hashtab_; DW_TSHASHTYPE (*hashfunc_)(const void *key); }; struct ts_entry { const void * keyptr; /* So that a keyptr of 0 (if added) is not confused with an empty hash slot, we must mark used slots as used in the hash tab */ unsigned char entryused; struct ts_entry *next; }; enum search_intent_t { want_insert, only_find, want_delete }; static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, struct ts_entry **parent_ptr); static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), int depth); /* A trivial integer-based percentage calculation. Percents >100 are reasonable for a hash-with-chains situation (even if they might not be the best choice for performance). */ static unsigned long calculate_allowed_fill(unsigned long fill_percent, unsigned long ct) { unsigned long v = 0; if (ct < 100000) { unsigned long v2 = (ct *fill_percent)/100; return v2; } v = (ct /100)*fill_percent; return v; } /* Initialize the hash and pass in the hash function. If the entry count needed is unknown, pass in 0 as a count estimate, but if the number of hash entries needed can be estimated, pass in the estimate (which need not be prime, we actually use the nearest higher prime from the above table). If the estimated count is Return the tree base, or return NULL if insufficient memory. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE(*hashfunc)(const void *key), unsigned long size_estimate) { unsigned long prime_to_use = primes[0]; unsigned entry_index = 0; unsigned k = 0; struct hs_base *base = 0; base = *(struct hs_base **)treeptr; if (base) { /* initalized already. */ return base ; } base = calloc(sizeof(struct hs_base),1); if (!base) { /* Out of memory. */ return NULL ; } prime_to_use = primes[0]; while(size_estimate && (size_estimate > prime_to_use)) { k = k +1; prime_to_use = primes[k]; if (prime_to_use == 0) { /* Oops. Too large. */ free(base); return NULL; } entry_index = k; } base->tablesize_ = prime_to_use; base->allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if (base->allowed_fill_< (base->tablesize_/2)) { free(base); /* Oops. We are in trouble. Coding mistake here. */ return NULL; } base->record_count_ = 0; base->tablesize_entry_index_ = entry_index; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ base->hashfunc_ = hashfunc; base->hashtab_ = calloc(sizeof(struct ts_entry),base->tablesize_); if (!base->hashtab_) { free(base); return NULL; } *treeptr = base; return base; } /* We don't really care whether hashpos or chainpos are 32 or 64 bits. 32 suffices. */ static void print_entry(struct ts_entry *t,const char *descr, char *(* keyprint)(const void *), unsigned long hashpos, unsigned long chainpos) { char *v = 0; if (!t->entryused) { return; } v = keyprint(t->keyptr); printf( "[%4lu.%02lu] 0x%08" DW_PR_DUx " %s\n", hashpos,chainpos, (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, v, descr); } /* For debugging */ static void dumptree_inner(const struct hs_base *h, char *(* keyprint)(const void *), const char *descr, int printdetails) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; unsigned long hashused = 0; unsigned long maxchainlength = 0; unsigned long chainsgt1 = 0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " size %" DW_PR_DUu " entries %" DW_PR_DUu " allowed %" DW_PR_DUu " %s\n", (Dwarf_Unsigned)(uintptr_t)h, (Dwarf_Unsigned)h->tablesize_, (Dwarf_Unsigned)h->record_count_, (Dwarf_Unsigned)h->allowed_fill_, descr); for ( ; ix < tsize; ix++,p++) { unsigned long chainlength = 0; struct ts_entry*n = 0; int chainpos = 0; if (p->entryused) { ++hashused; chainlength = 1; if (printdetails) { print_entry(p,"head",keyprint,ix,chainpos); } } chainpos++; for (n = p->next; n ; n = n->next) { chainlength++; if (printdetails) { print_entry(n,"chain",keyprint,ix,chainpos); } } if (chainlength > maxchainlength) { maxchainlength = chainlength; } if (chainlength > 1) { chainsgt1++; } } printf("Hashtable: %lu of %lu hash entries used.\n", hashused,tsize); printf("Hashtable: %lu chains length longer than 1. \n", chainsgt1); printf("Hashtable: %lu is maximum chain length.\n", maxchainlength); } /* Dumping the tree. */ void dwarf_tdump(const void*headp_in, char *(* keyprint)(const void *), const char *msg) { const struct hs_base *head = (const struct hs_base *)headp_in; if (!head) { printf("dumptree null tree ptr : %s\n",msg); return; } dumptree_inner(head,keyprint,msg,1); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } e->keyptr = key; e->entryused = 1; e->next = 0; return e; } static void resize_table(struct hs_base *head, int (*compar)(const void *, const void *)) { struct hs_base newhead; unsigned new_entry_index = 0; unsigned long prime_to_use = 0; /* Copy the values we have. */ newhead = *head; /* But drop the hashtab_ from new. calloc below. */ newhead.hashtab_ = 0; newhead.record_count_ = 0; new_entry_index = head->tablesize_entry_index_ +1; prime_to_use = primes[new_entry_index]; if (prime_to_use == 0) { /* Oops, too large. Leave table size as is, though it will get slow as it overfills. */ return; } newhead.tablesize_ = prime_to_use; newhead.allowed_fill_ = calculate_allowed_fill( allowed_fill_percent, prime_to_use); if (newhead.allowed_fill_< (newhead.tablesize_/2)) { /* Oops. We are in trouble. */ return; } newhead.tablesize_entry_index_ = new_entry_index; newhead.hashtab_ = calloc(sizeof(struct ts_entry), newhead.tablesize_); if (!newhead.hashtab_) { /* Oops, too large. Leave table size as is, though things will get slow as it overfills. */ free(newhead.hashtab_); return; } { /* Insert all the records from the old table into the new table. */ int fillnewfail = 0; unsigned long ix = 0; unsigned long tsize = head->tablesize_; struct ts_entry *p = &head->hashtab_[0]; for ( ; ix < tsize; ix++,p++) { int inserted = 0; struct ts_entry*n = 0; if (fillnewfail) { break; } if (p->keyptr) { tsearch_inner(p->keyptr, &newhead,compar, want_insert, &inserted, 0); if (!inserted) { fillnewfail = 1; break; } } for (n = p->next; n ; n = n->next) { inserted = 0; tsearch_inner(n->keyptr, &newhead,compar, want_insert, &inserted, 0); if (!inserted) { fillnewfail = 1; break; } } } if (fillnewfail) { free(newhead.hashtab_); return; } } /* Now get rid of the chain entries of the old table. */ dwarf_tdestroy_inner(head,0,0); /* Now get rid of the old table itself. */ free(head->hashtab_); head->hashtab_ = 0; *head = newhead; return; } /* Inner search of the hash and synonym chains. */ static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, /* owner_ptr used for delete. Only set if the to-be-deleted item is on a chain, not in the hashtab. Points to the item pointing to the to-be-deleted-item.*/ struct ts_entry **owner_ptr) { struct ts_entry *s =0; struct ts_entry *c =0; struct ts_entry *q =0; int kc = 0; DW_TSHASHTYPE keyhash = 0; DW_TSHASHTYPE hindx = 0; struct ts_entry *chain_parent = 0; if (!head->hashfunc_) { /* Not fully initialized. */ return NULL; } keyhash = head->hashfunc_(key); if (intent == want_insert) { if (head->record_count_ > head->allowed_fill_) { resize_table(head,compar); } } hindx = keyhash%head->tablesize_; s = &head->hashtab_[hindx]; if (!s->entryused) { /* Not found. */ if (intent != want_insert) { return NULL; } /* Insert in the base hash table in an empty slot. */ *inserted = 1; head->record_count_++; s->keyptr = (const void *)key; s->entryused = 1; s->next = 0; return s; } kc = compar(key,s->keyptr); if (kc == 0 ) { /* found! */ if (want_delete) { *owner_ptr = 0; } return (void *)&(s->keyptr); } chain_parent = s; for (c = s->next; c; c = c->next) { kc = compar(key,c->keyptr); if (kc == 0 ) { /* found! */ if (want_delete) { *owner_ptr = chain_parent; } return (void *)&(c->keyptr); } chain_parent = c; } if (intent != want_insert) { return NULL; } /* Insert following head record of the chain. */ q = allocate_ts_entry(key); if (!q) { return q; } q->next = s->next; s->next = q; head->record_count_++; *inserted = 1; return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct hs_base **rootp = (struct hs_base **)headin; struct hs_base *head = *rootp; struct ts_entry *r = 0; int inserted = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!head) { /* something is wrong here, not initialized. */ return NULL; } r = tsearch_inner(key,head,compar,want_insert,&inserted,&nullme); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const *rootp, int (*compar)(const void *, const void *)) { /* Nothing will change, but we discard const so we can use tsearch_inner(). */ struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *r = 0; /* inserted flag won't be set. */ int inserted = 0; /* nullme won't be set. */ struct ts_entry * nullme = 0; /* Get to actual tree. */ if (!head) { return NULL; } r = tsearch_inner(key,head,compar,only_find,&inserted,&nullme); if (!r) { return NULL; } return (void *)(&(r->keyptr)); } /* Unlike the simple binary tree case, a fully-empty hash situation does not null the *rootp */ void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *found = 0; /* inserted flag won't be set. */ int inserted = 0; struct ts_entry * parentp = 0; if (!head) { return NULL; } found = tsearch_inner(key,head,compar,want_delete,&inserted, &parentp); if (found) { if (parentp) { /* Delete a chain entry. */ head->record_count_--; parentp->next = found->next; /* We free our storage. It would be up to caller to do a tfind to find a record and delete content if necessary. */ free(found); return (void *)&(parentp->keyptr); } /* So found is the head of a chain. */ if (found->next) { /* Delete a chain entry, pull up to hash tab, freeing up the chain entry. */ struct ts_entry *pullup = found->next; *found = *pullup; free(pullup); head->record_count_--; return (void *)&(found->keyptr); } else { /* Delete a main hash table entry. Problem: what the heck to return as a keyptr pointer? Well, we return NULL. As in the standard tsearch, returning NULL does not mean failure! Here it just means 'empty chain somewhere'. */ head->record_count_--; found->next = 0; found->keyptr = 0; found->entryused = 0; return NULL; } } return NULL; } static void dwarf_twalk_inner(const struct hs_base *h, struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth), UNUSEDARG unsigned level) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; for ( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; if (p->keyptr) { action((void *)(&(p->keyptr)),dwarf_leaf,level); } for (n = p->next; n ; n = n->next) { action((void *)(&(n->keyptr)),dwarf_leaf,level); } } } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth)) { const struct hs_base *head = (const struct hs_base *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->hashtab_; /* Get to actual tree. */ dwarf_twalk_inner(head,root,action,0); } static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), UNUSEDARG int depth) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; for ( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; struct ts_entry*prev = 0; if (p->keyptr && p->entryused) { if (free_node) { free_node((void *)(p->keyptr)); } --h->record_count_; } /* Now walk and free up the chain entries. */ for (n = p->next; n ; ) { if (free_node) { free_node((void *)(n->keyptr)); } --h->record_count_; prev = n; n = n->next; free(prev); } } } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct hs_base *head = (struct hs_base *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->hashtab_; dwarf_tdestroy_inner(head,free_node,0); free(root); free(head); } libdwarf-20210528/tsearch/ChangeLog20150000664000175000017500000000020613644370703014214 000000000000002015-09-15 David Anderson * dwarf_tsearchred.c: Fixed indentation errors. 2015-01-01 David Anderson * A new year begins. libdwarf-20210528/tsearch/ESSAY.txt0000664000175000017500000003631613644370703013572 00000000000000Some thoughts about tsearch. David Anderson Updated 15 February 2014 Updated 24 June 2018 (fixing a typo and regularizing line lengths). Tsearch() was defined and implemented fairly early in the history of UNIX, but I don't know exactly when. The earliest documentation I have is from the 1991 edition of UNIX System V Release 4 Programmer's Reference Manual. It is useful because it enables one to make a searchable tree of, well, any data one might have need to search. Tsearch never needs to understand the format of the data. The functions defined there are tsearch(), tfind(), tdelete(), and twalk(). The description is just as difficult to understand as the documentation in release 3.54 of the Linux man-pages project (the most recent I have on hand). The Single Unix Specification page on tsearch() etc is slightly different text from the Programmer's Reference Manual and the Linux man page, but no clearer. The confusion is partly due to the interface definition. Until the late 20th century only limited attention was given to interface design. By the late 20th century it seems clear that any newly designed tsearch-like functionality would have a significantly different interface. An example of an improved interface is the GNU/Linux function hsearch_r(). Making the return value a small integer defining what the function actually did (and using other arguments to return additional values as necessary) significantly simplifies the discussion. Here though we are talking about the old and standard interface. We attempt to clarify the messy parts. See the examples provided for actual code. The functions and tables of tsearch are not thread safe. Nor thread-aware. Any access to one of tables at the same time the table is being updated will lead to chaos eventually. Any table tsearch maintains consists of records of undefined (meaning the definition is local to the internals) content each record of which contains, as one element, a copy of a KEY pointer. In the following I freely use tsearch for dwarf_tsearch etc. The functionality and interfaces are identical. ========= Further reading The canonical reference for binary trees and the algorithm reference for most of the tsearch code is Donald E. Knuth, "The Art of Computer Programming" Volume 3 Sorting and Searching, Second Edition. "Algorithms" Fourth Edition, Robert Sedgewick and Kevin Wayne, is the basis for the red-black tree coding. Wikipedia has quite a few entries of interest. http://en.wikipedia.org/wiki/Self-balancing_binary_search_tree http://en.wikipedia.org/wiki/Tree_traversal http://en.wikipedia.org/wiki/Red–black_tree are just a few. After implementing tsearch I looked briefly at some other projects. freecode.net: See the 'GNU libavl' project. The libavl libary is a GNU project in C with each tree type having a uniquely-named but consistent set of interfaces. The interface design is much more sensible than Unix TSEARCH. You will probably find it in most any Linux distribution. The 2.0.3 tarfile source has no configure step and the 2.0.3 Makefile failed for me, it placed -lm too early on the command line building texitree means the version mentioned on freecode.net: ftp://ftp.gnu.org/pub/gnu/avl/avl-2.0.3.tar.gz is rather old but shows internal evidence of last being updated in 2007 (*.pdf and other file timestamps in the tar file). The Makefile fails for me doing plain 'make'. Doing 'make program' to just build the source works fine. The interface definitions are more sensible than tsearch, rb_delete returns the deleted item when it succeeds, for example. freecode.net: See the 'libredblack' project. This project tarfile was last updated in 2003. It is on sourceforge at http://sourceforge.net/projects/redblacktree/ Implemented in C. Configure worked (version 1.3) but the make step failed running the python app ./rbgen due to the presence of the string %prefix on line 9 of rbgen. Removing that one line of python commentary from Eric Raymond fixed the build! There is a good amount of C #define magic making it harder to read the source than one might expect. The interface definitions are more sensible than tsearch, rb_delete returns the deleted item when it succeeds, for example. freecode.net: See the project 'Template based B+ Tree'. Is in C++ and can be used for searches which are file or memory based through use of C++ templates by the implemenation. Have not attempted to build it. ========= tsearch: void *tsearch(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); Our terminology comes from the above declaration. tsearch() returns a pointer. If tsearch fails due to an out of memory or internal error it returns NULL. Otherwise it returns a non-null pointer (see Return value, below). KEY: First we will define KEY as it is ordinarily used. KEY is a pointer to an object you define and initialize. The object must remain in stable storage for as long as the table has a copy of the KEY pointing to the object. Example: struct mystruct *key_a = malloc(sizeof(struct mystruct)); initialize(key_a, my data to fill in struct...); void *r = tsearch(key_a,&treeroot,comparfunc); ROOTP: This must be the address of a void* datum. Before the first call of tsearch the value of *rootp must be NULL (set by you somehow). The contents are maintained by tsearch thereafter. COMPAR: A function you write whose argments (when tsearch internals call it) are KEY pointers from two records (your records). The function should return -1 if the record KEY l points to is considered less than the recorda KEY r points to. Return zero if the values are considered to match. Return 1 otherwise. Example: int comparefunc(const void *l,const void *r) { struct mystruct *lp = l; struct mystruct *rp = r; if(lp->myv < rp->myv) return -1; if(lp->myv == rp->myv) return 0; return 1; } Of course the comparison need not be of simple values, it could involve anything. This is just a simple sketch. Return value: If tsearch() returns NULL something went wrong. There was insufficient memory or an internal error of some kind. Lets call the KEY passed in KEYa. Otherwise tsearch() returns a pointer to a KEY for this object. Dereference to get an actual KEY (a pointer to your object). Lets call this dereferenced KEY key_deref. struct mystruct *key_deref = *(struct mystruct *)r; if KEYa == key_deref then: KEYa was added to the tree. Hence the tree now has a copy of the value of key_a. else: KEYa matched a record in the tree and you need to free any space you allocated to build the key for this tsearch call. In our example: free(key_a). I hope the above clarifies the use of tsearch somewhat. ============ Tfind: void *find(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); The interfaces are the same but the return value is (in contrast with tsearch) reasonably clear: A non-null return is a key (pointer). It never adds a new record, it simple tries to find a record. A NULL return means either that the search-ed for record did not exist or that something internal went wrong or perhaps that something incorrect was detected at runtime in the arguments passed in. ============ Tdelete: void *tdelete(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); The arguments are the same as tsearch/tfind, but the return value is a bit odd. If something goes wrong or if the record does not exist, it returns NULL. That is straightforward. If the record is deleted tdelete is supposed to return a pointer to the parent of the deleted record. The content of the deleted record is NOT deleted. If the record deleted was the last record in the tree, a NULL is returned and *rootp is set to NULL. Thus restoring initial conditions of an empty tree. If the record deleted was the root (of the records in the tree as of the call) then what is this supposed to return? No available documentation suggests an answer. The current dwarf_tdelete implementations return some record or other in this case. In the case of dwarf_tdelete() for a hash 'tree' if the node was the last in a hash chain then NULL is returned. (ugly, but it is difficult to figure out what else to do). All this means that it is a waste of time to inspect the return value from tdelete. So to do a tdelete and do any necessary memory free do: key = xxxx t = tfind(key,&root,compar_func) if (t) { tdelete(key,&root,compar_func) } free key free r where what 'free key' means is to free whatever 'key = xxxx' allocated. Which means do the same for 'free r'. Of course if your keys point into to a static array of data then free is unnecessary, but how often will the data be in static memory? And if it is in static storage, why do any free at all? ============ Tdestroy: void *tdestroy((void * root, void (*free_node)(void * key)); This frees all memory the tree system has and along the way it calls 'free_node' for each node in the tree. It empties the tree, but, oddly, the root argument is a simple pointer to the root, not a pointer-to-pointer. Hence this routine can free the tree, but cannot assign a NULL to the root. So you should do root = 0; after calling tdestroy(). ============ Twalk: void *twalk((const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); ============ Tdump: void tdump(const void *rootp, char *(*keyprint)(const void *key), const char * msg); This is unique to the dwarf_tsearch library. It prints (to standard out) a representation of the tree. The output is indented one space per level and ordered such that turning the output 90 degrees clockwise shows a kind of picture of the tree structure in the way trees are normally shown in books. It may be of slight interest for debugging trees if the trees are not too large. The 'msg' argument is just a character string of interest to you, something identifying the output. It is printed once and otherwise ignored. The 'keyprint' argument is a pointer to a function you write. The function is called for each node in turn. It should return a pointer to a string with whatever data from the passed-in-by-tdump key you wish to show. Normally the pointer returned from keyprint should be pointing to a static area so there is no issue with memory leakage to worry about. tdump will print the returned string immediately and will not refer to it again. ============ tsearch use using pointers (declarations left out): The struct here is entirely ours: tsearch neither knows nor cares how it is laid out. mt = struct example_tentry *mt = (struct example_tentry *)calloc(sizeof(struct example_tentry),1); mt->mt_key = keyvalue; mt->mt_data = datavalue; errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on %d, give up insertrecsbypointer\n",i); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if(re != mt) { /* found existing entry. */ mt_free_func(mt); } else { /* New entry mt was added. */ } } In this case the mt_compare_func() might if using a struct look like: int mt_compare_func(const void *l, const void *r) { const struct example_tentry *ml = l; const struct example_tentry *mr = r; /* If the key were a string, one could use strcmp() instead of the comparisons here */ if(ml->mt_key < mr->mt_key) { return -1; } if(ml->mt_key > mr->mt_key) { return 1; } return 0; } ============ tsearch use using values (declarations left out): void *mt = (void *)key; errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, value_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on %d, give up insertrecsbypointer\n",i); exit(1); } else { /* successful search.mt might have been added by the call, or maybe it was already in the tree. It is impossible to tell which */ } In this case the value_compare_func might look like: int value_compare_func(const void *l, const void *r) { VALTYPE lp = (VALTYPE)l; VALTYPE rp = (VALTYPE)r; if(lp < rp) { return -1; } if(lp > rp) { return 1; } return 0; } In this case the free_node function would look like void free_node { /* Do nothing. */ } In this case, there is never any free() calls you need to make as the key is not a pointer to anything. =================== If I were designing the interfaces in 2014 I might do as follows. I think the GNU hsearch_r interfaces are a fine approach and could be extended to tsearch(). But I propose something slightly different. struct tsearch_base; /* opaque struct, content defined by the search code, content not made public */ int compare_func(void *l, void*r); /* you define comparison function */ int free_func(void *n); /* you define free function */ None of the proposed interfaces touch errno. All functions return 0 on success and an errno on failure. They return EINVAL if an argument is incorrect somehow. int tcreate(struct tsearch_base **base,compare_func,free_func) allocate a struct_tsearch_base record and puts a pointer to it in *base. Records the compare and free_func pointers. A call on this by uses is a requirement . returns: ENOMEM if out of memory. EINVAL if something wrong with an argument or an internal problem. int tsearch(void *key,struct tsearch_base *base); returns: ENOMEM if out of memory. EINVAL if something wrong with an argument or an internal problem. int tfind(void *key,struct tsearch_base *base); returns: ESRCH if not found. EINVAL if something wrong with an argument or an internal problem. int tdelete(void *key,struct tsearch_base *base,void **keyout); If successful, tdelete deletes the record key identifies and returns that record's recorded key through *keyout. So if a free()or other action is required you can take that action. The 'base' struct tsearch_base record is NOT freed, it remains, whether the tree has any records left or not. returns: ESRCH if key not found. EINVAL if something wrong with an argument or an internal problem. int tsize(struct tsearch_base *base,unsigned long*count_out); Stores a count of the records currently recorded in the tree in *count_out. EINVAL if something wrong with an argument or an internal problem. int tdestroy(struct tsearch_base **base); A call is a requirement on users -- to free up the tree space. Calls free_func on each node in the tree and frees all tree memory and does *base = NULL to reset your tree pointer. returns: EINVAL if something wrong with an argument or an internal problem. ================= libdwarf-20210528/tsearch/dwarf_tsearch.c0000664000175000017500000000371713644370703015124 00000000000000/* Copyright (c) 2013-2014, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(TSEARCH_USE_BAL) #include "dwarf_tsearchbal.c" #elif defined(TSEARCH_USE_BIN) #include "dwarf_tsearchbin.c" #elif defined(TSEARCH_USE_EPP) #include "dwarf_tsearchepp.c" #elif defined(TSEARCH_USE_HASH) #include "dwarf_tsearchhash.c" #elif defined(TSEARCH_USE_RED) #include "dwarf_tsearchred.c" #else #error Missing tsearch algorithm #endif libdwarf-20210528/tsearch/Makefile0000664000175000017500000000547013644370703013602 00000000000000 EXTRA=-Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wold-style-definition -Wno-pointer-sign # -Wcast-qual causes issue. We cast away const with # respect to create keyptr in places as we will actually eventually # request (calling code we do not control) that data possibly # be freed (and hence is changed). OPTS= -g -Wall $(EXTRA) -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs CC = gcc HDR=dwarf_tsearch.h config.h TESTMAIN = tsearch_tester.c TS = dwarf_tsearchbin.c TSE = dwarf_tsearchepp.c TSH = dwarf_tsearchhash.c TSR = dwarf_tsearchred.c TSB = dwarf_tsearchbal.c TESTMAINOBJ = tsearch_testerstd.o all: binarysearch eppingerdel hashsearch gnusearch redblack balancedsearch tsearch_testerstd.o: $(TESTMAIN) $(HDR) $(CC) $(OPTS) -c $(TESTMAIN) -o tsearch_testerstd.o dwarf_tsearchbin.o: $(TS) $(HDR) $(CC) $(OPTS) -c $(TS) binarysearch: dwarf_tsearchbin.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchbin.o -o binarysearch dwarf_tsearchbal.o: $(TSB) $(HDR) $(CC) $(OPTS) -c $(TSB) balancedsearch: dwarf_tsearchbal.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchbal.o -o balancedsearch dwarf_tsearchepp.o: $(TSE) $(HDR) $(CC) $(OPTS) -c $(TSE) eppingerdel: dwarf_tsearchepp.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchepp.o -o eppingerdel dwarf_tsearchhash.o: $(TSH) $(HDR) $(CC) $(OPTS) -c $(TSH) hashsearch: dwarf_tsearchhash.o $(TESTMAIN) $(HDR) $(CC) $(OPTS) -DHASHSEARCH -c $(TESTMAIN) -o tsearch_testerhash.o $(CC) $(OPTS) tsearch_testerhash.o dwarf_tsearchhash.o -o hashsearch # Needs a special compile of tsearch_tester. gnusearch: $(TESTMAINOBJ) $(HDR) $(TESTMAIN) $(CC) $(OPTS) -DLIBC_TSEARCH -c $(TESTMAIN) -o tsearch_testergnu.o $(CC) $(OPTS) tsearch_testergnu.o -o gnusearch dwarf_tsearchred.o: $(TSR) $(HDR) $(CC) $(OPTS) -c $(TSR) redblack: dwarf_tsearchred.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchred.o -o redblack valgrind: valgrind -v --leak-check=full ./binarysearch valgrind -v --leak-check=full ./eppingerdel valgrind -v --leak-check=full ./hashsearch valgrind -v --leak-check=full ./gnusearch valgrind -v --leak-check=full ./redblack valgrind -v --leak-check=full ./balancedsearch test: all sh RUNTEST clean: rm -f junk* rm -f *.o rm -f gnusearch rm -f redblack rm -f binarysearch rm -f simplesearch rm -f eppingerdel rm -f hashsearch rm -f balancedsearch rm -f testfail rm -f testpass rm -f testfailerrs libdwarf-20210528/tsearch/ChangeLog20190000664000175000017500000000213213644370703014220 000000000000002019-05-26 David Anderson * dwarf_tsearch.h: Always include config.h. Make DW_TSHASHTYPE uintptr_t. Delete a blank line. 2019-05-25 David Anderson * Makefile : adding more warning checks, leaving one out with an explanation. * config.h: Now creates ARGSUSED. Define HAVE_CONFIG_H 1 * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchred.c,tsearch_tester.c: Now with more places using (uintptr_t) to avoid warnings and with ARGSUSED in appropriate places. Ensured indents ok and no trailing whitespace. 2019-05-25 David Anderson * Makefile: Added warning flags. * config.h: Updated as we want to include stdint.h * dwarf_tsearch.h * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchhash.c,dwarf_tsearchred.c: Now include stdint.h and define Dwarf_Unsigned for printf purposes and define DW_PR_DUx for print portability. 2019-01-02 David Anderson * ChangeLog: Renamed ChangeLog2018 * Makefile.am: Now with ChangeLog2018 in dist files list. libdwarf-20210528/tsearch/dwarf_tsearchbal.c0000664000175000017500000007023713771752441015610 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2 And based on chapter 6.2.3 Balanced Trees (sometimes call AVL trees) Algorithm A and the sketch on deletion. The wikipedia page on AVL trees is also quite useful. A Key equation is: bal-factor-node-k = height-left-subtree - height-right-subtree We don't know the absolute height, but we do know the balance factor of the pointed-to subtrees (-1,0, or 1). And we always know if we are adding or deleting a node. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include /* for printf */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define IMPLEMENTD15 1 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* head is a special link. rlink points to root node. head-> llink is a tree depth value. Using a pointer. root = head->rlink. The keypointer and balance fields of the head node are not used. Might be sensible to use the head balance field as a tree depth instead of using llink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. We will request free, so const void * is not quite right. */ void *keyptr; int balance; /* Knuth 6.2.3 algorithm A */ struct ts_entry * llink; struct ts_entry * rlink; }; static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[40]; /* This is a safe sprintf. No need for esb here. */ len = sprintf(number,"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG unsigned long(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging, mainly. We print the tree with the head node unnumbered and the root node called level 0. In Knuth algorithms where we have p[k] when k is zero k refers to the head node. Handy as then the root node is not special at all. But here it just looks better as shown, perhaps. The ordering here is so that if you turned an output page with the left side at the top then the tree sort of just shows up nicely in what most think of as a normal way. */ static void tdump_inner(struct ts_entry *t, char *(keyprint)(const void *), const char *descr, int level) { const char * keyv = ""; if (!t) { return; } tdump_inner(t->rlink,keyprint,"right",level+1); printlevel(level); if (t->keyptr) { keyv = keyprint(t->keyptr); } printf("0x%08" DW_PR_DUx " " "<%s %s> " " " "%s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", keyv, t->balance, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); tdump_inner(t->llink,keyprint,"left ",level+1); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the depth. */ int dwarf_check_balance_inner(struct ts_entry *t,int level,int maxdepth, int *founderror,const char *prefix) { int l = 0; int r = 0; if (level > maxdepth) { printf("%s Likely internal erroneous link loop, " "got to depth %d.\n", prefix,level); exit(1); } if (!t) { return 0; } if (!t->llink && !t->rlink) { if (t->balance != 0) { printf("%s: Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return 1; } l = dwarf_check_balance_inner(t->llink,level+1,maxdepth, founderror,prefix); r = dwarf_check_balance_inner(t->rlink,level+1,maxdepth, founderror,prefix); if (l ==r && t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " d should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; return l+1; } if (l > r) { if ((l-r) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " l %d r %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, l,r); (*founderror)++; } if (t->balance != -1) { printf("%s Balance at 0x%" DW_PR_DUx " should be -1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return l+1; } if (r != l) { if ((r-l) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " r %d l %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, r,l); (*founderror)++; } if (t->balance != 1) { printf("%s Balance at 0x%" DW_PR_DUx " should be 1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } else { if (t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } return r+1; } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 0; size_t headdepth = 0; int errcount = 0; int depth = 0; struct ts_entry*root = 0; if (finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } if (!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; headdepth = head->llink - (struct ts_entry *)0; if (!root) { printf("%s check balance null tree ptr\n",prefix); return; } maxdepth = headdepth+10; /* Counting in levels, not level number of top level. */ headdepth++; depth = dwarf_check_balance_inner(root,depth,maxdepth, &errcount,prefix); if (depth != headdepth) { printf("%s Head node says depth %lu, it is really %d\n", prefix, (unsigned long)headdepth, depth); ++errcount; } if (errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* Dumping the tree to stdout. */ void dwarf_tdump(const void*headp_in, char *(*keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)headp_in; struct ts_entry *root = 0; size_t headdepth = 0; if (!head) { printf("dumptree null tree ptr : %s\n",msg); return; } headdepth = head->llink - (struct ts_entry *)0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " tree-depth %d: %s\n", (Dwarf_Unsigned)(uintptr_t)head, (int)headdepth, msg); root = head->rlink; if (!root) { printf("Empty tree\n"); return; } tdump_inner(root,keyprint,"top",0); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if (a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if (a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } /* We will eventually ask it be freed, so being const void * in is not quite right. */ e->keyptr = (void *)key; e->balance = 0; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *q = allocate_ts_entry(key); if (!q) { /* out of memory */ return NULL; } setlink(p,kc,q); /* Non-NULL means inserted. */ return q; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if (q) { *inserted = 1; } return q; } /* Algorithm A of Knuth 6.2.3, balanced tree. key is pointer to a user data area containing the key and possibly more. We could recurse on this routine, but instead we iterate (like Knuth does, but using for (;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* head, int (*compar)(const void *, const void *), int*inserted, UNUSEDARG struct ts_entry **nullme, UNUSEDARG int * comparres) { /* t points to parent of p */ struct ts_entry *t = head; /* p moves down tree, p starts as root. */ struct ts_entry *p = head->rlink; /* s points where rebalancing may be needed. */ struct ts_entry *s = p; struct ts_entry *r = 0; struct ts_entry *q = 0; int a = 0; int kc = 0; for (;;) { /* A2. */ kc = compar(key,p->keyptr); if (kc) { /* A3 and A4 handled here. */ q = getlink(p,kc); if (!q) { /* Does step A5. */ q = tsearch_inner_do_insert(key,kc,inserted,p); if (!q) { /* Out of memory. */ return q; } break; /* to A5. */ } if (q->balance) { t = p; s = q; } p = q; continue; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* A5: work already done. */ /* A6: */ { /* Balance factors on nodes betwen S and Q need to be changed from zero to +-1 */ int kc2 = compar(key,s->keyptr); if (kc2 < 0) { a = -1; } else { a = 1; } r = p = getlink(s,a); while (p != q) { int kc3 = compar(key,p->keyptr); if (kc3 < 0) { p->balance = -1; p = p->llink; } else if (kc3 > 0) { p->balance = 1; p = p->rlink; } else { /* ASSERT: p == q */ break; } } } /* A7: */ { if (! s->balance) { /* Tree has grown higher. */ s->balance = a; /* Counting in pointers, not integers. Ugh. */ head->llink = head->llink + 1; return q; } if (s->balance == -a) { /* Tree is more balanced */ s->balance = 0; return q; } if (s->balance == a) { /* Rebalance. */ if (r->balance == a) { /* single rotation, step A8. */ p = r; setlink(s,a,getlink(r,-a)); setlink(r,-a,s); s->balance = 0; r->balance = 0; } else if (r->balance == -a) { /* double rotation, step A9. */ p = getlink(r,-a); setlink(r,-a,getlink(p,a)); setlink(p,a,r); setlink(s,a,getlink(p,-a)); setlink(p,-a,s); if (p->balance == a) { s->balance = -a; r->balance = 0; } else if (p->balance == 0) { s->balance = 0; r->balance = 0; } else if (p->balance == -a) { s->balance = 0; r->balance = a; } p->balance = 0; } else { fprintf(stderr,"Impossible balanced tree " "situation!\n"); /* Impossible. Cannot be here. */ exit(1); } } else { fprintf(stderr,"Impossible balanced tree situation!!\n"); /* Impossible. Cannot be here. */ exit(1); } } /* A10: */ if (s == t->rlink) { t->rlink = p; } else { t->llink = p; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headin; struct ts_entry *head = 0; struct ts_entry *r = 0; int inserted = 0; /* kcomparv should be ignored */ int kcomparv = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!headp) { return NULL; } head = *headp; if (!head) { struct ts_entry *root = 0; head = allocate_ts_entry(0); if (!head) { return NULL; } root = allocate_ts_entry(key); if (!root) { free(head); return NULL; } head->rlink = root; /* head->llink is used for the depth, as a count */ /* head points to the special head node ... */ *headin = head; return (void *)(&(root->keyptr)); } r = tsearch_inner(key,head,compar,&inserted,&nullme,&kcomparv); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search without insert. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry * const *phead = (struct ts_entry * const*)rootp; struct ts_entry *head = 0; struct ts_entry *p = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } p = head->rlink; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)(&(p->keyptr)); } p = getlink(p,kc); } return NULL; } /* Used for an array of records used in the deletion code. k == 0 for the special head node which is never matched by input. k == 1 etc. */ struct pkrecord { struct ts_entry *pk; int ak; /* Is -1 or +1 */ }; /* Here we rearrange the tree so the node p to be deleted is a node with a null left link. With that done we can fix pkarray and then we can use the pkarray to rebalance. It's a bit long, so we refactor out the code from where it is called. The rearrangement is Algorithm 6.2.2D in Knuth. PRECONDITION: p,p->rlink, pp non-null. RETURNS: new high index of pkarray. */ static unsigned rearrange_tree_so_p_llink_null( struct pkrecord * pkarray, unsigned k, UNUSEDARG struct ts_entry *head, struct ts_entry *r, struct ts_entry *p, UNUSEDARG int pak, UNUSEDARG struct ts_entry *pp, int ppak) { struct ts_entry *s = 0; unsigned k2 = 0; /* indexing pkarray */ int pbalance = p->balance; /* Step D3 */ /* Since we are going to modify the tree by movement of a node down the tree a ways, we need to build pkarray with the (not yet found) new next node, in pkarray[k], not p. The deletion will be of p, but by then p will be moved in the tree so it has a null left link. P's possibly-non-null right link */ k2 = k; k2++; r = p->rlink; pkarray[k2].pk = r; pkarray[k2].ak = -1; s = r->llink; /* Move down and left to get a null llink. */ while (s->llink) { k2++; r = s; s = r->llink; pkarray[k2].pk = r; pkarray[k2].ak = -1; } /* Now we move S up in place (in the tree) of the node P we will delete. and p replaces s. Finally winding up with a newly shaped balanced tree. */ { struct ts_entry *tmp = 0; int sbalance = s->balance; s->llink = p->llink; r->llink = p; p->llink = 0; tmp = p->rlink; p->rlink = s->rlink; s->rlink = tmp; setlink(pp,ppak,s); s->balance = pbalance; p->balance = sbalance; /* Now the tree is rearranged and still in balance. */ /* Replace the previous k position entry with S. We trace the right link off of the moved S node. */ pkarray[k].pk = s; pkarray[k].ak = 1; r->llink = p->rlink; /* Now p is out of the tree and we start the rebalance at r. pkarray Index k2. */ } /* Step D4 */ free(p); return k2; } /* Returns deleted node parent unless the head changed. Returns NULL if wanted node not found or the tree is now empty or the head node changed. Sets *did_delete if it found and deleted a node. Sets *tree_empty if there are no more user nodes present. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *head, int (*compar)(const void *, const void *), int *tree_empty, int *did_delete ) { struct ts_entry *p = 0; struct ts_entry *pp = 0; struct pkrecord * pkarray = 0; size_t depth = head->llink - (struct ts_entry *)0; unsigned k = 0; /* Allocate extra, head is on the stack we create here and the depth might increase. */ depth = depth + 4; pkarray = calloc(sizeof(struct pkrecord),depth); if (!pkarray) { /* Malloc fails, we could abort... */ return NULL; } k = 0; pkarray[k].pk=head; pkarray[k].ak=1; p = head->rlink; while(p) { int kc = 0; k++; kc = compar(key,p->keyptr); pkarray[k].pk = p; pkarray[k].ak = kc; if (!kc) { break; } p = getlink(p,kc); } if (!p) { /* Node to delete never found. */ free(pkarray); return NULL; } { struct ts_entry *t = 0; struct ts_entry *r = 0; int pak = 0; int ppak = 0; p = pkarray[k].pk; pak = pkarray[k].ak; pp = pkarray[k-1].pk; ppak = pkarray[k-1].ak; /* Found a match. p to be deleted. */ t = p; *did_delete = 1; if (!t->rlink) { if (k == 1 && !t->llink) { *tree_empty = 1; /* upper level will fix up head node. */ free(t); free(pkarray); return NULL; } /* t->llink might be NULL. */ setlink(pp,ppak,t->llink); /* ASSERT: t->llink NULL or t->llink has no children, balance zero and balance of t->llink not changing. */ k--; /* Step D4. */ free(t); goto balance; } #ifdef IMPLEMENTD15 /* Step D1.5 */ if (!t->llink) { setlink(pp,ppak,t->rlink); /* we change the left link off ak */ k--; /* Step D4. */ free(t); goto balance; } #endif /* IMPLEMENTD15 */ /* Step D2 */ r = t->rlink; if (!r->llink) { /* We decrease the height of the right tree. */ r->llink = t->llink; setlink(pp,ppak,r); pkarray[k].pk = r; pkarray[k].ak = 1; /* The following essential line not mentioned in Knuth AFAICT. */ r->balance = t->balance; /* Step D4. */ free(t); goto balance; } /* Step D3, we rearrange the tree and pkarray so the balance step can work. step D2 is insufficient so not done. */ k = rearrange_tree_so_p_llink_null(pkarray,k, head,r, p,pak,pp,ppak); goto balance; } /* Now use pkarray decide if rebalancing needed and, if needed, to rebalance. k here matches l-1 in Knuth. */ balance: { unsigned k2 = k; /* We do not want a test in the for () itself. */ for ( ; 1 ; k2--) { struct ts_entry *pk = 0; int ak = 0; int bk = 0; if (k2 == 0) { /* decreased in height */ head->llink--; goto cleanup; } pk = pkarray[k2].pk; if (!pk) { /* Nothing here to work with. Move up. */ continue; } ak = pkarray[k2].ak; bk = pk->balance; if (bk == ak) { pk->balance = 0; continue; } if (bk == 0) { pk->balance = -ak; goto cleanup; } /* ASSERT: bk == -ak. We will use bk == adel here (just below). */ /* Rebalancing required. Here we use (1) and (2) in 6.2.3 to adjust the nodes */ { /* Rebalance. We use s for what is called A in Knuth Case 1, Case 2 page 461. r For what is called B. So the link movement logic looks similar to the tsearch insert case.*/ struct ts_entry *r = 0; struct ts_entry *s = 0; struct ts_entry *pa = 0; int pak = 0; int adel = -ak; s = pk; r = getlink(s,adel); pa = pkarray[k2-1].pk; pak = pkarray[k2-1].ak; if (r->balance == adel) { /* case 1. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,r); s->balance = 0; r->balance = 0; continue; } else if (r->balance == -adel) { /* case 2 */ /* x plays the role of p in step A9 */ struct ts_entry*x = getlink(r,-adel); setlink(r,-adel,getlink(x,adel)); setlink(x,adel,r); setlink(s,adel,getlink(x,-adel)); setlink(x,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,x); if (x->balance == adel) { s->balance = -adel; r->balance = 0; } else if (x->balance == 0) { s->balance = 0; r->balance = 0; } else if (x->balance == -adel) { s->balance = 0; r->balance = adel; } x->balance = 0; continue; } else { /* r->balance == 0 case 3 we do a single rotation and we are done. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); setlink(pa,pak,r); r->balance = -adel; /*s->balance = r->balance = 0; */ goto cleanup; } } } } cleanup: free(pkarray); #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return pp; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int tree_empty = 0; int did_delete = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } if (!head->rlink) { return NULL; } parentp = tdelete_inner(key,head,compar,&tree_empty,&did_delete); if (tree_empty) { head->rlink = 0; head->llink = 0; free(head); *phead = 0; return NULL; } /* ASSERT: head->rlink non-null. */ if (did_delete) { if (!parentp) { parentp = head->rlink; } return (void *)(&(parentp->keyptr)); } /* Not deleted */ return NULL; } static void dwarf_twalk_inner(struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if (p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if (p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { return; } /* Get to actual tree. */ dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if (p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if (p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (root) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } libdwarf-20210528/tsearch/dwarf_tsearchbin.c0000664000175000017500000003523613771752130015615 00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2, algorithm T and Algorithm D. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #include /* for printf */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* INVARIANT: The head node has no user data. head->llink is null, head->rlink points to the real user top node (root of the user tree). So the physical top node we call 'head'. No user data. The user top node we call 'root' here. It has a user key. Though we intend that head->rlink be non-NULL except briefly when a tdelete removes the last node (in which case we remove the head too before returning) the code is a bit cautious and tests for a non-NULL head->rlink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. */ const void *keyptr; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging. Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* For debugging. This prints the nodes with the parent (in each case) in between the children. So it is a tree with root at the left. */ static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if (!t) { return; } dumptree_inner(t->rlink,keyprint,"left ",level+1); if (t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"right",level+1); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if (a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if (a < 0) { return(t->llink); } return(t->rlink); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if (!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if (!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head,msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root,msg); dumptree_inner(root,keyprint,"top",0); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if (!e) { return NULL; } e->keyptr = key; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *e = allocate_ts_entry(key); if (!e) { /* out of memory */ return NULL; } setlink(p,kc,e); /* Non-NULL means inserted. */ return e; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if (q) { *inserted = 1; } return q; } /* Algorithm T of Knuth 6.2.2.2 key is pointer to a user data area containing the key and possibly more. We iterate like Knuth does, but using for (;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* localrootp, int (*compar)(const void *, const void *), int*inserted) { struct ts_entry* p = localrootp; for (;;) { struct ts_entry *r = 0; /* T2. */ int kc = compar(key,p->keyptr); if (kc < 0) { /* T3. */ struct ts_entry *l = p->llink; if (l) { p = l; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } else if (kc > 0 ) { /* T4. */ struct ts_entry *r2 = p->rlink; if (r2) { p = r2; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* Can never get here. */ return 0; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry *head = 0; struct ts_entry *root = 0; struct ts_entry *r = 0; int inserted = 0; if (!headpin) { return NULL; } head = (struct ts_entry *)*headpin; if (head) { root = head->rlink; } if (!head || !root) { int allocatedhead = 0; if (!head) { head = allocate_ts_entry(0); allocatedhead = 1; } if (!head) { return NULL; } root = allocate_ts_entry(key); if (!root) { if (allocatedhead) { free(head); } return NULL; } head->rlink = root; *headpin = head; return (void *)(&(root->keyptr)); } root = head->rlink; r = tsearch_inner(key,root,compar,&inserted); if (!r) { return NULL; } /* Was this found or inserted? Value is the same either way, but the pointer to return is not the same! */ /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*headppin, int (*compar)(const void *, const void *)) { struct ts_entry *head = (struct ts_entry *)*headppin; struct ts_entry **proot = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; if (!headppin) { return NULL; } head = (struct ts_entry *)*headppin; if (!head) { return NULL; } proot = &head->rlink; root = *proot; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if (!p) { return NULL; } { /* In Knuth Algorithm D, the parenthetical comment "(For example, if Q===RLINK(P) for some P we would set RLINK(P)<- LLINK(T).)" informs us that Q is assumed to be a conceptual name for some RLINK or LLINK, not a C local variable. In the rest of this algorithm variables can be ordinary C pointers, but not true for Q. Hence in the following we use *q to set Q. */ struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *r = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. Here *q is what Knuth calls q. */ t = *q; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if (s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } /* Step D4. */ if (!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if (emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if (!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. Other than one might say, the fake parent phead (with only rlink, but that has no key so we ignore). */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if (p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if (p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *headin, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)headin; const struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if (p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if (p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. The user must zero out the head node, we have no way to do that in the defined interface. */ void dwarf_tdestroy(void *headin, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)headin; struct ts_entry *root = 0; if (!head) { return; } root = head->rlink; if (head) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } libdwarf-20210528/configure.ac0000664000175000017500000004356114054252004012767 00000000000000###Copyright (C) 2018 Vincent Torri ###This code is public domain and can be freely used or copied. dnl defines the version name of the libdwarf.so m4_define([v_maj], [1]) m4_define([v_min], [0]) m4_define([v_mic], [0]) ###m4_define([v_ver], [v_maj.v_min.v_mic]) ###Returning to older version, .so.1 m4_define([v_ver], [v_maj]) m4_define([v_rel], []) m4_define([lt_cur], [m4_eval(v_maj + v_min)]) m4_define([lt_rev], [v_mic]) m4_define([lt_age], [v_min]) ### Sets the release name. ###m4_define([v_date], [m4_esyscmd_s([date "+%Y%m%d"])]) m4_define([v_date], [20210528]) ###Also set version in CMakeLists.txt AC_PREREQ([2.52]) ### 2nd arg to AC_INIT is the version 'number'. AC_INIT([libdwarf], [v_date], [libdwarf-list -at- linuxmail -dot- org]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIRS([m4]) ### Additional options to configure AC_ARG_ENABLE([dwarfgen], [AS_HELP_STRING([--enable-dwarfgen], [enable dwarfgen compilation @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_dwarfgen="yes"], [enable_dwarfgen="no"]) ], [enable_dwarfgen="no"]) AM_CONDITIONAL([HAVE_DWARFGEN], [test "x${enable_dwarfgen}" = "xyes"]) AC_ARG_ENABLE([dwarfexample], [AS_HELP_STRING([--enable-dwarfexample], [enable dwarfexample compilation @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_dwarfexample="yes"], [enable_dwarfexample="no"]) ], [enable_dwarfexample="no"]) AM_CONDITIONAL([HAVE_DWARFEXAMPLE], [test "x${enable_dwarfexample}" = "xyes"]) ### Solely for checking libdwarf allocation counts,sizes ### Do not use without a good reason . See libdwarf/dwarf_alloc.c AC_ARG_ENABLE(globalallocsums,AS_HELP_STRING([--enable-global-alloc-sums], [Enables some allocation counting in dwarf_alloc.c (default is NO)]), [ AC_DEFINE([HAVE_GLOBAL_ALLOC_SUMS],[1], [Define 1 if want some specialized allocation counting] ) [enable_globalallocsums="yes"] ], [enable_globalallocsums="no"]) AC_ARG_ENABLE([sanitize], [AS_HELP_STRING([--enable-sanitize], [enable sanitize compiler option @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_sanitize="yes"], [enable_sanitize="no"]) ], [enable_sanitize="no"]) AC_ARG_ENABLE([oldframecol], [AS_HELP_STRING([--enable-oldframecol], [enable old frame columns @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_oldframecol="yes"], [enable_oldframecol="no"]) ], [enable_oldframecol="no"]) AS_IF( [test "x${enable_oldframecol}" = "xyes"], [AC_DEFINE( [HAVE_OLD_FRAME_CFA_COL], [1], [Set to 1 if old frame columns are enabled.])]) AC_ARG_ENABLE([namestable], [AS_HELP_STRING([--enable-namestable], [enable name string functions implemented as binary search (default is with C switch) @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_namestable="yes"], [enable_namestable="no"]) ], [enable_namestable="no"]) AS_IF( [test "x${enable_namestable}" = "xyes"], [AC_SUBST([dwarf_namestable], [-s])], [AC_SUBST([dwarf_namestable], [-t])]) AC_ARG_ENABLE([libelf], [AS_HELP_STRING([--disable-libelf], [disable use of libelf (default is enable) @<:@default=yes@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [dwarf_with_libelf="yes"], [dwarf_with_libelf="no"]) ], [dwarf_with_libelf="yes"]) AC_ARG_ENABLE([windowspath], [AS_HELP_STRING([--enable-windowspath], [Detect certain Windows paths as full paths (default is NO)])], [ AC_DEFINE([HAVE_WINDOWS_PATH],[1], [Define 1 if want to allow Windows full path detection] ) [enable_windowspath="yes"] ], [ enable_windowspath="no" ]) AC_ARG_ENABLE([wall], [AS_HELP_STRING([--enable-wall], [enable -Wall and other options @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_wall="yes"], [enable_wall="no"]) ], [enable_wall="no"]) AC_ARG_ENABLE(nonstandardprintf,AS_HELP_STRING([--enable-nonstandardprintf], [Use a special printf format for 64bit (default is NO)]), [ AC_DEFINE([HAVE_NONSTANDARD_PRINTF_64_FORMAT],[1], [Define 1 if need nonstandard printf format for 64bit] ) [enable_nonstandardprintf="yes"] ], [enable_nonstandardprintf="no"]) AC_ARG_ENABLE(havecustomlibelf,AS_HELP_STRING([--enable-havecustomlibelf], [including a custom libelf library (default is NO)]), [ AC_DEFINE([HAVE_CUSTOM_LIBELF],[1], [Define 1 if including a custom libelf library] ) [enable_havecustomlibelf="yes"] ], [enable_havecustomlibelf="no"]) ### Default options with respect to host AC_CANONICAL_HOST have_win32="no" case "$host_os" in mingw*) have_win32="yes" ;; esac AM_CONDITIONAL([HAVE_WIN32], [test "x${have_win32}" = "xyes"]) ### Checks for programs AM_PROG_AR ### We don't use dist-xz *.xz output from make dist, ### so don't mention it. AM_INIT_AUTOMAKE([1.6]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) LT_INIT([win32-dll disable-shared static]) version_info="lt_cur:lt_rev:lt_age" release_info="v_rel" AC_SUBST([version_info]) AC_SUBST([release_info]) AC_PROG_CC AC_PROG_CXX AC_PROG_CC_C_O ###PKG_PROG_PKG_CONFIG Intentionally not using pkg-config ### Checks for libraries AC_SUBST([DWARF_LIBS]) AC_ARG_VAR([DWARF_LIBS], [linker flags when linking libdwarf]) ### Checks for header files ### MacOS does not have malloc.h AC_CHECK_HEADERS([unistd.h sys/types.h regex.h malloc.h]) ### for uintptr_t AC_CHECK_HEADERS([stdint.h inttypes.h stddef.h]) AC_CHECK_HEADERS([windows.h]) AC_CHECK_HEADERS([zlib.h]) AS_IF( [test "x${ac_cv_header_zlib_h}" = "xyes"], [ have_pc_zlib="yes" ; echo "have zlib" ; DWARF_LIBS="${DWARF_LIBS} -lz" ], [ have_pc_zlib="no" ; echo "no zlib" ]) ### for use in casts to uint to avoid 32bit warnings. ### Also needed by C++ cstdint AC_TYPE_UINTPTR_T AC_TYPE_INTPTR_T ### Now we know uintptr_t is either in stdint.h or ### is defined in config.h by configure. # test Elf headers in the preprocessor path search CPPFLAGS_save=${CPPFLAGS} ### we set $dwarf_with_libelf above. if test $dwarf_with_libelf = "yes" ; then AC_CHECK_HEADERS([sgidefs.h]) AC_CHECK_HEADERS([libelf.h libelf/libelf.h]) AC_CHECK_HEADERS([elf.h elfaccess.h sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h sys/ia64/elf.h]) ### if no libelf.h add no -lelf and turn off ### libelf recognition. AS_IF([test "x${ac_cv_header_libelf_h}" != "xyes" -a "x${ac_cv_header_libelf_libelf_h}" != "xyes" ], [ dwarf_with_libelf="no" echo "no libelf headers, no libelf" ], [ DWARF_LIBS="${DWARF_LIBS} -lelf" dwarf_with_libelf="yes" echo "Allowing use of libelf." AC_DEFINE([DWARF_WITH_LIBELF],[1], [Set to 1 as we are building with libelf]) ]) ### begin checking for Elf structs # Elf64_Rela in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rela p; p.r_offset = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_RELA], [1], [Set to 1 if Elf64_Rela defined in elf.h.]) have_elf64_rela="yes" ], [have_elf64_rela="no"]) AS_IF( [test "x${have_elf64_rela}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rela p; p.r_offset = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_RELA], [1], [Set to 1 if Elf64_Rela defined in elf.h.]) have_elf64_rela="yes" ], [have_elf64_rela="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Rela in elf.h]) AC_MSG_RESULT([${have_elf64_rela}]) # Elf64_Rel in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rel p; p.r_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_R_INFO], [1], [Set to 1 if Elf64_Rel structure as r_info field.]) have_elf64_rel="yes" ], [have_elf64_rel="no"]) AS_IF( [test "x${have_elf64_rel}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rel p; p.r_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_R_INFO], [1], [Set to 1 if Elf64_Rel structure as r_info field.]) have_elf64_rel="yes" ], [have_elf64_rel="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Rel in elf.h]) AC_MSG_RESULT([${have_elf64_rel}]) # Elf64_Sym in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Sym p; p.st_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_SYM], [1], [Set to 1 if Elf64_Sym defined in elf.h.]) have_elf64_sym="yes" ], [have_elf64_sym="no"]) AS_IF( [test "x${have_elf64_sym}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Sym p; p.st_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_SYM], [1], [Set to 1 if Elf64_Sym defined in elf.h.]) have_elf64_sym="yes" ], [have_elf64_sym="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Sym in elf.h]) AC_MSG_RESULT([${have_elf64_sym}]) ### end checking for Elf structs ### Checks for Elf structures # test if struct _Elf is used instead of struct Elf AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; ]], [[ struct _Elf *a = 0; ]]) ], [ have_struct__elf="yes" struct_elf="struct _Elf" ], [ have_struct__elf="no" struct_elf="struct Elf" ]) AC_MSG_CHECKING([whether struct _Elf is used]) AC_MSG_RESULT([${have_struct__elf}]) else ### end where dwarf_with_libelf == "no" via ### --disable-libelf have_struct__elf="no" struct_elf="struct Elf" have_elf64_rela="no" have_elf64_rel="no" have_elf64_sym="no" fi AC_SUBST([struct_elf]) ### Checks for compiler characteristics AC_C_BIGENDIAN([AC_DEFINE([WORDS_BIGENDIAN], [1], [Set to 1 if bigendian build])],,) AC_SUBST([DWARF_BIGENDIAN],[${ac_cv_c_bigendian}]) AC_ARG_VAR([DWARF_BIGENDIAN], [big endian yes/no needed for dwarfexample test]) # gcc accepts even totally bogus -Wno flags. Other compilers..no # -Wno-long-long suppresses warnings on 'long long' # -Wno-pedantic-ms-format (which only exists in mingw) # suppresses warnings about I64 printf format. AS_IF( [ test "x$enable_wall" = "xyes" ], [ cxx_compiler_flags="-Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" c_compiler_flags="-Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs -Werror" ] ) AS_IF( [ test "x$enable_nonstandardprintf" = "xyes" ], [ cxx_compiler_flags="$cxx_compiler_flags -Wno-pedantic-ms-format" c_compiler_flags="$c_compiler_flags -Wno-pedantic-ms-format" ] ) DWARF_CHECK_CXX_COMPILER_FLAGS([${cxx_compiler_flags}]) DWARF_CHECK_C_COMPILER_FLAGS([${c_compiler_flags}]) # unused attribute AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ static unsigned int foo(unsigned int x, __attribute__ ((unused)) int y){ unsigned int x2 = x + 1; return x2; } int goo() { unsigned int y = 0; y = foo(12, y); } ]], [[ ]]) ], [ have_unused="yes" AC_DEFINE( [HAVE_UNUSED_ATTRIBUTE], [1], [Set to 1 if __attribute__ ((unused)) is available.]) ], [have_unused="no"]) AC_MSG_CHECKING([whether "unused" attribute is available]) AC_MSG_RESULT([${have_unused}]) # sanitize AS_IF( [test "x${enable_sanitize}" = "xyes"], [ CFLAGS_save=${CFLAGS} CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" DWARF_CFLAGS= AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]], [[]])], [ enable_sanitize="yes" DWARF_CFLAGS="$DWARF_CFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer" ], [enable_sanitize="no"]) CFLAGS="${CFLAGS_save} ${DWARF_CFLAGS}" DWARF_CFLAGS= ]) AC_MSG_CHECKING([whether sanitize options are used]) AC_MSG_RESULT([${enable_sanitize}]) ### Checks for linker characteristics ### Checks for library functions AC_FUNC_ALLOCA if test $dwarf_with_libelf = "yes" ; then # elf64_getehdr CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS}" LIBS_save=${LIBS} LIBS="${LIBS} ${DWARF_LIBS}" AC_SEARCH_LIBS( [elf64_getehdr], [elf], [ have_getehdr="yes" AC_DEFINE( [HAVE_ELF64_GETEHDR], [1], [Set to 1 if the elf64_getehdr function is in libelf.]) ], [have_getehdr="no"]) AC_SEARCH_LIBS( [elf64_getshdr], [elf], [ have_getshdr="yes" AC_DEFINE( [HAVE_ELF64_GETSHDR], [1], [Set to 1 if the elf64_getshdr function is in libelf.]) ], [have_getshdr="no"]) CPPFLAGS=${CPPFLAGS_save} LIBS=${LIBS_save} else have_getehdr="no" have_getshdr="no" fi AS_IF( [test "x${have_pc_zlib}" = "xno" -a "x${have_zlib}" = "xyes"], [AC_SEARCH_LIBS([z], [have_zlib="yes"], [have_zlib="no"])]) AS_IF( [test "x${have_pc_zlib}" = "xyes" -o "x${have_zlib}" = "xyes"], [ have_zlib="yes" AC_DEFINE([HAVE_ZLIB], [1], [Set to 1 if zlib decompression is available.]) AC_DEFINE([HAVE_ZLIB_H], [1], [Set to 1 if zlib.h header file is available.]) ], [ have_zlib="no" ]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_REGEX_H # include #endif ]], [[ int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); ]]) ], [ AC_DEFINE([HAVE_REGEX], [1], [Set to 1 if regex is usable.]) have_regex="yes" ], [have_regex="no"]) AC_MSG_CHECKING([for regex library]) AC_MSG_RESULT([${have_regex}]) ### Checks for system services AC_CONFIG_FILES([ Makefile libdwarf/Makefile dwarfdump/Makefile dwarfgen/Makefile dwarfexample/Makefile ]) ### libdwarf needs to be adjusted to support struct Elf ### or struct _Elf, whichever the system defines in libelf. AC_CONFIG_COMMANDS([libdwarf/libdwarf.h], [ sh $src/scripts/fixlibdwarfelf.sh $haself $src $top ], [ haself=${have_struct__elf} top=${ac_pwd} src=${srcdir} ] ) AC_OUTPUT echo echo "$PACKAGE $VERSION" echo echo "Configuration Options Summary:" echo echo " BuildOS..............: ${build_os}" echo " HostOS...............: ${host_os}" echo echo " shared library.......: ${enable_shared}" echo " static library.......: ${enable_static}" echo echo " zlib support.........: ${have_zlib}" echo " sanitize support.....: ${enable_sanitize}" echo " BuildOS-BigEndian....: ${ac_cv_c_bigendian}" echo echo " libdwarf.............: always" echo " old frame column...: ${enable_oldframecol}" echo " names table........: ${enable_namestable}" echo " elf64_getehdr......: ${have_getehdr}" echo " elf64_getshdr......: ${have_getshdr}" echo " Elf64_Rela.........: ${have_elf64_rela}" echo " Elf64_Sym..........: ${have_elf64_sym}" echo " Elf spelled........: ${struct_elf}" echo " libelf.............: ${dwarf_with_libelf}" echo " Windows path corr..: ${enable_windowspath}" echo " Nonstandardprintf..: ${enable_nonstandardprintf}" echo " Custom libelf......: ${enable_havecustomlibelf}" echo " dwarfdump............: always" echo " elf64_getehdr......: ${have_getehdr}" echo " Elf64_Rel (r_info).: ${have_elf64_rel}" echo " regex..............: ${have_regex}" echo " dwarfgen.............: ${enable_dwarfgen}" echo " dwarfexample.........: ${enable_dwarfexample}" echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS ${c_compiler_flags}" echo " LDFLAGS..............: $LDFLAGS" echo " LIBS.................: $LIBS" echo " DWARF_LIBS...........: $DWARF_LIBS" echo echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" echo libdwarf-20210528/install-sh0000755000175000017500000003601014054252020012470 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # Note that $RANDOM variable is not portable (e.g. dash); Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p' feature. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libdwarf-20210528/compile0000755000175000017500000001632714054252020012053 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libdwarf-20210528/bugxml/0000775000175000017500000000000014050564025012053 500000000000000libdwarf-20210528/bugxml/bugrecord.py0000775000175000017500000002346614050024007014326 00000000000000#!/usr/bin/python3 # Copyright (c) 2016-2016 David Anderson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the example nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. import sys # Use only
 or 
all by itself in data.xml. # No other data on either of such lines. # All the lines between these two markers should be # shown in individual lines. def xmlize(linea, inhtml, inpre): outi = [] l = linea if l.find("
") != -1:
        if inhtml == "y":
            s2 = "

" + l + "\n" else: s2 = l + "\n" inpre = "y" return s2, inpre if l.find("
") != -1: if inhtml == "y": s2 = l + "\n" + "

" else: s2 = l + "\n" inpre = "n" return s2, inpre if inpre == "y" and inhtml == "n": outi += [""] for c in l: if c == "<": outi += ["<"] elif c == ">": outi += [">"] elif c == "&": outi += ["&"] # elif c == "'": # outi += ["'"] elif c == '"': outi += ["""] else: outi += [c] if inpre == "y" and inhtml == "n": outi += [""] outi += ["\n"] s2 = "".join(outi) return s2, inpre def paraline(name, linea): inpre = "n" out = "" if len(linea) < 1: out = "

" + name + ":" + "

" return out out = "

" + name + ": " out += linea out += "

" return out def paralines(name, lines): inpre = "n" if len(lines) < 1: out = "

" + name + ":" + "

" return out out = "

" + name + ": " for lin in lines: f, inpre = xmlize(lin, "y", inpre) out += f out += "

" return out def para(name, str): if str == None: out = "

" + name + ":" + "

" elif len(str) > 0: out = "

" + name + ": " + str + "

" else: out = "

" + name + ":" + "

" return out class bugrecord: def __init__(self, dwid): self._id = dwid.strip() self._cve = "" self._datereported = "" self._reportedby = "" self._vulnerability = [] self._product = "" self._description = [] self._datefixed = "" self._references = [] self._gitfixid = "" self._tarrelease = "" def setcve(self, pubid): if self._cve != "": print("Duplicate cve ", self._cve, pubid) sys.exit(1) self._cve = pubid.strip() def setdatereported(self, rep): if self._datereported != "": print("Duplicate datereported ", self._datereported, rep) sys.exit(1) self._datereported = rep.strip() def setreportedby(self, rep): if self._reportedby != "": print("Duplicate reportedby ", self._reportedby, rep) sys.exit(1) self._reportedby = rep.strip() def setvulnerability(self, vuln): if len(self._vulnerability) != 0: print("Duplicate vulnerability ", self._vulnerability, vuln) sys.exit(1) self._vulnerability = vuln def setproduct(self, p): if len(self._product) != 0: print("Duplicate product ", self._product, p) sys.exit(1) self._product = p.strip() def setdescription(self, d): if len(self._description) != 0: print("Duplicate description ", self._description, d) sys.exit(1) self._description = d def setdatefixed(self, d): if len(self._datefixed) != 0: print("Duplicate datefixed ", self._datefixed, d) sys.exit(1) self._datefixed = d.strip() def setreferences(self, r): if len(self._references) != 0: print("Duplicate references ", self._references, r) sys.exit(1) self._references = r def setgitfixid(self, g): if len(self._gitfixid) != 0: print("Duplicate gitfixid ", self._gitfixid, g) sys.exit(1) self._gitfixid = g.strip() def settarrelease(self, g): if len(self._tarrelease) != 0: print("Duplicate tarrelease ", self._tarrelease, g) sys.exit(1) self._tarrelease = g.strip() def plist(self, title, lines): if lines == None: print(title) return if len(lines) == 1: print(title, lines[0]) return print(title) for l in lines: print(l) def printbug(self): print("") print("id:", self._id) print("cve:", self._cve) print("datereported:", self._datereported) print("reportedby:", self._reportedby) self.plist("vulnerability:", self._vulnerability) print("product:", self._product) self.plist("description:", self._description) print("datefixed:", self._datefixed) self.plist("references:", self._references) print("gitfixid:", self._gitfixid) print("tarrelease:", self._tarrelease) def generate_html(self): s5 = "".join(self._id) t = "".join(['

', self._id, "

"]) txt = [t] inpre = "n" s, inp = xmlize(self._id, "y", inpre) t = paraline("id", s) txt += [t] s, inp = xmlize(self._cve, "y", inpre) t = paraline("cve", s) txt += [t] s, inp = xmlize(self._datereported, "y", inpre) t = paraline("datereported", s) txt += [t] s, inp = xmlize(self._reportedby, "y", inpre) t = paraline("reportedby", s) txt += [t] # MULTI t = paralines("vulnerability", self._vulnerability) txt += [t] s, inp = xmlize(self._product, "y", inpre) t = paraline("product", s) txt += [t] # MULTI t = paralines("description", self._description) txt += [t] s, inp = xmlize(self._datefixed, "y", inpre) t = paraline("datefixed", s) txt += [t] # MULTI t = paralines("references", self._references) txt += [t] s, inp = xmlize(self._gitfixid, "y", inpre) t = paraline("gitfixid", s) txt += [t] s, inp = xmlize(self._tarrelease, "y", inpre) t = paraline("tarrelease", s) txt += [t] t = '

[top]

' txt += [t] return txt def paraxml(self, start, main, term): # For single line xml remove the newline from the main text line. out = start l = main.strip() if len(l) > 0: out += l out += term + "\n" return out def paraxmlN(self, start, main, term): # For multi line xml leave newlines present. out = start inpre = "n" for x in main: l = x.rstrip() t, inpre = xmlize(l, "n", inpre) if len(t) > 0: out += t out += term + "\n" return out def generate_xml(self): txt = [] t = "" txt += [t] inpre = "n" s, inpre = xmlize(self._id, "n", inpre) s = self.paraxml("", s, "") s, inpre = xmlize(self._cve, "n", inpre) t = self.paraxml("", s, "") txt += [t] s, inpre = xmlize(self._datereported, "n", inpre) t = self.paraxml("", s, "") txt += [t] s, inpre = xmlize(self._reportedby, "n", inpre) t = self.paraxml("", s, "") txt += [t] s, inpre = xmlize(self._product, "n", inpre) t = self.paraxml("", s, "") txt += [t] # MULTI p = self._vulnerability t = self.paraxmlN("", p, "") txt += [t] # MULTI p = self._description t = self.paraxmlN("", p, "") txt += [t] s, inpre = xmlize(self._datefixed, "n", inpre) t = self.paraxml("", s, "") txt += [t] # MULTI p = self._references t = self.paraxmlN("", p, "") txt += [t] s, inpre = xmlize(self._gitfixid, "n", inpre) t = self.paraxml("", s, "") txt += [t] s, inpre = xmlize(self._tarrelease, "n", inpre) t = self.paraxml("", s, "") txt += [t] t = "" txt += [t] return txt libdwarf-20210528/bugxml/readbugs.py0000775000175000017500000001717314050024237014151 00000000000000#!/usr/bin/python3 # Copyright (c) 2016-2016 David Anderson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the example nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. import os import sys sys.path.append(os.path.abspath("/home/davea/dwarf/code/bugxml")) import bugrecord def ignore_this_line(d, inrecord): if len(d) < 1: if inrecord == "y": return "n" else: return "y" s = str(d) if s[0] == "#": return "y" return "n" def closeouttext(bugrec, intext, text, linecount): if intext == "d": bugrec.setdescription(text) return elif intext == "v": bugrec.setvulnerability(text) return elif intext == "r": bugrec.setreferences(text) return if intext == "": return print("bogus closeout line at line ", linecount) sys.exit(1) def readbugs(iname): name = iname if len(name) == 0: name = "/home/davea/dwarf/code/bugxml/data.txt" try: file = open(name, "r") except IOError as message: print("failed to open ", name, message) inrecord = "n" linecount = 0 text = [] usedid = {} intext = "" bugrec = "" buglist = [] while 1: try: rec = file.readline() except EOFError: break if len(rec) < 1: # eof break linecount += 1 if ignore_this_line(rec, inrecord) == "y": continue rec = rec.rstrip() if inrecord == "n": if len(rec) == 0: continue if rec.find(":") == -1: print("bogus non-blank line at line ", linecount) sys.exit(1) if inrecord == "y" and len(rec) > 0: # A multi line entry may have ":" in it. if intext != "" and rec[0] == " ": s3 = "".join(rec) text += [s3] continue low = rec.find(":") fldname = rec[0 : low + 1] fldval = rec[low + 1 :] if fldname == "id:": if inrecord == "y": print("bogus id: at line ", linecount) sys.exit(1) inrecord = "y" f = fldval.strip() if f in usedid: print("Duplicate Key:", f, "Giving up.") sys.exit(1) usedid[f] = 1 s4 = "".join(fldval) bugrec = bugrecord.bugrecord(s4) elif fldname == "cve:": closeouttext(bugrec, intext, text, linecount), intext = "" text = [] s4 = "".join(fldval) bugrec.setcve(s4) elif fldname == "datereported:": closeouttext(bugrec, intext, text, linecount), intext = "" text = [] s4 = "".join(fldval) bugrec.setdatereported(s4) elif fldname == "reportedby:": closeouttext(bugrec, intext, text, linecount), intext = "" text = [] s4 = "".join(fldval) bugrec.setreportedby(s4) elif fldname == "vulnerability:": closeouttext(bugrec, intext, text, linecount), intext = "v" text = [] if len(fldval) > 0: s4 = "".join(fldval) text = [s4] elif fldname == "product:": closeouttext(bugrec, intext, text, linecount), intext = "" text = [] s4 = "".join(fldval) bugrec.setproduct(s4) elif fldname == "description:": closeouttext(bugrec, intext, text, linecount), text = [] intext = "d" if len(fldval) > 0: s4 = "".join(fldval) text = [s4] elif fldname == "datefixed:": closeouttext(bugrec, intext, text, linecount), text = [] intext = "" s4 = "".join(fldval) bugrec.setdatefixed(s4) elif fldname == "references:": closeouttext(bugrec, intext, text, linecount), text = [] intext = "r" if len(fldval) > 0: s4 = "".join(fldval) text = [s4] elif fldname == "gitfixid:": closeouttext(bugrec, intext, text, linecount), text = [] intext = "" s4 = "".join(fldval) bugrec.setgitfixid(s4) elif fldname == "tarrelease:": closeouttext(bugrec, intext, text, linecount), text = [] intext = "" s4 = "".join(fldval) bugrec.settarrelease(s4) elif fldname == "endrec:": closeouttext(bugrec, intext, text, linecount), text = [] if inrecord == "n": print("bogus endrec: at line ", linecount) sys.exit(1) buglist += [bugrec] inrecord = "n" text = [] intext = "" inrecord = "n" file.close() return buglist def sort_by_id(myl): """Sort the list of objects by name.""" auxiliary = [(x._id, x) for x in myl] auxiliary.sort() return [x[1] for x in auxiliary] def write_line(file, l): file.write(l + "\n") def write_all_lines(file, txt): for t in txt: write_line(file, t) def generatehtml(list2, name): try: file = open(name, "w") except IOError as message: print("failed to open ", name, message) sys.exit(1) for b in list2: txt = b.generate_html() write_all_lines(file, txt) write_line(file, "") write_line(file, "") file.close() def generatexml(list2, name): try: file = open(name, "w") except IOError as message: print("failed to open ", name, message) sys.exit(1) t = '' write_line(file, t) write_line(file, "") for b in list2: txt = b.generate_xml() write_all_lines(file, txt) write_line(file, "") file.close() if __name__ == "__main__": list = readbugs("") list2 = sort_by_id(list) list2.reverse() # for b in list2: # b.printbug() generatehtml(list2, "./dwarfbugtail") generatexml(list2, "./dwarfbuglohi.xml") list2.reverse() generatehtml(list2, "./dwarfbuglohitail") libdwarf-20210528/bugxml/README0000644000175000017500000000164513743575426012676 00000000000000 The files here are for maintaining a list of bugs fixed so html and xml can be posted to prevanders.net and CVE (see cert.org) issues can reference a public database. This is intended mainly for bugs that can result in application crashes as such can represent a vulnerability that can be exploited. Bugs that result simply in errors in output (but no crash) will typically not be mentioned. Bugs in dwarfdump are not vulnerabilities in the same way and at present these do not get CVE identifiers. To update the report with a new bug prepend a copy of data.template to data.txt. Then enter the data available for the new bug. To update the local web page to check it go to /home/davea/web4/gweb and do sh dwarfbugupdate.sh which will use ./readbugs.py here to update the relevant web pages. Carefully follow the existing formats, the parser is very very simple. David Anderson Created: 2016-05-03. Updated: 2017-07-06. libdwarf-20210528/bugxml/data.txt0000644000175000017500000013150513746605465013467 00000000000000 id: DW202010-003 cve: a cve id requested 29 Oct 2020 datereported: 2020-10-27 reportedby: Casper Sun vulnerability: Passing null to %s due to corrupt line table header. product: libdwarf description: If a DWARF5 line table header has an invalid FORM for a pathname, the fi_file_name field may be null and printing it via %s can result in referencing memory at address 0, possibly generating segmentation violation or application crash. Now in case of null we provide a fixed string of and for the form code we print the value and so there are no unpredictable effects. datefixed: 2020-10-28 references: regressiontests/c-sun2/nullpointer gitfixid: faf99408e3f9f706fc3809dd400e831f989778d3 tarrelease: endrec: DW202010-003 id: DW202010-002 cve: a cve id requested 29 Oct 2020 datereported: 2020-10-27 reportedby: Casper Sun vulnerability: A very deep DIE tree can corrupt random data. product: dwarfdump description: An object file where the DIEs depth of nesting exceeds the limit of 800 levels due to corruption or a compiler bug can result in exhausting the die stack array and writing past its end. A segmentation fault is possible. The code at the point of error was not adjusting the array index properly so an invalid dereference could occur. Now the test code is correct and the array overflow is detected resulting in a normal error return. Additional places where this could occur were identified and the proper test added. datefixed: 2020-10-28 references: regressiontests/c-sun2/globaloverflow gitfixid: a7fa8edd640b74daf8e7a442dcec96640875b4fb tarrelease: endrec: DW202010-002 id: DW202010-001 cve: waiting for cve id to be granted datereported: 2020-10-10 reportedby: Casper Sun vulnerability: A carefully corrupted line table can crash calling app product: libdwarf description: A carefully crafted object with an invalid line table could cause libdwarf to dereference a pointer reading a single byte outside of the intended .debug_line section and potentially outside of memory visible to the library. A segmentation fault is possible. The code testing for the error was coded incorrectly so an invalid dereference could occur. Now the test code is correct and the error is detected resulting in a normal error return. datefixed: 2020-10-17 references: regressiontests/c-sun/poc gitfixid: 95f634808c01f1c61bbec56ed2395af997f397ea tarrelease: endrec: DW202010-001 id: DW201801-001 cve: datereported: 2018-01-28 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section can crash dwarfdump product: dwarfdump description: A carefully crafted object with an invalid frame section set of initial-instructions can crash the frame-instructions decode in dwarfdump. In addition, a couple places in libdwarf are not as careful in checking frame data as they should be. A segmentation-fault/core-dump is possible. datefixed: 2018-01-29 references: sarubbo-11/testcase{1,2,3,4,5}.bin gitfixid: 7af0ecddfafed88446969cbf8c888356ad485d99 tarrelease: 2018-01-29 endrec: DW201801-001 id: DW201712-001 cve: datereported: 2017-12-01 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section could let caller crash product: libdwarf description: A carefully crafted object with an invalid frame section can result in passing back data to a caller of dwarf_get_fde_augmentation_data() is erroneous and will result in the caller reference off the end of the frame section. A segmentation-fault/core-dump is possible. datefixed: 2017-12-01 references: sarubbo-10/1.crashes.bin gitfixid: 329ea8e56bc9550260cae6e2e9756bfbe7e2ff6d tarrelease: endrec: DW201712-001 id: DW201711-002 cve: datereported: 2017-11-08 reportedby: Agostino Sarubbo vulnerability: Incorrect line table section could crash caller product: libdwarf description: An carefully crafted object with a invalid line table section crafted to end early at a particular point resulted in dereferencing outside the line table from libdwarf/dwarf_line_table_reader_common.c . A segmentation-fault/core-dump is possible. datefixed: 2017-11-08 references: regressiontests/sarubbo-9/3.crashes.bin gitfixid: a1644f4dde7dd5990537ff7ad22a9e94b8723186 tarrelease: endrec: DW201711-002 id: DW201711-001 cve: datereported: 2017-11-01 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section could crash caller product: libdwarf description: A carefully crafted object with a resulting invalid frame section with DW_CFA_advance_loc1 implying data off-the-end-of-section will dereference an invalid pointer. A segmentation fault and core dump is possible. Corrected code checks now. datefixed: 2017-11-02 references: regressiontests/sarubbo-8/1.crashes.bin gitfixid: 44349d7991e44dd3751794f76537cabcf65ee28d tarrelease: endrec: DW201711-001 id: DW201709-001 cve: datereported: 2017-09-19 reportedby: Agostino Sarubbo vulnerability: Incorrect abbrev section could crash caller. product: libdwarf description: A fuzzed object with a resulting invalid abbrev section where the end of section follows an abbrev tag would dereference a non-existent has-child byte. datefixed: 2017-09-26 references: regressiontests/sarubbo-3/1.crashes.bin gitfixid: bcc2e33908e669bacd397e3c941ffd1db3005d17 tarrelease: endrec: DW201709-001 id: DW201706-001 cve: CVE-2017-9998 datereported: 2017-06-28 reportedby: team OWL337 vulnerability: Addition overflow in libdwarf leads to segmentation violation product: libdwarf description: A fuzzed object with a resulting invalid value can overflow when added to a valid pointer (depending on how the runtime memory is laid out) and thereafter a dereference results in a segmentation violation).
 see
  https://bugzilla.redhat.com/show_bug.cgi?id=1465756
  for contact information of those finding the bug.
  Fabian Wolff sent email and provided
  the link to the web page.
 
datefixed: 2017-07-06 references: regressiontests/wolff/POC1 gitfixid: e91681e8841291f57386f26a90897fd1dcf92a6e tarrelease: endrec: DW201706-001 id: DW201703-007 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in strncmp (libelf bug) product: libdwarf (libelf) description: 7/7. A heap overflow in strncmp() is due to libelf failing to check arguments to elf_ strptr. This is not a bug in libdwarf, it is a libelf bug. A pointer for being in bounds (in a few places in this function) and a failure in a check in dwarf_attr_list(). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180133==ERROR: AddressSanitizer: heap-buffer-overflow 
   on address 0x60d00000cff1 at pc 0x0000004476f4 
   bp 0x7fff87dd7dd0 sp 0x7fff87dd7590
 READ of size 8 at 0x60d00000cff1 thread T0
    #0 0x4476f3 in __interceptor_strncmp (/home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/dwarfdump+0x4476f3)
    #1 0x7992ae in this_section_dwarf_relevant /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:608:13
    #2 0x781064 in _dwarf_setup /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:722:14
    #3 0x77d59c in dwarf_object_init /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:922:20

 With Ubuntu 16.04 libelf dwarfdump gets:
 ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
 a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash7 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-007 id: DW201703-006 cve: CVE-2017-9052 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in dwarf_formsdata product: libdwarf description: 6/7. A heap overflow in dwarf_formsdata() is due to a failure to check a pointer for being in bounds (in a few places in this function) and a failure in a check in dwarf_attr_list(). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180130==ERROR: AddressSanitizer: heap-buffer-overflow 
  on address 0x61100000589c at pc 0x0000006cab95 
  bp 0x7fff749aab10 sp 0x7fff749aab08
 READ of size 1 at 0x61100000589c thread T0
    #0 0x6cab94 in dwarf_formsdata /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_form.c:937:9
    #1 0x567daf in get_small_encoding_integer_and_name /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:1533:16
    #2 0x562f28 in get_attr_value /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:5030:24
    #3 0x555f86 in print_attribute /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:3357:13

 After fixes applied dwarfdump says:
 ERROR:  dwarf_attrlist:  DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash6 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-006 id: DW201703-005 cve: CVE-2017-9053 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in _dwarf_read_loc_expr_op() product: libdwarf description: 5/7. A heap overflow in _dwarf_read_loc_expr_op() is due to a failure to check a pointer for being in bounds (in a few places in this function). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180112==ERROR: AddressSanitizer: heap-buffer-overflow 
  on address 0x60800000bf72 at pc 0x00000084dd52 
  bp 0x7ffc12136fd0 sp 0x7ffc12136fc8
 READ of size 1 at 0x60800000bf72 thread T0
    #0 0x84dd51 in _dwarf_read_loc_expr_op /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc.c:250:9
    #1 0x841f16 in _dwarf_get_locdesc_c /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc2.c:109:15
    #2 0x837d08 in dwarf_get_loclist_c /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc2.c:685:18
    #3 0x57dff2 in get_location_list /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:3812:16

 After fixes applied dwarfdump says:
 ERROR:  dwarf_get_loclist_c:  DW_DLE_LOCEXPR_OFF_SECTION_END 
 (343) Corrupt dwarf
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash5 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-005 id: DW201703-004 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in set_up_section strlen product: libdwarf (libelf) description: 4/7. An apparent heap overflow that gives the appearance of being in libdwarf is due to libelf call elf_strptr() failing to fully check that its arguments make sense. This is not a bug in libdwarf, it is a libelf bug. The test object is intentionally corrupted (fuzzed). The submission was with Ubuntu 14.04. With Ubuntu 16.04 there is no sanitizer error report.

 A portion of sanitizer output with Ubuntu 14.04:
 ==180109==ERROR: AddressSanitizer: heap-buffer-overflow 
   on address 0x60b00000b000 at pc 0x00000048fd12 
   bp 0x7fff4ad31ef0 sp 0x7fff4ad316b0
 READ of size 16 at 0x60b00000b000 thread T0
    #0 0x48fd11 in __interceptor_strlen (/home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/dwarfdump+0x48fd11)
    #1 0x7a84a4 in set_up_section /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:285:27
    #2 0x79aaa5 in enter_section_in_de_debug_sections_array /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:355:5
    #3 0x78170b in _dwarf_setup /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:746:19

 With Ubuntu 16.04 libelf one gets:
 ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
 a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash4 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-004 id: DW201703-003 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in strcmp product: libdwarf (libelf) description: 3/7. An apparent heap overflow that gives the appearance of being in libdwarf is due to libelf call elf_strptr() failing to fully check that its arguments make sense. This is not a bug in libdwarf, it is a libelf bug. The test object is intentionally corrupted (fuzzed). The submission was with Ubuntu 14.04. With Ubuntu 16.04 there is no sanitizer error report.

 A portion of sanitizer output with Ubuntu 14.04:
  ==180106==ERROR: AddressSanitizer: heap-buffer-overflow 
    on address 0x60f00000ef09 at pc 0x000000447300 
    bp 0x7ffc667dce10 sp 0x7ffc667dc5d0
  READ of size 4 at 0x60f00000ef09 thread T0
    #0 0x4472ff in __interceptor_strcmp (/home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/dwarfdump+0x4472ff)
    #1 0x79938f in this_section_dwarf_relevant /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:612:12
    #2 0x781064 in _dwarf_setup /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:722:14
    #3 0x77d59c in dwarf_object_init /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:922:20
    #4 0x899d4f in dwarf_elf_init_file_ownership /

  With Ubuntu 16.04 libelf one gets:
  ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
  a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash3 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-003 id: DW201703-002 cve: CVE-2017-9054 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in _dwarf_decode_s_leb128_chk() product: libdwarf description: 2/7. In _dwarf_decode_s_leb128_chk() a byte pointer was dereferenced just before was checked as being in bounds. The test object is intentionally corrupted (fuzzed).

 A portion of sanitizer output:
  .debug_line: line number info for a single cu
  ==180103==ERROR: AddressSanitizer: heap-buffer-overflow 
    on address 0x610000007ffc at pc 0x0000007b0f5b 
    bp 0x7ffe06bbf510 sp 0x7ffe06bbf508
  READ of size 1 at 0x610000007ffc thread T0
    #0 0x7b0f5a in _dwarf_decode_s_leb128_chk /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_leb.c:304:9
    #1 0x7e753e in read_line_table_program /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./
       dwarf_line_table_reader_common.c:1167:17
    #2 0x7d7fe3 in _dwarf_internal_srclines /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./dwarf_line.c:690:15
    #3 0x7f9dbb in dwarf_srclines_b /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./dwarf_line.c:944:12
    #4 0x5caaa5 in print_line_numbers_this_cu /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_lines.c:762:16

  After fix applied one gets:
  ERROR:  dwarf_srclines:  DW_DLE_LEB_IMPROPER (329) 
  Runs off end of section or CU
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash2 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-002 id: DW201703-001 cve: CVE-2017-9055 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in dwarf_formsdata product: libdwarf description: 1/7. In dwarf_formsdata() a few data types were not checked as being in bounds. The test object is intentionally corrupted (fuzzed).

 A portion of sanitizer output:
 LOCAL_SYMBOLS:
 < 1><0x0000002f>    DW_TAG_subprogram

 ==180088==ERROR: AddressSanitizer: heap-buffer-overflow on 
  address 0x60800000bf72 at pc 0x0000006cab95 bp 
  0x7fff31425830 sp 0x7fff31425828
  READ of size 1 at 0x60800000bf72 thread T0
    #0 0x6cab94 in dwarf_formsdata /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_form.c:937:9
    #1 0x567daf in get_small_encoding_integer_and_name /home/
       ubuntu/subjects/build-asan/libdwarf/dwarfdump/print_die.c:1533:16
    #2 0x576f38 in check_for_type_unsigned /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:4301:11
    #3 0x56ad8c in formxdata_print_value /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:4374:39
    #4 0x5643be in get_attr_value /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:5140:24
    #5 0x555f86 in print_attribute /home/ubuntu/subjects/build
  ...

  After fixes applied dwarfdump gets:
  ERROR:  dwarf_attrlist:  DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash1 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-001 id: DW201611-006 cve: CVE-2016-9480 datereported: 2016-11-14 reportedby: Puzzor (Shi Ji) vulnerability: Heap buffer overflow product: libdwarf description: An object with corrupt contents causes a memory reference out of bounds, a heap buffer overflow reference.
 heap-buffer-overflow in dwarf_util.c:208 for val_ptr

 # Version
 bb9a3492ac5713bed9cf3ae58ddb7afa6e9e98f8
 (in regression tests here named  heap_buf_overflow.o)


 # ASAN Output
 <0> tag: 17 DW_TAG_compile_unit  name: "strstrnocase.c" FORM 0xe "DW_FORM_strp"
 <1> tag: 46 DW_TAG_subprogram  name: "is_strstrnocase" FORM 0xe "DW_FORM_strp"
 =================
 ==1666==ERROR: AddressSanitizer: heap-buffer-overflow on address 
   0xb5846db9 at p
 c 0x080b3a1b bp 0xbfa75d18 sp 0xbfa75d08
 READ of size 1 at 0xb5846db9 thread T0
    #0 0x80b3a1a in _dwarf_get_size_of_val /home/puzzor/libdwarf-code/
        libdwarf/dwarf_util.c:208
    #1 0x8056602 in _dwarf_next_die_info_ptr /home/puzzor/libdwarf-code/
        libdwarf/dwarf_die_deliv.c:1353
    #2 0x8057f4b in dwarf_child /home/puzzor/libdwarf-code/libdwarf/
       dwarf_die_de liv.c:1688
    #3 0x804b5fa in get_die_and_siblings simplereader.c:637
    #4 0x804b65c in get_die_and_siblings simplereader.c:643
    #5 0x804b3f3 in read_cu_list simplereader.c:611
    #6 0x804aeae in main simplereader.c:533
    #7 0xb6ffe275 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18275)
    #8 0x80491c0  (/home/puzzor/libdwarf-code/dwarfexample/simplereader+
         0x80491c 0)

 0xb5846db9 is located 0 bytes to the right of 249-byte region 
    [0xb5846cc0,0xb5846db9)
 allocated by thread T0 here:
    #0 0xb727fae4 in __interceptor_malloc (/usr/lib/i386-linux-gnu/libasan.so.
       3+ 0xc3ae4)
    #1 0xb71a9b98  (/usr/lib/i386-linux-gnu/libelf.so.1+0x9b98)
 
For the orignal bug report see
 https://sourceforge.net/p/libdwarf/bugs/5/
 
datefixed: 2016-11-16 references: regressiontests/puzzor/heap_buf_overflow.o gitfixid: 5dd64de047cd5ec479fb11fe7ff2692fd819e5e5 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201611-005 cve: datereported: 2016-11-11 reportedby: Agostino Sarubbo vulnerability: negation of -9223372036854775808 cannot be represented in type product: libdwarf description: With the right bit pattern in a signed leb number the signed leb decode would execute an unary minus with undefined effect. This is not known to generate an incorrect value, but it could, one supposes. datefixed: 2016-11-11 references: regressiontests/sarubbo-2/00050-libdwarf-negate-itself gitfixid: 4f19e1050cd8e9ddf2cb6caa061ff2fec4c9b5f9 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201611-004 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Heap overflow in dwarf_skim_forms() product: libdwarf description: If a non-terminated string in a DWARF5 macro section ends a section it can result in accessing memory not in the application. dwarf_macro5.c(in _dwarf_skim_forms()). datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00027-libdwarf-heapoverflow-_dwarf_skim_forms gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 endrec: id: DW201611-003 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Bad aranges length leads to overflow and bad pointer product: libdwarf description: in dwarf_arange.c(dwarf_get_aranges_list) an aranges header with corrupt data could, with an overflowing calculation, result in pointers to invalid or inappropriate memory being dereferenced. datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00026-libdwarf-heapoverflow-dwarf_get_aranges_list gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201611-002 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: heap overflow in get_attr_value product: libdwarf description: Libdwarf failed to check for a bogus length in dwarf_form.c (dwarf_formblock()) resulting in a pointer pointing outside of the intended memory region. Anything could happen in the subsequent use of the bogus pointer.
 0x61300000de1c is located 0 bytes to the right of 348-byte region 
 [0x61300000dcc0,0x61300000de1c) 
 allocated by thread T0 here: 
   #0 0x4c0ad8 in malloc /var/tmp/portage/sys-devel/llvm-3.8.1-
 r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52 
   #1 0x7f883cfc6206 in __libelf_set_rawdata_wrlock /tmp/portage/dev-
 libs/elfutils-0.166/work/elfutils-0.166/libelf/elf_getdata.c:318
 
datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00025-libdwarf-heapoverflow-get_attr_value gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201611-001 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Memory allocation failure in do_decompress_zlib product: libdwarf description: In decompressing a zlib compressed section if the decompressed section size is nonsense (too large) an attempted malloc will fail and could let an exception propagate to callers.
  ==27994==WARNING: AddressSanitizer failed to allocate 0x62696c2f7273752f
  bytes ==27994==AddressSanitizer's allocator is terminating the process
  instead of returning 0
  ...
   #6 0x4c0ab1 in malloc /var/tmp/portage/sys-devel/llvm-3.8.1-
r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:53
#7 0x5b582e in do_decompress_zlib
/tmp/dwarf-20161021/libdwarf/dwarf_init_finish.c:1085:12
   #8 0x5b582e in _dwarf_load_section
/tmp/dwarf-20161021/libdwarf/dwarf_init_finish.c:1159
   #9 0x5bb479 in dwarf_srcfiles
/tmp/dwarf-20161021/libdwarf/./dwarf_line.c:336:11
   #10 0x5145cd in print_one_die_section
 
datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00024-libdwarf-memalloc-do_decompress_zlib gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201609-004 cve: datereported: 20160917 reportedby: Puzzor vulnerability: libdwarf 20160613 Out-of-Bounds read product: libdwarf description: read line table program Out-of-Bounds read line_ptr in dwarf_line_table_reader_common.c:1433 Out-of-Bounds read See:
 https://bugzilla.redhat.com/show_bug.cgi?id=1377015
 https://sourceforge.net/p/libdwarf/bugs/4/
 
 # Address Sanitizer Output
 ==27763==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4603f84 at pc 0x8408ede bp 0xffff6518 sp 0xffff6510
 READ of size 1 at 0xf4603f84 thread T0
 #0 0x8408edd in read_line_table_program /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line_table_reader_common.c:1433
 #1 0x83f716c in _dwarf_internal_srclines /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line.c:690
 #2 0x841436c in dwarf_srclines_b /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line.c:944
 #3 0x81fbc28 in print_line_numbers_this_cu /home/puzzor/test-fuzzing/code/dwarfdump/print_lines.c:763
 #4 0x815c191 in print_one_die_section /home/puzzor/test-fuzzing/code/dwarfdump/print_die.c:850
 #5 0x81565c1 in print_infos /home/puzzor/test-fuzzing/code/dwarfdump
 
datefixed: 20160923 references: regressiontests/DW201609-004/poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-003 cve: CVE-2016-7410 datereported: 20160913 reportedby: https://marc.info/?l=oss-security&m=147391785920048&w=2 vulnerability: libdwarf 20160613 heap-buffer-overflow product: libdwarf description: With AddressSanitizer, we found a Heap-Buffer-overflow in the latest release version of dwarfdump. The crash output is as follows:
  See also:
  https://marc.info/?l=oss-security&m=147378394815872&w=2
  The testcase poc is from this web page.
  
  ==17411==ERROR: AddressSanitizer: heap-buffer-overflow on address
  0xf3808904 at pc 0x80a6f76 bp 0xffb95e78 sp 0xffb95a5c
  READ of size 4 at 0xf3808904 thread T0
  ==17411==WARNING: Trying to symbolize code, but external symbolizer is
  not initialized!
    #0 0x80a6f75 in __interceptor_memcpy ??:?
    #1 0x8426c3b in _dwarf_read_loc_section
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc.c:919
    #2 0x84250e2 in _dwarf_get_loclist_count
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc.c:970
    #3 0x8438826 in dwarf_get_loclist_c
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc2.c:551
    #4 0x81a1be8 in get_location_list
  /home/starlab/fuzzing/dwarf-20160613/dwarfdump/print_die.c:3523
    #5 0x816e1a2 in print_attribute
  
_dwarf_get_loclist_header_start() is not cautious about values in the header being absurdly large. Unclear as yet if this is the problem but it is a potential problem (fixed for next release).
  Address Sanitizer in gcc reproduces the report.
  In _dwarf_read_loc_section() the simple calculation of
  loc_section_end was wrong, so end-of section was
  incorrect for the local reads.
  With that fixed we get DW_DLE_READ_LITTLEENDIAN_ERROR when
  libdwarf attempts to read off end of section.
  
datefixed: 20160923 references: regressiontests/DW201609-003/poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-002 cve: CVE-2016-7511 datereported: 20160918 reportedby: Shi Ji (@Puzzor) vulnerability: libdwarf 20160613 Integer Overflow product: libdwarf description: In dwarf_get_size_of_val() with fuzzed DWARF data we get a SEGV.
  See
  https://sourceforge.net/p/libdwarf/bugs/3/
  
  ==6825== ERROR: AddressSanitizer: SEGV on unknown address 0x0583903c (pc 0xb61f1a98 sp 0xbfa388b4 bp 0xbfa38d08 T0)
  AddressSanitizer can not provide additional info.
  #1 0xb61e3c0b (/usr/lib/i386-linux-gnu/libasan.so.0+0xdc0b)
  #2 0x80a21b1 in _dwarf_get_size_of_val /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_util.c:210
  #3 0x8054214 in _dwarf_next_die_info_ptr /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1340
  #4 0x80557a5 in dwarf_child /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1640
  #5 0x804b23f in get_die_and_siblings /home/fuzzing/fuzzing/dwarf-20160613/dwarfexample/./simplereader.c:573
  
_dwarf_make_CU_Context() is insufficiently cautious about the length of a CU being absurd. Unclear as yet if this is the problem but it is a problem and is fixed for next release. datefixed: 20160923 references: regressiontests/DW201609-002/DW201609-002-poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-001 cve: datereported: 20160916 reportedby: STARLAB https://sourceforge.net/p/libdwarf/bugs/2/ vulnerability: libdwarf 20160613 die_info_ptr in dwarf_die_deliv.c: 1533 Out-Of_bounds product: libdwarf description: At line 1533 of dwarf_die_deliv.c a pointer dereference is done with a pointer pointing past the end of the CU data.
 see
 https://sourceforge.net/p/libdwarf/bugs/2/
 
 ==8054==ERROR: AddressSanitizer: heap-buffer-overflow on 
    address 0xf4c027ab at pc 0x819e4a4 bp 0xff88eb38 sp 0xff88eb30
 READ of size 1 at 0xf4c027ab thread T0
 #0 0x819e4a3 in dwarf_siblingof_b /home/starlab/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1533
 #1 0x8116201 in print_die_and_children_internal /home/starlab/fuzzing/dwarf-20160613/dwarfdump/print_die.c:1157
 Bug report on sourceforge.net bug list for libdwarf.
 The bad pointer dereference is due to libdwarf 
 not noticing that the DWARF in that file is corrupt.
 In addtion
 The code was not noticing that it could dereference
 a pointer that pointed out of bounds in the end-sibling-list
 loop. 
 
 The example from the bug report (DW201609-001-poc) has
 the same problem.
 dwarfdump now reports DW_DLE_SIBLING_LIST_IMPROPER
 on both test2.o and DW201609-001-poc.
 
datefixed: 20160917 references: regressiontests/DW201609-001/test2.o regressiontests/DW201609-001/DW201609-001-poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-019 cve: CVE-2016-5028 datereported: 20160523 reportedby: Yue Liu vulnerability: Null dereference in print_frame_inst_bytes (dwarfdump) product: libdwarf description: The null dereference is due to a corrupted object file. Libdwarf was not dealing with empty (bss-like) sections since it really did not expect to see such in sections it reads! Now libdwarf catches the object error so dwarfdump sees the section as empty (as indeed it is!). datefixed: 20160523 references: regressiontests/liu/NULLdeference0522c.elf gitfixid: a55b958926cc67f89a512ed30bb5a22b0adb10f4 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-018 cve: CVE-2016-5029 datereported: 20160522 reportedby: Yue Liu vulnerability: Null dereference in create_fullest_file_path(). product: libdwarf description: The null dereference in create_fullest_file_path() causes a crash. This is due to corrupted dwarf and the fix detects this corruption and if that null string pointer happens undetected a static string is substituted so readers can notice the situation.
  202             }
 203             if (dirno > 0 && fe->fi_dir_index > 0) {
 204                 inc_dir_name = (char *) 
                         line_context->lc_include_directories[
 205                     fe->fi_dir_index - 1];
 206                 incdirnamelen = strlen(inc_dir_name);  <- $pc
 207             }
 208             full_name = (char *) _dwarf_get_alloc(dbg, 

 #0  create_fullest_file_path (dbg=,
 fe=0x68d510, line_context=0x68c4f0, name_ptr_out=, error=0x7fffffffe2b8) at ./dwarf_line.c:206

 #1  0x00007ffff7b6d3f9 in dwarf_filename (context=, fileno_in=, ret_filename=0x7fffffffe280,
 error=0x7fffffffe2b8) at ./dwarf_line.c:1418

 #2  dwarf_linesrc (line=,
 ret_linesrc=, error=) at
 ./dwarf_line.c:1436
 
datefixed: 20160522 references: regressiontests/liu/NULLdereference0522.elf gitfixid: acae971371daa23a19358bc62204007d258fbc5e tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-017 cve: CVE-2016-5030 datereported: 20160519 reportedby: Yue Liu vulnerability: Null dereference bug in _dwarf_calculate_info_section_end_ptr(). product: libdwarf description: NULL dereference bug in _dwarf_calculate_info_section_end_ptr().
 1742         Dwarf_Off off2 = 0;
 1743         Dwarf_Small *dataptr = 0;
 1744     
 1745         dbg = context->cc_dbg;
 1746         dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:                 <- $pc
 1747             dbg->de_debug_types.dss_data;
 1748         off2 = context->cc_debug_offset;
 1749         info_start = dataptr + off2;
 1750         info_end = info_start + context->cc_length +
 
 #0  _dwarf_calculate_info_section_end_ptr
 (context=context@entry=0x0) at dwarf_query.c:1746
 
 #1  0x00002aaaaace307d in
 _dwarf_extract_string_offset_via_str_offsets
 (dbg=dbg@entry=0x655a70, info_data_ptr=0x6629f0
 "", attrnum=attrnum@entry=121,
 attrform=attrform@entry=26, cu_context=0x0,
 str_sect_offset_out=str_sect_offset_out@entry=0x7fffffffd718,
 error=error@entry=0x7fffffffd878) at dwarf_form.c:1099
 
 #2  0x00002aaaaacf4ed7 in dwarf_get_macro_defundef
 (macro_context=macro_context@entry=0x65b790,
 op_number=op_number@entry=1,
 line_number=line_number@entry=0x7fffffffd858,
 index=index@entry=0x7fffffffd860,
 offset=offset@entry=0x7fffffffd868,
 forms_count=forms_count@entry=0x7fffffffd7ce,
 macro_string=macro_string@entry=0x7fffffffd870,
 error=error@entry=0x7fffffffd878) at dwarf_macro5.c:557
 
 ------
 
 _dwarf_calculate_info_section_end_ptr (context=context@entry=0x0) at 
   dwarf_query.c:1746
 1746        dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:
 gef> p/x $rdi
 $4 = 0x0
 
datefixed: 20160522 references: regressiontests/liu/NULLdereference0519.elf gitfixid: 6fa3f710ee6f21bba7966b963033a91d77c952bd tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-016 cve: datereported: 20160519 reportedby: Yue Liu vulnerability: Invalid dwarf leads to dwarfdump crash in print_frame_inst_bytes. product: dwarfdump description: Corrupted dwarf crashes dwarfdump
 1297         }
 1298         len = len_in;
 1299         endpoint = instp + len;
 1300         for (; len > 0;) {
 1301             unsigned char ibyte = *instp;           <- $pc
 1302             int top = ibyte & 0xc0;
 1303             int bottom = ibyte & 0x3f;
 1304             int delta = 0;
 1305             int reg = 0;

 #0  print_frame_inst_bytes (dbg=dbg@entry=0x655ca0,
 cie_init_inst=, len_in=,
 data_alignment_factor=-4, code_alignment_factor=4,
 addr_size=addr_size@entry=4, offset_size=4, version=3,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:1301

 #1  0x000000000041b70c in print_one_cie
 (dbg=dbg@entry=0x655ca0, cie=,
 cie_index=cie_index@entry=2, address_size=,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:1161

 #2  0x000000000041cf52 in print_frames (dbg=0x655ca0,
 print_debug_frame=print_debug_frame@entry=1, print_eh_frame=0,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:2229

 gef> p/x $r13
 $1 = 0x4bcad8
 gef> p/x *$r13
 Cannot access memory at address 0x4bcad8
 
datefixed: 20160522 references: regressiontests/liu/OOB_READ0519.elf gitfixid: 6fa3f710ee6f21bba7966b963033a91d77c952bd tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-015 cve: CVE-2016-5031 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in print_frame_inst_bytes() product: libdwarf description: Test object shows an invalid read in print_frame_inst_bytes().
 1294         for (; len > 0;) {
 1295             unsigned char ibyte = *instp;           <- $pc
 1296             int top = ibyte & 0xc0;

 #0  print_frame_inst_bytes (dbg=dbg@entry=0x654c80, 
    cie_init_inst=, len=503715, data_alignment_factor=-4, 
    code_alignment_factor=1, addr_size=addr_size@entry=4, offset_size=4, 
    version=3, config_data=config_data@entry=0x63bda0 
    ) at print_frames.c:1295
 #1  0x000000000041b64c in print_one_cie (dbg=dbg@entry=0x654c80, 
    cie=, cie_index=cie_index@entry=1, 
    address_size=, config_data=
    config_data@entry=0x63bda0 ) at print_frames.c:1161
 #2  0x000000000041ce92 in print_frames (dbg=0x654c80, 
    print_debug_frame=print_debug_frame@entry=1, print_eh_frame=0, 
    config_data=config_data@entry=0x63bda0 ) 
    at print_frames.c:2209

 gef> x/10x $r13
 0x5e7981:       Cannot access memory at address 0x5e7981
 gef> p/x $r13
 $14 = 0x5e7981
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_03.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-014 cve: CVE-2016-5032 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in dwarf_get_xu_hash_entry() product: libdwarf description: Test object shows an invalid read in dwarf_get _xu_hash_entry, lin 211.
 #0  dwarf_get_xu_hash_entry (xuhdr=xuhdr@entry=0x657360, 
    index=index@entry=2897626028, hash_value=
    hash_value@entry=0x7fffffffd5b0, 
    index_to_sections=index_to_sections@entry=0x7fffffffd5a8, 
    err=err@entry=0x7fffffffdb08) at dwarf_xu_index.c:211
 #1  0x00002aaaaacfd05e in _dwarf_search_fission_for_key (
    dbg=0x654a50, error=0x7fffffffdb08, percu_index_out=,
    key_in=0x7fffffffd670, xuhdr=0x657360) at dwarf_xu_index.c:363
 #2  dwarf_get_debugfission_for_key (dbg=dbg@entry=0x654a50, 
    key=key@entry=0x7fffffffd670, key_type=key_type@entry=0x2aaaaad15e2a 
    "tu", percu_out=percu_out@entry=0x65a830, 
    error=error@entry=0x7fffffffdb08) at dwarf_xu_index.c:577
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_02.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-013 cve: CVE-2016-5033 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in print_exprloc_content product: libdwarf description: Test object shows an invalid write in print_exprloc_content.
 #0  print_exprloc_content (dbg=dbg@entry=0x654ea0, 
    die=die@entry=0x65b110, attrib=attrib@entry=0x65b590, 
    esbp=esbp@entry=0x7fffffffcef0, showhextoo=1) at print_die.c:4182
 #1  0x0000000000412fb1 in get_attr_value (dbg=dbg@entry=0x654ea0, 
    tag=, die=die@entry=0x65b110, 
    dieprint_cu_goffset=dieprint_cu_goffset@entry=11, 
    attrib=attrib@entry=0x65b590, srcfiles=srcfiles@entry=0x0, 
    cnt=cnt@entry=0, esbp=esbp@entry=0x7fffffffcef0, show_form=0, 
    local_verbose=0) at print_die.c:4972
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_01.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-012 cve: CVE-2016-5034 datereported: 20160513 reportedby: Yue Liu vulnerability: OOB write. From relocation records product: libdwarf description: Test object shows an invalid write in dwarf_elf_access.c (when doing the relocations). Adding the relocation value to anything overflowed and disguised the bad relocation record. With a 32bit kernel build the test could show a double-free and coredump due to the unchecked invalid writes from relocations. datefixed: 20160517 references: regressiontests/liu/HeapOverflow0513.elf gitfixid: 10ca310f64368dc083efacac87732c02ef560a92 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-011 cve: CVE-2016-5035 datereported: 20160506 reportedby: Yue Liu vulnerability: OOB read bug in _dwarf_read_line_table_header product: libdwarf description: Test object shows null dereference at line 62 of dwarf_line_table_reader.c. Frame code and linetable code was not noticing data corruption. datefixed: 20160512 references: regressiontests/liu/OOB_read4.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-010 cve: CVE-2016-5036 datereported: 20160506 reportedby: Yue Liu vulnerability: OOB read bug in dump_block product: libdwarf description: Test object shows null dereverence at line 186 of dump_block() in print_sections.c Frame code was not noticing frame data corruption. datefixed: 20160512 references: regressiontests/liu/OOB_read3.elf regressiontests/liu/OOB_read3_02.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-009 cve: CVE-2016-5037 datereported: 20160505 reportedby: Yue Liu vulnerability: NULL dereference in _dwarf_load_section product: libdwarf description: Test object shows null dereverence at line 1010 if(!strncmp("ZLIB",(const char *)src,4)) { in dwarf_init_finish.c The zlib code was not checking for a corrupted length-value. datefixed: 20160506 references: regressiontests/liu/NULLderefer0505_01.elf gitfixid: b6ec2dfd850929821626ea63fb0a752076a3c08a tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-008 cve: CVE-2016-5038 datereported: 20160505 reportedby: Yue Liu vulnerability: OOB read in dwarf_get_macro_startend_file() product: libdwarf description: Test object shows out of bound read. OOB at: line 772 *src_file_name = macro_context->mc_srcfiles[trueindex]; in dwarf_macro5.c A string offset into .debug_str is outside the bounds of the .debug_str section. datefixed: 20160512 references: regressiontests/liu/OOB0505_02.elf regressiontests/liu/OOB0505_02_02.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-007 cve: CVE-2016-5039 datereported: 20160505 reportedby: Yue Liu vulnerability: OOB read bug in get_attr_value() product: libdwarf description: Test object shows out of bound read. Object had data all-bits-on so the existing length check did not work due to wraparound. Added a check not susceptible to that error (DW_DLE_FORM_BLOCK_LENGTH_ERROR). datefixed: 20160506 references: regressiontests/liu/OOB0505_01.elf gitfixid: eb1472afac95031d0c9dd8c11d527b865fe7deb8 gittag: 20160507 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-006 cve: datereported: 20160505 reportedby: Yue Liu vulnerability: Two Heap-Overflow bug product: libdwarf description: Two test objects showing a heap overflow in libdwarf when using dwarfdump. It seems that these were fixed by the previous git update. Neither gdb nor valgrind find any errors when building with yesterday's commit. datefixed: 20160504 references: regressiontests/liu/free_invalid_address.elf regressiontests/liu/heapoverflow01b.elf gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-001 cve: CVE-2016-5044 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a duplicate free() in libdwarf and the calling application will crash. product: libdwarf description: In file dwarf_elf_access.c:1071
 WRITE_UNALIGNED(dbg,target_section + offset,
     &outval,sizeof(outval),reloc_size);
 
A crafted ELF file may lead to a large offset value, which bigger than the size of target_section heap chunk, then this WRITE_UNALIGNED() function will write the value of &outval out of the heap chunk. offset is a 64bit unsigned int value, so this is more than a heap overflow bug, but also a Out-of-Bound write bug. So WRITE_UNALIGNED() need more strictly checking to prevent this. datefixed: 20160504 references: regressiontests/liu/heapoverflow01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332141
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f gittag: 20160507 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-002 cve: CVE-2016-5043 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a read outside the bounds of in memory data so the calling application can crash. product: libdwarf description: Out of bound read bug in libdwarf git code. dwarf_dealloc() did not check the Dwarf_Ptr space argument before using it. This will lead to a out-of-bound read bug.
 backtrace:
 #0  dwarf_dealloc (dbg=dbg@entry=0x655f30, space=0xa0,
 alloc_type=alloc_type@entry=1) at dwarf_alloc.c:477
 #1  0x00002aaaaacf3296 in dealloc_srcfiles
 (dbg=0x655f30, srcfiles=0x66b8f0, srcfiles_count=17) at
 dwarf_macro5.c:1025 #2  0x00002aaaaacf50e6 in dealloc_srcfiles
 (srcfiles_count=, srcfiles=,
 dbg=) at dwarf_macro5.c:1021 -----

 gef> p &r->rd_dbg
 $14 = (void **) 0x90
 
datefixed: 20160504 references: regressiontests/liu/outofbound01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332144
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-003 cve: CVE-2016-5042 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in an infinite loop that eventually crashes the application. product: libdwarf description: In dwarf_get_aranges_list() an invalid count will iterate, reading from memory addresses that increase till it all fails. datefixed: 20160504 references: regressiontests/liu/infiniteloop.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332145
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-004 cve: CVE-2016-5041 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a null dereference reading debugging information entries which crashes the application. product: libdwarf description: If no DW_AT_name is present in a debugging information entry using DWARF5 macros a null dereference in dwarf_macro5.c will crash the application. datefixed: 20160504 references: regressiontests/liu/null01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332148
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-005 cve: CVE-2016-5040 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in reading a compilation unit header that crashes the application. product: libdwarf description: If the data read for a compilation unit header contains a too large length value the library will read outside of its bounds and crash the application. datefixed: 20160504 references: regressiontests/liu/null02.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332149
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: libdwarf-20210528/bugxml/data.template0000664000175000017500000000016413644370703014450 00000000000000id: cve: datereported: reportedby: vulnerability: product: description: datefixed: references: gitfixid: endrec: libdwarf-20210528/test-driver0000755000175000017500000001104214054252021012661 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libdwarf-20210528/config.h.in0000664000175000017500000001260014054252020012510 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Set to 1 as we are building with libelf */ #undef DWARF_WITH_LIBELF /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define 1 if including a custom libelf library */ #undef HAVE_CUSTOM_LIBELF /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Set to 1 if the elf64_getehdr function is in libelf. */ #undef HAVE_ELF64_GETEHDR /* Set to 1 if the elf64_getshdr function is in libelf. */ #undef HAVE_ELF64_GETSHDR /* Set to 1 if Elf64_Rela defined in elf.h. */ #undef HAVE_ELF64_RELA /* Set to 1 if Elf64_Rel structure as r_info field. */ #undef HAVE_ELF64_R_INFO /* Set to 1 if Elf64_Sym defined in elf.h. */ #undef HAVE_ELF64_SYM /* Define to 1 if you have the header file. */ #undef HAVE_ELFACCESS_H /* Define to 1 if you have the header file. */ #undef HAVE_ELF_H /* Define 1 if want some specialized allocation counting */ #undef HAVE_GLOBAL_ALLOC_SUMS /* Define to 1 if the system has the type `intptr_t'. */ #undef HAVE_INTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBELF_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBELF_LIBELF_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define 1 if need nonstandard printf format for 64bit */ #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT /* Set to 1 if old frame columns are enabled. */ #undef HAVE_OLD_FRAME_CFA_COL /* Set to 1 if regex is usable. */ #undef HAVE_REGEX /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H /* Define to 1 if you have the header file. */ #undef HAVE_SGIDEFS_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_386_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_AMD64_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_SPARC_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IA64_ELF_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Set to 1 if __attribute__ ((unused)) is available. */ #undef HAVE_UNUSED_ATTRIBUTE /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define 1 if want to allow Windows full path detection */ #undef HAVE_WINDOWS_PATH /* Set to 1 if zlib decompression is available. */ #undef HAVE_ZLIB /* Set to 1 if zlib.h header file is available. */ #undef HAVE_ZLIB_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Set to 1 if bigendian build */ #undef WORDS_BIGENDIAN /* Define to the type of a signed integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef intptr_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t libdwarf-20210528/missing0000755000175000017500000001533614054252020012073 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: